diff --git a/.github/workflows/modoboa.yml b/.github/workflows/modoboa.yml index 867480493..8f45f6e61 100644 --- a/.github/workflows/modoboa.yml +++ b/.github/workflows/modoboa.yml @@ -180,9 +180,9 @@ jobs: run: | sudo apt-get install gettext cd frontend - nvm install 14 + nvm install 20 yarn install - make translations + yarn gettext:compile yarn build cd .. - name: Build packages diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..ee04d8d38 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,29 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: +- repo: local + hooks: + - id: pylint + name: pylint + entry: pylint + language: system + types: [python] + args: + [ + "-rn", + "-sn", + "--fail-under=5" + ] +- repo: https://github.com/psf/black + rev: '24.2.0' + hooks: + - id: black +- repo: https://github.com/pre-commit/mirrors-eslint + rev: 'v9.0.0-beta.0' + hooks: + - id: eslint + files: \.(js|vue)$ + types: [file] + additional_dependencies: + - eslint + - eslint-plugin-vue diff --git a/dev-requirements.txt b/dev-requirements.txt index 06d73f33c..05818ca08 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,2 +1,5 @@ django-bower django-debug-toolbar +pre-commit +black +pylint diff --git a/doc/conf.py b/doc/conf.py index 10b565e31..19b41d2d2 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -19,9 +19,10 @@ import sys class Mock(MagicMock): @classmethod def __getattr__(cls, name): - return MagicMock() + return MagicMock() -MOCK_MODULES = ['rrdtool'] + +MOCK_MODULES = ["rrdtool"] sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES) # If extensions (or modules to document with autodoc) are in another directory, @@ -196,8 +197,7 @@ htmlhelp_basename = "Modoboadoc" # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ("index", "Modoboa.tex", "Modoboa Documentation", - "Antoine Nguyen", "manual"), + ("index", "Modoboa.tex", "Modoboa Documentation", "Antoine Nguyen", "manual"), ] # The name of an image file (relative to this directory) to place at the top of @@ -228,10 +228,7 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ("index", "modoboa", "Modoboa Documentation", - ["Antoine Nguyen"], 1) -] +man_pages = [("index", "modoboa", "Modoboa Documentation", ["Antoine Nguyen"], 1)] intersphinx_mapping = { "amavis": ("http://modoboa-amavis.readthedocs.org/en/latest/", None) diff --git a/docker-compose.yml b/docker-compose.yml index d5a21a4c6..649b68a76 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -49,10 +49,10 @@ services: context: . dockerfile: docker/Dockerfile.front.dev ports: - - 8080:8080 + - 3000:3000 volumes: - ./frontend/:/home/node/ - command: "yarn serve" + command: "yarn dev --host" environment: DOCKER: "yes" depends_on: diff --git a/docker/Dockerfile.front.dev b/docker/Dockerfile.front.dev index 5e335639f..6d3a0b90b 100644 --- a/docker/Dockerfile.front.dev +++ b/docker/Dockerfile.front.dev @@ -1,4 +1,4 @@ -FROM node:16.10-alpine +FROM node:20.11-alpine ENV HOME=/home/node/ diff --git a/frontend/.browserslistrc b/frontend/.browserslistrc index 214388fe4..dc3bc09a2 100644 --- a/frontend/.browserslistrc +++ b/frontend/.browserslistrc @@ -1,3 +1,4 @@ > 1% last 2 versions not dead +not ie 11 diff --git a/frontend/.gitignore b/frontend/.eslintignore similarity index 99% rename from frontend/.gitignore rename to frontend/.eslintignore index 403adbc1e..11f5d7142 100644 --- a/frontend/.gitignore +++ b/frontend/.eslintignore @@ -2,7 +2,6 @@ node_modules /dist - # local env files .env.local .env.*.local diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index 2be9576ed..992cd90ae 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -1,32 +1,17 @@ module.exports = { root: true, env: { - node: true - }, - extends: [ - 'plugin:vue/essential', - '@vue/standard' - ], - parserOptions: { - parser: '@babel/eslint-parser' + node: true, }, + extends: ['plugin:vue/vue3-recommended', 'eslint:recommended', 'prettier'], rules: { - 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', - 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', - 'vue/valid-v-slot': ['error', { - allowModifiers: true - }], - 'vue/multi-word-component-names': 'off' + 'vue/component-name-in-template-casing': [ + 'error', + 'PascalCase', + { + registeredComponentsOnly: true, + ignores: [], + }, + ], }, - overrides: [ - { - files: [ - '**/__tests__/*.{j,t}s?(x)', - '**/tests/unit/**/*.spec.{j,t}s?(x)' - ], - env: { - mocha: true - } - } - ] } diff --git a/frontend/.prettierrc.json b/frontend/.prettierrc.json new file mode 100644 index 000000000..9d313aa4a --- /dev/null +++ b/frontend/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "semi": false, + "trailingComma": "es5", + "singleQuote": true +} diff --git a/frontend/.yarnrc b/frontend/.yarnrc deleted file mode 100644 index 199188096..000000000 --- a/frontend/.yarnrc +++ /dev/null @@ -1,5 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -lastUpdateCheck 1676556135834 diff --git a/frontend/Makefile b/frontend/Makefile deleted file mode 100644 index 1e98a11ff..000000000 --- a/frontend/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# On OSX the PATH variable isn't exported unless "SHELL" is also set, see: http://stackoverflow.com/a/25506676 -SHELL = /bin/bash -NODE_BINDIR = ./node_modules/.bin -export PATH := $(NODE_BINDIR):$(PATH) - -INPUT_DIR = src -# Where to write the files generated by this makefile. -OUTPUT_DIR = . - -# Available locales for the app. -LOCALES = br cs de el es en fi fr it ja nl pt pt-br pl po ru sv tr zh-hant - -# Name of the generated .po files for each available locale. -LOCALE_FILES ?= $(patsubst %,$(OUTPUT_DIR)/locale/%/LC_MESSAGES/app.po,$(LOCALES)) - -GETTEXT_HTML_SOURCES = $(shell find $(INPUT_DIR) -name '*.vue' -o -name '*.html' 2> /dev/null) -GETTEXT_VUE_SOURCES = $(shell find $(INPUT_DIR) -name '*.vue') -GETTEXT_JS_SOURCES = $(shell find $(INPUT_DIR) -name '*.vue' -o -name '*.js') - -# Makefile Targets -.PHONY: clean makemessages translations - -clean: - rm -f /tmp/template.pot $(INPUT_DIR)/translations.json - -makemessages: /tmp/template.pot - -translations: ./$(INPUT_DIR)/translations.json - -# Create a main .pot template, then generate .po files for each available language. -# Thanx to Systematic: https://github.com/Polyconseil/systematic/blob/866d5a/mk/main.mk#L167-L183 -/tmp/template.pot: $(GETTEXT_HTML_SOURCES) -# `dir` is a Makefile built-in expansion function which extracts the directory-part of `$@`. -# `$@` is a Makefile automatic variable: the file name of the target of the rule. -# => `mkdir -p /tmp/` - mkdir -p $(dir $@) - which gettext-extract -# Extract gettext strings from templates files and create a POT dictionary template. - gettext-extract --quiet --output $@ $(GETTEXT_HTML_SOURCES) - gettext-extract --startDelimiter "" --endDelimiter "" --quiet --output $@ $(GETTEXT_VUE_SOURCES) -# Extract gettext strings from JavaScript files. - xgettext --language=JavaScript --keyword=npgettext:1c,2,3 \ - --from-code=utf-8 --join-existing --no-wrap \ - --package-name=$(shell node -e "console.log(require('./package.json').name);") \ - --package-version=$(shell node -e "console.log(require('./package.json').version);") \ - --output $@ $(GETTEXT_JS_SOURCES) -# Generate .po files for each available language. - @for lang in $(LOCALES); do \ - export PO_FILE=$(OUTPUT_DIR)/locale/$$lang/LC_MESSAGES/app.po; \ - echo "msgmerge --backup=off --update $$PO_FILE $@"; \ - mkdir -p $$(dirname $$PO_FILE); \ - [ -f $$PO_FILE ] && msgmerge --backup=off --lang=$$lang --update $$PO_FILE $@ || msginit --no-translator --locale=$$lang --input=$@ --output-file=$$PO_FILE; \ - msgattrib --no-wrap --no-obsolete -o $$PO_FILE $$PO_FILE; \ - done; - -$(INPUT_DIR)/translations.json: clean /tmp/template.pot - gettext-compile --output $@ $(LOCALE_FILES) diff --git a/frontend/README.md b/frontend/README.md index f9842600d..f0924d045 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -1,29 +1,69 @@ -# frontend +# base ## Project setup + ``` -yarn install +# yarn +yarn + +# npm +npm install + +# pnpm +pnpm install + +# pnpm +bun install ``` ### Compiles and hot-reloads for development + ``` -yarn serve +# yarn +yarn dev + +# npm +npm run dev + +# pnpm +pnpm dev + +# bun +bun run dev ``` ### Compiles and minifies for production -``` -yarn build -``` -### Run your unit tests ``` -yarn test:unit +# yarn +yarn build + +# npm +npm run build + +# pnpm +pnpm build + +# bun +bun run build ``` ### Lints and fixes files + ``` +# yarn yarn lint + +# npm +npm run lint + +# pnpm +pnpm lint + +# bun +bun run lint ``` ### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). + +See [Configuration Reference](https://vitejs.dev/config/). diff --git a/frontend/babel.config.js b/frontend/babel.config.js deleted file mode 100644 index e9558405f..000000000 --- a/frontend/babel.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - presets: [ - '@vue/cli-plugin-babel/preset' - ] -} diff --git a/frontend/gettext.config.js b/frontend/gettext.config.js new file mode 100644 index 000000000..3ea2ba7cb --- /dev/null +++ b/frontend/gettext.config.js @@ -0,0 +1,24 @@ +module.exports = { + output: { + path: './src/locale', + locales: [ + 'en', + 'br', + 'cs', + 'de', + 'el', + 'es', + 'fi', + 'fr', + 'it', + 'ja', + 'nl', + 'pl', + 'pt', + 'ru', + 'sv', + 'tr', + 'zh', + ], + }, +} diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 000000000..a11602a38 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,14 @@ + + + + + + + Welcome to Modoboa + + + +
+ + + diff --git a/frontend/jsconfig.json b/frontend/jsconfig.json new file mode 100644 index 000000000..b6bd4c8dc --- /dev/null +++ b/frontend/jsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "esnext", + "baseUrl": "./", + "moduleResolution": "node", + "paths": { + "@/*": ["src/*"] + }, + "lib": ["esnext", "dom", "dom.iterable", "scripthost"] + } +} diff --git a/frontend/locale/br/LC_MESSAGES/app.po b/frontend/locale/br/LC_MESSAGES/app.po deleted file mode 100644 index 8f40c8ed8..000000000 --- a/frontend/locale/br/LC_MESSAGES/app.po +++ /dev/null @@ -1,2144 +0,0 @@ -# Breton translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:17+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: br\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "(lazhet)" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "Kont" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "Kont krouet" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -#, fuzzy -msgid "Account not found!" -msgstr "Kont krouet" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "Kont hizivaet" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "Oberioù" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "Ouzhpennañ" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "Chomlec'h" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "Domanioù meret" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "Merourien" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "Alias" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "Alias krouet" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "Aliasoù" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Aliases:" -msgstr "Aliasoù" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "API" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "API moned" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -#, fuzzy -msgid "Associated domains" -msgstr "Domanioù meret" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "O vezañ anavezet" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "Stumm Ereet/anvet" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "Cheñch ger-tremen" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "Kochit an dibarzh ma ne vez ket kriptet ar gerioù-tremen endalc'het en ho restr" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "Serriñ" - -#: src/components/alarms/AlarmList.vue:84 -#, fuzzy -msgid "Close alarm" -msgstr "Serriñ" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "Serriñ" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "Kadarnadur" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "Kenderc'hel war ar fazi" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "Krouit ur merour domani" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "Krouiñ ur voest-posteloù evit ar merour." - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "Krouiñ aliasoù" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "Deiziad krouidigezh" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "Kriptañ ar gerioù-tremen" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "Taolenn-stur" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "Kota boest-posteloù dre-ziouer" - -#: src/components/domains/DomainLimitationsForm.vue:6 -msgid "Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "Deskrivadur" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "Lazhet" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "Alc'hwez DKIM" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "DNS" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "Statud DNS" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "Domani" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "Merour an domani" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "Domani krouet" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "Domanioù" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "Chomlec'h postel" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -#, fuzzy -msgid "Email providers" -msgstr "Chomlec'h postel" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "Enaouiñ ar sinadur DKIM" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "Enaouiñ ar gwiriañ DNS" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "Enaouet" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "Diamzeriet da" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "C'hwitet" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "Ger-tremen ankouaeet?" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "Treuzkas" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "Treuzkas kemennadennoù ha stokiñ eiladennoù e-barzh ar voest-posteloù lec'hel" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "Treuzkas hizivaet" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -#, fuzzy -msgid "Forwarded" -msgstr "Treuzkas" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "Anv klok" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -#, fuzzy -msgid "Fully aligned" -msgstr "Linennet penn-da-benn" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "Hollek" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "Genel ur ger-tremen dre-zegouezh evit ar merour." - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "Identelezhioù" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -#, fuzzy -msgid "Identities deleted" -msgstr "Identelezhioù" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "Emporzhiañ" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "Emporzhiañ domanioù" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "Emporzhiañ identelezhioù" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "Titouroù" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "Stumm staliet" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "Mirout eiladennoù lec'hel" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "Deiziad aozañ diwezhañ" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "Live" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "Enroller" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "Digevreañ" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "Boest-posteloù" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -#, fuzzy -msgid "Mailbox aliases:" -msgstr "Boest-posteloù" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Mailbox:" -msgstr "Boest-posteloù" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "Boest-posteloù" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "Implij" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -#, fuzzy -msgid "Migration deleted" -msgstr "Deiziad krouidigezh" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -#, fuzzy -msgid "Migrations" -msgstr "Kadarnadur" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "Aozet" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "Anv" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "Kont nevez" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "Alias nevez" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "Domani nevez" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "Da-heul" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "Neket ganet" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -#, fuzzy -msgid "Old account" -msgstr "Kont nevez" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "Hegerz ez eus un hizivadenn pe muioc'h" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "Dibarzhioù" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "Linennet dre an hanter" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "Ger-tremen" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "Niverenn bellgomz" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "Profil" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "Profil hizivaet" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -#, fuzzy -msgid "Provider created" -msgstr "Domani krouet" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -#, fuzzy -msgid "Provider updated" -msgstr "Profil hizivaet" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "Kota" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "Kota evit ar voest-posteloù-mañ. Gellout a ra bezañ ezpleget e Ko, Mo (diouer) pe Go c'hoazh. Termeniñ un dalvoudegezh ispisial pe implijit talvoudegezh an domani. Laoskit goullo evit termeniñ un dalvoudegezh divevenn (berzet evit ar verourien zomani)." - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Kota rannet kenetre 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/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "Chomlec'h dre-zegouezh" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "Ger-tremen dre-zegouezh" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "Resever(ien)" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "Reseverien" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "Derc'hel soñj ac'hanon" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "Eilgwerzher" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "Mammennoù" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "Implij mammennoù" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "Rol" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "Enrollañ" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "Klask" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "Eil chomlec'h postel" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -#, fuzzy -msgid "Send only account" -msgstr "Kont nevez" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "Chomlec'hioù ar c'haser" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "Skejer" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "Arventennoù" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "Diskouez an alc'hwez" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "Implijer diazez" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -#, fuzzy -msgid "Statistics" -msgstr "Statud" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "Statud" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "Kas" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "Berradenn" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "Dreist-merour" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "Balizoù" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "Hollad" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "Treuzdougen" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -#, fuzzy -msgid "Trusted sources" -msgstr "Mammennoù fizius" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "Doare" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "Dizanv" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "Mammennoù dizanv/Gourdrouzioù" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "divevennet" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -#, fuzzy -msgid "Unlimited" -msgstr "divevennet" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "Hizivaat" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "Hizivaet" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "Implijout un dalvoudegezh domani dre-ziouer" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "Anv implier" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "Degemer mat e-barzh Modoboa" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "Gant ur voest-posteloù" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "Disklotadurioù gerioù-tremen" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "Ar vaezienn-mañ a zo rekiset" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/cs/LC_MESSAGES/app.po b/frontend/locale/cs/LC_MESSAGES/app.po deleted file mode 100644 index 4f1c6e5bf..000000000 --- a/frontend/locale/cs/LC_MESSAGES/app.po +++ /dev/null @@ -1,2126 +0,0 @@ -# Czech translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: cs\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==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Aliases:" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Mailbox:" -msgstr "" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -msgid "Migrations" -msgstr "" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -msgid "Provider created" -msgstr "" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -msgid "Provider updated" -msgstr "" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -msgid "Send only account" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -msgid "Unlimited" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/de/LC_MESSAGES/app.po b/frontend/locale/de/LC_MESSAGES/app.po deleted file mode 100644 index 2850ed170..000000000 --- a/frontend/locale/de/LC_MESSAGES/app.po +++ /dev/null @@ -1,2150 +0,0 @@ -# German translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:17+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "(deaktiviert)" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "Konto" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "Konto erstellt" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -#, fuzzy -msgid "Account not found!" -msgstr "Konto erstellt" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "Konto aktualisiert" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "Aktionen" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "Hinzufügen" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "Adresse" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "Administrierte Domains" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "Administratoren" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "Alias" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "Alias erstellt" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "Aliase" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Aliases:" -msgstr "Aliase" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "API" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "API Zugriff" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "Antworten" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -#, fuzzy -msgid "Associated domains" -msgstr "Administrierte Domains" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "Authentifizierung" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "Gebundenes Format" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "Passwort ändern" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "Auswählen, wenn Kennwörter in Datei nicht verschlüsselt sind" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "Schließen" - -#: src/components/alarms/AlarmList.vue:84 -#, fuzzy -msgid "Close alarm" -msgstr "Schließen" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "Schließen" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "Bestätigung" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "Glückwunsch! Die Zwei-Faktor-Authentifizierung ist nun für diesen Account aktiviert." - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "Bei Fehler fortfahren" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "Domain-Administrator erstellen" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "Erzeuge Postfach für den Administrator." - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "Aliase erstellen" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "Erstellungsdatum" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "Passwörter verschlüsseln" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "Dashboard" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "Datum" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "Tag" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "Standard Postfach Kontingent" - -#: src/components/domains/DomainLimitationsForm.vue:6 -msgid "Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Auf Postfächer angewendete Quota. Kann in KB, MB (Voreinstellung) oder GB angegeben werden. 0 eingeben, um keine Quota zu verwenden." - -#: src/components/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "Beschreibung" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "Deaktiviere 2-Faktor-Authentifizierung" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "Deaktiviert" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "DKIM Schlüssel" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "DNS" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "DNS Status" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "Domain" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "Domain Administrator" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "Domain erstellt." - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "Domains" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "E-Mail Adresse" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -#, fuzzy -msgid "Email providers" -msgstr "E-Mail Adresse" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "Aktiviere 2FA" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "Aktiviere DKIM Signierung" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "Aktiviere DNS Prüfungen" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "Aktiviert" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "Gib den Code der per SMS zugestellt wurde" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "Läuft ab am" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "Fehlgeschlagen" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "Passwort vergessen?" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "Weiterleiten" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "Nachricht weiterleiten und Kopie in Mailbox ablegen" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "Weiterleitung aktualisiert" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -#, fuzzy -msgid "Forwarded" -msgstr "Weiterleiten" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "Von" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "Vollständiger Name" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -#, fuzzy -msgid "Fully aligned" -msgstr "Voll zugeordnet" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "Allgemein" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "Zufällig generiertes Passwort für den Administrator verwenden." - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "Identitäten" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -#, fuzzy -msgid "Identities deleted" -msgstr "Identitäten" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "Import" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "Domains importieren" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "Identitäten importieren" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "Information" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "Installierte Version" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "Lokale Kopien behalten" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "Datum der letzten Änderung" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "Stufe" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "Logger" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "Logout" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "Postfächer" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -#, fuzzy -msgid "Mailbox aliases:" -msgstr "Mailboxen" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Mailbox:" -msgstr "Postfächer" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "Mailboxen" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "Verwendung" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -#, fuzzy -msgid "Migration deleted" -msgstr "Erstellungsdatum" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -#, fuzzy -msgid "Migrations" -msgstr "Bestätigung" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "Verändert" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "Monat" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "Name" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "Neues Konto" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "Neuer Alias" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "Neue Domain" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -#, fuzzy -msgid "New provider" -msgstr "Neue Wiederherstellungscodes" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "Neue Wiederherstellungscodes" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "Weiter" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "Nicht generiert" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -#, fuzzy -msgid "Old account" -msgstr "Neues Konto" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "Eine oder mehrere Aktualisierungen sind verfügbar" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "Optionen" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "Teilweise zugeordnet" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "Passwort" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "Telefonnummer" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "Pincode" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "Bitte die Primäre Email-Adresse eingeben" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "Profil" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "Profil aktualisiert" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -#, fuzzy -msgid "Provider created" -msgstr "Domain erstellt." - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -#, fuzzy -msgid "Provider updated" -msgstr "Profil aktualisiert" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "Quota dieses Postfachs. Kann in KB, MB (Voreinstellung) oder GB angegeben werden. Eigenen Wert eingeben oder Voreinstellung der Domain verwenden lassen. Frei lassen, um Quota auf unlimitiert zu setzen (nur Super-Administratoren)." - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Von Postfächern gemeinsam genutzte Quota/Speicherplatz. Kann in KB, MB (Voreinstellung) oder GB angegeben werden. 0 eingeben, um keine Quota zu verwenden." - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "Zufällige Adresse" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "Zufälliges Passwort" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "Empfänger" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "Empfänger" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "Registrieren" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "An mich erinnern" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "Reseller" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "Setze Wiederherstellungscodes zurück" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "Ressourcen" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "Ressourcen-Verbrauch" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "Rolle" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "Speichern" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "Suchen" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "Zweite E-Mail Adresse" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -#, fuzzy -msgid "Secured" -msgstr "Sicherheit" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "Sicherheit" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -#, fuzzy -msgid "Send only account" -msgstr "Neues Konto" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "Ab­sen­der­ad­res­sen " - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "Separator" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "Einstellungen" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "Zeige Schlüssel" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "Normaler Benutzer" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -#, fuzzy -msgid "Statistics" -msgstr "Statistiken" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "Status" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "Abschicken" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "Zusammenfassung" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "Super-Administrator" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "Tags" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "Bis" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "Total" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -#, fuzzy -msgid "Trusted sources" -msgstr "Vertraute Quellen" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" -"Zwei-Faktor-Authentifizierung (2FA) ist noch nicht für diesen Account aktiviert.\n" -"Aktiviere dieses Feature, um die Account-Sicherheit zu erhöhen." - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -#, fuzzy -msgid "Two-Factor Authentication is enabled for your account." -msgstr "Glückwunsch! Die Zwei-Faktor-Authentifizierung ist nun für diesen Account aktiviert." - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "Typ" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "Unbekannt" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "Unbekannte Quellen / Bedrohungen" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "unbegrenzt" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -#, fuzzy -msgid "Unlimited" -msgstr "unbegrenzt" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "Aktualisieren" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "Aktualisieren" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "Standardwert der Domain verwenden" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "Benutzername" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "Woche" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "Willkommen zu Modoboa" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "Mit einem Postfach" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "Jahr" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "Passwörter stimmen nicht überein" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/de_DE/LC_MESSAGES/app.po b/frontend/locale/de_DE/LC_MESSAGES/app.po deleted file mode 100644 index f501d8d03..000000000 --- a/frontend/locale/de_DE/LC_MESSAGES/app.po +++ /dev/null @@ -1,1945 +0,0 @@ -# -# Translators: -# bdaniel93, 2023 -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-02-26 14:37+0100\n" -"Last-Translator: bdaniel93, 2023\n" -"Language-Team: German (Germany) (https://www.transifex.com/tonio/teams/13749/de_DE/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: easygettext\n" -"Language: de_DE\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "(deaktiviert)" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "Eine Dokumentation der API ist verfügbar" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:205 -msgid "" -"A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" -"Ein neuer Schlüssel wird in Kürze generiert. Aktualisieren Sie später die " -"Seite, um ihn anzuzeigen." - -#: src/components/identities/AccountRoleForm.vue:39 -#: src/components/identities/AccountRoleForm.vue:69 -msgid "" -"A user with all privileges, can do anything. By default, such a user does " -"not have a mailbox so he can't access end-user features." -msgstr "" -"Ein Benutzer mit allen Rechten kann alles tun. Standardmäßig hat ein solcher" -" Benutzer kein Postfach, sodass er nicht auf Endbenutzerfunktionen zugreifen" -" kann." - -#: src/components/identities/AccountRoleForm.vue:34 -#: src/components/identities/AccountRoleForm.vue:64 -msgid "" -"A user with no privileges but with a mailbox. He will be allowed to use all " -"end-user features: webmail, calendar, contacts, filters." -msgstr "" -"Ein Benutzer ohne Berechtigungen, aber mit einem Postfach. Er darf alle " -"Endnutzerfunktionen nutzen: Webmail, Kalender, Kontakte, Filter." - -#: src/components/identities/AccountRoleForm.vue:24 -#: src/components/identities/AccountRoleForm.vue:54 -msgid "" -"A user with privileges on one or more domain. He will be allowed to " -"administer mailboxes and he can also have a mailbox." -msgstr "" -"Ein Benutzer mit Berechtigungen für eine oder mehrere Domänen. Er darf " -"Postfächer verwalten und kann auch ein Postfach haben." - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "Absoluter Zeitbereich" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "Konto" - -#: src/components/identities/AccountCreationForm.vue:131 -#: src/components/identities/AccountCreationForm.vue:181 -msgid "Account created" -msgstr "Konto erstellt" - -#: src/components/identities/IdentityList.vue:79 -#: src/components/identities/IdentityList.vue:160 -msgid "Account deleted" -msgstr "Konto gelöscht" - -#: src/components/identities/AccountForm.vue:65 -#: src/components/identities/AccountForm.vue:192 -msgid "Account updated" -msgstr "Konto aktualisiert" - -#: src/components/domains/DomainList.vue:29 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/domains/DomainList.vue:171 -#: src/components/identities/IdentityList.vue:101 -msgid "Actions" -msgstr "Aktionen" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "Hinzufügen" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "Fügen Sie einen neuen Domain-Alias ​​hinzu" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "Administrator hinzufügen" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "Absenderadresse hinzufügen" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/domains/DNSDetail.vue:177 -#: src/components/identities/AliasCreationForm.vue:40 -#: src/components/identities/AccountSenderAddresses.vue:63 -msgid "Address" -msgstr "Adresse" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "Adresse:" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "Verwaltete Domänen" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "Administrator hinzugefügt" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:106 -msgid "Administrator name" -msgstr "Administratorname" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "Administrator entfernt" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:113 -#: src/components/domains/DomainList.vue:255 -msgid "Administrators" -msgstr "Administratoren" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "Administratoren von {{ domain.name }}" - -#: src/components/domains/DomainList.vue:119 -#: src/components/layout/Navbar.vue:63 -#: src/components/domains/DomainList.vue:261 -#: src/components/layout/Navbar.vue:178 -msgid "Alarms" -msgstr "Alarme" - -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "Alias" - -#: src/components/identities/AliasCreationForm.vue:82 -#: src/components/identities/AliasCreationForm.vue:102 -msgid "Alias created" -msgstr "Alias erstellt" - -#: src/components/identities/IdentityList.vue:53 -#: src/components/identities/IdentityList.vue:134 -msgid "Alias deleted" -msgstr "Alias gelöscht" - -#: src/components/identities/AliasForm.vue:28 -#: src/components/identities/AliasForm.vue:111 -msgid "Alias updated" -msgstr "Alias ​​aktualisiert" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "" -"Alias(es) of this mailbox. To create a catchall alias, just enter the domain" -" name (@domain.tld)." -msgstr "" -"Alias(e) dieses Postfachs. Um einen Catchall-Alias ​​zu erstellen, geben Sie" -" einfach den Domänennamen (@domain.tld) ​​ein." - -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainSummary.vue:31 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:65 -#: src/components/identities/AccountCreationForm.vue:93 -#: src/components/domains/DomainList.vue:167 -#: src/components/identities/AccountCreationForm.vue:112 -#: src/components/identities/AccountCreationForm.vue:115 -#: src/components/identities/AccountCreationForm.vue:143 -msgid "Aliases" -msgstr "Aliase" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "Ausrichtung" - -#: src/components/layout/Navbar.vue:99 src/components/layout/Navbar.vue:214 -msgid "API" -msgstr "API" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "API-Zugriff" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "API-Token in Zwischenablage kopiert" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "API-Token erstellt" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "API-Token gelöscht" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "Anwenden" - -#: src/components/layout/Navbar.vue:73 src/views/logs/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:188 -msgid "Audit trail" -msgstr "Audit Trail" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "Authentifizierung" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "Automatische Konfiguration" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "Autoconfig-Eintrag (Mozilla) nicht gefunden" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "Autoconfig-Eintrag (Mozilla): %{ value }" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "Autodiscover-Eintrag (Microsoft) nicht gefunden" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "Autodiscover-Eintrag (Microsoft): %{ value }" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "Zurück" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "Bind/named Format. Zum Kopieren klicken" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "Body" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:94 -#: src/components/identities/AliasForm.vue:55 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/components/layout/ConfirmDialog.vue:53 src/views/user/APISetup.vue:87 -msgid "Cancel" -msgstr "Abbruch" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "Passwort ändern" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" -"Sehen Sie sich die folgende Liste an, um verwandte Komponenten zu finden" - -#: src/views/identities/Identities.vue:45 -#: src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" -"Aktivieren Sie diese Option, wenn die in Ihrer Datei enthaltenen Passwörter " -"nicht verschlüsselt sind" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "Eine Domäne wählen" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "Wähle eine Rolle" - -#: src/App.vue:18 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:26 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "Schließen" - -#: src/components/alarms/AlarmList.vue:21 -#: src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "Geschlossen" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "Bestätigen und erstellen" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "Bestätigung" - -#: src/components/user/TwoFactorAuthForm.vue:34 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "" -"Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" -"Glückwunsch! Die Zwei-Faktor-Authentisierung ist nun für diesen Account " -"aktiviert." - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "Verbinden" - -#: src/components/tools/ImportForm.vue:19 -msgid "Continue on error" -msgstr "Bei Fehler fortfahren" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "Legen Sie fest, ob diese Domain Nachrichten senden und empfangen darf" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "In Zwischenablage kopieren" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "Token in Zwischenablage kopieren" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:105 -msgid "Create a domain administrator" -msgstr "Erstelle einen Domänenadministrator" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "Erstelle ein Postfach für den Administrator." - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:119 -msgid "Create aliases" -msgstr "Aliase erstellen" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "Erstelle Standardaliase für die Domäne." - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "Erstellungsdatum" - -#: src/views/identities/Identities.vue:45 -#: src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "Passwörter verschlüsseln" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "Aktuelles Passwort" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "Tägliches Sendelimit für Nachrichten" - -#: src/components/domains/DomainSummary.vue:23 -msgid "Daily sending limit" -msgstr "Tägliches Sendelimit" - -#: src/components/layout/Navbar.vue:45 src/components/layout/Navbar.vue:160 -msgid "Dashboard" -msgstr "Dashboard" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "Datum" - -#: src/components/tools/TimeSerieChart.vue:50 -#: src/components/tools/TimeSerieChart.vue:108 -msgid "Day" -msgstr "Tag" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:19 -#: src/components/domains/DomainCreationForm.vue:92 -msgid "Default mailbox quota" -msgstr "Standard Postfachkontingent" - -#: src/components/domains/DomainLimitationsForm.vue:6 -msgid "" -"Default quota applied to mailboxes. Can be expressed in KB, MB (default) or " -"GB. A value of 0 means no quota." -msgstr "" -"Auf Postfächer angewendetes Standardkontingent. Kann in KB, MB (Standard) " -"oder GB ausgedrückt werden. Ein Wert von 0 bedeutet kein limitiertes " -"Kontingent." - -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:162 -#: src/components/identities/IdentityList.vue:174 -#: src/components/identities/IdentityList.vue:185 -#: src/components/domains/DomainList.vue:257 -#: src/components/identities/IdentityList.vue:243 -#: src/components/identities/IdentityList.vue:255 -#: src/components/identities/IdentityList.vue:266 -msgid "Delete" -msgstr "Löschen" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "Token löschen" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/components/identities/AliasCreationForm.vue:51 -msgid "Description" -msgstr "Beschreibung" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "Detail" - -#: src/components/user/TwoFactorAuthForm.vue:57 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Disable 2FA" -msgstr "2FA deaktivieren" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "Deaktiviert" - -#: src/components/domains/DNSDetail.vue:87 -#: src/components/domains/DNSDetail.vue:51 -msgid "DKIM key" -msgstr "DKIM-Schlüssel" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:99 -msgid "DKIM key length" -msgstr "DKIM-Schlüssellänge" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:98 -msgid "DKIM key selector" -msgstr "DKIM-Selektor" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:189 -msgid "" -"DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" -"Für diese Domain sind bereits DKIM-Schlüssel vorhanden. Möchten Sie sie " -"überschreiben?" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "Öffentlicher DKIM-Schlüssel für" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "DKIM-Eintrag gefunden" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "DKIM-Eintrag nicht gefunden" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "DKIM Signierung" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "DMARC" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "DMARC-Eintrag gefunden" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "DMARC-Eintrag nicht gefunden" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "DMARC-Unterstützung scheint für diese Domain nicht aktiviert zu sein." - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:82 -#: src/components/domains/DomainCreationForm.vue:160 -#: src/components/domains/DomainCreationForm.vue:166 -msgid "DNS" -msgstr "DNS" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "DNS-Checks" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "DNS-Konfiguration für" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "Hilfe zur DNS-Konfiguration" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:168 -msgid "DNS status" -msgstr "DNS-Status" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "Kontoordner nicht löschen" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "Domänenordner nicht löschen" - -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:118 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "Möchten Sie den Alias ​​%{ alias } wirklich löschen?" - -#: src/components/identities/IdentityList.vue:92 -#: src/components/identities/IdentityList.vue:174 -msgid "Do you really want to delete the selected identities?" -msgstr "Möchten Sie die ausgewählten Identitäten wirklich löschen?" - -#: src/components/alarms/AlarmList.vue:10 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:74 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "Domäne" - -#: src/components/identities/AccountRoleForm.vue:22 -#: src/components/identities/AccountRoleForm.vue:52 -msgid "Domain administrator" -msgstr "Domänen-Administrator" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "Domänen-Alias erstellt" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "Domänen-Aliase gelöscht" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "Domänen-Alias aktualisiert" - -#: src/components/domains/DomainCreationForm.vue:174 -#: src/components/domains/DomainCreationForm.vue:225 -msgid "Domain created" -msgstr "Domäne erstellt." - -#: src/components/identities/AccountCreationForm.vue:52 -#: src/components/identities/AccountCreationForm.vue:102 -msgid "Domain default value" -msgstr "Standardwert der Domäne" - -#: src/components/domains/DomainList.vue:70 -#: src/components/domains/DomainList.vue:212 -msgid "Domain deleted" -msgstr "Domäne gelöscht" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "Domänenname (z. B. domain.tld)" - -#: src/components/domains/DomainForm.vue:53 -#: src/components/domains/DomainForm.vue:215 -msgid "Domain updated" -msgstr "Domäne aktualisiert" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "Standardwert der Domäne" - -#: src/components/layout/Navbar.vue:51 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:166 -msgid "Domains" -msgstr "Domänen" - -#: src/components/tools/ImportForm.vue:19 -msgid "Don't treat duplicated objects as errors" -msgstr "Doppelte Objekte nicht als Fehler behandeln" - -#: src/components/domains/DomainList.vue:114 -#: src/components/identities/IdentityList.vue:157 -#: src/components/identities/IdentityList.vue:169 -#: src/components/domains/DomainList.vue:256 -#: src/components/identities/IdentityList.vue:238 -#: src/components/identities/IdentityList.vue:250 -msgid "Edit" -msgstr "Bearbeiten" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "Konto bearbeiten" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "Alias bearbeiten" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "Domäne bearbeiten" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "Domain-Alias ​​bearbeiten" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "Element" - -#: src/components/identities/AccountCreationForm.vue:48 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Email" -msgstr "E-Mail" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "E-Mail-Addresse" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "Leer" - -#: src/components/user/TwoFactorAuthForm.vue:68 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "2FA aktivieren" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:85 -msgid "Enable DKIM signing" -msgstr "Aktiviere DKIM-Signierung" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:84 -msgid "Enable DNS checks" -msgstr "Aktiviere DNS-Prüfungen" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:39 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "Enabled" -msgstr "Aktiviert" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:70 -msgid "Enter a simple username or an email address" -msgstr "Geben Sie einen Benutzernamen oder eine E-Mail-Adresse ein" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:68 -msgid "Enter an email address" -msgstr "Geben Sie eine E-Mail-Adresse ein" - -#: src/views/TwoFA.vue:12 -msgid "" -"Enter the code from the two-factor app on your mobile device. If you have " -"lost your device, you may enter one of your recovery codes." -msgstr "" -"Geben Sie den Code aus der Zwei-Faktor-App auf Ihrem Mobilgerät ein. Wenn " -"Sie Ihr Gerät verloren haben, können Sie einen Ihrer Wiederherstellungscodes" -" eingeben." - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "Geben Sie den Code ein, den Sie soeben per SMS erhalten haben" - -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "err" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "Fehler" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "Beispiel: 10 MB. Leer lassen für unbegrenzt" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasGeneralForm.vue:49 -#: src/components/identities/AliasCreationForm.vue:46 -msgid "Expire at" -msgstr "Läuft ab am" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "Konten und Aliase in CSV exportieren" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "Domänen und Aliase in CSV exportieren" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "Fehlgeschlagen" - -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountGeneralForm.vue:32 -#: src/components/user/ProfileForm.vue:45 -#: src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:17 -#: src/components/identities/AccountCreationForm.vue:80 -msgid "First name" -msgstr "Vorname" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "Passwort vergessen?" - -#: src/components/layout/Navbar.vue:123 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:238 -msgid "Forward" -msgstr "Weiterleiten" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "Nachricht weiterleiten und Kopie im Postfach ablegen" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "Weiterleitung aktualisiert" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "Weitergeleitet" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "Weiterleitungen mit ARC" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "Von" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "Vollständiger Name" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:99 -msgid "Fullname/recipient" -msgstr "Vollständiger Name/Empfänger" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "Vollständig zugeordnet" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 src/views/domains/Domain.vue:11 -#: src/components/domains/DomainCreationForm.vue:74 -#: src/components/domains/DomainCreationForm.vue:159 -#: src/components/domains/DomainCreationForm.vue:165 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:69 -msgid "General" -msgstr "Allgemein" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "Allgemeine Informationen" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "Allgemeine Einstellungen" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "Generieren" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:57 -msgid "Generate a new DKIM key" -msgstr "Generiere einen neuen DKIM-Schlüssel" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "Zufällig generiertes Passwort für den Administrator verwenden." - -#: src/components/identities/AccountRoleForm.vue:29 -#: src/components/identities/AccountRoleForm.vue:59 -msgid "help" -msgstr "Hilfe" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "" -"Here is an example of DNS configuration (bind format). Replace values " -"between [ ] by the appropriate ones." -msgstr "" -"Hier ist ein Beispiel für die DNS-Konfiguration (Bind-Format). Ersetzen Sie " -"die Werte zwischen [ ] durch die entsprechenden." - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "Hostname Ihres Automx-Servers" - -#: src/components/identities/AccountCreationForm.vue:27 -#: src/components/identities/AccountCreationForm.vue:85 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:135 -msgid "Identification" -msgstr "Identifikation" - -#: src/components/layout/Navbar.vue:57 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:172 -msgid "Identities" -msgstr "Identitäten" - -#: src/components/identities/IdentityList.vue:112 -#: src/components/identities/IdentityList.vue:193 -msgid "Identities deleted" -msgstr "Identitäten gelöscht" - -#: src/components/tools/CreationForm.vue:26 -#: src/components/tools/CreationForm.vue:99 -msgid "" -"If you close this form now, your modifications won't be saved. Do you " -"confirm?" -msgstr "" -"Wenn Sie dieses Formular jetzt schließen, werden Ihre Änderungen nicht " -"gespeichert. Trotzdem schließen?" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "" -"If you configured it recently, please wait for the first report to be " -"received and processed." -msgstr "" -"Falls kürzlich konfiguriert, warten Sie bitte, bis der erste Bericht " -"empfangen und verarbeitet wurde." - -#: src/components/tools/ImportForm.vue:29 -msgid "Import" -msgstr "Import" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "Importiere Konten und Aliase aus CSV-Datei" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "Domänen importieren" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "Importiere Domänen und Aliase aus CSV-Datei" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "Identitäten importieren" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" -"Geben Sie einen oder mehrere Empfänger an, die durch ein Komma (,) getrennt " -"sind." - -#: src/components/layout/Navbar.vue:92 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:207 -msgid "Information" -msgstr "Information" - -#: src/components/user/TwoFactorAuthForm.vue:14 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" -"Installieren Sie einen Soft-Token-Authentifikator wie FreeOTP oder Google " -"Authenticator aus dem App-Store und scannen Sie den QR-Code." - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "Installierte Komponenten" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "Installierte Version" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "Ungültiges Reset-Token." - -#: src/views/Login.vue:35 src/views/Login.vue:95 -msgid "Invalid username and/or password" -msgstr "Ungültiger Benutzername und / oder Passwort" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "IP-Adresse Ihres Modoboa-Servers" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" -"Es zeigt eine Zusammenfassung des Status Ihres Modoboa-Servers und einige " -"nützliche Informationen über das Produkt." - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "Lokale Kopien behalten" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "Sprache" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "Letztes Anmeldedatum" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "Datum der letzten Änderung" - -#: src/components/identities/AccountCreationForm.vue:31 -#: src/components/identities/AccountGeneralForm.vue:41 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:25 -#: src/components/identities/AccountCreationForm.vue:81 -msgid "Last name" -msgstr "Nachname" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "Aktuellste Version" - -#: src/components/identities/AccountMailboxForm.vue:8 -msgid "Leave empty for no limit" -msgstr "Leer lassen für unbegrenzt" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "Stufe" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -msgid "Limitations" -msgstr "Einschränkungen" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "Logger" - -#: src/components/layout/Navbar.vue:139 src/components/layout/Topbar.vue:6 -#: src/components/layout/Topbar.vue:53 src/components/layout/Navbar.vue:254 -msgid "Logout" -msgstr "Ausloggen" - -#: src/components/layout/Navbar.vue:69 src/components/layout/Navbar.vue:184 -msgid "Logs" -msgstr "Logs" - -#: src/components/alarms/AlarmList.vue:11 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountCreationForm.vue:89 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:75 -#: src/components/identities/AccountCreationForm.vue:96 -#: src/components/identities/AccountCreationForm.vue:139 -msgid "Mailbox" -msgstr "Postfach" - -#: src/components/domains/DomainSummary.vue:27 -msgid "Mailboxes" -msgstr "Postfächer" - -#: src/components/alarms/AlarmList.vue:12 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:76 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "Nachricht" - -#: src/views/logs/Messages.vue:3 -msgid "Message history" -msgstr "Nachrichtenverlauf" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/identities/AccountCreationForm.vue:106 -msgid "Message sending limit" -msgstr "Sendelimit für Nachrichten" - -#: src/components/domains/DomainSummary.vue:24 -msgid "messages" -msgstr "Nachrichten" - -#: src/components/layout/Navbar.vue:78 src/components/layout/Navbar.vue:193 -msgid "Messages" -msgstr "Nachrichten" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "Geändert" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "Ändern" - -#: src/components/tools/TimeSerieChart.vue:52 -#: src/components/tools/TimeSerieChart.vue:110 -msgid "Month" -msgstr "Monat" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "MX-Einträge" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:24 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:176 -#: src/components/domains/DomainList.vue:166 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/identities/IdentityList.vue:98 -msgid "Name" -msgstr "Name" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "Name des Administrators" - -#: src/components/domains/DomainForm.vue:14 -msgid "Name:" -msgstr "Name:" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "Noch nie angemeldet" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 -#: src/views/identities/Identities.vue:3 -msgid "New" -msgstr "Neu" - -#: src/components/identities/AccountCreationForm.vue:1 -msgid "New account" -msgstr "Neues Konto" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "Neuer Alias" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "Neue Domäne" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "Neue Wiederherstellungscodes" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "Weiter" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:61 -#: src/components/identities/IdentityList.vue:42 -#: src/components/identities/IdentityList.vue:67 -#: src/components/identities/IdentityList.vue:97 -#: src/components/tools/CreationForm.vue:30 -#: src/components/domains/DNSDetail.vue:193 -#: src/components/domains/DomainList.vue:203 -#: src/components/identities/IdentityList.vue:123 -#: src/components/identities/IdentityList.vue:148 -#: src/components/identities/IdentityList.vue:178 -#: src/components/tools/CreationForm.vue:103 -msgid "No" -msgstr "Nein" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "Für dieses Konto ist keine Absenderadresse definiert" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "Kein Sendelimit" - -#: src/components/domains/DNSDetail.vue:97 -#: src/components/domains/DNSDetail.vue:61 -msgid "Not generated" -msgstr "Nicht generiert" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "" -"Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" -"Anzahl der Nachrichten, die diese Domäne pro Tag senden kann. Leer lassen " -"für unbegrenzt." - -#: src/components/identities/AccountMailboxForm.vue:8 -msgid "" -"Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" -"Anzahl der Nachrichten, die dieses Postfach pro Tag senden kann. Leer lassen" -" für unbegrenzt." - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "Ok" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "OK" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "Ein oder mehrere Updates sind verfügbar" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "Geöffnet" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "Offene Alarme" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:103 -#: src/components/domains/DomainCreationForm.vue:162 -msgid "Options" -msgstr "Optionen" - -#: src/components/parameters/ParametersForm.vue:61 -#: src/components/parameters/ParametersForm.vue:138 -msgid "Parameters updated" -msgstr "Parameter aktualisiert" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "Teilweise zugeordnet" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "Teilweise vertrauenswürdige Quellen/Weiterleitungen" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "Passwort" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:101 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:151 -msgid "Password copied to clipboard" -msgstr "Passwort in Zwischenablage kopiert" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "Passwort-Wiederherstellung" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "Passwort aktualisiert" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "Ausstehend" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "Zeitraum" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "Telefonnummer" - -#: src/components/user/TwoFactorAuthForm.vue:20 -#: src/components/user/TwoFactorAuthForm.vue:13 -msgid "Pin code" -msgstr "PIN-Code" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "Bitte geben Sie Ihre primäre E-Mail-Adresse ein" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "Problem" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "Fortfahren" - -#: src/components/layout/Navbar.vue:106 src/components/layout/Navbar.vue:133 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:221 -#: src/components/layout/Navbar.vue:248 -msgid "Profile" -msgstr "Profil" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "Profil aktualisiert" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" -"Stellen Sie eine CSV-Datei bereit, dessen Zeilen eines der folgenden Formate" -" respektieren:" - -#: src/components/logs/MessageList.vue:9 -#: src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "Warteschlangen-ID" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:50 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/domains/DomainList.vue:170 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:100 -msgid "Quota" -msgstr "Quota" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "" -"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a" -" custom value or use domain's default one. Leave empty to define an " -"unlimited value (not allowed for domain administrators)." -msgstr "" -"Quota dieses Postfachs. Kann in KB, MB (Voreinstellung) oder GB angegeben " -"werden. Definiere einen benutzerdefinierten Wert oder verwende den " -"Standardwert der Domäne. Leer lassen, um einen unbegrenzten Wert zu " -"definieren (für Domänenadministratoren nicht zulässig)." - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "" -"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " -"A value of 0 means no quota." -msgstr "" -"Zwischen Postfächern geteilte Quota. Kann in KB, MB (Standard) oder GB " -"ausgedrückt werden. Ein Wert von 0 bedeutet keine Quota zu verwenden." - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "Quota:" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:39 -msgid "Random address" -msgstr "Zufällige Adresse" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/identities/AccountCreationForm.vue:84 -msgid "Random password" -msgstr "Zufälliges Passwort" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "Raw-Format. Zum Kopieren klicken" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "Empfänger" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:55 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:73 -msgid "Recipients" -msgstr "Empfänger" - -#: src/components/user/TwoFactorAuthForm.vue:27 -#: src/components/user/TwoFactorAuthForm.vue:20 -msgid "Register" -msgstr "Registrieren" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "Relative Zeitbereiche" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "Relay" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "Login speichern" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "Entferne diese Adresse" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "Entferne diesen Administrator" - -#: src/components/identities/AccountRoleForm.vue:27 -#: src/components/identities/AccountRoleForm.vue:57 -msgid "Reseller" -msgstr "Reseller" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "SMS erneut senden" - -#: src/components/user/TwoFactorAuthForm.vue:60 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Reset recovery codes" -msgstr "Wiederherstellungscodes zurücksetzen" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:83 -msgid "Resources" -msgstr "Ressourcen" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "Ressourcennutzung" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "Zurücksetzen erneut versuchen" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -#: src/views/user/PasswordRecoveryForm.vue:78 -msgid "Return to login" -msgstr "Zurück zum Login" - -#: src/components/identities/AccountCreationForm.vue:21 -#: src/components/identities/AccountCreationForm.vue:23 -#: src/components/identities/AccountCreationForm.vue:81 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:71 -#: src/components/identities/AccountCreationForm.vue:73 -#: src/components/identities/AccountCreationForm.vue:131 -msgid "Role" -msgstr "Rolle" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:97 -#: src/components/identities/AliasForm.vue:58 -msgid "Save" -msgstr "Speichern" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "Suche" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "Sekundäre E-Mail-Adresse" - -#: src/components/layout/Navbar.vue:112 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:227 -msgid "Security" -msgstr "Sicherheit" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "Wähle ein Konto aus" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "Datei aussuchen" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "Absenderadresse hinzugefügt" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "Absenderadresse gelöscht" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "Ab­sen­der­ad­res­sen " - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:169 -msgid "Sending limit" -msgstr "Sendelimit" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "Sendelimit:" - -#: src/components/tools/ImportForm.vue:17 -msgid "Separator" -msgstr "Separator" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:130 -msgid "Service" -msgstr "Service" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "Service:" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Settings" -msgstr "Einstellungen" - -#: src/components/parameters/ParametersForm.vue:20 -msgid "Settings: thislabel" -msgstr "Einstellungen: " - -#: src/components/domains/DNSDetail.vue:91 -#: src/components/domains/DNSDetail.vue:55 -msgid "Show key" -msgstr "Zeige Schlüssel" - -#: src/components/identities/AccountRoleForm.vue:32 -#: src/components/identities/AccountRoleForm.vue:62 -msgid "Simple user" -msgstr "Normaler Benutzer" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:24 -msgid "Specify an email address" -msgstr "Geben Sie eine E-Mail-Adresse an" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "SPF-Eintrag gefunden" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "SPF-Eintrag nicht gefunden" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "Beginne mit der Eingabe eines Namens ..." - -#: src/views/domains/Domain.vue:14 -msgid "Statistics" -msgstr "Statistiken" - -#: src/components/alarms/AlarmList.vue:9 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:73 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "Status" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "Abschicken" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "Zusammenfassung" - -#: src/components/identities/AccountRoleForm.vue:37 -#: src/components/identities/AccountRoleForm.vue:67 -msgid "Super administrator" -msgstr "Super-Administrator" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:100 -msgid "Tags" -msgstr "Tags" - -#: src/components/tools/ImportForm.vue:9 -msgid "" -"The first element of each line is mandatory and must be equal to one of the " -"previous values." -msgstr "" -"Das erste Element jeder Zeile ist obligatorisch und muss gleich einem der " -"vorherigen Werte sein." - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" -"Die folgenden Wiederherstellungscodes können jeweils einmal verwendet " -"werden, um den Zugriff auf Ihr Konto wiederherzustellen, falls Sie " -"beispielsweise Ihr Telefon verlieren. Achten Sie darauf, diese sicher " -"aufzubewahren, da Sie sonst nicht mehr auf Ihr Konto zugreifen können." - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" -"Die folgenden Wiederherstellungscodes können jeweils einmal verwendet " -"werden, um den Zugriff auf Ihr Konto wiederherzustellen, falls Sie " -"beispielsweise Ihr Telefon verlieren. Achten Sie darauf, diese sicher " -"aufzubewahren, da Sie sonst nicht mehr auf Ihr Konto zugreifen können." - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "Diese Seite befindet sich noch im Aufbau." - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "Titel" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "An" - -#: src/views/Login.vue:39 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 src/views/Login.vue:99 -msgid "Too many unsuccessful attempts, please try later." -msgstr "Zu viele Versuche, bitte versuchen Sie es später erneut." - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "Total" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "TOTP erneut gesendet." - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:128 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "Transport" -msgstr "Transport" - -#: src/components/alarms/AlarmList.vue:8 -#: src/components/alarms/AlarmList.vue:72 -msgid "Triggered" -msgstr "Ausgelöst" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "Vertrauenswürdige Quellen" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "Zwei-Faktor-Authentifizierung" - -#: src/components/user/TwoFactorAuthForm.vue:64 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "" -"Two-Factor Authentication (2FA) is not yet activated for your account. " -"Enabling this feature will increase your account's security." -msgstr "" -"Die Zwei-Faktor-Authentifizierung (2FA) ist für diesen Account noch nicht " -"aktiviert. Die Aktivierung dieser Funktion erhöht die Sicherheit des " -"Accounts." - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "Zwei-Faktor-Authentifizierungscode" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:77 -msgid "Type" -msgstr "Typ" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "Typ:" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "Unbekannt" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "Unbekannte Quellen / Bedrohungen" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:69 -msgid "unlimited" -msgstr "unbegrenzt" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "Aktualisieren" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "Kennwort aktualisieren" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "Update Einstellungen" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:178 -msgid "Updated" -msgstr "Aktualisiert" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:66 -msgid "Use domain default value" -msgstr "Standardwert der Domäne verwenden" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" -"Der Benutzer scheint falsch zu sein, zur Anmeldung zurückkehren oder den " -"Prozess neu starten?" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "Benutzer unbekannt." - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:29 -#: src/components/identities/AccountGeneralForm.vue:19 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:7 -#: src/components/identities/AccountCreationForm.vue:79 -msgid "Username" -msgstr "Benutzername" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "Benutzername:" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "Gültig" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "Überprüfung" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "Code überprüfen" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:54 -#: src/components/identities/IdentityList.vue:35 -#: src/components/identities/IdentityList.vue:60 -#: src/components/identities/IdentityList.vue:91 -#: src/components/tools/CreationForm.vue:25 src/views/user/APISetup.vue:40 -#: src/components/domains/DNSDetail.vue:187 -#: src/components/domains/DomainList.vue:196 -#: src/components/identities/IdentityList.vue:116 -#: src/components/identities/IdentityList.vue:141 -#: src/components/identities/IdentityList.vue:172 -#: src/components/tools/CreationForm.vue:98 src/views/user/APISetup.vue:81 -msgid "Warning" -msgstr "Warnung" - -#: src/components/tools/TimeSerieChart.vue:51 -#: src/components/tools/TimeSerieChart.vue:109 -msgid "Week" -msgstr "Woche" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "Willkommen bei Modoboa" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "Mit einem Postfach" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:114 -msgid "With mailbox" -msgstr "Mit Postfach" - -#: src/components/tools/TimeSerieChart.vue:53 -#: src/components/tools/TimeSerieChart.vue:111 -msgid "Year" -msgstr "Jahr" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:29 -#: src/components/domains/DNSDetail.vue:194 -#: src/components/domains/DomainList.vue:204 -#: src/components/identities/IdentityList.vue:124 -#: src/components/identities/IdentityList.vue:149 -#: src/components/identities/IdentityList.vue:179 -#: src/components/tools/CreationForm.vue:102 -msgid "Yes" -msgstr "Ja" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "Sie sind dabei, Ihren API-Zugriffstoken zu löschen" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "Sie können ein anderes Zeichen als Trennzeichen verwenden" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "Ihr API-Token wurde noch nicht generiert." - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "Ihr API-Token lautet:" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "Passwörter stimmen nicht überein" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "Dieses Feld muss eine gültige Zahl sein" - -#: src/plugins/vee-validate.js:20 -msgid "This field is required" -msgstr "Dieses Feld ist erforderlich" - -#: src/plugins/vee-validate.js:37 -msgid "Invalid password" -msgstr "Ungültiges Passwort" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "ja" - -#: src/filters/index.js:7 -msgid "no" -msgstr "nein" - -#: src/components/parameters/ParametersForm.vue:97 -msgid "Settings: " -msgstr "Einstellungen:" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "Sie sind gedrosselt, bitte versuchen Sie es später erneut." diff --git a/frontend/locale/el/LC_MESSAGES/app.po b/frontend/locale/el/LC_MESSAGES/app.po deleted file mode 100644 index 65b9e603d..000000000 --- a/frontend/locale/el/LC_MESSAGES/app.po +++ /dev/null @@ -1,2126 +0,0 @@ -# Greek translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: el\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Aliases:" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Mailbox:" -msgstr "" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -msgid "Migrations" -msgstr "" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -msgid "Provider created" -msgstr "" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -msgid "Provider updated" -msgstr "" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -msgid "Send only account" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -msgid "Unlimited" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/en/LC_MESSAGES/app.po b/frontend/locale/en/LC_MESSAGES/app.po deleted file mode 100644 index 5ffae891b..000000000 --- a/frontend/locale/en/LC_MESSAGES/app.po +++ /dev/null @@ -1,2121 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: en\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: easygettext\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Aliases:" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Mailbox:" -msgstr "" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -msgid "Migrations" -msgstr "" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -msgid "Provider created" -msgstr "" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -msgid "Provider updated" -msgstr "" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -msgid "Send only account" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -msgid "Unlimited" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/es/LC_MESSAGES/app.po b/frontend/locale/es/LC_MESSAGES/app.po deleted file mode 100644 index 6f60fa80f..000000000 --- a/frontend/locale/es/LC_MESSAGES/app.po +++ /dev/null @@ -1,2144 +0,0 @@ -# Spanish translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: es\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "(deshabilitado)" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "Cuenta" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "Cuenta creada" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -#, fuzzy -msgid "Account not found!" -msgstr "Cuenta creada" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "Cuenta actualizada" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "Acciones" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "Añadir" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "Dirección" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "Dominios administrados" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "Administradores" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "Alias" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "Alias creado" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "Alias" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Aliases:" -msgstr "Alias" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "API" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "Acceso API" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "Aplicar" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -#, fuzzy -msgid "Associated domains" -msgstr "Dominios administrados" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "Autenticación" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "Formato inválido" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "Cambiar contraseña" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "Marque esta opción si las contraseñas que contiene su fichero no están cifradas" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "Confirmación" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "Continúe en error." - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "Crear un administrador del dominio" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "Crear mailbox para el administrador." - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "Crear alias" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "Fecha de creación" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "Contraseñas cifradas" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "Panel de Control" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "Día" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "Cuota de mailbox por defecto" - -#: src/components/domains/DomainLimitationsForm.vue:6 -msgid "Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Cuota de mailbox predeterminda en MB. Un valor de 0 significa ningún limite." - -#: src/components/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "Descripción" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "Deshabilitado" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "Estado de DNS" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "Dominio" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "Administrador del dominio" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "Dominio creado" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "Dominios" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "Dirección de email" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -#, fuzzy -msgid "Email providers" -msgstr "Dirección de email" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "Activar comprobación de DNS" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "Activado" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "Caduca en" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "¿Ha olvidado su contraseña?" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "Siguiente" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "Reenvía mensajes y guarda copias en su mailbox local" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "Reenvío actualizado" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -#, fuzzy -msgid "Forwarded" -msgstr "Siguiente" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "Nombre completo" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -#, fuzzy -msgid "Fully aligned" -msgstr "Nombre completo" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "General" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "Crear mailbox para el administrador." - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "Identidades" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -#, fuzzy -msgid "Identities deleted" -msgstr "Identidades" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "Importar" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "Importar dominios" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "Importar identidades" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "Información" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "Versión instalada" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "Mantener copias locales" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "Última fecha de modificación" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "Nivel" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "Logger" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "Salir" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "Mailboxes" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -#, fuzzy -msgid "Mailbox aliases:" -msgstr "Mailboxes" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Mailbox:" -msgstr "Mailboxes" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "Mailboxes" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "Uso" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -#, fuzzy -msgid "Migration deleted" -msgstr "Fecha de creación" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -#, fuzzy -msgid "Migrations" -msgstr "Confirmación" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "Modificado" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "Mes" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "Nombre" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "Nueva cuenta" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "Nuevo alias" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "Nuevo dominio" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "Siguiente" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "Sin definir" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -#, fuzzy -msgid "Old account" -msgstr "Nueva cuenta" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "Una o más actualizaciones están disponibles" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "Opciones" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "Contraseña" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "Numero de telefono " - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "Perfil actualizado" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -#, fuzzy -msgid "Provider created" -msgstr "Dominio creado" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -#, fuzzy -msgid "Provider updated" -msgstr "Perfil actualizado" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "Cuota en MB para este mailbox. Defina un valor por defecto o use el del dominio por defecto. Déjelo vacío para definir un valor ilimitado (no permitido para los administradores del dominio)" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Cuota de mailbox predeterminda en MB. Un valor de 0 significa ningún limite." - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "Dirección aleatoria" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "Dirección aleatoria" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "Destinatario(s)" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "Destinatarios" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "Recuerdame" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "Revendedor" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "Recursos" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "Uso de recursos" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "Rol" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "Guardar" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "Buscar" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "Email secundario" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -#, fuzzy -msgid "Send only account" -msgstr "Nueva cuenta" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "Direcciónes de remitente" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "Separador" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "Configuración" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "Usuario normal" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -#, fuzzy -msgid "Statistics" -msgstr "Estadísticas" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "Estatus" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "Enviar" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "Resumen" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "Super administrador" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "Tags" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -#, fuzzy -msgid "Trusted sources" -msgstr "Recursos" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "Tipo" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "Desconocido" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "ilimitado" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -#, fuzzy -msgid "Unlimited" -msgstr "ilimitado" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "Actualizar" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "Actualizado" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "Usar el valor por defecto del dominio" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "Nombre de usuario" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "Semana" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "Bienvenido a Modoboa" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "Con una mailbox" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "Año" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "Las contraseñas no coinciden" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/fi/LC_MESSAGES/app.po b/frontend/locale/fi/LC_MESSAGES/app.po deleted file mode 100644 index 7a6d19a09..000000000 --- a/frontend/locale/fi/LC_MESSAGES/app.po +++ /dev/null @@ -1,2174 +0,0 @@ -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: \n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: fi\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"Generated-By: easygettext\n" -"X-Generator: Poedit 3.2.2\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "(ei käytössä)" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "API:n dokumentaatio on saatavilla" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "Uusi avain luodaan pian. Päivitä sivu hetken kuluttua nähdäksesi sen." - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "Käyttäjä, jolla on kaikki oikeudet, voi tehdä mitä tahansa. Oletusarvoisesti tällaisella käyttäjällä ei ole postilaatikkoa, joten hän ei voi käyttää loppukäyttäjän ominaisuuksia." - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "Käyttäjä, jolla ei ole oikeuksia mutta jolla on postilaatikko. Hän saa käyttää kaikkia loppukäyttäjän ominaisuuksia: webmail, kalenteri, yhteystiedot, suodattimet." - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "Käyttäjä, jolla on oikeuksia yhdessä tai useammassa verkkotunnuksessa. Hänellä on oikeus hallinnoida postilaatikoita ja hänellä voi myös olla postilaatikko." - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "Määrämittainen aikaraja" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "Tili" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "Tili luotu" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -#, fuzzy -msgid "Account not found!" -msgstr "DMARC-tietuetta ei löydy" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "Tili päivitetty" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "Toiminnot" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "Lisää" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "Lisää uusi verkkotunnuksen alias" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "Lisää järjestelmänvalvoja" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "Lisää lähettäjän osoite" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "Osoite" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "Osoite:" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "Hallinnoidut verkkotunnukset" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "Järjestelmänvalvoja lisäsi" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "Järjestelmänvalvojan nimi" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "Järjestelmänvalvoja poistettu" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "Ylläpitäjät" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "{{ domain.name }}:n ylläpitäjät" - -#: src/components/alarms/AlarmList.vue:58 -#, fuzzy -msgid "Alarm closed" -msgstr "Hälytykset" - -#: src/components/alarms/AlarmList.vue:51 -#, fuzzy -msgid "Alarm deleted" -msgstr "Verkkotunnuksen alias poistettu" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "Hälytykset" - -#: src/components/alarms/AlarmList.vue:70 -#, fuzzy -msgid "Alarms deleted" -msgstr "Verkkotunnuksen alias poistettu" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "Alias" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "Alias luotu" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "Alias päivitetty" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "Tämän postilaatikon alias-nimet. Jos haluat luoda catchall-aliaksen, kirjoita vain verkkotunnus (@domain.tld)." - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "Aliakset" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Aliases:" -msgstr "Aliakset" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "API" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "API-pääsy" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "API-tunniste kopioitu leikepöydälle" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "API-tunniste luotu" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "API-tunniste poistettu" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "Käytä" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -#, fuzzy -msgid "Associated domains" -msgstr "Hallinnoidut verkkotunnukset" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "Tarkastusketju" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "Tunnistautuminen" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "Automaattinen asetusten määrittäminen" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "autoconfig-tallennetta (Mozilla) ei löydy" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "autoconfig-tietue (Mozilla): %{ value }" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "autodiscover-tietuetta (Microsoft) ei löydy" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "autodiscover-tietue (Microsoft): %{ value }" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "Takaisin" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "Bind/nimetty muoto. Kopioi klikkaamalla" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "Peruuta" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -#, fuzzy -msgid "Change password" -msgstr "Vaihda salasana" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "Valitse tämä vaihtoehto, jos tiedostosi sisältämiä salasanoja ei ole salakirjoitettu" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "Valitse verkkotunnus" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "Valitse käyttäjätyyppisi" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "Sulje" - -#: src/components/alarms/AlarmList.vue:84 -#, fuzzy -msgid "Close alarm" -msgstr "Sulje" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -#, fuzzy -msgid "Closed" -msgstr "Suljettu" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "Vahvista ja luo" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "Vahvistus" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "Onnittelut! Kaksivaiheinen tunnistus on nyt käytössä tililläsi." - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "Yhdistä" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "Jatka virheestä" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "Määritä, saako tämä verkkotunnus lähettää ja vastaanottaa viestejä" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "Kopioi leikepöydälle" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "Kopioi turvatunnus leikepöydälle" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "Luo verkkotunnuksen ylläpitäjä" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "Luo ylläpitäjän postilaatikko." - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "Luo aliaksia" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "Luo verkkotunnuksen tavanomaiset aliakset." - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "Luontipäivä" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "Salakirjoita salasanat" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "Nykyinen salasana" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "Päivittäinen viestien lähetysraja" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "Päivittäinen lähetysraja" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "Työpöytä" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "Päivämäärä" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "Päivä" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "Oletuspostilaatikkokiintiö" - -#: src/components/domains/DomainLimitationsForm.vue:6 -msgid "Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Postilaatikoihin sovellettava oletuskiintiö. Voidaan ilmaista kilotavuina, megatavuina (oletus) tai gigatavuina. Arvo 0 tarkoittaa, ettei kiintiötä ole." - -#: src/components/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "Poista" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "Poista avain" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "Kuvaus" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "Poista kaksivaiheinen tunnistautuminen (2FA) käytöstä" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "Pois käytöstä" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "DKIM-avain" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "DKIM-avaimen pituus" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "DKIM-avaimen valitsin-tietue" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "DKIM-avaimet ovat jo olemassa tälle verkkotunnukselle. Haluatko korvata ne?" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "DKIM julkinen avain tietueelle" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "DKIM-tietue löydetty" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "DKIM-tietuetta ei löydy" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "DKIM-allekirjoitus" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "DMARC-tietue löydetty" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "DMARC-tietuetta ei löydy" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "DNS" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "DNS-tarkistukset" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "DNS-määritykset" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "DNS-määritysapu" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "DNS-tila" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "Älä poista tilikansiota" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "Älä poista verkkotunnuksen kansiota" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "Haluatko todella poistaa aliaksen %{ alias }?" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -#, fuzzy -msgid "Do you really want to delete the selected identities?" -msgstr "Haluatko todella poistaa aliaksen %{ alias }?" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "Verkkotunnus" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "Luo verkkotunnuksen ylläpitäjä" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "Verkkotunnuksen alias luotu" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "Verkkotunnuksen alias poistettu" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "Verkkotunnuksen alias päivitetty" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "Verkkotunnus luotu" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "Verkkotunnuksen oletusarvo" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "Verkkotunnus (esim. domain.tld)" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "Verkkotunnus päivitetty" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "verkkotunnuksen oletusarvo" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "Sinulla ei ole oikeutta tuoda verkkotunnuksia" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "Älä käsittele päällekkäisiä objekteja virheinä" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "Muokkaa" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "Muokkaa tiliä" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "Muokkaa aliasta" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "Muokkaa verkkotunnusta" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "Muokkaa verkkotunnusta" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "Sähköposti" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "Sähköpostiosoite" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -#, fuzzy -msgid "Email providers" -msgstr "Sähköpostiosoite" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "Tyhjä" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "Ota käyttöön kaksivaiheinen tunnistus (2FA)" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "Ota DKIM-allekirjoitus käyttöön" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "Ota DNS-tarkistukset käyttöön" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "Käytössä" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "Anna yksinkertainen käyttäjätunnus tai sähköpostiosoite" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "Syötä oikean muotoinen sähköpostiosoite" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "Syötä koodi mobiililaitteesi kaksivaiheisen tunnistuksen sovelluksesta. Jos olet hukannut laitteesi, voit syöttää yhden palautuskoodeistasi." - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "Kirjoita tekstiviestillä saamasi koodi" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "Esim: 10 MB. Jätä tyhjäksi, jos et halua rajoitusta" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "Vanhenee" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "Vie tilit ja aliakset CSV-tiedostoon" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "Vie verkkotunnukset ja aliakset CSV-tiedostoon" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "Etunimi" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "Unohditko salasanasi?" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "Välitä" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "Välitä viestit ja tallenna kopiot paikalliseen postilaatikkoon" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "Välitystieto päivitetty" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -#, fuzzy -msgid "Forwarded" -msgstr "Välitä" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "Lähde" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "Koko nimi" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "Koko nimi/saaja" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -#, fuzzy -msgid "Fully aligned" -msgstr "Koko nimi" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "Yleiset" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "Yleiset tiedot" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "Yleiset asetukset" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "Luo" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "Luo uusi DKIM-avain" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "Luo satunnainen salasana järjestelmänvalvojalle." - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "ohje" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "Tässä on esimerkki DNS-määrityksistä (bind-muodossa). Korvaa [ ]:n välissä olevat arvot sopivilla arvoilla." - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "automx-palvelimen nimi" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "Tunniste" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "Identiteetit" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -#, fuzzy -msgid "Identities deleted" -msgstr "Identiteetit" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "Jos suljet tämän lomakkeen nyt, muutokset eivät tallennu. Vahvistatko?" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -#, fuzzy -msgid "IMAP Migration" -msgstr "Automaattinen asetusten määrittäminen" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "Tuonti" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "Tuo tilejä ja aliaksia CSV-tiedostosta" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "Tuo verkkotunnuksia" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "Tuo verkkotunnukset ja aliakset CSV-tiedostosta" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "Tuo identiteetit" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "Ilmoita yksi tai useampi vastaanottaja pilkulla (,) erotettuna" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -#, fuzzy -msgid "Information" -msgstr "Tiedot" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" -"Asenna soft token -autentikointiohjelma, kuten FreeOTP tai Google\n" -" Authenticator sovelluskaupasta ja käytä \n" -" sovellusta QR-koodin skannaamiseen." - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "Asennettu versio" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "Virheellinen käyttäjätunnus ja/tai salasana" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "Modoboa-palvelimen IP-osoite" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" -"Esittää yhteenvedon Modoboa-palvelimesi tilasta sekä\n" -" hyödyllisiä tietoja tuotteesta." - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "Säilytä paikallisia kopioita" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "Kieli" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "Viimeisin kirjautumispäivä" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "Viimeisin muutospäivä" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "Sukunimi" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "Jätä tyhjäksi, jos rajaa ei ole" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "Taso" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "Rajoitukset" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "Lokikirja" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "Kirjaudu ulos" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "Postilaatikko" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -#, fuzzy -msgid "Mailbox aliases:" -msgstr "Postilaatikot" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Mailbox:" -msgstr "Postilaatikko" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "Postilaatikot" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "Viesti" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "Viestien historia" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "Viestien lähetysraja" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "viestit" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "Viestit" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -#, fuzzy -msgid "Migration deleted" -msgstr "Luontipäivä" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -#, fuzzy -msgid "Migrations" -msgstr "Rajoitukset" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "Muokattu" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "Muokkaa" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "Kuukausi" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "MX-tietueet" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "Nimi" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "Ylläpitäjän nimi" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -#, fuzzy -msgid "Name of the domain to migrate" -msgstr "Ylläpitäjän nimi" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "Nimi:" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "Ei koskaan kirjautunut sisään" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "Uusi" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "Uusi tili" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "Uusi alias" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "Uusi verkkotunnus" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -#, fuzzy -msgid "New provider" -msgstr "Uudet palautuskoodit" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "Uudet palautuskoodit" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "Seuraava" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "Ei" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "Tälle tilille ei ole määritelty lähettäjän osoitetta" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "Ei lähetysrajaa" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "Ei luotu" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "Viestien määrä, jonka tämä verkkotunnus voi lähettää päivässä. Jätä tyhjäksi, jos et halua rajoitusta." - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "Viestien määrä, jonka tämä postilaatikko voi lähettää päivässä. Jätä tyhjäksi, jos et halua rajoitusta." - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "OK" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -#, fuzzy -msgid "Old account" -msgstr "Muokkaa tiliä" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "Yksi tai useampi päivitys on saatavilla" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -#, fuzzy -msgid "Opened" -msgstr "Avattu" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "Avatut hälytykset" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "Vaihtoehdot" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "Parametrit päivitetty" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "Salasana" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "Salasana kopioitu leikepöydälle" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -#, fuzzy -msgid "Password recovery" -msgstr "Salasana" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "Salasana päivitetty" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "Odottaa" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "Jakso" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "Puhelinnumero" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "Pin-koodi" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "Täytä ensisijainen sähköpostiosoitteesi" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "Ongelma" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "Jatka" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "Profiili" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "Profiili päivitetty" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "Toimita CSV-tiedosto, jonka rivit ovat jossakin seuraavista muodoista:" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -#, fuzzy -msgid "Provider created" -msgstr "API-tunniste luotu" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -#, fuzzy -msgid "Provider deleted" -msgstr "API-tunniste poistettu" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -#, fuzzy -msgid "Provider name" -msgstr "Etunimi" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -#, fuzzy -msgid "Provider updated" -msgstr "Profiili päivitetty" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "Jonon ID" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "Verkkotunnuksen oletuskiintiö" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "Tämän postilaatikon kiintiö, joka voidaan ilmaista kilotavuina, megatavuina (oletus) tai gigatavuina. Määritä oma arvo tai käytä toimialueen oletusarvoa. Jätä tyhjäksi, jos haluat määrittää rajoittamattoman arvon (ei sallittu toimialueen ylläpitäjille)." - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Postilaatikoiden kesken jaettu kiintiö. Voidaan ilmaista kilotavuina (KB), megatavuina (MB) (oletus) tai gigatavuina (GB). Arvo 0 tarkoittaa, ettei kiintiötä ole." - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "Kiintiö:" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "Satunnainen osoite" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "Satunnainen salasana" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "Raakamuoto. Kopioi napsauttamalla" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "Vastaanottaja(t)" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "Vastaanottajat" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "Rekisteröidy" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "Suhteelliset aikavälialueet" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "Välitysrele" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "Muista minut" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "Poista tämä osoite" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "Poista tämä ylläpitäjä" - -#: src/components/alarms/AlarmList.vue:91 -#, fuzzy -msgid "Reopen alarm" -msgstr "Avatut hälytykset" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "Jälleenmyyjä" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "Resurssit" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "Resurssien käyttö" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "Rooli" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "Tallenna" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "Hae" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "Toissijainen sähköpostiosoite" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -#, fuzzy -msgid "Secured" -msgstr "Turvallisuus" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "Turvallisuus" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "Valitse tili" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "Valitse tiedosto" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -#, fuzzy -msgid "Send only account" -msgstr "Valitse tili" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "Lähettäjän osoite lisätty" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "Lähettäjän osoite poistettu" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "Lähettäjän osoitteet" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "Lähetysraja" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "Lähetysraja:" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "Erotin" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "Palvelu" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "Palvelu:" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "Asetukset" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "Asetukset: tämä etiketti" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "Näytä avain" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "Yksinkertainen käyttäjä" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "Määritä sähköpostiosoite" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "SPF-tietue löydetty" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "SPF-tietuetta ei löydy" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "Aloita nimen kirjoittaminen tästä..." - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -#, fuzzy -msgid "Statistics" -msgstr "Tilastot" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "Tila" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "Lähetä" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "Yhteenveto" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "Pääylläpitäjä" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "Tunnisteet" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "Kunkin rivin ensimmäinen elementti on pakollinen, ja sen on oltava yhtä suuri kuin jokin edellisistä arvoista." - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" -"Seuraavia palautuskoodeja voidaan käyttää kerran kutakin seuraavista syistä\n" -" jotta voit saada tilisi uudelleen käyttöön, jos menetät tilisi\n" -" esimerkiksi puhelimesi. Muista tallentaa ne turvalliseen paikkaan,\n" -" muuten et pääse enää tilillesi." - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" -"Seuraavia palautuskoodeja voidaan käyttää kerran kutakin, jotta\n" -" saada tilisi takaisin, jos kadotat puhelimesi\n" -" esimerkiksi. Varmista, että tallennat ne turvalliseen paikkaan, muutoin\n" -" et pääse enää käyttämään tiliäsi." - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "Tämä sivu on vielä rakenteilla." - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "Vastaanottaja" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "Siirto" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -#, fuzzy -msgid "Trusted sources" -msgstr "Resurssit" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "Kaksivaiheinent tunnistus" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "Kaksivaiheista tunnistusta (2FA) ei ole vielä aktivoitu tilillesi. Tämän ominaisuuden käyttöönotto lisää tilisi turvallisuutta." - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "Kaksivaiheisen tunnistuksen koodi" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -#, fuzzy -msgid "Two-Factor Authentication is enabled for your account." -msgstr "Onnittelut! Kaksivaiheinen tunnistus on nyt käytössä tililläsi." - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "Tyyppi" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "Tyyppi:" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "Tuntematon" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "rajoittamaton" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -#, fuzzy -msgid "Unlimited" -msgstr "rajoittamaton" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "Päivitä" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "Vaihda salasana" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "Päivitä asetukset" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "Päivitetty" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "Käytä verkkotunnuksen oletusarvoa" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -#, fuzzy -msgid "User unknown." -msgstr "Tuntematon" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "Käyttäjätunnus" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "Käyttäjätunnus:" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "Kelvollinen" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "Vahvistus" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "Tarkista koodi" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "Varoitus" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "Viikko" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "Tervetuloa Modoboaan" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "Postilaatikolla" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "Postilaatikolla" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "Vuosi" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "Kyllä" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "Olet poistamassa API-pääsytunnistetta" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "Voit käyttää erottimena eri merkkiä." - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "API-pääsytunnistetta ei ole vielä luotu." - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "API-pääsytunnisteesi on:" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "Salasanat eivät täsmää" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "Tämän kentän on oltava numero" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "Tämä kenttä on pakollinen" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "Virheellinen salasana" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "Asetukset: " - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "kyllä" - -#: src/filters/index.js:7 -msgid "no" -msgstr "ei" diff --git a/frontend/locale/fr/LC_MESSAGES/app.po b/frontend/locale/fr/LC_MESSAGES/app.po deleted file mode 100644 index a543594cd..000000000 --- a/frontend/locale/fr/LC_MESSAGES/app.po +++ /dev/null @@ -1,2144 +0,0 @@ -# -# Translators: -# Che Akycow, 2023 -# Antoine Nguyen , 2023 -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"Last-Translator: Antoine Nguyen , 2023\n" -"Language-Team: French (https://app.transifex.com/tonio/teams/13749/fr/)\n" -"Language: fr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: easygettext\n" -"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "(désactivé)" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "Une documentation de l'API est disponible" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "Une nouvelle clé sera générée bientôt. Actualisez dans un moment la page pour la voir." - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "Un utilisateur ayant tous les privilège, peut tout faire. Par défaut, il n'a pas de boîte mail et ne peut donc pas accéder aux fonctionnalités d'un utilisateur final." - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "Un utilisateur sans privilèges mais ayant une boîte mail. Il sera autorisé à utiliser toutes les fonctionnalités de l'utilisateur final : webmail, calendrier, contacts, filtres." - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "Un utilisateur avec des privilèges sur un ou plusieurs domaines. Il sera autorisé à administrer les boîtes mail et il peut avoir aussi une boîte aux lettres." - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "Plage de temps absolue" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "Compte" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "Compte créé" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "Compte supprimé" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "Compte introuvable !" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "Compte mis à jour" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "Actions" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "Ajouter" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "Ajouter un nouvel alias de domaine" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "Ajouter un administrateur" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "Ajouter l'adresse de l'expéditeur" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "Adresse" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "Adresse (nom d'hôte ou IP)" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "Adresse :" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "Domaines administrés" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "L'administrateur a ajouté" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "Nom de l'administrateur" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "Administrateur supprimé" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "Administrateurs" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "Administrateur de {{ domain.name }}" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "Alarme fermée" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "Alarme supprimée" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "Alarme ré-ouverte" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "Alarmes" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "Alarmes supprimées" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "Alias" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "Alias créé" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "Alias supprimé" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "Alias mis à jour" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "Alias(s) de cette boîte aux lettres. Pour créer un alias fourre-tout, entrer uniquement le nom du domaine (@domain.tld)." - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "Alias" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Aliases:" -msgstr "Alias" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "Alignement" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "API" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "Accès API" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "Jeton API copié dans votre presse-papier" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "Jeton API créé" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "Jeton API supprimé" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "Appliquer" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "Domaines associés" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "Journal des modifications" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "Authentification" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "Configuration automatique" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "Enregistrement autoconfig (Mozilla) introuvable" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "Enregistrement autoconfig (Mozilla) : %{ value }" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "Enregistrement autodiscover (Microsoft) non trouvé" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "Enregistrement autodiscover (Microsoft): %{ value }" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "Retour" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "Format bind/named. Cliquez pour copier" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "Corps" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "Annuler" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "Modifier le mot de passe" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "Vérifier la connexion :" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "Consulter la liste suivante pour trouver des composants associés" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "Cochez cette option si les mots de passe contenus dans votre fichier ne sont pas chiffrés" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "Choisissez un domaine" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "Choisissez un rôle" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "Fermer" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "Fermer l'alarme" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "Fermé" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "Confirmer et créer" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "Confirmation" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "Félicitations ! l'authentification à double facteur est maintenant activée sur votre compte" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "Connexion" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "Continuer en cas d'erreur" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "Contrôler si ce domaine sera autorisé à envoyer et recevoir des messages." - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "Copier dans le presse-papiers" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "Copier le jeton dans la presse-papiers" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "Créer un administrateur de domaine" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "Créer une boite aux lettres pour l'administrateur" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "Créer des alias" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "Créer des aliases standard pour le domaine" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "Date de création" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "Chiffrer les mots de passe" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "Mot de passe actuel" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "Limite quotidienne d'envoi de messages" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "Limite d'envoi quotidienne" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "Tableau de bord" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "Date" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "Jour" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "Quota par défaut pour une boîte aux lettres" - -#: src/components/domains/DomainLimitationsForm.vue:6 -msgid "Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "Supprimer" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "Supprimer le jeton" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "Description" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "Détail" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "Désactiver l'authentification à double facteur" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "Désactivés" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "Clé DKIM" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "Longeur de clé DKIM" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "Sélecteur de clé DKIM" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "Des clés DKIM existent déjà pour ce domaine. Voulez-vous les écraser?" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "Clé publique DKIM pour " - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "Enregistrement DKIM trouvé" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "Enregistrement DKIM introuvable" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "Signature DKIM" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "DMARC" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "Enregistrement DMARC trouvé" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "Enregistrement DMARC introuvable" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "La support DMARC ne semble pas actif pour ce domaine." - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "DNS" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "Vérifications DNS" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "Configuration DNS pour" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "Aide à la configuration du DNS" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "Statut DNS" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "Ne pas supprimer le dossier du compte" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "Ne pas supprimer le dossier des domaines" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "Voulez-vous réellement supprimer l'alias %{ alias }?" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "Voulez-vous vraiment supprimer les identités sélectionnées?" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "Domaine" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "Administrateur de domaine" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "Alias de domaine créé" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "Alias de domaine supprimé" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "Alias de domaine mise à jour" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "Domaine créé" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "Valeur du domaine par défaut" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "Supprimer le domaine" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "Nom de domaine (ex: domaine.tld)" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "Domaine mise à jour" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "La valeur par défaut du domaine" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "Domaines" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "Ne pas traiter les objets dupliqués comme des erreurs" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "Modifier" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "Modifier le compte" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "Modifier l'alias" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "Modifier le domaine" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "Modifier l'alias de domaine" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "Modifier le fournisseur" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "élément" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "E-mail" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "Adresse email" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "Fournisseurs de messagerie" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "Vide" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "Activer 2FA" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "Activer la signature DKIM" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "Activer les tests DNS" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "Activé" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "Entrer un nom d'utilisateur simple ou une adresse e-mail" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "Entrer une adresse e-mail" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "Entrez le code de l'application à double facteur sur votre téléphone mobile. Si vous avez perdu votre appareil, vous pouvez entrez l'un de vos code de récupération." - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "Entrez le code que vous venez de recevoir par SMS" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "erreur" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "Erreur" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "Ex: 10MB. Laisser vide pour aucune limite" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "Expire le" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "Exporter les comptes et les alias au format CSV" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "Exporter les domaines et les alias au format CSV" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "Échoué" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "Prénom" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "Mot de passe oublié ?" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "Transfert" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "Transférer les messages et stocker des copies dans votre boîte aux lettres locale" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "Transfert mise à jour" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "Transféré" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "Transporteur avec ARC" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "De" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "Nom complet" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "Nom complet / destinataire" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "Entièrement aligné" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "Général" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "Information générale" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "Paramètres généraux " - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "Générer" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "Générer une nouvelle clé DKIM" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "Générer un mot de passe aléatoire pour cet administrateur." - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "aide" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "Voici un exemplaire de configuration DNS (format bind). Remplacer les valeurs entre [ ] par les valeurs appropriées." - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "Nom d'hôte de votre serveur automx" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "Identification" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "Identités" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "Identités supprimées" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "Si vous fermez ce formulaire maintenant, vos modifications ne seront pas sauvegardées. Confirmez-vous ?" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "Si vous l'avez récemment configuré, veuillez attendre que le premier rapport soit reçu et traité. " - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "Migration IMAP" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "Port IMAP" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "Importer" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "Importation de comptes et alias à partir d'un fichier CSV" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "Importer des domaines" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "Importation de domaines et alias à partir d'un fichier CSV" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "Importer des identités" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "Indiquer un ou plusieurs destinataires séparés par une virgule (,) " - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "Information" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" -"Installez un logiciel d'authentification de jeton comme FreeOTP ou google\n" -" Authentification depuis votre magasin d'applications et utilisez\n" -" cette application pour scanner ce QR code." - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "Composants installés" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "Version installée" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "Jeton de réinitialisation incorrect." - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "Nom d'utilisateur et/ou mot de passe incorrect" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "Adresse IP de votre serveur Modoboa" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "La connexion IMAP est-elle sécurisée via l'utilisation de SSL/TLS ou StartTLS" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" -"Il présentera un résumé du statut de votre serveur Modoboa\n" -" et quelques informations utiles sur le produit." - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "Conserver des copies locales" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "Langage" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "Date de dernière connexion" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "Date de dernière modification" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "Nom de famille" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "Dernière version" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "Laisser vide pour aucune limite" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "Niveau" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "Limites" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "Domaine local (optionnel)" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "Logger" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "Déconnexion" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "Boîte aux lettres" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -#, fuzzy -msgid "Mailbox aliases:" -msgstr "Boîtes aux lettres" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Mailbox:" -msgstr "Boîte aux lettres" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "Boîtes aux lettres" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "Message" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "Historique des messages" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "Limite d'envoi des messages" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "messages" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "Messages" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "Migration supprimée" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -msgid "Migrations" -msgstr "Migrations" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "Modifié" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "Modifier" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "Mois" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "Enregistrements MX" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "Nom" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "Nom de l'administrateur" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "Nom du domaine à migrer" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "Nom :" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "Jamais connecté" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "Nouvelle" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "Nouveau compte" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "Nouvel alias" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "Nouveau domaine" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "Nouveau fournisseur" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "Nouveaux codes de récupération" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "Suivant" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "Non" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "Aucun domaine associé" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "Aucune adresse d'expéditeur définie pour ce compte" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "Pas de limite d'envoi" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "Non générée" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -#, fuzzy -msgid "Number of allowed mailbox aliases:" -msgstr "Nombre de domaines associés :" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Number of allowed mailboxes:" -msgstr "Nombre de domaines associés :" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Number of associated alias:" -msgstr "Nombre de domaines associés :" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "Nombre de domaines associés :" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "Nombre de messages que ce domaine peut envoyer par jour. Laisser vide pour aucune limite." - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "Nombre de messages que cette boîte aux lettres peut envoyer par jour. Laisser vide pour aucune limite." - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "Ok" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "OK" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "Ancien compte" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "Une ou plusieurs mise à jour sont disponibles" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "Ouvert" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "Alarmes ouvertes" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "Options" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "Paramètres mis à jour" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "Partiellement aligné" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "Sources partiellement fiables / Transitaires" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "Mot de passe" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "Mot de passe copié dans la presse-papier" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "Récupération de mot de passe" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "Mot de passe mis à jour" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "En attente" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "Période" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "Numéro de téléphone" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "Code Pin" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "Veillez renseigner votre adresse e-mail principale" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "Port" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "Problème" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "Procéder" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "Profil" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "Profil mis à jour" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "Fournir un fichier CSV dont les lignes respectent l'un des formats suivants:" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "Fournisseur" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -msgid "Provider created" -msgstr "Fournisseur créé" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "Fournisseur supprimé" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "Nom du fournisseur" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -msgid "Provider updated" -msgstr "Fournisseur mis à jour" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "Fournisseurs" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "ID de file" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "Quota" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "Quota pour cette boite. Peut être exprimé en Ko, Mo (défaut) ou Go. Définir une valeur spécifique ou utiliser la valeur par défaut du domaine. Laisser vide pour définir une valeur illimitée (interdit pour les admins. de domaine)." - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Quota partagé entre les boîtes aux lettres. Peut être exprimé en Ko, Mo (défaut) ou Go. Une valeur à 0 signifie pas de quota." - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "Quota:" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "Adresse aléatoire" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "Mot de passe aléatoire" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "Format brut. Cliquer pour copier" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "Destinataire(s)" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "Destinataires" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "Enregistrer" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "Intervalles des temps relatifs" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "Relais" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "Recharger" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "Se souvenir de moi" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "Supprimer cette adresse" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "Supprimer cet administrateur" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "Ré-ouvrir l'alarme" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "Revendeur" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "Renvoyer le SMS." - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "Rénitialiser les codes de récupération" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "Ressources" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "Utilisation des ressources" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "Réessayer la rénitialisation" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "Retour à la connexion" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "Rôle" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "Enregistrer" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "Chercher" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "E-mail secondaire" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "Sécurisé" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "Sécurité" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "Sélectionner un compte" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "Sélectionner un fichier" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -#, fuzzy -msgid "Send only account" -msgstr "Sélectionner un compte" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "Adresse d'expédition ajoutée" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "Adresse d'expédition supprimée" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "Adresses d'expédition" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "Limite d'envoi" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "Limite d'envoi :" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "Séparateur" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "Service" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "Service :" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "Paramètres" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "Paramètres : thislabel" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "Afficher la clé" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "Utilisateur simple" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "Spécifier une adresse e-mail" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "Enregistrement SPF trouvé" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "Enregistrement SPF introuvable" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "Commencer à saisir un nom ici..." - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "Statistiques" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "Statut" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "Soumettre" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "Résumé" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "Super administrateur" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "Tags" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "Le premier élément de chaque ligne est obligatoire et doit être égal à l'une des valeurs précédentes." - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" -"Le code de récupération suivant est à usage unique\n" -" pour vous permettre d'accéder à votre compte, en cas de perte de votre\n" -" téléphone par exemple. Soyez convaincu de l'avoir sauvegardé dans un endroit sûr,\n" -" sinon vous ne pourrez plus jamais accéder à votre compte. " - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "Les codes de récupération suivants peuvent être utilisés une fois chacun pour vous permettre de récupérer un accès à votre compte, au cas où vous perdriez votre téléphone par exemple. Assurez-vous de les conserver dans un lieu sûr, autrement vous ne serez définitivement plus en mesure d'accéder à votre compte." - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "Cette page est en cours de construction." - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "titre" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "A" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "Trop de tentatives sans succès, veuillez réessayer plus tard" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "Total" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "TOTP envoyé." - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "Transport" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "Déclenché" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "Sources de confiance" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "Authentification à double facteur" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "L'authentification à double facteur (2FA) n'est pas encore activée pour votre compte. L'activation de cette fonctionnalité augmentera la sécurité de votre compte." - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "Code d'authentification double facteur" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -#, fuzzy -msgid "Two-Factor Authentication is enabled for your account." -msgstr "Félicitations ! l'authentification à double facteur est maintenant activée sur votre compte" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "Type" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "Type :" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "Inconnu" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "Sources inconnues / Menaces" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "illimité" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -#, fuzzy -msgid "Unlimited" -msgstr "illimité" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "Mettre à jour" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "Mise à jour du mot de passe" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "Mise à jour des paramètres" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "Mis à jour" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "Utiliser la valeur par défaut du domaine" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "L'utilisateur semble erroné, revenez à la connexion ou redémarrer réinitialisez le processus " - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "Utilisateur inconnu." - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "Nom d'utilisateur" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "Nom d'utilisateur :" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "Valide" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "Vérification" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "Vérifier le code" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "Avertissement" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "Semaine" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "Bienvenue dans Modoboa" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "Avec une boite aux lettres" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "Avec boîte aux lettres" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "Année" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "Oui" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "Vous êtes sur le point de supprimer votre jeton d'accès à l'API" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "Vous pouvez utiliser autre caractère comme séparateur" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "Vous avez une ou plusieurs alarmes ouvertes" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "Votre jeton API n'a pas encore été généré." - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "Votre jeton API est :" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "Les mots de passe diffèrent" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "Ce champ doit contenir un numéro valide" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "Ce champ est requis" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "Mot de passe incorrect" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "Spécifier un numéro de port correct" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "Paramètres :" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "Votre limite est atteinte, veuillez réessayer plus tard" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "oui" - -#: src/filters/index.js:7 -msgid "no" -msgstr "non" diff --git a/frontend/locale/it/LC_MESSAGES/app.po b/frontend/locale/it/LC_MESSAGES/app.po deleted file mode 100644 index dfba7b2d2..000000000 --- a/frontend/locale/it/LC_MESSAGES/app.po +++ /dev/null @@ -1,2145 +0,0 @@ -# Italian translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: it\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "(disabilitato)" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "Account" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "Account creato" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -#, fuzzy -msgid "Account not found!" -msgstr "Account creato" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "Account aggiornato" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "Azioni" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "Aggiungi" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "Indirizzo" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "Domini amministrati" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "Amministratori" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "Alias" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "Alias creato" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "Alias" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Aliases:" -msgstr "Alias" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "API" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "Accesso API" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "Applica" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -#, fuzzy -msgid "Associated domains" -msgstr "Domini amministrati" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "Autenticazione" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "Formato bind/named" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "Cambia password" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "Seleziona questa opzione se le password contenute nel file non sono criptate" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "Chiudi" - -#: src/components/alarms/AlarmList.vue:84 -#, fuzzy -msgid "Close alarm" -msgstr "Chiudi" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "Chiudi" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "Conferma" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "Continuare in caso di errore" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "Crea un amministratore di dominio" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "Crea una casella di posta per l'amministratore." - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "Crea alias" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "Data di creazione" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "Cripta le password" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "Giorno" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "Dimensione massima predefinita per le mailbox" - -#: src/components/domains/DomainLimitationsForm.vue:6 -msgid "Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Valore predefinito per lo spazio massimo confiviso tra le mailbox. Può essere espresso in KB, MB (predefinito) o GB. Il valore 0 indica nessun limite." - -#: src/components/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "Descrizione" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "Disabilitato" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "Chiave DKIM" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "DNS" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "Stato del DNS" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "Dominio" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "Amministratore di dominio" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "Dominio creato" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "Domini" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "Indirizzo email" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -#, fuzzy -msgid "Email providers" -msgstr "Indirizzo email" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "Abilita la firma DKIM" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "Abilita i controlli DNS" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "Abilitato" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "Scade il" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "Fallito" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "Password dimenticata?" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "Inoltra" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "Inoltra i messaggi e memorizza le copie nella tua casella di posta locale" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "Inoltro aggiornato" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -#, fuzzy -msgid "Forwarded" -msgstr "Inoltra" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "Nome completo" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -#, fuzzy -msgid "Fully aligned" -msgstr "Completamente allineato" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "Generale" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "Genera una password casuale per l'amministratore." - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "Identità" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -#, fuzzy -msgid "Identities deleted" -msgstr "Identità" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "Importa" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "Importa domini" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "Identità di importazione" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "Informazioni" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "Versione installata" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "Mantieni copie locali" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "Data dell'ultima modifica" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "Livello" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "Logger" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "Esci" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "Caselle di posta" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -#, fuzzy -msgid "Mailbox aliases:" -msgstr "Caselle di posta" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Mailbox:" -msgstr "Caselle di posta" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "Caselle di posta" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "Utilizzo" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -#, fuzzy -msgid "Migration deleted" -msgstr "Data di creazione" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -#, fuzzy -msgid "Migrations" -msgstr "Conferma" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "Modificato" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "Mese" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "Nome" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "Nuovo account" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "Nuovo alias" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "Nuovo dominio" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "Successivo" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "Non generata" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -#, fuzzy -msgid "Old account" -msgstr "Nuovo account" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "Sono disponibili nuovi aggiornamenti" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "Opzioni" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "Parzialmente allineato" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "Password" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "Numero di telefono" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "Profilo" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "Profilo aggiornato" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -#, fuzzy -msgid "Provider created" -msgstr "Dominio creato" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -#, fuzzy -msgid "Provider updated" -msgstr "Profilo aggiornato" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "Dimensione massima" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "Dimensione massima per questa mailbox, può essere espressa in KB, MB (predefinito) o GB. Definire un valore personalizzato o utilizzare quello predefinito per il dominio. Lasciare vuoto per specificare un valore non limitato (non permesso per amministratori di dominio)." - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Spazio massimo confiviso tra le mailbox. Può essere espresso in KB, MB (predefinito) o GB. Il valore 0 indica nessun limite." - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "Indirizzo casuale" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "Password casuale" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "Destinatario(i)" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "Destinatari" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "Ricordami" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "Rivenditore" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "Risorse" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "Utilizzo risorse" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "Ruolo" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "Salva" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "Ricerca" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "Email secondaria" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -#, fuzzy -msgid "Send only account" -msgstr "Nuovo account" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "Indirizzi mittenti" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "Separatore" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "Impostazioni" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "Visualizza chiave" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "Utente semplice" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -#, fuzzy -msgid "Statistics" -msgstr "Statistiche" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "Stato" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "Invia" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "Sommario" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "Super amministratore" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "Tag" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "Totale" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "Trasporto" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -#, fuzzy -msgid "Trusted sources" -msgstr "Fonti attendibili" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "Tipo" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "Sconosciuto" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "Fonti sconosciute / Minaccie" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "senza limiti" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -#, fuzzy -msgid "Unlimited" -msgstr "senza limiti" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "Aggiorna" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "Aggiornato" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "Usa il valore predefinito" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "Nome utente" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "Settimana" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "Benvenuti in Modoboa" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "Con una casella di posta" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "Anno" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "Le password non corrispondono" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "Questo campo è obbligatorio" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/ja/LC_MESSAGES/app.po b/frontend/locale/ja/LC_MESSAGES/app.po deleted file mode 100644 index 6660814af..000000000 --- a/frontend/locale/ja/LC_MESSAGES/app.po +++ /dev/null @@ -1,2126 +0,0 @@ -# Japanese translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: ja\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Aliases:" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Mailbox:" -msgstr "" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -msgid "Migrations" -msgstr "" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -msgid "Provider created" -msgstr "" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -msgid "Provider updated" -msgstr "" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -msgid "Send only account" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -msgid "Unlimited" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/nl/LC_MESSAGES/app.po b/frontend/locale/nl/LC_MESSAGES/app.po deleted file mode 100644 index 72fbff1f7..000000000 --- a/frontend/locale/nl/LC_MESSAGES/app.po +++ /dev/null @@ -1,2126 +0,0 @@ -# Dutch translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: nl\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Aliases:" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Mailbox:" -msgstr "" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -msgid "Migrations" -msgstr "" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -msgid "Provider created" -msgstr "" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -msgid "Provider updated" -msgstr "" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -msgid "Send only account" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -msgid "Unlimited" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/pl/LC_MESSAGES/app.po b/frontend/locale/pl/LC_MESSAGES/app.po deleted file mode 100644 index ba0455a3a..000000000 --- a/frontend/locale/pl/LC_MESSAGES/app.po +++ /dev/null @@ -1,2126 +0,0 @@ -# Polish translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: pl\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==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Aliases:" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Mailbox:" -msgstr "" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -msgid "Migrations" -msgstr "" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -msgid "Provider created" -msgstr "" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -msgid "Provider updated" -msgstr "" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -msgid "Send only account" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -msgid "Unlimited" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/po/LC_MESSAGES/app.po b/frontend/locale/po/LC_MESSAGES/app.po deleted file mode 100644 index 491c15c03..000000000 --- a/frontend/locale/po/LC_MESSAGES/app.po +++ /dev/null @@ -1,2125 +0,0 @@ -# Language po translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: po\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Aliases:" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Mailbox:" -msgstr "" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -msgid "Migrations" -msgstr "" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -msgid "Provider created" -msgstr "" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -msgid "Provider updated" -msgstr "" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -msgid "Send only account" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -msgid "Unlimited" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/pt-br/LC_MESSAGES/app.po b/frontend/locale/pt-br/LC_MESSAGES/app.po deleted file mode 100644 index a4eeb8c1b..000000000 --- a/frontend/locale/pt-br/LC_MESSAGES/app.po +++ /dev/null @@ -1,2125 +0,0 @@ -# Language pt-br translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: pt-br\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Aliases:" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Mailbox:" -msgstr "" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -msgid "Migrations" -msgstr "" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -msgid "Provider created" -msgstr "" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -msgid "Provider updated" -msgstr "" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -msgid "Send only account" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -msgid "Unlimited" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/pt/LC_MESSAGES/app.po b/frontend/locale/pt/LC_MESSAGES/app.po deleted file mode 100644 index 0e8ccc9ad..000000000 --- a/frontend/locale/pt/LC_MESSAGES/app.po +++ /dev/null @@ -1,2126 +0,0 @@ -# Portuguese translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: pt\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Aliases:" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Mailbox:" -msgstr "" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -msgid "Migrations" -msgstr "" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -msgid "Provider created" -msgstr "" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -msgid "Provider updated" -msgstr "" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -msgid "Send only account" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -msgid "Unlimited" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/ru/LC_MESSAGES/app.po b/frontend/locale/ru/LC_MESSAGES/app.po deleted file mode 100644 index 01381e657..000000000 --- a/frontend/locale/ru/LC_MESSAGES/app.po +++ /dev/null @@ -1,2144 +0,0 @@ -# Russian translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\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=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "Разрешен" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "Добавить аккаунт" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "Аккаунт создан" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -#, fuzzy -msgid "Account not found!" -msgstr "Аккаунт создан" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "аккаунт изменен" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "Действие" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "Адрес" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "Адрес" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "Список квот" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "Администраторы" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "Синоним" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "Синоним создан" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "Синоним(ы)" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Aliases:" -msgstr "Синоним(ы)" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "API" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "Применить" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -#, fuzzy -msgid "Associated domains" -msgstr "Список квот" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "Аутентификация" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "Неверный формат" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "Изменить пароль" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "Выберите эту опцию если пароль в вашем файле не зашифрован " - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "Подтверждение" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "Продолжать при ошибке" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "Создание администратора домена" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "Создание администратора домена" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "Создание синонимов" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "Дата создания" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "Шифровать пароль" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "Приборная панель" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "День" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "Разрешен" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "Статистика" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "Администратор домена" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "Домен создан" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "Домены" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "Е-майл адрес" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -#, fuzzy -msgid "Email providers" -msgstr "Е-майл адрес" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "Разрешено" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "Забыли пароль?" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "Перенаправленые" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "Перенаправление сообщения, и сохранение копии в вашем локальном почтовом ящике" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "Перенаправление обновлено" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -#, fuzzy -msgid "Forwarded" -msgstr "Перенаправленые" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "Имя файла" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -#, fuzzy -msgid "Fully aligned" -msgstr "Имя файла" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "Основные" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "Создание администратора домена" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "Пользователи" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -#, fuzzy -msgid "Identities deleted" -msgstr "Пользователи" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "Импорт" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "Импорт доменов" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "Импорт информации о пользователях" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "Информация" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "Установленная версия" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "Сохранить локальную копию" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "Дата последней модификации" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "Уровень" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "Логгер" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "Завершить сеанс" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "Почтовые ящики" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -#, fuzzy -msgid "Mailbox aliases:" -msgstr "Почтовые ящики" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Mailbox:" -msgstr "Почтовые ящики" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "Почтовые ящики" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "использование (%%)" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -#, fuzzy -msgid "Migration deleted" -msgstr "Дата создания" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -#, fuzzy -msgid "Migrations" -msgstr "Подтверждение" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "Синоним изменен" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "Месяц" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "Логин" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "Новый аккаунт" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "Новый синоним" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "Новый домен" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "Следующая" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "Получатель не определен" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -#, fuzzy -msgid "Old account" -msgstr "Новый аккаунт" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "Доступны одно или более обновлений." - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "Опции" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "Пароль" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "Профиль обновлен" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -#, fuzzy -msgid "Provider created" -msgstr "Домен создан" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -#, fuzzy -msgid "Provider updated" -msgstr "Профиль обновлен" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "Квота в мегабайтах для этого почтового ящика. Определите собственное значение или используйте значение по умолчанию для родительского домена. Оставьте пустым для неограниченного значения. (Не разрешено администраторам домена)" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "Ошибочный запрос" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "Ошибочный запрос" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "Получатели" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "Получатели" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "Запомнить меня" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "Реселлер" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "Ресурсы" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "Использование ресурсов" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "Роль" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "Сохранить" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "Поиск" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -#, fuzzy -msgid "Send only account" -msgstr "Новый аккаунт" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "Ошибочный запрос" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "Разделитель" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "Настройки" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "Обычный пользователь" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -#, fuzzy -msgid "Statistics" -msgstr "Статистика" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "Статистика" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "Подтвердить" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "Супер администратор" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "Теги" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -#, fuzzy -msgid "Trusted sources" -msgstr "Ресурсы" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "Неизвестное" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "Не лимитировано" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -#, fuzzy -msgid "Unlimited" -msgstr "Не лимитировано" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "Обновление" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "Обновление" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "Используются значения домена по умолчанию " - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "Логин пользователя" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "Неделя" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "Добро пожаловать в Modoboa!" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "Год" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "Пароли не совпадают" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/sv/LC_MESSAGES/app.po b/frontend/locale/sv/LC_MESSAGES/app.po deleted file mode 100644 index 42dfcb195..000000000 --- a/frontend/locale/sv/LC_MESSAGES/app.po +++ /dev/null @@ -1,2148 +0,0 @@ -# Swedish translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: sv\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "(inaktiverad)" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "Konto" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "Konto skapat" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -#, fuzzy -msgid "Account not found!" -msgstr "Konto skapat" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "Konto uppdaterat" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "Åtgärder" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "Lägg till" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "Adress" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "Administrerade domäner" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "Administratörer" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "Alias" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "Alias skapat" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "Alias" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Aliases:" -msgstr "Alias" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "API" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "API åtkomst" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "Applicera" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -#, fuzzy -msgid "Associated domains" -msgstr "Administrerade domäner" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "Autentisering" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "Bind/named format" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "Ändra lösenord" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "Markera det här alternativet om lösenord i filen inte är krypterad" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "Stäng" - -#: src/components/alarms/AlarmList.vue:84 -#, fuzzy -msgid "Close alarm" -msgstr "Stäng" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "Stäng" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "Bekräftelse" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "Grattis! Tvåfaktorsautentisering är nu aktiverat för ditt konto." - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "Fortsätt vid fel" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "Skapa en domän administratör" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "Skapa en brevlåda för administratören." - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "Skapa alias." - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "Skapelsedatum" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "Krypterade lösenord" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "Kontrollpanel" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "Dag" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "Standard brevlåde kvota" - -#: src/components/domains/DomainLimitationsForm.vue:6 -msgid "Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Standardkvota i MB applicerad på nya brevlådor. 0 betyder ingen kvota." - -#: src/components/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "Beskrivning" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "Inaktivera 2FA" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "Inaktiverad" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "DKIM nyckel" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "DNS" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "DNS status" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "Domän" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "Domänadministratör" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "Domän skapad" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "Domäner" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "E-post adress" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -#, fuzzy -msgid "Email providers" -msgstr "E-post adress" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "Aktivera 2FA" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "Aktivera DKIM-signering" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "Aktivera DNS kontroller" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "Aktiverad" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "Ange koden du precis fick via SMS" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "Går ut" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "Misslyckades" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "Glömt ditt lösenord?" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "Vidarebefordra" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "Vidarebefordra meddelande och spara kopia i din lokala brevlåda" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "Vidarebefordring uppdaterad" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -#, fuzzy -msgid "Forwarded" -msgstr "Vidarebefordra" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "Fullständigt nam" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -#, fuzzy -msgid "Fully aligned" -msgstr "Helt i linje" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "Generellt" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "Skapa ett slumpmässigt lösenord för administratören." - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "Konton" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -#, fuzzy -msgid "Identities deleted" -msgstr "Konton" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "Importera" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "Importera domäner" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "Importera konton" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "Information" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "Installerad version" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "Behåll lokal kopia" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "Senast ändrad" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "Nivå" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "Loggare" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "Logga ut" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "Brevlådor" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -#, fuzzy -msgid "Mailbox aliases:" -msgstr "Brevlådor" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -#, fuzzy -msgid "Mailbox:" -msgstr "Brevlådor" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "Brevlådor" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "Användande" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -#, fuzzy -msgid "Migration deleted" -msgstr "Skapelsedatum" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -#, fuzzy -msgid "Migrations" -msgstr "Bekräftelse" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "Ändrad" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "Månad" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "Namn" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "Nytt konto" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "Nytt alias" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "Ny domän" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -#, fuzzy -msgid "New provider" -msgstr "Nya återställningskoder" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "Nya återställningskoder" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "Nästa" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "Ej genererad" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -#, fuzzy -msgid "Old account" -msgstr "Nytt konto" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "En eller fler uppdateringar finns tillgängliga" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "Inställningar" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "Delvis i linje" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "Lösenord" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "Telefonnummer" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "Pinkod" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "Var vänlig fyll i din primära e-postadress" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "Profil" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "Profil uppdaterad" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -#, fuzzy -msgid "Provider created" -msgstr "Domän skapad" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -#, fuzzy -msgid "Provider updated" -msgstr "Profil uppdaterad" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "Kvot i MB för denna brevlåda. Definiera ett anpassat värde eller använda domänens förvalda. Lämna tomt för att definiera ett obegränsat värde (ej tillåtet för domänadministratörer)." - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "Standardkvota i MB applicerad på nya brevlådor. 0 betyder ingen kvota." - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "Slumpmässig adress" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "Slumpmässigt lösenord" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "Mottagare" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "Mottagare" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "Registrera" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "Kom ihåg mig" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "Återförsäljare" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "Återställ återställningskoder" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "Resurser" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "Resurs användande" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "Roll" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "Spara" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "Sök" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "Sekundär e-post" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -#, fuzzy -msgid "Secured" -msgstr "Säkerhet" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "Säkerhet" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -#, fuzzy -msgid "Send only account" -msgstr "Nytt konto" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "Avsändaradress" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "Separator" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "Inställningar" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "Visa nyckel" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "Enkel användare" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -#, fuzzy -msgid "Statistics" -msgstr "Statistik" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "Status" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "Skicka" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "Sammanställning" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "Super administratör" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "Tagg" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "Totalt" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "Transport" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -#, fuzzy -msgid "Trusted sources" -msgstr "Betrodda källor" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "Tvåfaktorsautentisering (2FA) har inte aktiverats för ditt konto. Aktivering ökar ditt kontos säkerhet." - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -#, fuzzy -msgid "Two-Factor Authentication is enabled for your account." -msgstr "Grattis! Tvåfaktorsautentisering är nu aktiverat för ditt konto." - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "Typ" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "Okänt" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "Okända källor / Hot" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "obegränsad" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -#, fuzzy -msgid "Unlimited" -msgstr "obegränsad" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "Uppdatera" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "Uppdaterad" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "Använd domänens standardvärde" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "Användarnamn" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "Vecka" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "Välkommen till Modoboa" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "Med en brevlåda" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "År" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "Lösenord matchar inte" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "Detta fält är obligatoriskt" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/tr/LC_MESSAGES/app.po b/frontend/locale/tr/LC_MESSAGES/app.po deleted file mode 100644 index 32c2280ba..000000000 --- a/frontend/locale/tr/LC_MESSAGES/app.po +++ /dev/null @@ -1,2133 +0,0 @@ -# Turkish translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: tr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Aliases:" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "API" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "API erişimi" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "Kimlik Doğrulama" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "Parolayı değiştirin" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "Kapat" - -#: src/components/alarms/AlarmList.vue:84 -#, fuzzy -msgid "Close alarm" -msgstr "Kapat" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "Onayla" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "Tebrikler! Artık hesabınız için İki Faktörlü Kimlik Doğrulama etkinleştirildi." - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "Gösterge Paneli" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "Tarih" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "Tanım" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "2FA'yı devre dışı bırak" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "Alan adı Yöneticisi" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "2FA'yı etkinleştir" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "Az önce SMS ile aldığınız kodu giriniz" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "Parolanızı mı unuttunuz?" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "Kimden" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "Genel" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "Bilgi" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "Kurulu sürüm" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "Seviye" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "Kayıtçı" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "Çıkış Yapın" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Mailbox:" -msgstr "" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "İleti" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -#, fuzzy -msgid "Migrations" -msgstr "Onayla" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "İsim" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -#, fuzzy -msgid "New provider" -msgstr "Yeni kurtarma kodları" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "Yeni kurtarma kodları" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "Sonraki" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "Hayır" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "Bir veya daha fazla güncelleme mevcut" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "Parola" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "Telefon numarası" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "Pin kodu" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "Lütfen birincil e-posta adresinizi girin" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "Profil" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "Profil güncellendi" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -#, fuzzy -msgid "Provider created" -msgstr "Profil güncellendi" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -#, fuzzy -msgid "Provider updated" -msgstr "Profil güncellendi" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "Kayıt ol" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "Beni hatırla" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "Bayii" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "Kurtarma kodlarını sıfırla" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "Rol" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "Kaydet" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "İkincil e-posta" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -#, fuzzy -msgid "Secured" -msgstr "Güvenlik" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "Güvenlik" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -msgid "Send only account" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "Ayarlar" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "Basit kullanıcı" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "Gönder" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "Süper Yönetici" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "Kime" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "Hesabınız için İki Faktörlü Kimlik Doğrulama (2FA) henüz etkinleştirilmedi. Bu özelliği etkinleştirmek hesabınızın güvenliğini artıracaktır." - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -#, fuzzy -msgid "Two-Factor Authentication is enabled for your account." -msgstr "Tebrikler! Artık hesabınız için İki Faktörlü Kimlik Doğrulama etkinleştirildi." - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "Bilinmeyen" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -msgid "Unlimited" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "Güncelle" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "Kullanıcı adı" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "Modoboa'ya hoş geldiniz" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "Evet" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "Parolalar uyuşmuyor" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "Bu alan gerekli" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/locale/zh-hant/LC_MESSAGES/app.po b/frontend/locale/zh-hant/LC_MESSAGES/app.po deleted file mode 100644 index 31f32b2c9..000000000 --- a/frontend/locale/zh-hant/LC_MESSAGES/app.po +++ /dev/null @@ -1,2125 +0,0 @@ -# Language zh-hant translations for Modoboa package. -# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER -# This file is distributed under the same license as the Modoboa package. -# Automatically generated, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: Modoboa 0.1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-07 16:39+0100\n" -"PO-Revision-Date: 2023-02-23 11:26+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: zh-hant\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:12 -msgid "(disabled)" -msgstr "" - -#: src/views/user/APISetup.vue:29 -msgid "A documentation of the API is available" -msgstr "" - -#: src/components/domains/DNSDetail.vue:47 -#: src/components/domains/DNSDetail.vue:207 -msgid "A new key will be generated soon. Refresh the page in a moment to see it." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:63 -#: src/components/identities/AccountRoleForm.vue:93 -msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:42 -#: src/components/identities/AccountRoleForm.vue:72 -msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:49 -#: src/components/identities/AccountRoleForm.vue:79 -msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:16 -msgid "Absolute time range" -msgstr "" - -#: src/views/identities/Account.vue:3 src/views/identities/Identities.vue:20 -msgid "Account" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:166 -#: src/components/identities/AccountCreationForm.vue:218 -msgid "Account created" -msgstr "" - -#: src/components/identities/IdentityList.vue:80 -#: src/components/identities/IdentityList.vue:162 -msgid "Account deleted" -msgstr "" - -#: src/views/identities/Account.vue:29 src/views/identities/Account.vue:64 -msgid "Account not found!" -msgstr "" - -#: src/components/identities/AccountForm.vue:73 -#: src/components/identities/AccountForm.vue:258 -msgid "Account updated" -msgstr "" - -#: src/components/alarms/AlarmList.vue:20 -#: src/components/domains/DomainList.vue:30 -#: src/components/identities/IdentityList.vue:6 -#: src/components/identities/IdentityList.vue:2 -#: src/components/identities/IdentityList.vue:20 -#: src/components/imap_migration/MigrationsList.vue:16 -#: src/components/imap_migration/ProvidersList.vue:20 -#: src/components/imap_migration/ProvidersList.vue:112 -#: src/components/imap_migration/MigrationsList.vue:71 -#: src/components/alarms/AlarmList.vue:100 -#: src/components/domains/DomainList.vue:173 -#: src/components/identities/IdentityList.vue:102 -msgid "Actions" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Add" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Add a new domain alias" -msgstr "" - -#: src/components/domains/AdministratorList.vue:30 -msgid "Add administrator" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:24 -msgid "Add sender address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:19 -#: src/components/identities/AccountSenderAddresses.vue:12 -#: src/components/identities/AliasCreationForm.vue:20 -#: src/components/imap_migration/ProviderCreationForm.vue:30 -#: src/components/imap_migration/ProvidersList.vue:16 -#: src/components/imap_migration/ProviderCreationForm.vue:52 -#: src/components/imap_migration/ProvidersList.vue:108 -#: src/components/domains/DNSDetail.vue:179 -#: src/components/identities/AccountSenderAddresses.vue:63 -#: src/components/identities/AliasCreationForm.vue:42 -msgid "Address" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:6 -msgid "Address (hostname or IP)" -msgstr "" - -#: src/components/identities/AliasForm.vue:14 -msgid "Address:" -msgstr "" - -#: src/components/identities/DomainAdminDomains.vue:3 -msgid "Administered domains" -msgstr "" - -#: src/components/domains/AdministratorList.vue:53 -#: src/components/domains/AdministratorList.vue:121 -msgid "Administrator added" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:55 -#: src/components/domains/DomainCreationForm.vue:108 -msgid "Administrator name" -msgstr "" - -#: src/components/domains/AdministratorList.vue:60 -#: src/components/domains/AdministratorList.vue:128 -msgid "Administrator removed" -msgstr "" - -#: src/components/domains/AdministratorList.vue:5 -#: src/components/domains/DomainList.vue:114 -#: src/components/domains/DomainList.vue:257 -msgid "Administrators" -msgstr "" - -#: src/components/domains/AdministratorList.vue:4 -msgid "Administrators of {{ domain.name }}" -msgstr "" - -#: src/components/alarms/AlarmList.vue:58 -msgid "Alarm closed" -msgstr "" - -#: src/components/alarms/AlarmList.vue:51 -msgid "Alarm deleted" -msgstr "" - -#: src/components/alarms/AlarmList.vue:64 -msgid "Alarm re-opened" -msgstr "" - -#: src/components/domains/DomainList.vue:120 -#: src/components/layout/Navbar.vue:66 -#: src/components/domains/DomainList.vue:263 -#: src/components/layout/Navbar.vue:181 -msgid "Alarms" -msgstr "" - -#: src/components/alarms/AlarmList.vue:70 -msgid "Alarms deleted" -msgstr "" - -#: src/components/identities/AccountForm.vue:88 -#: src/views/domains/Domains.vue:23 src/views/identities/Alias.vue:3 -#: src/views/identities/Identities.vue:23 -msgid "Alias" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:85 -#: src/components/identities/AliasCreationForm.vue:107 -msgid "Alias already exists, redirecting to edit page" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:93 -#: src/components/identities/AliasCreationForm.vue:115 -msgid "Alias created" -msgstr "" - -#: src/components/identities/IdentityList.vue:54 -#: src/components/identities/IdentityList.vue:136 -msgid "Alias deleted" -msgstr "" - -#: src/components/identities/AliasForm.vue:30 -#: src/components/identities/AliasForm.vue:113 -msgid "Alias updated" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainSummary.vue:33 -#: src/components/identities/AccountAliases.vue:3 -#: src/components/identities/AccountCreationForm.vue:77 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:109 -#: src/components/domains/DomainList.vue:169 -#: src/components/identities/AccountCreationForm.vue:129 -#: src/components/identities/AccountCreationForm.vue:132 -#: src/components/identities/AccountCreationForm.vue:161 -msgid "Aliases" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Aliases:" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:4 -msgid "Alignment" -msgstr "" - -#: src/components/layout/Navbar.vue:124 src/components/layout/Navbar.vue:239 -msgid "API" -msgstr "" - -#: src/views/user/APISetup.vue:3 -msgid "API access" -msgstr "" - -#: src/views/user/APISetup.vue:24 src/views/user/APISetup.vue:65 -msgid "API token copied to your clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:33 src/views/user/APISetup.vue:74 -msgid "API token created" -msgstr "" - -#: src/views/user/APISetup.vue:55 src/views/user/APISetup.vue:96 -msgid "API token deleted" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:19 -msgid "Apply" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:36 -#: src/components/imap_migration/ProviderCreationForm.vue:45 -#: src/components/imap_migration/ProviderForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:19 -#: src/components/imap_migration/ProviderCreationForm.vue:58 -#: src/components/imap_migration/ProviderCreationForm.vue:67 -#: src/components/imap_migration/ProvidersList.vue:111 -msgid "Associated domains" -msgstr "" - -#: src/components/layout/Navbar.vue:81 src/views/monitoring/AuditTrail.vue:3 -#: src/components/layout/Navbar.vue:196 -msgid "Audit trail" -msgstr "" - -#: src/components/domains/DNSDetail.vue:59 -#: src/components/domains/DNSDetail.vue:23 -msgid "Authentication" -msgstr "" - -#: src/components/domains/DNSDetail.vue:26 -#: src/components/domains/DomainDNSConfig.vue:31 -msgid "Auto configuration" -msgstr "" - -#: src/components/domains/DNSDetail.vue:45 -#: src/components/domains/DNSDetail.vue:9 -msgid "autoconfig record (Mozilla) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:40 -#: src/components/domains/DNSDetail.vue:4 -msgid "autoconfig record (Mozilla): %{ value }" -msgstr "" - -#: src/components/domains/DNSDetail.vue:55 -#: src/components/domains/DNSDetail.vue:19 -msgid "autodiscover record (Microsoft) not found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:50 -#: src/components/domains/DNSDetail.vue:14 -msgid "autodiscover record (Microsoft): %{ value }" -msgstr "" - -#: src/components/tools/CreationForm.vue:24 -msgid "Back" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:14 -msgid "Bind/named format. Click to copy" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:26 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:19 -msgid "body" -msgstr "" - -#: src/components/domains/DomainForm.vue:122 -#: src/components/identities/AccountForm.vue:138 -#: src/components/identities/AliasForm.vue:55 -#: src/components/imap_migration/ProviderForm.vue:53 -#: src/components/layout/ConfirmDialog.vue:14 src/views/user/APISetup.vue:46 -#: src/views/user/APISetup.vue:87 src/components/layout/ConfirmDialog.vue:53 -msgid "Cancel" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:10 -msgid "Change password" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:14 -msgid "Check connection:" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:8 -msgid "Check out the following list to find related components" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Check this option if passwords contained in your file are not crypted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:56 -#: src/components/domains/DomainAliasForm.vue:26 -msgid "Choose a domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:5 -msgid "Choose a role" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:15 -#: src/components/user/TwoFactorAuthForm.vue:8 -msgid "Click here to copy the key" -msgstr "" - -#: src/App.vue:22 src/App.vue:14 src/App.vue:2 -#: src/components/domains/AdministratorList.vue:36 -#: src/components/domains/DomainAliasForm.vue:21 -#: src/components/domains/DomainDKIMKey.vue:22 -#: src/components/domains/DomainDNSConfig.vue:40 -#: src/components/tools/ImportForm.vue:28 -#: src/components/user/RecoveryCodesResetDialog.vue:23 -msgid "Close" -msgstr "" - -#: src/components/alarms/AlarmList.vue:84 -msgid "Close alarm" -msgstr "" - -#: src/components/alarms/AlarmList.vue:22 src/components/alarms/AlarmList.vue:5 -msgid "Closed" -msgstr "" - -#: src/components/tools/CreationForm.vue:40 -msgid "Confirm and create" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:108 -#: src/components/identities/AccountPasswordForm.vue:58 -msgid "Confirmation" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:46 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "" - -#: src/views/Login.vue:23 -msgid "Connect" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Continue on error" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:8 -msgid "Control if this domain will be allowed to send and receive messages" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainCreationForm.vue:10 -#: src/components/domains/DomainCreationForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:11 -#: src/components/identities/AccountPasswordForm.vue:13 -#: src/components/identities/AccountPasswordForm.vue:3 -msgid "Copy to clipboard" -msgstr "" - -#: src/views/user/APISetup.vue:20 -msgid "Copy token to clipboard" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:71 -#: src/components/parameters/ParametersForm.vue:151 -msgid "Could not save parameters" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:54 -#: src/components/domains/DomainOptionsForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:107 -msgid "Create a domain administrator" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "Create a mailbox for the administrator." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:68 -#: src/components/domains/DomainOptionsForm.vue:8 -#: src/components/domains/DomainCreationForm.vue:121 -msgid "Create aliases" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:8 -msgid "Create standard aliases for the domain." -msgstr "" - -#: src/components/domains/DomainSummary.vue:7 -#: src/components/identities/AccountSummary.vue:7 -#: src/components/identities/AliasSummary.vue:7 -msgid "Creation date" -msgstr "" - -#: src/views/identities/Identities.vue:45 src/views/identities/Identities.vue:1 -msgid "Crypt passwords" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:29 -#: src/components/identities/AccountPasswordForm.vue:11 -msgid "Current password" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:43 -#: src/components/identities/AccountMailboxForm.vue:26 -msgid "Daily message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:25 -#: src/components/identities/AccountSummary.vue:46 -#: src/components/identities/AccountSummary.vue:15 -msgid "Daily sending limit" -msgstr "" - -#: src/components/layout/Navbar.vue:48 src/components/layout/Navbar.vue:163 -msgid "Dashboard" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:8 -#: src/components/logs/MessageList.vue:10 -#: src/components/logs/MessageList.vue:43 -#: src/components/logs/AuditTrailList.vue:40 -msgid "Date" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:57 -#: src/components/tools/TimeSerieChart.vue:115 -msgid "Day" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:41 -#: src/components/domains/DomainLimitationsForm.vue:6 -#: src/components/domains/DomainSummary.vue:20 -#: src/components/domains/DomainCreationForm.vue:94 -msgid "Default mailbox quota" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:6 -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/alarms/AlarmList.vue:77 -#: src/components/alarms/AlarmList.vue:103 -#: src/components/domains/DomainAliasForm.vue:24 -#: src/components/domains/DomainList.vue:116 -#: src/components/identities/IdentityList.vue:164 -#: src/components/identities/IdentityList.vue:176 -#: src/components/identities/IdentityList.vue:187 -#: src/components/imap_migration/MigrationsList.vue:50 -#: src/components/imap_migration/ProvidersList.vue:45 -#: src/components/imap_migration/ProvidersList.vue:137 -#: src/components/imap_migration/MigrationsList.vue:105 -#: src/components/domains/DomainList.vue:259 -#: src/components/identities/IdentityList.vue:246 -#: src/components/identities/IdentityList.vue:258 -#: src/components/identities/IdentityList.vue:269 -msgid "Delete" -msgstr "" - -#: src/views/user/APISetup.vue:23 -msgid "Delete token" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:16 -#: src/components/identities/AliasCreationForm.vue:31 -#: src/components/identities/AliasGeneralForm.vue:87 -#: src/components/identities/AliasSummary.vue:19 -#: src/components/admin/ComponentsInformationTable.vue:54 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasGeneralForm.vue:56 -msgid "Description" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:37 -msgid "Detail" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:75 -#: src/components/user/TwoFactorAuthForm.vue:11 -msgid "Disable 2FA" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:6 -#: src/components/domains/DNSStatusChip.vue:13 -msgid "Disabled" -msgstr "" - -#: src/components/domains/DNSDetail.vue:89 -#: src/components/domains/DNSDetail.vue:2 -msgid "DKIM key" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:48 -#: src/components/domains/DomainDNSForm.vue:5 -#: src/components/domains/DomainCreationForm.vue:101 -msgid "DKIM key length" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:47 -#: src/components/domains/DomainDNSForm.vue:4 -#: src/components/domains/DomainCreationForm.vue:100 -msgid "DKIM key selector" -msgstr "" - -#: src/components/domains/DNSDetail.vue:30 -#: src/components/domains/DNSDetail.vue:191 -msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:4 -msgid "DKIM public key for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:71 -#: src/components/domains/DNSDetail.vue:35 -msgid "DKIM record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:74 -#: src/components/domains/DNSDetail.vue:38 -msgid "DKIM record not found" -msgstr "" - -#: src/components/domains/DomainForm.vue:44 -msgid "DKIM signing" -msgstr "" - -#: src/views/domains/Domain.vue:17 -msgid "DMARC" -msgstr "" - -#: src/components/domains/DNSDetail.vue:79 -#: src/components/domains/DNSDetail.vue:43 -msgid "DMARC record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:82 -#: src/components/domains/DNSDetail.vue:46 -msgid "DMARC record not found" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:50 -msgid "DMARC support does not seem to be enabled for this domain." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:31 -#: src/components/domains/DomainCreationForm.vue:109 -#: src/components/domains/DomainCreationForm.vue:115 -#: src/components/domains/DomainForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:84 -#: src/components/domains/DomainCreationForm.vue:162 -#: src/components/domains/DomainCreationForm.vue:168 -msgid "DNS" -msgstr "" - -#: src/components/domains/DomainForm.vue:39 -msgid "DNS checks" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:4 -msgid "DNS configuration for" -msgstr "" - -#: src/components/domains/DNSDetail.vue:4 -msgid "DNS configuration help" -msgstr "" - -#: src/components/domains/DomainList.vue:27 -#: src/components/domains/DomainList.vue:170 -msgid "DNS status" -msgstr "" - -#: src/components/identities/IdentityList.vue:51 -msgid "Do not delete account folder" -msgstr "" - -#: src/components/domains/DomainList.vue:77 -msgid "Do not delete domain folder" -msgstr "" - -#: src/components/identities/IdentityList.vue:37 -#: src/components/identities/IdentityList.vue:120 -msgid "Do you really want to delete the alias %{ alias }?" -msgstr "" - -#: src/components/identities/IdentityList.vue:93 -#: src/components/identities/IdentityList.vue:176 -msgid "Do you really want to delete the selected identities?" -msgstr "" - -#: src/components/alarms/AlarmList.vue:17 -#: src/components/identities/AliasGeneralForm.vue:56 -#: src/views/domains/Domain.vue:3 src/views/domains/Domains.vue:20 -#: src/components/alarms/AlarmList.vue:97 -#: src/components/identities/AliasGeneralForm.vue:31 -msgid "Domain" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:47 -#: src/components/identities/AccountRoleForm.vue:77 -msgid "Domain administrator" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:51 -#: src/components/domains/DomainAliasForm.vue:120 -msgid "Domain alias created" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainAliasForm.vue:109 -msgid "Domain alias deleted" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:59 -#: src/components/domains/DomainAliasForm.vue:128 -msgid "Domain alias updated" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:178 -#: src/components/domains/DomainCreationForm.vue:231 -msgid "Domain created" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:62 -#: src/components/identities/AccountCreationForm.vue:114 -msgid "Domain default value" -msgstr "" - -#: src/components/domains/DomainList.vue:71 -#: src/components/domains/DomainList.vue:214 -msgid "Domain deleted" -msgstr "" - -#: src/components/domains/DomainGeneralForm.vue:3 -msgid "Domain name (ex: domain.tld)" -msgstr "" - -#: src/components/domains/DomainForm.vue:56 -#: src/components/domains/DomainForm.vue:218 -msgid "Domain updated" -msgstr "" - -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:2 -msgid "domain's default value" -msgstr "" - -#: src/components/layout/Navbar.vue:54 src/views/domains/Domains.vue:3 -#: src/components/layout/Navbar.vue:169 -msgid "Domains" -msgstr "" - -#: src/components/tools/ImportForm.vue:21 -msgid "Don't treat duplicated objects as errors" -msgstr "" - -#: src/components/domains/DomainList.vue:115 -#: src/components/identities/IdentityList.vue:159 -#: src/components/identities/IdentityList.vue:171 -#: src/components/imap_migration/ProvidersList.vue:51 -#: src/components/imap_migration/ProvidersList.vue:143 -#: src/components/domains/DomainList.vue:258 -#: src/components/identities/IdentityList.vue:241 -#: src/components/identities/IdentityList.vue:253 -msgid "Edit" -msgstr "" - -#: src/views/identities/AccountEdit.vue:2 -msgid "Edit account" -msgstr "" - -#: src/views/identities/AliasEdit.vue:2 -msgid "Edit alias" -msgstr "" - -#: src/views/domains/DomainEdit.vue:2 -msgid "Edit domain" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:20 -#: src/components/domains/DomainAliasForm.vue:89 -msgid "Edit domain alias" -msgstr "" - -#: src/views/imap_migration/ProviderEdit.vue:2 -msgid "Edit provider" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:59 -msgid "element" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:58 -#: src/components/identities/AccountCreationForm.vue:110 -msgid "Email" -msgstr "" - -#: src/components/identities/AliasGeneralForm.vue:35 -#: src/components/identities/AliasGeneralForm.vue:15 -msgid "Email address" -msgstr "" - -#: src/components/layout/Navbar.vue:98 src/components/layout/Navbar.vue:213 -msgid "Email providers" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -#: src/components/tools/CreationSummary.vue:32 -msgid "Empty" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:86 -#: src/components/user/TwoFactorAuthForm.vue:5 -msgid "Enable 2FA" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:34 -#: src/components/domains/DomainDNSForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:87 -msgid "Enable DKIM signing" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:33 -#: src/components/domains/DomainDNSForm.vue:2 -#: src/components/domains/DomainCreationForm.vue:86 -msgid "Enable DNS checks" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:27 -#: src/components/domains/DomainGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:46 -#: src/components/identities/AccountForm.vue:39 -#: src/components/identities/AccountGeneralForm.vue:13 -#: src/components/identities/AliasForm.vue:17 -#: src/components/identities/AliasGeneralForm.vue:11 -#: src/components/domains/DomainCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:98 -msgid "Enabled" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:20 -#: src/components/identities/AccountGeneralForm.vue:71 -msgid "Enter a simple username or an email address" -msgstr "" - -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountGeneralForm.vue:69 -msgid "Enter an email address" -msgstr "" - -#: src/views/TwoFA.vue:12 -msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:11 -msgid "Enter the code you've just received by SMS" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:84 -#: src/components/user/TwoFactorAuthForm.vue:109 -#: src/views/user/PasswordRecoveryForm.vue:62 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:73 -msgid "err" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:18 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:66 -msgid "Error" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Ex: 10MB. Leave empty for no limit" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:26 -#: src/components/identities/AliasGeneralForm.vue:79 -#: src/components/identities/AliasSummary.vue:15 -#: src/components/identities/AliasCreationForm.vue:48 -#: src/components/identities/AliasGeneralForm.vue:49 -msgid "Expire at" -msgstr "" - -#: src/views/identities/Identities.vue:8 -msgid "Export accounts and aliases to CSV" -msgstr "" - -#: src/views/domains/Domains.vue:8 -msgid "Export domains and aliases to CSV" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:25 -#: src/components/dmarc/DmarcAligmentChart.vue:37 -#: src/components/dmarc/DmarcAligmentChart.vue:143 -#: src/components/dmarc/DmarcAligmentChart.vue:155 -msgid "Failed" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:37 -#: src/components/identities/AccountGeneralForm.vue:35 -#: src/components/user/ProfileForm.vue:45 src/components/user/ProfileForm.vue:9 -#: src/components/identities/AccountGeneralForm.vue:18 -#: src/components/identities/AccountCreationForm.vue:89 -msgid "First name" -msgstr "" - -#: src/views/Login.vue:17 src/views/user/PasswordRecoveryChangeForm.vue:6 -#: src/views/user/PasswordRecoveryForm.vue:6 -msgid "Forgot password?" -msgstr "" - -#: src/components/layout/Navbar.vue:148 src/views/user/Forward.vue:3 -#: src/components/layout/Navbar.vue:263 -msgid "Forward" -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Forward messages and store copies into your local mailbox" -msgstr "" - -#: src/components/user/ForwardForm.vue:19 -#: src/components/user/ForwardForm.vue:52 -msgid "Forward updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:24 -#: src/components/dmarc/DmarcAligmentChart.vue:36 -#: src/components/dmarc/DmarcAligmentChart.vue:142 -#: src/components/dmarc/DmarcAligmentChart.vue:154 -msgid "Forwarded" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:42 -msgid "Forwarders with ARC" -msgstr "" - -#: src/components/logs/MessageList.vue:13 -#: src/components/tools/TimeSerieChart.vue:17 -#: src/components/logs/MessageList.vue:46 -msgid "From" -msgstr "" - -#: src/components/identities/AccountSummary.vue:16 -msgid "Full name" -msgstr "" - -#: src/components/identities/IdentityList.vue:18 -#: src/components/identities/IdentityList.vue:100 -msgid "Fullname/recipient" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:22 -#: src/components/dmarc/DmarcAligmentChart.vue:34 -#: src/components/dmarc/DmarcAligmentChart.vue:140 -#: src/components/dmarc/DmarcAligmentChart.vue:152 -msgid "Fully aligned" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:23 -#: src/components/domains/DomainCreationForm.vue:108 -#: src/components/domains/DomainCreationForm.vue:114 -#: src/components/domains/DomainForm.vue:7 -#: src/components/identities/AliasCreationForm.vue:17 -#: src/components/identities/AliasCreationForm.vue:49 -#: src/components/identities/AliasForm.vue:7 -#: src/components/imap_migration/ProviderCreationForm.vue:27 -#: src/components/imap_migration/ProviderCreationForm.vue:44 -#: src/components/imap_migration/ProviderForm.vue:7 -#: src/views/domains/Domain.vue:11 -#: src/components/imap_migration/ProviderCreationForm.vue:49 -#: src/components/imap_migration/ProviderCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:76 -#: src/components/domains/DomainCreationForm.vue:161 -#: src/components/domains/DomainCreationForm.vue:167 -#: src/components/identities/AliasCreationForm.vue:39 -#: src/components/identities/AliasCreationForm.vue:71 -msgid "General" -msgstr "" - -#: src/components/domains/DomainSummary.vue:3 -#: src/components/identities/AccountSummary.vue:3 -#: src/components/identities/AliasSummary.vue:3 -msgid "General information" -msgstr "" - -#: src/components/user/ProfileForm.vue:3 -msgid "General settings" -msgstr "" - -#: src/views/user/APISetup.vue:12 -msgid "Generate" -msgstr "" - -#: src/components/domains/DNSDetail.vue:95 -#: src/components/domains/DNSDetail.vue:8 -msgid "Generate a new DKIM key" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:6 -msgid "Generate a random password for the administrator." -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:56 -#: src/components/identities/AccountRoleForm.vue:86 -msgid "help" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:8 -msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:33 -#: src/components/domains/DomainDNSConfig.vue:34 -msgid "hostname of your automx server" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:34 -#: src/components/identities/AccountCreationForm.vue:98 -#: src/components/identities/AccountForm.vue:29 src/views/Login.vue:6 -#: src/components/identities/AccountCreationForm.vue:86 -#: src/components/identities/AccountCreationForm.vue:150 -msgid "Identification" -msgstr "" - -#: src/components/layout/Navbar.vue:60 src/views/identities/Identities.vue:3 -#: src/components/layout/Navbar.vue:175 -msgid "Identities" -msgstr "" - -#: src/components/identities/IdentityList.vue:113 -#: src/components/identities/IdentityList.vue:195 -msgid "Identities deleted" -msgstr "" - -#: src/components/tools/CreationForm.vue:42 -#: src/components/tools/CreationForm.vue:116 -msgid "If you close this form now, your modifications won't be saved. Do you confirm?" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:52 -msgid "If you configured it recently, please wait for the first report to be received and processed." -msgstr "" - -#: src/components/layout/Navbar.vue:94 src/components/layout/Navbar.vue:209 -msgid "IMAP Migration" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:9 -msgid "IMAP Port" -msgstr "" - -#: src/components/tools/ImportForm.vue:31 -msgid "Import" -msgstr "" - -#: src/views/identities/Identities.vue:5 -msgid "Import accounts and aliases from CSV file" -msgstr "" - -#: src/views/domains/Domains.vue:37 -msgid "Import domains" -msgstr "" - -#: src/views/domains/Domains.vue:5 -msgid "Import domains and aliases from CSV file" -msgstr "" - -#: src/views/identities/Identities.vue:37 -msgid "Import identities" -msgstr "" - -#: src/components/user/ForwardForm.vue:5 -msgid "Indicate one or more recipients separated by a comma (,)" -msgstr "" - -#: src/components/layout/Navbar.vue:117 src/views/admin/Information.vue:3 -#: src/components/layout/Navbar.vue:232 -msgid "Information" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:26 -#: src/components/user/TwoFactorAuthForm.vue:19 -msgid "" -"Install a soft token authenticator like FreeOTP or Google\n" -" Authenticator from your application repository and use that\n" -" app to scan this QR code." -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:3 -msgid "Installed components" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:14 -#: src/components/admin/ComponentsInformationTable.vue:52 -msgid "Installed version" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:54 -#: src/views/user/PasswordRecoveryChangeForm.vue:114 -msgid "Invalid reset token." -msgstr "" - -#: src/views/Login.vue:37 src/views/Login.vue:97 -msgid "Invalid username and/or password" -msgstr "" - -#: src/components/domains/DomainDNSConfig.vue:12 -msgid "IP address of your Modoboa server" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" -msgstr "" - -#: src/views/Dashboard.vue:7 -msgid "" -"It will present a summary of your Modoboa server's status and\n" -" some useful information about the product." -msgstr "" - -#: src/components/user/ForwardForm.vue:6 -msgid "Keep local copies" -msgstr "" - -#: src/components/user/ProfileForm.vue:59 -#: src/components/user/ProfileForm.vue:21 -msgid "Language" -msgstr "" - -#: src/components/identities/AccountSummary.vue:11 -msgid "Last login date" -msgstr "" - -#: src/components/domains/DomainSummary.vue:11 -msgid "Last modification date" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:38 -#: src/components/identities/AccountGeneralForm.vue:44 -#: src/components/user/ProfileForm.vue:52 -#: src/components/user/ProfileForm.vue:15 -#: src/components/identities/AccountGeneralForm.vue:26 -#: src/components/identities/AccountCreationForm.vue:90 -msgid "Last name" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:53 -msgid "Latest version" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Leave empty for no limit" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:9 -#: src/components/logs/AuditTrailList.vue:41 -msgid "Level" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:38 -#: src/components/domains/DomainCreationForm.vue:110 -#: src/components/domains/DomainCreationForm.vue:116 -#: src/components/domains/DomainForm.vue:61 -#: src/components/domains/DomainCreationForm.vue:91 -#: src/components/domains/DomainCreationForm.vue:163 -#: src/components/domains/DomainCreationForm.vue:169 -msgid "Limitations" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:6 -msgid "Local domain (optional)" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:10 -#: src/components/logs/AuditTrailList.vue:42 -msgid "Logger" -msgstr "" - -#: src/components/layout/Navbar.vue:164 src/components/layout/Topbar.vue:6 -#: src/components/layout/Navbar.vue:279 src/components/layout/Topbar.vue:53 -msgid "Logout" -msgstr "" - -#: src/components/alarms/AlarmList.vue:18 -#: src/components/identities/AccountCreationForm.vue:56 -#: src/components/identities/AccountCreationForm.vue:105 -#: src/components/identities/AccountForm.vue:56 -#: src/components/alarms/AlarmList.vue:98 -#: src/components/identities/AccountCreationForm.vue:108 -#: src/components/identities/AccountCreationForm.vue:157 -msgid "Mailbox" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Mailbox:" -msgstr "" - -#: src/components/domains/DomainSummary.vue:29 -msgid "Mailboxes" -msgstr "" - -#: src/components/domains/DomainSummary.vue:17 -#: src/components/identities/AccountSummary.vue:40 -#: src/components/identities/AccountSummary.vue:9 -#: src/components/identities/AccountSummary.vue:1 -msgid "MB" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 -#: src/components/logs/AuditTrailList.vue:11 -#: src/components/alarms/AlarmList.vue:99 -#: src/components/logs/AuditTrailList.vue:43 -msgid "Message" -msgstr "" - -#: src/views/monitoring/Messages.vue:3 -msgid "Message history" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:42 -#: src/components/domains/DomainLimitationsForm.vue:9 -#: src/components/identities/AccountCreationForm.vue:66 -#: src/components/domains/DomainCreationForm.vue:95 -#: src/components/identities/AccountCreationForm.vue:118 -msgid "Message sending limit" -msgstr "" - -#: src/components/domains/DomainSummary.vue:26 -msgid "messages" -msgstr "" - -#: src/components/layout/Navbar.vue:86 src/components/layout/Navbar.vue:201 -msgid "Messages" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:29 -#: src/components/imap_migration/MigrationsList.vue:84 -msgid "Migration deleted" -msgstr "" - -#: src/components/layout/Navbar.vue:103 src/components/layout/Navbar.vue:218 -msgid "Migrations" -msgstr "" - -#: src/components/identities/AliasSummary.vue:11 -msgid "Modified" -msgstr "" - -#: src/components/tools/CreationSummary.vue:5 -msgid "Modify" -msgstr "" - -#: src/components/layout/Navbar.vue:72 src/components/layout/Navbar.vue:187 -msgid "Monitoring" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:59 -#: src/components/tools/TimeSerieChart.vue:117 -msgid "Month" -msgstr "" - -#: src/components/domains/DNSDetail.vue:9 -msgid "MX records" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:13 -#: src/components/domains/AdministratorList.vue:19 -#: src/components/domains/DNSDetail.vue:18 -#: src/components/domains/DomainAliasForm.vue:40 -#: src/components/domains/DomainCreationForm.vue:25 -#: src/components/domains/DomainList.vue:25 -#: src/components/domains/DomainOptionsForm.vue:4 -#: src/components/identities/IdentityList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:29 -#: src/components/imap_migration/ProvidersList.vue:15 -#: src/components/admin/ComponentsInformationTable.vue:51 -#: src/components/imap_migration/ProviderCreationForm.vue:51 -#: src/components/imap_migration/ProvidersList.vue:107 -#: src/components/domains/DomainAliasForm.vue:13 -#: src/components/domains/DNSDetail.vue:178 -#: src/components/domains/AdministratorList.vue:87 -#: src/components/domains/DomainCreationForm.vue:78 -#: src/components/domains/DomainList.vue:168 -#: src/components/identities/IdentityList.vue:99 -msgid "Name" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:4 -msgid "Name of the administrator" -msgstr "" - -#: src/components/imap_migration/ProviderAssociatedForm.vue:3 -msgid "Name of the domain to migrate" -msgstr "" - -#: src/components/domains/DomainForm.vue:14 -#: src/components/imap_migration/ProviderForm.vue:14 -msgid "Name:" -msgstr "" - -#: src/components/identities/AccountSummary.vue:13 -msgid "Never logged-in" -msgstr "" - -#: src/views/domains/Domains.vue:15 src/views/domains/Domains.vue:3 -#: src/views/identities/Identities.vue:15 src/views/identities/Identities.vue:3 -#: src/views/imap_migration/Providers.vue:7 -msgid "New" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:1 -#: src/components/imap_migration/MigrationsList.vue:15 -#: src/components/imap_migration/MigrationsList.vue:70 -msgid "New account" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:1 -msgid "New alias" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:1 -msgid "New domain" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:1 -msgid "New provider" -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:3 -msgid "New recovery codes" -msgstr "" - -#: src/components/tools/CreationForm.vue:27 -msgid "Next" -msgstr "" - -#: src/components/domains/DNSDetail.vue:35 -#: src/components/domains/DomainList.vue:62 -#: src/components/identities/IdentityList.vue:43 -#: src/components/identities/IdentityList.vue:68 -#: src/components/identities/IdentityList.vue:98 -#: src/components/tools/CreationForm.vue:46 -#: src/components/domains/DNSDetail.vue:195 -#: src/components/domains/DomainList.vue:205 -#: src/components/tools/CreationForm.vue:120 -#: src/components/identities/IdentityList.vue:125 -#: src/components/identities/IdentityList.vue:150 -#: src/components/identities/IdentityList.vue:180 -msgid "No" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:39 -msgid "No associated domains" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:6 -msgid "No sender address defined for this account" -msgstr "" - -#: src/components/domains/DomainForm.vue:74 -msgid "No sending limit" -msgstr "" - -#: src/components/domains/DNSDetail.vue:99 -#: src/components/domains/DNSDetail.vue:12 -msgid "Not generated" -msgstr "" - -#: src/components/identities/AccountForm.vue:123 -#: src/components/identities/AccountForm.vue:5 -msgid "Number of allowed mailbox aliases:" -msgstr "" - -#: src/components/identities/AccountForm.vue:120 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of allowed mailboxes:" -msgstr "" - -#: src/components/identities/AccountForm.vue:96 -#: src/components/identities/AccountForm.vue:2 -msgid "Number of associated alias:" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:36 -msgid "Number of associated domains:" -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:9 -msgid "Number of messages this domain can send per day. Leave empty for no limit." -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:9 -msgid "Number of messages this mailbox can send per day. Leave empty for no limit." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:31 -#: src/views/user/PasswordRecoveryForm.vue:77 -msgid "Ok" -msgstr "" - -#: src/components/layout/ConfirmDialog.vue:15 -#: src/components/layout/ConfirmDialog.vue:54 -msgid "OK" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:14 -#: src/components/imap_migration/MigrationsList.vue:69 -msgid "Old account" -msgstr "" - -#: src/components/admin/ComponentsInformationTable.vue:7 -msgid "One or more updates are available" -msgstr "" - -#: src/components/alarms/AlarmList.vue:19 src/components/alarms/AlarmList.vue:2 -msgid "Opened" -msgstr "" - -#: src/views/alarms/Alarms.vue:3 -msgid "Opened alarms" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:52 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/domains/DomainCreationForm.vue:105 -#: src/components/domains/DomainCreationForm.vue:164 -msgid "Options" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:66 -#: src/components/parameters/ParametersForm.vue:146 -msgid "Parameters updated" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:23 -#: src/components/dmarc/DmarcAligmentChart.vue:35 -#: src/components/dmarc/DmarcAligmentChart.vue:141 -#: src/components/dmarc/DmarcAligmentChart.vue:153 -msgid "Partially aligned" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:41 -msgid "Partially trusted sources / Forwarders" -msgstr "" - -#: src/components/identities/AccountPasswordForm.vue:88 -#: src/components/user/ProfileForm.vue:21 -#: src/components/user/TwoFactorAuthForm.vue:70 -#: src/components/user/TwoFactorAuthForm.vue:6 src/views/Login.vue:13 -#: src/components/identities/AccountPasswordForm.vue:42 -msgid "Password" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:127 -#: src/components/identities/AccountCreationForm.vue:124 -#: src/components/identities/AccountPasswordForm.vue:32 -#: src/components/domains/DomainCreationForm.vue:180 -#: src/components/identities/AccountPasswordForm.vue:103 -#: src/components/identities/AccountCreationForm.vue:176 -msgid "Password copied to clipboard" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:8 -msgid "Password recovery" -msgstr "" - -#: src/components/user/ProfileForm.vue:42 -#: src/components/user/ProfileForm.vue:112 -msgid "Password updated" -msgstr "" - -#: src/components/domains/DNSDetail.vue:14 -#: src/components/domains/DNSDetail.vue:31 -#: src/components/domains/DNSDetail.vue:4 -#: src/components/domains/DNSStatusChip.vue:9 -#: src/components/domains/DNSStatusChip.vue:16 -msgid "Pending" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:9 -#: src/components/tools/TimeSerieChart.vue:3 -msgid "Period" -msgstr "" - -#: src/components/identities/AccountSummary.vue:28 -#: src/components/user/ProfileForm.vue:12 -#: src/components/user/ProfileForm.vue:69 -#: src/components/user/ProfileForm.vue:30 -msgid "Phone number" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:32 -#: src/components/user/TwoFactorAuthForm.vue:25 -msgid "Pin code" -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:9 -msgid "Please fill-in your primary email address" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:31 -#: src/components/imap_migration/ProvidersList.vue:17 -#: src/components/imap_migration/ProviderCreationForm.vue:53 -#: src/components/imap_migration/ProvidersList.vue:109 -msgid "Port" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:12 -#: src/components/domains/DNSStatusChip.vue:19 -msgid "Problem" -msgstr "" - -#: src/views/user/APISetup.vue:47 src/views/user/APISetup.vue:88 -msgid "Proceed" -msgstr "" - -#: src/components/layout/Navbar.vue:131 src/components/layout/Navbar.vue:158 -#: src/views/user/Profile.vue:3 src/components/layout/Navbar.vue:246 -#: src/components/layout/Navbar.vue:273 -msgid "Profile" -msgstr "" - -#: src/components/user/ProfileForm.vue:33 -#: src/components/user/ProfileForm.vue:103 -msgid "Profile updated" -msgstr "" - -#: src/components/tools/ImportForm.vue:7 -msgid "Provide a CSV file where lines respect one of the following formats:" -msgstr "" - -#: src/components/imap_migration/MigrationsList.vue:13 -#: src/components/imap_migration/MigrationsList.vue:68 -msgid "Provider" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:98 -#: src/components/imap_migration/ProviderCreationForm.vue:120 -msgid "Provider created" -msgstr "" - -#: src/components/imap_migration/ProvidersList.vue:30 -#: src/components/imap_migration/ProvidersList.vue:122 -msgid "Provider deleted" -msgstr "" - -#: src/components/imap_migration/ProviderGeneralForm.vue:3 -msgid "Provider name" -msgstr "" - -#: src/components/imap_migration/ProviderForm.vue:46 -#: src/components/imap_migration/ProviderForm.vue:123 -msgid "Provider updated" -msgstr "" - -#: src/views/imap_migration/Providers.vue:3 -msgid "Providers" -msgstr "" - -#: src/components/logs/MessageList.vue:9 src/components/logs/MessageList.vue:42 -msgid "Queue ID" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:40 -#: src/components/domains/DomainLimitationsForm.vue:3 -#: src/components/domains/DomainList.vue:29 -#: src/components/domains/DomainSummary.vue:15 -#: src/components/identities/AccountCreationForm.vue:60 -#: src/components/identities/AccountMailboxForm.vue:14 -#: src/components/identities/AccountSummary.vue:33 -#: src/components/identities/AccountSummary.vue:2 -#: src/components/domains/DomainCreationForm.vue:93 -#: src/components/domains/DomainList.vue:172 -#: src/components/identities/AccountMailboxForm.vue:3 -#: src/components/identities/AccountCreationForm.vue:112 -msgid "Quota" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:5 -msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." -msgstr "" - -#: src/components/domains/DomainLimitationsForm.vue:3 -msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." -msgstr "" - -#: src/components/domains/DomainForm.vue:68 -#: src/components/identities/AccountForm.vue:64 -#: src/components/identities/AccountForm.vue:67 -#: src/components/identities/AccountForm.vue:2 -#: src/components/identities/AccountForm.vue:5 -msgid "Quota:" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:19 -#: src/components/identities/AliasGeneralForm.vue:2 -#: src/components/identities/AliasCreationForm.vue:41 -msgid "Random address" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:58 -#: src/components/domains/DomainOptionsForm.vue:6 -#: src/components/identities/AccountCreationForm.vue:41 -#: src/components/identities/AccountPasswordForm.vue:9 -#: src/components/domains/DomainCreationForm.vue:111 -#: src/components/identities/AccountCreationForm.vue:93 -msgid "Random password" -msgstr "" - -#: src/components/domains/DomainDKIMKey.vue:8 -msgid "Raw format. Click to copy" -msgstr "" - -#: src/components/user/ForwardForm.vue:4 -msgid "Recipient(s)" -msgstr "" - -#: src/components/identities/AliasCreationForm.vue:35 -#: src/components/identities/AliasCreationForm.vue:37 -#: src/components/identities/AliasCreationForm.vue:53 -#: src/components/identities/AliasForm.vue:34 -#: src/components/identities/AliasRecipients.vue:3 -#: src/components/identities/AliasCreationForm.vue:57 -#: src/components/identities/AliasCreationForm.vue:59 -#: src/components/identities/AliasCreationForm.vue:75 -msgid "Recipients" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:39 -#: src/components/user/TwoFactorAuthForm.vue:32 -msgid "Register" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:22 -msgid "Relative time ranges" -msgstr "" - -#: src/components/domains/DomainList.vue:26 -#: src/components/domains/DomainList.vue:10 -msgid "Relay" -msgstr "" - -#: src/components/alarms/AlarmList.vue:105 -msgid "Reload" -msgstr "" - -#: src/views/Login.vue:19 -msgid "Remember me" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:18 -#: src/components/identities/AccountSenderAddresses.vue:1 -msgid "Remove this address" -msgstr "" - -#: src/components/domains/AdministratorList.vue:24 -#: src/components/domains/AdministratorList.vue:1 -msgid "Remove this administrator" -msgstr "" - -#: src/components/alarms/AlarmList.vue:91 -msgid "Reopen alarm" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:54 -#: src/components/identities/AccountRoleForm.vue:84 -msgid "Reseller" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:21 -msgid "Resend SMS." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:78 -#: src/components/user/TwoFactorAuthForm.vue:14 -msgid "Reset recovery codes" -msgstr "" - -#: src/components/domains/DomainForm.vue:111 -#: src/components/identities/AccountForm.vue:112 -msgid "Resources" -msgstr "" - -#: src/components/tools/Resources.vue:3 -msgid "Resources usage" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:23 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:71 -msgid "Retry reset" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:24 -#: src/views/user/PasswordRecoveryForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:32 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:22 -#: src/views/user/PasswordRecoveryForm.vue:78 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:70 -msgid "Return to login" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:28 -#: src/components/identities/AccountCreationForm.vue:30 -#: src/components/identities/AccountCreationForm.vue:94 -#: src/components/identities/AccountForm.vue:7 -#: src/components/identities/AccountSummary.vue:20 -#: src/components/identities/AccountCreationForm.vue:80 -#: src/components/identities/AccountCreationForm.vue:82 -#: src/components/identities/AccountCreationForm.vue:146 -msgid "Role" -msgstr "" - -#: src/components/domains/DomainForm.vue:125 -#: src/components/identities/AccountForm.vue:141 -#: src/components/identities/AliasForm.vue:58 -#: src/components/imap_migration/ProviderForm.vue:56 -msgid "Save" -msgstr "" - -#: src/components/logs/AuditTrailList.vue:4 -#: src/components/logs/MessageList.vue:4 -msgid "Search" -msgstr "" - -#: src/components/identities/AccountSummary.vue:24 -#: src/components/user/ProfileForm.vue:77 -#: src/components/user/ProfileForm.vue:37 -msgid "Secondary email" -msgstr "" - -#: src/components/imap_migration/ProviderCreationForm.vue:32 -#: src/components/imap_migration/ProviderGeneralForm.vue:11 -#: src/components/imap_migration/ProvidersList.vue:18 -#: src/components/imap_migration/ProviderCreationForm.vue:54 -#: src/components/imap_migration/ProvidersList.vue:110 -msgid "Secured" -msgstr "" - -#: src/components/layout/Navbar.vue:137 src/views/user/Security.vue:3 -#: src/components/layout/Navbar.vue:252 -msgid "Security" -msgstr "" - -#: src/components/domains/AdministratorList.vue:12 -#: src/components/domains/AdministratorList.vue:2 -msgid "Select an account" -msgstr "" - -#: src/components/tools/ImportForm.vue:14 -msgid "Select file" -msgstr "" - -#: src/components/identities/AccountForm.vue:70 -#: src/components/identities/AccountForm.vue:8 -msgid "Send only" -msgstr "" - -#: src/components/identities/AccountCreationForm.vue:70 -#: src/components/identities/AccountMailboxForm.vue:12 -#: src/components/identities/AccountCreationForm.vue:122 -msgid "Send only account" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:38 -#: src/components/identities/AccountSenderAddresses.vue:89 -msgid "Sender address added" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:44 -#: src/components/identities/AccountSenderAddresses.vue:95 -msgid "Sender address deleted" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:3 -msgid "Sender addresses" -msgstr "" - -#: src/components/domains/DomainList.vue:28 -#: src/components/domains/DomainList.vue:171 -msgid "Sending limit" -msgstr "" - -#: src/components/domains/DomainForm.vue:71 -msgid "Sending limit:" -msgstr "" - -#: src/components/tools/ImportForm.vue:18 -msgid "Separator" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:79 -#: src/components/domains/DomainTransportForm.vue:3 -#: src/components/domains/DomainCreationForm.vue:132 -msgid "Service" -msgstr "" - -#: src/components/domains/DomainForm.vue:96 -msgid "Service:" -msgstr "" - -#: src/components/layout/Navbar.vue:111 src/components/layout/Navbar.vue:226 -msgid "Settings" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:21 -msgid "Settings: thislabel" -msgstr "" - -#: src/components/domains/DNSDetail.vue:93 -#: src/components/domains/DNSDetail.vue:6 -msgid "Show key" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:40 -#: src/components/identities/AccountRoleForm.vue:70 -msgid "Simple user" -msgstr "" - -#: src/components/identities/AccountSenderAddresses.vue:9 -#: src/components/identities/AccountSenderAddresses.vue:2 -#: src/plugins/vee-validate.js:31 -msgid "Specify an email address" -msgstr "" - -#: src/components/domains/DNSDetail.vue:63 -#: src/components/domains/DNSDetail.vue:27 -msgid "SPF record found" -msgstr "" - -#: src/components/domains/DNSDetail.vue:66 -#: src/components/domains/DNSDetail.vue:30 -msgid "SPF record not found" -msgstr "" - -#: src/components/identities/AccountAliasForm.vue:3 -#: src/components/identities/AliasRecipientForm.vue:3 -msgid "Start typing a name here..." -msgstr "" - -#: src/components/layout/Navbar.vue:76 src/views/domains/Domain.vue:14 -#: src/views/monitoring/Statistics.vue:3 src/components/layout/Navbar.vue:191 -msgid "Statistics" -msgstr "" - -#: src/components/alarms/AlarmList.vue:16 -#: src/components/logs/MessageList.vue:11 -#: src/components/alarms/AlarmList.vue:96 -#: src/components/logs/MessageList.vue:44 -msgid "Status" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:19 -#: src/views/user/PasswordRecoveryForm.vue:15 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:17 -msgid "Submit" -msgstr "" - -#: src/components/tools/CreationForm.vue:9 -#: src/components/tools/CreationForm.vue:32 -msgid "Summary" -msgstr "" - -#: src/components/identities/AccountRoleForm.vue:61 -#: src/components/identities/AccountRoleForm.vue:91 -msgid "Super administrator" -msgstr "" - -#: src/components/identities/IdentityList.vue:19 -#: src/components/identities/IdentityList.vue:101 -msgid "Tags" -msgstr "" - -#: src/components/tools/ImportForm.vue:9 -msgid "The first element of each line is mandatory and must be equal to one of the previous values." -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:51 -#: src/components/user/TwoFactorAuthForm.vue:7 -msgid "" -"The following recovery codes can be used one time each to\n" -" let you regain access to your account, in case you lose your\n" -" phone for example. Make sure to save them in a safe place,\n" -" otherwise you won't be able to access your account anymore." -msgstr "" - -#: src/components/user/RecoveryCodesResetDialog.vue:7 -msgid "" -"The following recovery codes can be used one time each to let\n" -" you regain access to your account, in case you lose your phone\n" -" for example. Make sure to save them in a safe place, otherwise\n" -" you won't be able to access your account anymore." -msgstr "" - -#: src/views/Dashboard.vue:6 -msgid "This page is still under construction." -msgstr "" - -#: src/views/user/PasswordRecoveryForm.vue:25 -msgid "title" -msgstr "" - -#: src/components/logs/MessageList.vue:12 -#: src/components/tools/TimeSerieChart.vue:18 -#: src/components/logs/MessageList.vue:45 -msgid "To" -msgstr "" - -#: src/views/Login.vue:41 src/views/user/PasswordRecoveryChangeForm.vue:62 -#: src/views/user/PasswordRecoveryForm.vue:69 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:46 src/views/Login.vue:101 -#: src/views/user/PasswordRecoveryForm.vue:115 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:94 -#: src/views/user/PasswordRecoveryChangeForm.vue:122 -msgid "Too many unsuccessful attempts, please try later." -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:33 -#: src/components/dmarc/DmarcSourceTable.vue:8 -#: src/components/dmarc/DmarcSourceTable.vue:3 -#: src/components/dmarc/DmarcAligmentChart.vue:151 -msgid "Total" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:37 -#: src/views/user/PasswordRecoverySmsTotpForm.vue:85 -msgid "TOTP resent." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:77 -#: src/components/domains/DomainCreationForm.vue:117 -#: src/components/domains/DomainForm.vue:89 -#: src/components/domains/DomainCreationForm.vue:130 -#: src/components/domains/DomainCreationForm.vue:170 -msgid "Transport" -msgstr "" - -#: src/components/alarms/AlarmList.vue:15 -#: src/components/alarms/AlarmList.vue:95 -msgid "Triggered" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:40 -msgid "Trusted sources" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:4 -msgid "Two factor authentication" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:82 -#: src/components/user/TwoFactorAuthForm.vue:1 -msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." -msgstr "" - -#: src/views/TwoFA.vue:11 -msgid "Two-factor authentication code" -msgstr "" - -#: src/components/user/TwoFactorAuthForm.vue:66 -#: src/components/user/TwoFactorAuthForm.vue:2 -msgid "Two-Factor Authentication is enabled for your account." -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:26 -#: src/components/domains/DomainGeneralForm.vue:6 -#: src/components/domains/DomainCreationForm.vue:79 -msgid "Type" -msgstr "" - -#: src/components/domains/DomainForm.vue:17 -msgid "Type:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:17 -#: src/components/domains/DNSStatusChip.vue:24 -msgid "Unknown" -msgstr "" - -#: src/components/dmarc/DmarcAligmentChart.vue:43 -msgid "Unknown sources / Threats" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:30 -#: src/components/identities/AccountMailboxForm.vue:87 -msgid "unlimited" -msgstr "" - -#: src/components/domains/DomainSummary.vue:16 -#: src/components/domains/DomainSummary.vue:21 -#: src/components/identities/AccountSummary.vue:35 -#: src/components/identities/AccountSummary.vue:4 -msgid "Unlimited" -msgstr "" - -#: src/components/domains/DomainAliasForm.vue:17 -#: src/components/user/ForwardForm.vue:10 -#: src/components/domains/DomainAliasForm.vue:86 -msgid "Update" -msgstr "" - -#: src/components/user/ProfileForm.vue:25 -msgid "Update Password" -msgstr "" - -#: src/components/user/ProfileForm.vue:16 -msgid "Update settings" -msgstr "" - -#: src/components/domains/DNSDetail.vue:20 -#: src/components/domains/DNSDetail.vue:180 -msgid "Updated" -msgstr "" - -#: src/components/identities/AccountMailboxForm.vue:27 -#: src/components/identities/AccountMailboxForm.vue:84 -msgid "Use domain default value" -msgstr "" - -#: src/views/user/PasswordRecoverySmsTotpForm.vue:43 -msgid "User seems wrong, return to login or restart reset the process?" -msgstr "" - -#: src/views/user/PasswordRecoveryChangeForm.vue:56 -#: src/views/user/PasswordRecoveryChangeForm.vue:116 -msgid "User unknown." -msgstr "" - -#: src/components/domains/AdministratorList.vue:18 -#: src/components/identities/AccountCreationForm.vue:36 -#: src/components/identities/AccountGeneralForm.vue:22 src/views/Login.vue:9 -#: src/components/domains/AdministratorList.vue:86 -#: src/components/identities/AccountGeneralForm.vue:8 -#: src/components/identities/AccountCreationForm.vue:88 -msgid "Username" -msgstr "" - -#: src/components/identities/AccountForm.vue:36 -msgid "Username:" -msgstr "" - -#: src/components/domains/DNSStatusChip.vue:15 -#: src/components/domains/DNSStatusChip.vue:22 -msgid "Valid" -msgstr "" - -#: src/views/TwoFA.vue:6 -msgid "Verification" -msgstr "" - -#: src/views/TwoFA.vue:19 -msgid "Verify code" -msgstr "" - -#: src/components/domains/DNSDetail.vue:29 -#: src/components/domains/DomainList.vue:55 -#: src/components/identities/IdentityList.vue:36 -#: src/components/identities/IdentityList.vue:61 -#: src/components/identities/IdentityList.vue:92 -#: src/components/tools/CreationForm.vue:41 src/views/user/APISetup.vue:40 -#: src/views/user/APISetup.vue:81 src/components/domains/DNSDetail.vue:189 -#: src/components/domains/DomainList.vue:198 -#: src/components/tools/CreationForm.vue:115 -#: src/components/identities/IdentityList.vue:118 -#: src/components/identities/IdentityList.vue:143 -#: src/components/identities/IdentityList.vue:174 -msgid "Warning" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:58 -#: src/components/tools/TimeSerieChart.vue:116 -msgid "Week" -msgstr "" - -#: src/views/Dashboard.vue:3 -msgid "Welcome to Modoboa" -msgstr "" - -#: src/components/domains/DomainOptionsForm.vue:7 -msgid "With a mailbox" -msgstr "" - -#: src/components/domains/DomainCreationForm.vue:63 -#: src/components/domains/DomainCreationForm.vue:116 -msgid "With mailbox" -msgstr "" - -#: src/components/tools/TimeSerieChart.vue:60 -#: src/components/tools/TimeSerieChart.vue:118 -msgid "Year" -msgstr "" - -#: src/components/domains/DNSDetail.vue:36 -#: src/components/domains/DomainList.vue:63 -#: src/components/identities/IdentityList.vue:44 -#: src/components/identities/IdentityList.vue:69 -#: src/components/identities/IdentityList.vue:99 -#: src/components/tools/CreationForm.vue:45 -#: src/components/domains/DNSDetail.vue:196 -#: src/components/domains/DomainList.vue:206 -#: src/components/tools/CreationForm.vue:119 -#: src/components/identities/IdentityList.vue:126 -#: src/components/identities/IdentityList.vue:151 -#: src/components/identities/IdentityList.vue:181 -msgid "Yes" -msgstr "" - -#: src/views/user/APISetup.vue:41 src/views/user/APISetup.vue:83 -msgid "You are about to delete your API access token" -msgstr "" - -#: src/components/tools/ImportForm.vue:10 -msgid "You can use a different character as separator." -msgstr "" - -#: src/App.vue:69 src/App.vue:110 -msgid "You have one or more opened alarms" -msgstr "" - -#: src/views/user/APISetup.vue:8 -msgid "Your API token has not been generated yet." -msgstr "" - -#: src/views/user/APISetup.vue:18 -msgid "Your API token is:" -msgstr "" - -#: src/mixins/importExport.js:23 -msgid "CSV seems to be badly formatted" -msgstr "" - -#: src/plugins/vee-validate.js:12 -msgid "Passwords mismatch" -msgstr "" - -#: src/plugins/vee-validate.js:16 -msgid "This field must be a valid number" -msgstr "" - -#: src/plugins/vee-validate.js:23 -msgid "This field must have a length of {length} characters" -msgstr "" - -#: src/plugins/vee-validate.js:27 -msgid "This field is required" -msgstr "" - -#: src/plugins/vee-validate.js:44 -msgid "Invalid password" -msgstr "" - -#: src/plugins/vee-validate.js:53 -msgid "Specify a valid port number" -msgstr "" - -#: src/components/parameters/ParametersForm.vue:101 -msgid "Settings: " -msgstr "" - -#: src/api/repository.js:38 -msgid "You are throttled, please try later." -msgstr "" - -#: src/filters/index.js:7 -msgid "yes" -msgstr "" - -#: src/filters/index.js:7 -msgid "no" -msgstr "" diff --git a/frontend/merge_translations.py b/frontend/merge_translations.py deleted file mode 100644 index 3414d755a..000000000 --- a/frontend/merge_translations.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python - -import os - -import polib - - -LOCALES = [ - "br", - "cs", - "de", - "el", - "es", - "fi", - "fr", - "it", - "ja", - "nl", - "pt", - "pt-br", - "pl", - "po", - "ru", - "sv", - "tr", - "zh-hant", -] - -OLD_TRANSLATION_MODULES = [ - "", - "admin", - "dnstools", - "ldapsync", - "limits", - "maillog", - "policyd", - "relaydomains", - "transport", - "dmarc", -] - - -def merge_translations(): - for locale in LOCALES: - target = f"locale/{locale}/LC_MESSAGES/app.po" - print(f"Opening {target}") - new_po = polib.pofile(target) - for module in OLD_TRANSLATION_MODULES: - prefix = f"../modoboa/{module}" if module else "../modoboa" - old_file = f"{prefix}/locale/{locale}/LC_MESSAGES/django.po" - if not os.path.exists(old_file): - continue - print(f"Opening {old_file}") - old_po = polib.pofile(old_file) - for entry in new_po: - old_entry = old_po.find(entry.msgid) - if old_entry: - entry.msgstr = old_entry.msgstr - new_po.save() - - -if __name__ == "__main__": - merge_translations() diff --git a/frontend/package.json b/frontend/package.json index 1c220fee1..85aaefdbb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,56 +1,44 @@ { - "name": "Modoboa", - "version": "0.1.0", + "name": "frontend", + "version": "3.0.0", "private": true, "scripts": { - "serve": "vue-cli-service serve", - "build": "vue-cli-service build", - "test:unit": "vue-cli-service test:unit", - "lint": "vue-cli-service lint" + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "lint": "eslint . --ext .js,.vue --fix src", + "lint-no-fix": "eslint --ext .js,.vue src", + "format": "prettier . --write", + "format-specific": "prettier --write", + "gettext:extract": "vue-gettext-extract", + "gettext:compile": "vue-gettext-compile" }, "dependencies": { - "@fontsource/rubik": "^4.5.0", - "@mdi/font": "^5.9.55", - "apexcharts": "^3.25.0", - "core-js": "^3.6.5", - "debounce": "^1.2.1", - "js-cookie": "^2.2.1", - "luxon": "^1.28.1", - "qrcode.vue": "~1.7.0", - "vee-validate": "^3.4.5", - "vue": "^2.6.14", - "vue-apexcharts": "^1.6.0", - "vue-cookie": "^1.1.4", - "vue-gettext": "^2.1.12", - "vue-router": "^3.2.0", - "vuetify": "^2.6.10", - "vuex": "^3.4.0" + "@mdi/font": "^7.3.67", + "apexcharts": "^3.45.2", + "axios": "^1.6.7", + "core-js": "^3.29.0", + "debounce": "^2.0.0", + "js-cookie": "^3.0.5", + "luxon": "^3.4.4", + "pinia": "^2.1.7", + "qrcode.vue": "^3.4.1", + "roboto-fontface": "*", + "vue": "^3.4.19", + "vue-router": "^4.0.0", + "vue3-apexcharts": "^1.5.2", + "vue3-gettext": "^3.0.0-beta.4", + "vuetify": "^3.5.4" }, "devDependencies": { - "@babel/core": "^7.12.16", - "@babel/eslint-parser": "^7.12.16", - "@vue/cli-plugin-babel": "~5.0.8", - "@vue/cli-plugin-eslint": "~5.0.8", - "@vue/cli-plugin-router": "~5.0.8", - "@vue/cli-plugin-unit-mocha": "~5.0.8", - "@vue/cli-plugin-vuex": "~5.0.8", - "@vue/cli-service": "~5.0.8", - "@vue/eslint-config-standard": "^6.1.0", - "@vue/test-utils": "^1.0.3", - "axios": "^1.6.0", - "chai": "^4.1.2", - "easygettext": "^2.15.0", - "eslint": "^7.32.0", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.1.0", - "eslint-plugin-standard": "^4.0.0", - "eslint-plugin-vue": "^8.0.3", - "sass": "~1.32.12", - "sass-loader": "^8.0.2", - "vue-cli-plugin-axios": "~0.0.4", - "vue-cli-plugin-vuetify": "~2.5.8", - "vue-template-compiler": "^2.6.11", - "vuetify-loader": "^1.3.0" + "@vitejs/plugin-vue": "^5.0.4", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-vue": "^9.21.1", + "prettier": "^3.1.1", + "sass": "^1.69.5", + "unplugin-fonts": "^1.0.3", + "vite": "^5.1.3", + "vite-plugin-vuetify": "^2.0.1" } } diff --git a/frontend/public/config.json b/frontend/public/config.json index 6015de042..ce94d8db3 100644 --- a/frontend/public/config.json +++ b/frontend/public/config.json @@ -1,4 +1,4 @@ { - "API_BASE_URL": "/api/v2/", - "API_DOC_URL": "/api/schema-v2/swagger/" + "API_BASE_URL": "/api/v2/", + "API_DOC_URL": "/api/schema-v2/swagger/" } diff --git a/frontend/public/index.html b/frontend/public/index.html deleted file mode 100644 index 412352865..000000000 --- a/frontend/public/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - <%= htmlWebpackPlugin.options.title %> - - - -
- - - diff --git a/frontend/src/App.vue b/frontend/src/App.vue index fc1870a5a..fd34c44f9 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,124 +1,5 @@ - - - + diff --git a/frontend/src/api/account.js b/frontend/src/api/account.js index b0c54554e..af181f383 100644 --- a/frontend/src/api/account.js +++ b/frontend/src/api/account.js @@ -3,45 +3,45 @@ import repository from './repository' const resource = 'account' export default { - getMe () { + getMe() { return repository.get(`/${resource}/me/`) }, - checkPassword (value) { + checkPassword(value) { return repository.post(`/${resource}/me/password/`, { password: value }) }, - verifyTFACode (code) { + verifyTFACode(code) { const payload = { code } return repository.post(`${resource}/tfa/verify/`, payload) }, - startTFASetup () { + startTFASetup() { return repository.post(`${resource}/tfa/setup/`) }, - getKeyForTFASetup () { + getKeyForTFASetup() { return repository.get(`${resource}/tfa/setup/key/`) }, - finalizeTFASetup (pinCode) { + finalizeTFASetup(pinCode) { const payload = { pin_code: pinCode } return repository.post(`${resource}/tfa/setup/check/`, payload) }, - disableTFA (data) { + disableTFA(data) { return repository.post(`${resource}/tfa/disable/`, data) }, - resetRecoveryCodes (data) { + resetRecoveryCodes(data) { return repository.post(`${resource}/tfa/reset_codes/`, data) }, - getForward () { + getForward() { return repository.get(`${resource}/forward/`) }, - setForward (data) { + setForward(data) { return repository.post(`${resource}/forward/`, data) }, - getAPIToken () { + getAPIToken() { return repository.get(`${resource}/api_token/`) }, - createAPIToken () { + createAPIToken() { return repository.post(`${resource}/api_token/`) }, - deleteAPIToken () { + deleteAPIToken() { return repository.delete(`${resource}/api_token/`) - } + }, } diff --git a/frontend/src/api/accounts.js b/frontend/src/api/accounts.js index 2b299ac05..cecdf8e70 100644 --- a/frontend/src/api/accounts.js +++ b/frontend/src/api/accounts.js @@ -3,25 +3,25 @@ import repository from './repository' const resource = 'accounts' export default { - getAll ({ domain, role }) { + getAll({ domain, role }) { return repository.get(`/${resource}/`, { params: { domain, role } }) }, - get (accountId) { + get(accountId) { return repository.get(`${resource}/${accountId}/`) }, - getRandomPassword () { - return repository.get(`${resource}/random_password`) + getRandomPassword() { + return repository.get(`${resource}/random_password/`) }, - validate (data) { + validate(data) { return repository.post(`${resource}/validate/`, data) }, - create (data) { + create(data) { return repository.post(`${resource}/`, data) }, - patch (accountId, data) { + patch(accountId, data) { return repository.patch(`${resource}/${accountId}/`, data) }, - delete (accountId, data) { + delete(accountId, data) { return repository.post(`${resource}/${accountId}/delete/`, data) - } + }, } diff --git a/frontend/src/api/admin.js b/frontend/src/api/admin.js index 45f53e838..489345a41 100644 --- a/frontend/src/api/admin.js +++ b/frontend/src/api/admin.js @@ -1,7 +1,7 @@ import repository from './repository' export default { - getComponentsInformation () { - return repository.get('/admin/components') - } + getComponentsInformation() { + return repository.get('/admin/components/') + }, } diff --git a/frontend/src/api/alarms.js b/frontend/src/api/alarms.js index 535b7cb34..a25b368ef 100644 --- a/frontend/src/api/alarms.js +++ b/frontend/src/api/alarms.js @@ -3,16 +3,18 @@ import repository from './repository' const resource = 'alarms' export default { - getAll (params) { + getAll(params) { return repository.get(`${resource}/`, { params }) }, - switchStatus (alarmId, data) { + switchStatus(alarmId, data) { return repository.patch(`${resource}/${alarmId}/switch/`, data) }, - delete (alarmId) { + delete(alarmId) { return repository.delete(`${resource}/${alarmId}/`) }, - bulkDelete (alarmsIds) { - return repository.delete(`${resource}/bulk_delete/`, { params: { ids: alarmsIds } }) - } + bulkDelete(alarmsIds) { + return repository.delete(`${resource}/bulk_delete/`, { + params: { ids: alarmsIds }, + }) + }, } diff --git a/frontend/src/api/aliases.js b/frontend/src/api/aliases.js index 469ef4b7b..fea9bb285 100644 --- a/frontend/src/api/aliases.js +++ b/frontend/src/api/aliases.js @@ -3,22 +3,25 @@ import repository from './repository' const resource = 'aliases' export default { - get (aliasId) { + getAll() { + return repository.get(`${resource}/`) + }, + get(aliasId) { return repository.get(`${resource}/${aliasId}/`) }, - getRandomAddress () { + getRandomAddress() { return repository.get(`${resource}/random_address/`) }, - validate (data) { + validate(data) { return repository.post(`${resource}/validate/`, data) }, - create (data) { + create(data) { return repository.post(`${resource}/`, data) }, - patch (aliasId, data) { + patch(aliasId, data) { return repository.patch(`${resource}/${aliasId}/`, data) }, - delete (aliasId) { + delete(aliasId) { return repository.delete(`${resource}/${aliasId}/`) - } + }, } diff --git a/frontend/src/api/auth.js b/frontend/src/api/auth.js index f496844fd..f9fade5dc 100644 --- a/frontend/src/api/auth.js +++ b/frontend/src/api/auth.js @@ -1,16 +1,16 @@ import repository from './repository' export default { - requestToken (data) { + requestToken(data) { return repository.post('/token/', data) }, - recoverPassword (data) { + recoverPassword(data) { return repository.post('/password_reset/', data) }, - checkSmsTotp (data) { + checkSmsTotp(data) { return repository.post('/sms_totp/', data) }, - changePassword (data) { + changePassword(data) { return repository.post('/reset_confirm/', data) - } + }, } diff --git a/frontend/src/api/domains.js b/frontend/src/api/domains.js index 19464e734..4bdb6bed1 100644 --- a/frontend/src/api/domains.js +++ b/frontend/src/api/domains.js @@ -4,66 +4,72 @@ const domainResource = 'domains' const domainAliasResource = 'domainaliases' export default { - getDomains () { + getDomains() { return repository.get(`/${domainResource}/`) }, - getDomain (domainId) { + getDomain(domainId) { return repository.get(`/${domainResource}/${domainId}/`) }, - getDomainDNSDetail (domainId) { + getDomainDNSDetail(domainId) { return repository.get(`/${domainResource}/${domainId}/dns_detail/`) }, - getDomainDmarcAlignment (domainId, period) { + getDomainDmarcAlignment(domainId, period) { return repository.get( `${domainResource}/${domainId}/dmarc/alignment_stats/`, { params: { period } } ) }, - getDomainAliases (domain) { + getDomainAliases(domain) { let url = `/${domainAliasResource}/` if (domain !== undefined) { url += `?domain=${domain}` } return repository.get(url) }, - getDomainAdministrators (domainId) { + getDomainAdministrators(domainId) { return repository.get(`/${domainResource}/${domainId}/administrators/`) }, - addDomainAdministrator (domainId, accountId) { - return repository.post(`/${domainResource}/${domainId}/administrators/add/`, { account: accountId }) + addDomainAdministrator(domainId, accountId) { + return repository.post( + `/${domainResource}/${domainId}/administrators/add/`, + { account: accountId } + ) }, - removeDomainAdministrator (domainId, accountId) { - return repository.post(`/${domainResource}/${domainId}/administrators/remove/`, { account: accountId }) + removeDomainAdministrator(domainId, accountId) { + return repository.post( + `/${domainResource}/${domainId}/administrators/remove/`, + { account: accountId } + ) }, - createDomain (data) { + createDomain(data) { return repository.post(`/${domainResource}/`, data) }, - updateDomain (domainId, data) { + updateDomain(domainId, data) { return repository.put(`/${domainResource}/${domainId}/`, data) }, - patchDomain (domainId, data) { + patchDomain(domainId, data) { return repository.patch(`/${domainResource}/${domainId}/`, data) }, - deleteDomain (domainId, data) { + deleteDomain(domainId, data) { return repository.post(`/${domainResource}/${domainId}/delete/`, data) }, - createDomainAlias (data) { + createDomainAlias(data) { return repository.post(`/${domainAliasResource}/`, data) }, - updateDomainAlias (aliasId, data) { + updateDomainAlias(aliasId, data) { return repository.put(`/${domainAliasResource}/${aliasId}/`, data) }, - deleteDomainAlias (aliasId) { + deleteDomainAlias(aliasId) { return repository.delete(`/${domainAliasResource}/${aliasId}/`) }, - exportAll () { + exportAll() { return repository.get(`/${domainResource}/export/`) }, - importFromCSV (data) { + importFromCSV(data) { return repository.post(`/${domainResource}/import/`, data, { headers: { - 'Content-Type': 'multipart/form-data' - } + 'Content-Type': 'multipart/form-data', + }, }) - } + }, } diff --git a/frontend/src/api/identities.js b/frontend/src/api/identities.js index 250770df9..b907cfed8 100644 --- a/frontend/src/api/identities.js +++ b/frontend/src/api/identities.js @@ -3,17 +3,17 @@ import repository from './repository' const resource = 'identities' export default { - getAll () { + getAll() { return repository.get(`${resource}/`) }, - exportAll () { + exportAll() { return repository.get(`/${resource}/export/`) }, - importFromCSV (data) { + importFromCSV(data) { return repository.post(`/${resource}/import/`, data, { headers: { - 'Content-Type': 'multipart/form-data' - } + 'Content-Type': 'multipart/form-data', + }, }) - } + }, } diff --git a/frontend/src/api/imap_migration/migrations.js b/frontend/src/api/imap_migration/migrations.js index 52efac6f1..feeb782a0 100644 --- a/frontend/src/api/imap_migration/migrations.js +++ b/frontend/src/api/imap_migration/migrations.js @@ -3,13 +3,13 @@ import repository from '@/api/repository' const resource = 'migrations' export default { - getMigrations (params) { + getMigrations(params) { return repository.get(`/${resource}/`, { params }) }, - getMigration (slug, query) { + getMigration(slug, query) { return repository.get(`/${resource}/${slug}/`, query) }, - deleteMigration (slug) { + deleteMigration(slug) { return repository.delete(`/${resource}/${slug}/`) - } + }, } diff --git a/frontend/src/api/imap_migration/providers.js b/frontend/src/api/imap_migration/providers.js index afe123257..13964d94b 100644 --- a/frontend/src/api/imap_migration/providers.js +++ b/frontend/src/api/imap_migration/providers.js @@ -3,28 +3,28 @@ import repository from '@/api/repository' const resource = 'email-providers' export default { - getProviders (params) { + getProviders(params) { return repository.get(`/${resource}/`, { params }) }, - getProvider (providerId) { + getProvider(providerId) { return repository.get(`/${resource}/${providerId}/`) }, - createProvider (params) { + createProvider(params) { return repository.post(`/${resource}/`, params) }, - updateProvider (slug, params) { + updateProvider(slug, params) { return repository.put(`/${resource}/${slug}/`, params) }, - patchProvider (providerId, params) { + patchProvider(providerId, params) { return repository.patch(`/${resource}/${providerId}/`, params) }, - deleteProvider (slug) { + deleteProvider(slug) { return repository.delete(`/${resource}/${slug}/`) }, - checkProvider (params) { + checkProvider(params) { return repository.post(`/${resource}/check_connection/`, params) }, - checkAssociatedDomain (params) { + checkAssociatedDomain(params) { return repository.post(`/${resource}/check_associated_domain/`, params) - } + }, } diff --git a/frontend/src/api/languages.js b/frontend/src/api/languages.js index 0c45bf824..022de5c88 100644 --- a/frontend/src/api/languages.js +++ b/frontend/src/api/languages.js @@ -3,7 +3,7 @@ import repository from './repository' const resource = 'languages' export default { - getAll () { + getAll() { return repository.get(`/${resource}/`) - } + }, } diff --git a/frontend/src/api/logs.js b/frontend/src/api/logs.js index 3949df695..6fd0171c1 100644 --- a/frontend/src/api/logs.js +++ b/frontend/src/api/logs.js @@ -3,10 +3,10 @@ import repository from './repository' const resource = 'logs' export default { - getAuditTrail (params) { + getAuditTrail(params) { return repository.get(`/${resource}/audit-trail/`, { params }) }, - getMessages (params) { + getMessages(params) { return repository.get(`/${resource}/messages/`, { params }) - } + }, } diff --git a/frontend/src/api/parameters.js b/frontend/src/api/parameters.js index a18069dde..fb3140b17 100644 --- a/frontend/src/api/parameters.js +++ b/frontend/src/api/parameters.js @@ -3,16 +3,16 @@ import repository from './repository' const resource = 'parameters' export default { - getApplications () { + getApplications() { return repository.get(`/${resource}/applications/`) }, - getApplication (app) { + getApplication(app) { return repository.get(`/${resource}/${app}/`) }, - getApplicationStructure (app) { + getApplicationStructure(app) { return repository.get(`/${resource}/structure/?app=${app}`) }, - saveApplication (app, data) { + saveApplication(app, data) { return repository.put(`/${resource}/${app}/`, data) - } + }, } diff --git a/frontend/src/api/repository.js b/frontend/src/api/repository.js index 0a45f4c5b..653af7ec3 100644 --- a/frontend/src/api/repository.js +++ b/frontend/src/api/repository.js @@ -1,19 +1,16 @@ import axios from 'axios' import Cookies from 'js-cookie' - -import router from '../router' -import store from '../store' -import { translate } from 'vue-gettext' -import { bus } from '@/main' +import router from '@/router' +import { useAuthStore } from '@/stores' const _axios = axios.create() -const { gettext: $gettext } = translate _axios.interceptors.request.use( function (config) { + const authStore = useAuthStore() // Do something before request is sent - if (store.state.auth.isAuthenticated) { - config.headers['Accept-Language'] = store.state.auth.authUser.language + if (authStore.isAuthenticated) { + config.headers['Accept-Language'] = authStore.authUser.language } return config }, @@ -35,35 +32,41 @@ _axios.interceptors.response.use( return Promise.reject(error) } if (error.response.status === 429) { - bus.$emit('notification', { msg: $gettext('You are throttled, please try later.'), type: 'error' }) return Promise.reject(error) } - if (error.response.status !== 401 || router.currentRoute.path === '/login/') { + if (error.response.status !== 401 || router.currentRoute.name === 'Login') { return Promise.reject(error) } const refreshToken = Cookies.get('refreshToken') + const authStore = useAuthStore() if (error.config.url.endsWith('/token/refresh/') || !refreshToken) { - store.dispatch('auth/logout') - if (router.history.current.name !== 'Login') { + authStore.$reset() + if (router.currentRoute.name !== 'Login') { router.push({ name: 'Login' }) } return Promise.reject(error) } - return _axios.post('/token/refresh/', { refresh: refreshToken }).then(resp => { - Cookies.set('token', resp.data.access, { sameSite: 'strict' }) - _axios.defaults.headers.common.Authorization = `Bearer ${resp.data.access}` - const config = error.config - config.headers.Authorization = `Bearer ${resp.data.access}` - return new Promise((resolve, reject) => { - _axios.request(config).then(resp => { - resolve(resp) - }).catch(error => { - reject(error) + return _axios + .post('/token/refresh/', { refresh: refreshToken }) + .then((resp) => { + Cookies.set('token', resp.data.access, { sameSite: 'strict' }) + _axios.defaults.headers.common.Authorization = `Bearer ${resp.data.access}` + const config = error.config + config.headers.Authorization = `Bearer ${resp.data.access}` + return new Promise((resolve, reject) => { + _axios + .request(config) + .then((resp) => { + resolve(resp) + }) + .catch((error) => { + reject(error) + }) }) }) - }).catch(error => { - Promise.reject(error) - }) + .catch((error) => { + Promise.reject(error) + }) } ) diff --git a/frontend/src/api/senderAddresses.js b/frontend/src/api/senderAddresses.js index a9920152f..3aca20952 100644 --- a/frontend/src/api/senderAddresses.js +++ b/frontend/src/api/senderAddresses.js @@ -3,16 +3,16 @@ import repository from './repository' const resource = 'senderaddresses' export default { - getAll () { + getAll() { return repository.get(`${resource}/`) }, - getAllForMailbox (mailboxId) { + getAllForMailbox(mailboxId) { return repository.get(`${resource}/`, { params: { mailbox: mailboxId } }) }, - create (data) { + create(data) { return repository.post(`${resource}/`, data) }, - delete (addressId) { + delete(addressId) { return repository.delete(`${resource}/${addressId}/`) - } + }, } diff --git a/frontend/src/api/statistics.js b/frontend/src/api/statistics.js index 381cd16b4..5a533319d 100644 --- a/frontend/src/api/statistics.js +++ b/frontend/src/api/statistics.js @@ -3,15 +3,15 @@ import repository from './repository' const resource = 'statistics' export default { - getStatistics ({ graphSet, period, graphicName, searchQuery, start, end }) { + getStatistics({ graphSet, period, graphicName, searchQuery, start, end }) { const args = { gset: graphSet, period, graphic: graphicName, searchquery: searchQuery, start: start, - end: end + end: end, } return repository.get(`${resource}/`, { params: args }) - } + }, } diff --git a/frontend/src/api/transports.js b/frontend/src/api/transports.js index 0fad80284..35227fd57 100644 --- a/frontend/src/api/transports.js +++ b/frontend/src/api/transports.js @@ -3,7 +3,7 @@ import repository from './repository' const resource = 'transports' export default { - getAll () { + getAll() { return repository.get(`/${resource}/`) - } + }, } diff --git a/frontend/src/assets/Modoboa_RVB-ORANGE.png b/frontend/src/assets/Modoboa_RVB-ORANGE.png deleted file mode 100644 index d1e118ba9..000000000 Binary files a/frontend/src/assets/Modoboa_RVB-ORANGE.png and /dev/null differ diff --git a/frontend/src/assets/logo.png b/frontend/src/assets/logo.png new file mode 100644 index 000000000..a5f23ae7b Binary files /dev/null and b/frontend/src/assets/logo.png differ diff --git a/frontend/src/assets/logo.svg b/frontend/src/assets/logo.svg new file mode 100644 index 000000000..d57771c6d --- /dev/null +++ b/frontend/src/assets/logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/src/assets/modoboa-logo.svg b/frontend/src/assets/modoboa-logo.svg deleted file mode 100644 index b1dbf2400..000000000 --- a/frontend/src/assets/modoboa-logo.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/frontend/src/assets/modoboa-typo.svg b/frontend/src/assets/modoboa-typo.svg deleted file mode 100644 index 33c3a6127..000000000 --- a/frontend/src/assets/modoboa-typo.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/frontend/src/components/account/ForwardForm.vue b/frontend/src/components/account/ForwardForm.vue new file mode 100644 index 000000000..4610c0e8e --- /dev/null +++ b/frontend/src/components/account/ForwardForm.vue @@ -0,0 +1,57 @@ + + + diff --git a/frontend/src/components/account/ProfileForm.vue b/frontend/src/components/account/ProfileForm.vue new file mode 100644 index 000000000..64563e34f --- /dev/null +++ b/frontend/src/components/account/ProfileForm.vue @@ -0,0 +1,165 @@ + + + diff --git a/frontend/src/components/account/RecoveryCodesResetDialog.vue b/frontend/src/components/account/RecoveryCodesResetDialog.vue new file mode 100644 index 000000000..af4eac6ec --- /dev/null +++ b/frontend/src/components/account/RecoveryCodesResetDialog.vue @@ -0,0 +1,38 @@ + + + diff --git a/frontend/src/components/account/TwoFactorAuthForm.vue b/frontend/src/components/account/TwoFactorAuthForm.vue new file mode 100644 index 000000000..0d09efdd0 --- /dev/null +++ b/frontend/src/components/account/TwoFactorAuthForm.vue @@ -0,0 +1,264 @@ + + + + + diff --git a/frontend/src/components/admin/ComponentsInformationTable.vue b/frontend/src/components/admin/ComponentsInformationTable.vue deleted file mode 100644 index 84b3fda86..000000000 --- a/frontend/src/components/admin/ComponentsInformationTable.vue +++ /dev/null @@ -1,72 +0,0 @@ - - - diff --git a/frontend/src/components/admin/alarms/AlarmList.vue b/frontend/src/components/admin/alarms/AlarmList.vue new file mode 100644 index 000000000..ae90785c4 --- /dev/null +++ b/frontend/src/components/admin/alarms/AlarmList.vue @@ -0,0 +1,211 @@ + + + + + diff --git a/frontend/src/components/admin/dmarc/DmarcAligmentChart.vue b/frontend/src/components/admin/dmarc/DmarcAligmentChart.vue new file mode 100644 index 000000000..83d418ab8 --- /dev/null +++ b/frontend/src/components/admin/dmarc/DmarcAligmentChart.vue @@ -0,0 +1,245 @@ + + + diff --git a/frontend/src/components/admin/dmarc/DmarcSourceTable.vue b/frontend/src/components/admin/dmarc/DmarcSourceTable.vue new file mode 100644 index 000000000..bf55d4a8e --- /dev/null +++ b/frontend/src/components/admin/dmarc/DmarcSourceTable.vue @@ -0,0 +1,50 @@ + + + diff --git a/frontend/src/components/admin/domains/DKIMKeyViewer.vue b/frontend/src/components/admin/domains/DKIMKeyViewer.vue new file mode 100644 index 000000000..74a6ff498 --- /dev/null +++ b/frontend/src/components/admin/domains/DKIMKeyViewer.vue @@ -0,0 +1,37 @@ + + + diff --git a/frontend/src/components/admin/domains/DNSDetail.vue b/frontend/src/components/admin/domains/DNSDetail.vue new file mode 100644 index 000000000..ce313ea41 --- /dev/null +++ b/frontend/src/components/admin/domains/DNSDetail.vue @@ -0,0 +1,256 @@ + + + diff --git a/frontend/src/components/admin/domains/DNSStatusChip.vue b/frontend/src/components/admin/domains/DNSStatusChip.vue new file mode 100644 index 000000000..ecf6bf681 --- /dev/null +++ b/frontend/src/components/admin/domains/DNSStatusChip.vue @@ -0,0 +1,47 @@ + + + diff --git a/frontend/src/components/admin/domains/DomainAdminList.vue b/frontend/src/components/admin/domains/DomainAdminList.vue new file mode 100644 index 000000000..36df096af --- /dev/null +++ b/frontend/src/components/admin/domains/DomainAdminList.vue @@ -0,0 +1,163 @@ + + + diff --git a/frontend/src/components/admin/domains/DomainAliasForm.vue b/frontend/src/components/admin/domains/DomainAliasForm.vue new file mode 100644 index 000000000..11ed03796 --- /dev/null +++ b/frontend/src/components/admin/domains/DomainAliasForm.vue @@ -0,0 +1,108 @@ + + + diff --git a/frontend/src/components/admin/domains/DomainCreationForm.vue b/frontend/src/components/admin/domains/DomainCreationForm.vue new file mode 100644 index 000000000..9a9a15430 --- /dev/null +++ b/frontend/src/components/admin/domains/DomainCreationForm.vue @@ -0,0 +1,323 @@ + + + + + diff --git a/frontend/src/components/admin/domains/DomainDKIMKey.vue b/frontend/src/components/admin/domains/DomainDKIMKey.vue new file mode 100644 index 000000000..82ab4b380 --- /dev/null +++ b/frontend/src/components/admin/domains/DomainDKIMKey.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/frontend/src/components/admin/domains/DomainDNSConfig.vue b/frontend/src/components/admin/domains/DomainDNSConfig.vue new file mode 100644 index 000000000..0756bf74b --- /dev/null +++ b/frontend/src/components/admin/domains/DomainDNSConfig.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/frontend/src/components/admin/domains/DomainEditForm.vue b/frontend/src/components/admin/domains/DomainEditForm.vue new file mode 100644 index 000000000..610a57898 --- /dev/null +++ b/frontend/src/components/admin/domains/DomainEditForm.vue @@ -0,0 +1,263 @@ + + + diff --git a/frontend/src/components/admin/domains/DomainList.vue b/frontend/src/components/admin/domains/DomainList.vue new file mode 100644 index 000000000..e7fd2a5c1 --- /dev/null +++ b/frontend/src/components/admin/domains/DomainList.vue @@ -0,0 +1,325 @@ + + + + + diff --git a/frontend/src/components/admin/domains/DomainSummary.vue b/frontend/src/components/admin/domains/DomainSummary.vue new file mode 100644 index 000000000..54174ddb1 --- /dev/null +++ b/frontend/src/components/admin/domains/DomainSummary.vue @@ -0,0 +1,52 @@ + + + diff --git a/frontend/src/components/admin/domains/form_steps/DomainDNSForm.vue b/frontend/src/components/admin/domains/form_steps/DomainDNSForm.vue new file mode 100644 index 000000000..17215e60d --- /dev/null +++ b/frontend/src/components/admin/domains/form_steps/DomainDNSForm.vue @@ -0,0 +1,59 @@ + + + diff --git a/frontend/src/components/admin/domains/form_steps/DomainGeneralForm.vue b/frontend/src/components/admin/domains/form_steps/DomainGeneralForm.vue new file mode 100644 index 000000000..c7d959f54 --- /dev/null +++ b/frontend/src/components/admin/domains/form_steps/DomainGeneralForm.vue @@ -0,0 +1,65 @@ + + + diff --git a/frontend/src/components/admin/domains/form_steps/DomainLimitationsForm.vue b/frontend/src/components/admin/domains/form_steps/DomainLimitationsForm.vue new file mode 100644 index 000000000..c09eadad0 --- /dev/null +++ b/frontend/src/components/admin/domains/form_steps/DomainLimitationsForm.vue @@ -0,0 +1,59 @@ + + + diff --git a/frontend/src/components/admin/domains/form_steps/DomainOptionsForm.vue b/frontend/src/components/admin/domains/form_steps/DomainOptionsForm.vue new file mode 100644 index 000000000..ba13a2f16 --- /dev/null +++ b/frontend/src/components/admin/domains/form_steps/DomainOptionsForm.vue @@ -0,0 +1,64 @@ + + + diff --git a/frontend/src/components/admin/domains/form_steps/DomainTransportForm.vue b/frontend/src/components/admin/domains/form_steps/DomainTransportForm.vue new file mode 100644 index 000000000..d78b800eb --- /dev/null +++ b/frontend/src/components/admin/domains/form_steps/DomainTransportForm.vue @@ -0,0 +1,79 @@ + + + diff --git a/frontend/src/components/admin/identities/AccountAliases.vue b/frontend/src/components/admin/identities/AccountAliases.vue new file mode 100644 index 000000000..9f51e9c5b --- /dev/null +++ b/frontend/src/components/admin/identities/AccountAliases.vue @@ -0,0 +1,16 @@ + + + diff --git a/frontend/src/components/admin/identities/AccountCreationForm.vue b/frontend/src/components/admin/identities/AccountCreationForm.vue new file mode 100644 index 000000000..2eeabad57 --- /dev/null +++ b/frontend/src/components/admin/identities/AccountCreationForm.vue @@ -0,0 +1,266 @@ + + + + + diff --git a/frontend/src/components/admin/identities/AccountEditForm.vue b/frontend/src/components/admin/identities/AccountEditForm.vue new file mode 100644 index 000000000..c4fbf5532 --- /dev/null +++ b/frontend/src/components/admin/identities/AccountEditForm.vue @@ -0,0 +1,331 @@ + + + diff --git a/frontend/src/components/admin/identities/AccountSenderAddresses.vue b/frontend/src/components/admin/identities/AccountSenderAddresses.vue new file mode 100644 index 000000000..0dfbdd8f4 --- /dev/null +++ b/frontend/src/components/admin/identities/AccountSenderAddresses.vue @@ -0,0 +1,109 @@ +Ac + + + diff --git a/frontend/src/components/admin/identities/AccountSummary.vue b/frontend/src/components/admin/identities/AccountSummary.vue new file mode 100644 index 000000000..a142c0117 --- /dev/null +++ b/frontend/src/components/admin/identities/AccountSummary.vue @@ -0,0 +1,65 @@ + + + diff --git a/frontend/src/components/admin/identities/AliasCreationForm.vue b/frontend/src/components/admin/identities/AliasCreationForm.vue new file mode 100644 index 000000000..89a110e73 --- /dev/null +++ b/frontend/src/components/admin/identities/AliasCreationForm.vue @@ -0,0 +1,151 @@ + + + diff --git a/frontend/src/components/admin/identities/AliasEditForm.vue b/frontend/src/components/admin/identities/AliasEditForm.vue new file mode 100644 index 000000000..8e51ea4bd --- /dev/null +++ b/frontend/src/components/admin/identities/AliasEditForm.vue @@ -0,0 +1,139 @@ + + + diff --git a/frontend/src/components/admin/identities/AliasRecipientsSummary.vue b/frontend/src/components/admin/identities/AliasRecipientsSummary.vue new file mode 100644 index 000000000..2cfd0e722 --- /dev/null +++ b/frontend/src/components/admin/identities/AliasRecipientsSummary.vue @@ -0,0 +1,16 @@ + + + diff --git a/frontend/src/components/admin/identities/AliasSummary.vue b/frontend/src/components/admin/identities/AliasSummary.vue new file mode 100644 index 000000000..230797a2b --- /dev/null +++ b/frontend/src/components/admin/identities/AliasSummary.vue @@ -0,0 +1,29 @@ + + + diff --git a/frontend/src/components/admin/identities/DomainAdminDomains.vue b/frontend/src/components/admin/identities/DomainAdminDomains.vue new file mode 100644 index 000000000..6a3a36cba --- /dev/null +++ b/frontend/src/components/admin/identities/DomainAdminDomains.vue @@ -0,0 +1,27 @@ + + + diff --git a/frontend/src/components/admin/identities/IdentityList.vue b/frontend/src/components/admin/identities/IdentityList.vue new file mode 100644 index 000000000..bc8501af0 --- /dev/null +++ b/frontend/src/components/admin/identities/IdentityList.vue @@ -0,0 +1,248 @@ + + + diff --git a/frontend/src/components/admin/identities/form_steps/AccountAliasForm.vue b/frontend/src/components/admin/identities/form_steps/AccountAliasForm.vue new file mode 100644 index 000000000..8aeb53cf8 --- /dev/null +++ b/frontend/src/components/admin/identities/form_steps/AccountAliasForm.vue @@ -0,0 +1,81 @@ + + + diff --git a/frontend/src/components/admin/identities/form_steps/AccountGeneralForm.vue b/frontend/src/components/admin/identities/form_steps/AccountGeneralForm.vue new file mode 100644 index 000000000..874c1e57a --- /dev/null +++ b/frontend/src/components/admin/identities/form_steps/AccountGeneralForm.vue @@ -0,0 +1,89 @@ + + + diff --git a/frontend/src/components/admin/identities/form_steps/AccountMailboxForm.vue b/frontend/src/components/admin/identities/form_steps/AccountMailboxForm.vue new file mode 100644 index 000000000..ba9e2d2cf --- /dev/null +++ b/frontend/src/components/admin/identities/form_steps/AccountMailboxForm.vue @@ -0,0 +1,136 @@ + + + + + diff --git a/frontend/src/components/admin/identities/form_steps/AccountPasswordSubForm.vue b/frontend/src/components/admin/identities/form_steps/AccountPasswordSubForm.vue new file mode 100644 index 000000000..8df0d5c8a --- /dev/null +++ b/frontend/src/components/admin/identities/form_steps/AccountPasswordSubForm.vue @@ -0,0 +1,130 @@ + + + diff --git a/frontend/src/components/admin/identities/form_steps/AccountRoleForm.vue b/frontend/src/components/admin/identities/form_steps/AccountRoleForm.vue new file mode 100644 index 000000000..a6de87647 --- /dev/null +++ b/frontend/src/components/admin/identities/form_steps/AccountRoleForm.vue @@ -0,0 +1,115 @@ + + + diff --git a/frontend/src/components/admin/identities/form_steps/AliasGeneralForm.vue b/frontend/src/components/admin/identities/form_steps/AliasGeneralForm.vue new file mode 100644 index 000000000..9cc31659d --- /dev/null +++ b/frontend/src/components/admin/identities/form_steps/AliasGeneralForm.vue @@ -0,0 +1,97 @@ + + + diff --git a/frontend/src/components/admin/identities/form_steps/AliasRecipientForm.vue b/frontend/src/components/admin/identities/form_steps/AliasRecipientForm.vue new file mode 100644 index 000000000..de9b8efe4 --- /dev/null +++ b/frontend/src/components/admin/identities/form_steps/AliasRecipientForm.vue @@ -0,0 +1,66 @@ + + + diff --git a/frontend/src/components/admin/imap_migration/MigrationsList.vue b/frontend/src/components/admin/imap_migration/MigrationsList.vue new file mode 100644 index 000000000..d5781ad65 --- /dev/null +++ b/frontend/src/components/admin/imap_migration/MigrationsList.vue @@ -0,0 +1,129 @@ + + + diff --git a/frontend/src/components/admin/imap_migration/ProviderCreationForm.vue b/frontend/src/components/admin/imap_migration/ProviderCreationForm.vue new file mode 100644 index 000000000..727f31f4e --- /dev/null +++ b/frontend/src/components/admin/imap_migration/ProviderCreationForm.vue @@ -0,0 +1,137 @@ + + + + + diff --git a/frontend/src/components/admin/imap_migration/ProviderForm.vue b/frontend/src/components/admin/imap_migration/ProviderForm.vue new file mode 100644 index 000000000..ad5b99abe --- /dev/null +++ b/frontend/src/components/admin/imap_migration/ProviderForm.vue @@ -0,0 +1,146 @@ + + + diff --git a/frontend/src/components/admin/imap_migration/ProvidersList.vue b/frontend/src/components/admin/imap_migration/ProvidersList.vue new file mode 100644 index 000000000..44dd0924d --- /dev/null +++ b/frontend/src/components/admin/imap_migration/ProvidersList.vue @@ -0,0 +1,144 @@ + + + diff --git a/frontend/src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue b/frontend/src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue new file mode 100644 index 000000000..76aea8b7b --- /dev/null +++ b/frontend/src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue @@ -0,0 +1,121 @@ + + + diff --git a/frontend/src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue b/frontend/src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue new file mode 100644 index 000000000..83411d3b2 --- /dev/null +++ b/frontend/src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/frontend/src/components/admin/logs/AuditTrailList.vue b/frontend/src/components/admin/logs/AuditTrailList.vue new file mode 100644 index 000000000..0ace1a75e --- /dev/null +++ b/frontend/src/components/admin/logs/AuditTrailList.vue @@ -0,0 +1,88 @@ + + + diff --git a/frontend/src/components/admin/logs/MessageList.vue b/frontend/src/components/admin/logs/MessageList.vue new file mode 100644 index 000000000..f16f491cf --- /dev/null +++ b/frontend/src/components/admin/logs/MessageList.vue @@ -0,0 +1,74 @@ + + + diff --git a/frontend/src/components/alarms/AlarmList.vue b/frontend/src/components/alarms/AlarmList.vue deleted file mode 100644 index 6f1e68360..000000000 --- a/frontend/src/components/alarms/AlarmList.vue +++ /dev/null @@ -1,211 +0,0 @@ - - - diff --git a/frontend/src/components/dmarc/DmarcAligmentChart.vue b/frontend/src/components/dmarc/DmarcAligmentChart.vue deleted file mode 100644 index 075dde9f5..000000000 --- a/frontend/src/components/dmarc/DmarcAligmentChart.vue +++ /dev/null @@ -1,259 +0,0 @@ - - - diff --git a/frontend/src/components/dmarc/DmarcSourceTable.vue b/frontend/src/components/dmarc/DmarcSourceTable.vue deleted file mode 100644 index d8271dc9a..000000000 --- a/frontend/src/components/dmarc/DmarcSourceTable.vue +++ /dev/null @@ -1,60 +0,0 @@ - - - diff --git a/frontend/src/components/domains/AdministratorList.vue b/frontend/src/components/domains/AdministratorList.vue deleted file mode 100644 index 70b233f8d..000000000 --- a/frontend/src/components/domains/AdministratorList.vue +++ /dev/null @@ -1,142 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DKIMKeyViewer.vue b/frontend/src/components/domains/DKIMKeyViewer.vue deleted file mode 100644 index f4cd0d153..000000000 --- a/frontend/src/components/domains/DKIMKeyViewer.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DNSDetail.vue b/frontend/src/components/domains/DNSDetail.vue deleted file mode 100644 index d9340d561..000000000 --- a/frontend/src/components/domains/DNSDetail.vue +++ /dev/null @@ -1,229 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DNSStatusChip.vue b/frontend/src/components/domains/DNSStatusChip.vue deleted file mode 100644 index ee8879dcf..000000000 --- a/frontend/src/components/domains/DNSStatusChip.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DomainAliasForm.vue b/frontend/src/components/domains/DomainAliasForm.vue deleted file mode 100644 index 3807b016f..000000000 --- a/frontend/src/components/domains/DomainAliasForm.vue +++ /dev/null @@ -1,150 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DomainCreationForm.vue b/frontend/src/components/domains/DomainCreationForm.vue deleted file mode 100644 index ebcf375ef..000000000 --- a/frontend/src/components/domains/DomainCreationForm.vue +++ /dev/null @@ -1,243 +0,0 @@ - - - - - diff --git a/frontend/src/components/domains/DomainDKIMKey.vue b/frontend/src/components/domains/DomainDKIMKey.vue deleted file mode 100644 index 0313937b5..000000000 --- a/frontend/src/components/domains/DomainDKIMKey.vue +++ /dev/null @@ -1,78 +0,0 @@ - - - - - diff --git a/frontend/src/components/domains/DomainDNSConfig.vue b/frontend/src/components/domains/DomainDNSConfig.vue deleted file mode 100644 index 4707d1469..000000000 --- a/frontend/src/components/domains/DomainDNSConfig.vue +++ /dev/null @@ -1,94 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DomainDNSForm.vue b/frontend/src/components/domains/DomainDNSForm.vue deleted file mode 100644 index de54e36f7..000000000 --- a/frontend/src/components/domains/DomainDNSForm.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DomainForm.vue b/frontend/src/components/domains/DomainForm.vue deleted file mode 100644 index 8f53b75b3..000000000 --- a/frontend/src/components/domains/DomainForm.vue +++ /dev/null @@ -1,246 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DomainGeneralForm.vue b/frontend/src/components/domains/DomainGeneralForm.vue deleted file mode 100644 index eb84698b0..000000000 --- a/frontend/src/components/domains/DomainGeneralForm.vue +++ /dev/null @@ -1,78 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DomainLimitationsForm.vue b/frontend/src/components/domains/DomainLimitationsForm.vue deleted file mode 100644 index 82ce575cd..000000000 --- a/frontend/src/components/domains/DomainLimitationsForm.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DomainList.vue b/frontend/src/components/domains/DomainList.vue deleted file mode 100644 index a72c98721..000000000 --- a/frontend/src/components/domains/DomainList.vue +++ /dev/null @@ -1,282 +0,0 @@ - - - - - diff --git a/frontend/src/components/domains/DomainOptionsForm.vue b/frontend/src/components/domains/DomainOptionsForm.vue deleted file mode 100644 index 4b64899e1..000000000 --- a/frontend/src/components/domains/DomainOptionsForm.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DomainSummary.vue b/frontend/src/components/domains/DomainSummary.vue deleted file mode 100644 index f94d24670..000000000 --- a/frontend/src/components/domains/DomainSummary.vue +++ /dev/null @@ -1,45 +0,0 @@ - - - diff --git a/frontend/src/components/domains/DomainTransportForm.vue b/frontend/src/components/domains/DomainTransportForm.vue deleted file mode 100644 index 89046d62e..000000000 --- a/frontend/src/components/domains/DomainTransportForm.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AccountAliasForm.vue b/frontend/src/components/identities/AccountAliasForm.vue deleted file mode 100644 index 3513ef96d..000000000 --- a/frontend/src/components/identities/AccountAliasForm.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AccountAliases.vue b/frontend/src/components/identities/AccountAliases.vue deleted file mode 100644 index a5d899979..000000000 --- a/frontend/src/components/identities/AccountAliases.vue +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AccountCreationForm.vue b/frontend/src/components/identities/AccountCreationForm.vue deleted file mode 100644 index 8b05020f8..000000000 --- a/frontend/src/components/identities/AccountCreationForm.vue +++ /dev/null @@ -1,239 +0,0 @@ - - - - - diff --git a/frontend/src/components/identities/AccountForm.vue b/frontend/src/components/identities/AccountForm.vue deleted file mode 100644 index 3564c4bc7..000000000 --- a/frontend/src/components/identities/AccountForm.vue +++ /dev/null @@ -1,298 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AccountGeneralForm.vue b/frontend/src/components/identities/AccountGeneralForm.vue deleted file mode 100644 index 47cab27f8..000000000 --- a/frontend/src/components/identities/AccountGeneralForm.vue +++ /dev/null @@ -1,103 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AccountMailboxForm.vue b/frontend/src/components/identities/AccountMailboxForm.vue deleted file mode 100644 index cab3c44f6..000000000 --- a/frontend/src/components/identities/AccountMailboxForm.vue +++ /dev/null @@ -1,129 +0,0 @@ - - - - - diff --git a/frontend/src/components/identities/AccountPasswordForm.vue b/frontend/src/components/identities/AccountPasswordForm.vue deleted file mode 100644 index d6b61edcb..000000000 --- a/frontend/src/components/identities/AccountPasswordForm.vue +++ /dev/null @@ -1,133 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AccountResourcesForm.vue b/frontend/src/components/identities/AccountResourcesForm.vue deleted file mode 100644 index a18785897..000000000 --- a/frontend/src/components/identities/AccountResourcesForm.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AccountRoleForm.vue b/frontend/src/components/identities/AccountRoleForm.vue deleted file mode 100644 index 955f8227b..000000000 --- a/frontend/src/components/identities/AccountRoleForm.vue +++ /dev/null @@ -1,99 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AccountSenderAddresses.vue b/frontend/src/components/identities/AccountSenderAddresses.vue deleted file mode 100644 index 9875eb4ed..000000000 --- a/frontend/src/components/identities/AccountSenderAddresses.vue +++ /dev/null @@ -1,103 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AccountSummary.vue b/frontend/src/components/identities/AccountSummary.vue deleted file mode 100644 index ac3571872..000000000 --- a/frontend/src/components/identities/AccountSummary.vue +++ /dev/null @@ -1,67 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AliasCreationForm.vue b/frontend/src/components/identities/AliasCreationForm.vue deleted file mode 100644 index 421e4fcbe..000000000 --- a/frontend/src/components/identities/AliasCreationForm.vue +++ /dev/null @@ -1,125 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AliasForm.vue b/frontend/src/components/identities/AliasForm.vue deleted file mode 100644 index 8e065dd47..000000000 --- a/frontend/src/components/identities/AliasForm.vue +++ /dev/null @@ -1,135 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AliasGeneralForm.vue b/frontend/src/components/identities/AliasGeneralForm.vue deleted file mode 100644 index a7d54d093..000000000 --- a/frontend/src/components/identities/AliasGeneralForm.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AliasRecipientForm.vue b/frontend/src/components/identities/AliasRecipientForm.vue deleted file mode 100644 index 01e8abfba..000000000 --- a/frontend/src/components/identities/AliasRecipientForm.vue +++ /dev/null @@ -1,72 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AliasRecipients.vue b/frontend/src/components/identities/AliasRecipients.vue deleted file mode 100644 index 329a94b65..000000000 --- a/frontend/src/components/identities/AliasRecipients.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/frontend/src/components/identities/AliasSummary.vue b/frontend/src/components/identities/AliasSummary.vue deleted file mode 100644 index fd37e1e41..000000000 --- a/frontend/src/components/identities/AliasSummary.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - diff --git a/frontend/src/components/identities/DomainAdminDomains.vue b/frontend/src/components/identities/DomainAdminDomains.vue deleted file mode 100644 index a0fc3d729..000000000 --- a/frontend/src/components/identities/DomainAdminDomains.vue +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/frontend/src/components/identities/IdentityList.vue b/frontend/src/components/identities/IdentityList.vue deleted file mode 100644 index 7d5231a52..000000000 --- a/frontend/src/components/identities/IdentityList.vue +++ /dev/null @@ -1,279 +0,0 @@ - - - diff --git a/frontend/src/components/imap_migration/MigrationsList.vue b/frontend/src/components/imap_migration/MigrationsList.vue deleted file mode 100644 index 96e886f65..000000000 --- a/frontend/src/components/imap_migration/MigrationsList.vue +++ /dev/null @@ -1,117 +0,0 @@ - - - diff --git a/frontend/src/components/imap_migration/ProviderAssociatedForm.vue b/frontend/src/components/imap_migration/ProviderAssociatedForm.vue deleted file mode 100644 index b8afa1401..000000000 --- a/frontend/src/components/imap_migration/ProviderAssociatedForm.vue +++ /dev/null @@ -1,143 +0,0 @@ - - - diff --git a/frontend/src/components/imap_migration/ProviderCreationForm.vue b/frontend/src/components/imap_migration/ProviderCreationForm.vue deleted file mode 100644 index f6d1ff314..000000000 --- a/frontend/src/components/imap_migration/ProviderCreationForm.vue +++ /dev/null @@ -1,132 +0,0 @@ - - - - - diff --git a/frontend/src/components/imap_migration/ProviderForm.vue b/frontend/src/components/imap_migration/ProviderForm.vue deleted file mode 100644 index f36070a87..000000000 --- a/frontend/src/components/imap_migration/ProviderForm.vue +++ /dev/null @@ -1,151 +0,0 @@ - - - diff --git a/frontend/src/components/imap_migration/ProviderGeneralForm.vue b/frontend/src/components/imap_migration/ProviderGeneralForm.vue deleted file mode 100644 index e7be4f3de..000000000 --- a/frontend/src/components/imap_migration/ProviderGeneralForm.vue +++ /dev/null @@ -1,174 +0,0 @@ - - - - - diff --git a/frontend/src/components/imap_migration/ProvidersList.vue b/frontend/src/components/imap_migration/ProvidersList.vue deleted file mode 100644 index f01209554..000000000 --- a/frontend/src/components/imap_migration/ProvidersList.vue +++ /dev/null @@ -1,154 +0,0 @@ - - - diff --git a/frontend/src/components/layout/ConfirmDialog.vue b/frontend/src/components/layout/ConfirmDialog.vue deleted file mode 100644 index 60e8c8ae9..000000000 --- a/frontend/src/components/layout/ConfirmDialog.vue +++ /dev/null @@ -1,79 +0,0 @@ - - - diff --git a/frontend/src/components/layout/Navbar.vue b/frontend/src/components/layout/Navbar.vue deleted file mode 100644 index 078d728e1..000000000 --- a/frontend/src/components/layout/Navbar.vue +++ /dev/null @@ -1,339 +0,0 @@ - - - - - diff --git a/frontend/src/components/layout/Topbar.vue b/frontend/src/components/layout/Topbar.vue deleted file mode 100644 index 5ad73909a..000000000 --- a/frontend/src/components/layout/Topbar.vue +++ /dev/null @@ -1,68 +0,0 @@ - - - diff --git a/frontend/src/components/login/LoginForm.vue b/frontend/src/components/login/LoginForm.vue new file mode 100644 index 000000000..239d44fa6 --- /dev/null +++ b/frontend/src/components/login/LoginForm.vue @@ -0,0 +1,101 @@ + + + diff --git a/frontend/src/components/login/PasswordRecoveryChangeForm.vue b/frontend/src/components/login/PasswordRecoveryChangeForm.vue new file mode 100644 index 000000000..d1be662e2 --- /dev/null +++ b/frontend/src/components/login/PasswordRecoveryChangeForm.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/frontend/src/components/login/PasswordRecoveryForm.vue b/frontend/src/components/login/PasswordRecoveryForm.vue new file mode 100644 index 000000000..8cdbdcddc --- /dev/null +++ b/frontend/src/components/login/PasswordRecoveryForm.vue @@ -0,0 +1,130 @@ + + + diff --git a/frontend/src/components/login/PasswordRecoverySmsTotpForm.vue b/frontend/src/components/login/PasswordRecoverySmsTotpForm.vue new file mode 100644 index 000000000..e771816ea --- /dev/null +++ b/frontend/src/components/login/PasswordRecoverySmsTotpForm.vue @@ -0,0 +1,140 @@ + + + diff --git a/frontend/src/components/login/TwofaForm.vue b/frontend/src/components/login/TwofaForm.vue new file mode 100644 index 000000000..a79e5a519 --- /dev/null +++ b/frontend/src/components/login/TwofaForm.vue @@ -0,0 +1,76 @@ + + + diff --git a/frontend/src/components/logs/AuditTrailList.vue b/frontend/src/components/logs/AuditTrailList.vue deleted file mode 100644 index 1b116ee52..000000000 --- a/frontend/src/components/logs/AuditTrailList.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/frontend/src/components/logs/MessageList.vue b/frontend/src/components/logs/MessageList.vue deleted file mode 100644 index ecffc036e..000000000 --- a/frontend/src/components/logs/MessageList.vue +++ /dev/null @@ -1,89 +0,0 @@ - - - diff --git a/frontend/src/components/parameters/ParametersForm.vue b/frontend/src/components/parameters/ParametersForm.vue deleted file mode 100644 index bf8bbf5f2..000000000 --- a/frontend/src/components/parameters/ParametersForm.vue +++ /dev/null @@ -1,174 +0,0 @@ - - - - - diff --git a/frontend/src/components/tools/ChoiceField.vue b/frontend/src/components/tools/ChoiceField.vue index 9f0c06857..97653a599 100644 --- a/frontend/src/components/tools/ChoiceField.vue +++ b/frontend/src/components/tools/ChoiceField.vue @@ -1,96 +1,127 @@ - diff --git a/frontend/src/components/tools/ConfirmDialog.vue b/frontend/src/components/tools/ConfirmDialog.vue new file mode 100644 index 000000000..5faae125f --- /dev/null +++ b/frontend/src/components/tools/ConfirmDialog.vue @@ -0,0 +1,73 @@ + + + diff --git a/frontend/src/components/tools/CreationForm.vue b/frontend/src/components/tools/CreationForm.vue index ae84d0ed7..f9b65fa4f 100644 --- a/frontend/src/components/tools/CreationForm.vue +++ b/frontend/src/components/tools/CreationForm.vue @@ -1,153 +1,165 @@ + +
+ - Confirm and create - -
- - - - - + {{ $gettext('Confirm and create') }} + + + + + + - diff --git a/frontend/src/components/tools/CreationSummary.vue b/frontend/src/components/tools/CreationSummary.vue index c3a8aab91..03ecf0902 100644 --- a/frontend/src/components/tools/CreationSummary.vue +++ b/frontend/src/components/tools/CreationSummary.vue @@ -1,44 +1,55 @@ - diff --git a/frontend/src/components/tools/ImportForm.vue b/frontend/src/components/tools/ImportForm.vue index e677d9333..e36c20a7b 100644 --- a/frontend/src/components/tools/ImportForm.vue +++ b/frontend/src/components/tools/ImportForm.vue @@ -1,108 +1,100 @@ - diff --git a/frontend/src/components/tools/LoadingData.vue b/frontend/src/components/tools/LoadingData.vue new file mode 100644 index 000000000..d637bcc2d --- /dev/null +++ b/frontend/src/components/tools/LoadingData.vue @@ -0,0 +1,13 @@ + diff --git a/frontend/src/components/tools/MenuItems.vue b/frontend/src/components/tools/MenuItems.vue index aee966ecd..78bba96f6 100644 --- a/frontend/src/components/tools/MenuItems.vue +++ b/frontend/src/components/tools/MenuItems.vue @@ -1,21 +1,28 @@ - diff --git a/frontend/src/components/tools/Resources.vue b/frontend/src/components/tools/Resources.vue deleted file mode 100644 index 6bdae983c..000000000 --- a/frontend/src/components/tools/Resources.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/frontend/src/components/tools/ResourcesForm.vue b/frontend/src/components/tools/ResourcesForm.vue index 7f196ee16..467b3ee38 100644 --- a/frontend/src/components/tools/ResourcesForm.vue +++ b/frontend/src/components/tools/ResourcesForm.vue @@ -1,51 +1,33 @@ - diff --git a/frontend/src/components/tools/ResourcesView.vue b/frontend/src/components/tools/ResourcesView.vue new file mode 100644 index 000000000..a28092972 --- /dev/null +++ b/frontend/src/components/tools/ResourcesView.vue @@ -0,0 +1,32 @@ + + + diff --git a/frontend/src/components/tools/TimeSerieChart.vue b/frontend/src/components/tools/TimeSerieChart.vue index 7c16b0453..9c8ba1f1d 100644 --- a/frontend/src/components/tools/TimeSerieChart.vue +++ b/frontend/src/components/tools/TimeSerieChart.vue @@ -1,168 +1,160 @@ - diff --git a/frontend/src/constants.json b/frontend/src/constants.json index b67288602..b689aec6b 100644 --- a/frontend/src/constants.json +++ b/frontend/src/constants.json @@ -1,4 +1,4 @@ { - "ALARM_OPENED": 1, - "ALARM_CLOSED": 2 + "ALARM_OPENED": 1, + "ALARM_CLOSED": 2 } diff --git a/frontend/src/filters/index.js b/frontend/src/filters/index.js deleted file mode 100644 index 34fd40abe..000000000 --- a/frontend/src/filters/index.js +++ /dev/null @@ -1,23 +0,0 @@ -import Vue from 'vue' -import { DateTime } from 'luxon' -import { translate } from 'vue-gettext' -const { gettext: $gettext } = translate - -Vue.filter('yesno', function (value) { - return (value) ? $gettext('yes') : $gettext('no') -}) - -/* -** Return a human readable version of the given date string. -*/ -Vue.filter('date', function (value) { - return DateTime.fromISO(value).setLocale('en').toLocaleString(DateTime.DATETIME_MED) -}) - -/* -** Truncate given string. -*/ -Vue.filter('truncate', function (text, length, clamp) { - clamp = clamp || '...' - return text.length > length ? text.slice(0, length) + clamp : text -}) diff --git a/frontend/src/layouts/dashboard/DashboardLayout.vue b/frontend/src/layouts/dashboard/DashboardLayout.vue new file mode 100644 index 000000000..00b805f6c --- /dev/null +++ b/frontend/src/layouts/dashboard/DashboardLayout.vue @@ -0,0 +1,44 @@ + + + diff --git a/frontend/src/layouts/dashboard/DashboardView.vue b/frontend/src/layouts/dashboard/DashboardView.vue new file mode 100644 index 000000000..577ca6243 --- /dev/null +++ b/frontend/src/layouts/dashboard/DashboardView.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/frontend/src/layouts/dashboard/NavBar.vue b/frontend/src/layouts/dashboard/NavBar.vue new file mode 100644 index 000000000..be6152fcc --- /dev/null +++ b/frontend/src/layouts/dashboard/NavBar.vue @@ -0,0 +1,352 @@ + + + + + diff --git a/frontend/src/layouts/default/DefaultLayout.vue b/frontend/src/layouts/default/DefaultLayout.vue new file mode 100644 index 000000000..2d73a6430 --- /dev/null +++ b/frontend/src/layouts/default/DefaultLayout.vue @@ -0,0 +1,9 @@ + + + diff --git a/frontend/src/layouts/default/DefaultView.vue b/frontend/src/layouts/default/DefaultView.vue new file mode 100644 index 000000000..f6a4d2ed3 --- /dev/null +++ b/frontend/src/layouts/default/DefaultView.vue @@ -0,0 +1,9 @@ + + + diff --git a/frontend/src/locale/LINGUAS b/frontend/src/locale/LINGUAS new file mode 100644 index 000000000..999dd46f6 --- /dev/null +++ b/frontend/src/locale/LINGUAS @@ -0,0 +1 @@ +en br cs de el es fi fr it ja nl pl pt ru sv tr zh \ No newline at end of file diff --git a/frontend/src/locale/br/app.po b/frontend/src/locale/br/app.po new file mode 100644 index 000000000..19d0d67e4 --- /dev/null +++ b/frontend/src/locale/br/app.po @@ -0,0 +1,2012 @@ +# Breton translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:17+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: br\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +#, fuzzy +msgid "account" +msgstr "Kont" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "Kont" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "Kont krouet" + +#: src/stores/accounts.store.js:62 +#, fuzzy +msgid "Account successfully deleted" +msgstr "Kont krouet" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "Kont hizivaet" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "Oberioù" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "Ouzhpennañ" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "Chomlec'h" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "Domanioù meret" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "Merourien" + +#: src/components/admin/domains/DomainAdminList.vue:6 +#, fuzzy +msgid "Administrators of" +msgstr "Merourien" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +#, fuzzy +msgid "Alarm deleted" +msgstr "Deiziad krouidigezh" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +#, fuzzy +msgid "alias" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "Alias" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +#, fuzzy +msgid "Alias already added" +msgstr "Alias krouet" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +#, fuzzy +msgid "Alias successfully created" +msgstr "Alias krouet" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +#, fuzzy +msgid "Alias updated" +msgstr "Alias krouet" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "Aliasoù" + +#: src/components/admin/identities/AccountEditForm.vue:124 +#, fuzzy +msgid "Aliases:" +msgstr "Aliasoù" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "API" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "API moned" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +#, fuzzy +msgid "API token created" +msgstr "Kont krouet" + +#: src/views/account/APISetupView.vue:114 +#, fuzzy +msgid "API token deleted" +msgstr "Deiziad krouidigezh" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +#, fuzzy +msgid "Associated domain" +msgstr "Domanioù meret" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +#, fuzzy +msgid "Associated domains" +msgstr "Domanioù meret" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "O vezañ anavezet" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "Stumm Ereet/anvet" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "Cheñch ger-tremen" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" +"Kochit an dibarzh ma ne vez ket kriptet ar gerioù-tremen endalc'het en ho " +"restr" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "Serriñ" + +#: src/components/admin/alarms/AlarmList.vue:133 +#, fuzzy +msgid "Close alarm" +msgstr "Serriñ" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "Serriñ" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "Kadarnadur" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "Kenderc'hel war ar fazi" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "Krouit ur merour domani" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "Krouiñ ur voest-posteloù evit ar merour." + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "Krouiñ aliasoù" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "Deiziad krouidigezh" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "Kriptañ ar gerioù-tremen" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +#, fuzzy +msgid "Current password" +msgstr "Kriptañ ar gerioù-tremen" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "Taolenn-stur" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "Kota boest-posteloù dre-ziouer" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +msgid "" +"Default quota applied to mailboxes. Can be expressed in KB, MB (default) or " +"GB. A value of 0 means no quota." +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "Deskrivadur" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +#, fuzzy +msgid "Disable 2FA" +msgstr "Lazhet" + +#: src/components/admin/domains/DomainList.vue:80 +#, fuzzy +msgid "disabled" +msgstr "(lazhet)" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "Lazhet" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "Alc'hwez DKIM" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "DNS" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "Statud DNS" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +#, fuzzy +msgid "domain" +msgstr "Domani" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "Domani" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "Merour an domani" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "Domani krouet" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +#, fuzzy +msgid "Domain default value" +msgstr "Implijout un dalvoudegezh domani dre-ziouer" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +#, fuzzy +msgid "domain's default value" +msgstr "Implijout un dalvoudegezh domani dre-ziouer" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "Domanioù" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +#, fuzzy +msgid "Edit account" +msgstr "Kont nevez" + +#: src/views/admin/identities/AliasEditView.vue:3 +#, fuzzy +msgid "Edit alias" +msgstr "Alias nevez" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +#, fuzzy +msgid "Edit provider" +msgstr "Chomlec'h postel" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "Chomlec'h postel" + +#: src/layouts/dashboard/NavBar.vue:233 +#, fuzzy +msgid "Email providers" +msgstr "Chomlec'h postel" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +#, fuzzy +msgid "Enable 2FA" +msgstr "Enaouet" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "Enaouiñ ar sinadur DKIM" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "Enaouiñ ar gwiriañ DNS" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "Enaouet" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +#, fuzzy +msgid "Enter an email address" +msgstr "Chomlec'h postel" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "Diamzeriet da" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "C'hwitet" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +#, fuzzy +msgid "Field is required" +msgstr "Ar vaezienn-mañ a zo rekiset" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +#, fuzzy +msgid "First name" +msgstr "Anv klok" + +#: src/components/login/LoginForm.vue:96 +#, fuzzy +msgid "Forgot password" +msgstr "Ger-tremen ankouaeet?" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +#, fuzzy +msgid "Forgot password?" +msgstr "Ger-tremen ankouaeet?" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "Treuzkas" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" +"Treuzkas kemennadennoù ha stokiñ eiladennoù e-barzh ar voest-posteloù lec'hel" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "Treuzkas hizivaet" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +#, fuzzy +msgid "Forwarded" +msgstr "Treuzkas" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "Anv klok" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +#, fuzzy +msgid "Fully aligned" +msgstr "Linennet penn-da-benn" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "Hollek" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +#, fuzzy +msgid "General settings" +msgstr "Hollek" + +#: src/views/account/APISetupView.vue:18 +#, fuzzy +msgid "Generate" +msgstr "Hollek" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +#, fuzzy +msgid "Generated address" +msgstr "Chomlec'hioù ar c'haser" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "Identelezhioù" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "Emporzhiañ" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "Emporzhiañ domanioù" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "Emporzhiañ identelezhioù" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "Titouroù" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +#, fuzzy +msgid "Installed components" +msgstr "Stumm staliet" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "Stumm staliet" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +#, fuzzy +msgid "Invalid password" +msgstr "Ger-tremen dre-zegouezh" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "Mirout eiladennoù lec'hel" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "Deiziad aozañ diwezhañ" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +#, fuzzy +msgid "Latest version" +msgstr "Stumm staliet" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "Live" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "Enroller" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "Digevreañ" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "Boest-posteloù" + +#: src/components/admin/identities/AccountEditForm.vue:164 +#, fuzzy +msgid "Mailbox aliases:" +msgstr "Boest-posteloù" + +#: src/components/admin/identities/AccountEditForm.vue:157 +#, fuzzy +msgid "Mailbox:" +msgstr "Boest-posteloù" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "Boest-posteloù" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "Implij" + +#: src/views/admin/monitoring/MessagesView.vue:3 +#, fuzzy +msgid "Message history" +msgstr "Implij" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +#, fuzzy +msgid "Migration deleted" +msgstr "Deiziad krouidigezh" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +#, fuzzy +msgid "Migrations" +msgstr "Kadarnadur" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "Aozet" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "Anv" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +#, fuzzy +msgid "Name:" +msgstr "Anv" + +#: src/components/admin/domains/DomainEditForm.vue:16 +#, fuzzy +msgid "Name: " +msgstr "Anv" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "Kont nevez" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "Alias nevez" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "Domani nevez" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +#, fuzzy +msgid "New provider" +msgstr "Chomlec'h postel" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "Da-heul" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +#, fuzzy +msgid "No associated domains" +msgstr "Domanioù meret" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "Neket ganet" + +#: src/components/admin/identities/AccountEditForm.vue:165 +#, fuzzy +msgid "Number of allowed mailbox aliases:" +msgstr "Boest-posteloù" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +#, fuzzy +msgid "Number of associated domains:" +msgstr "Domanioù meret" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +#, fuzzy +msgid "Old account" +msgstr "Kont nevez" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "Hegerz ez eus un hizivadenn pe muioc'h" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "Dibarzhioù" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +#, fuzzy +msgid "Parameters updated" +msgstr "Profil hizivaet" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "Linennet dre an hanter" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "Ger-tremen" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +#, fuzzy +msgid "Password mismatch" +msgstr "Disklotadurioù gerioù-tremen" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +#, fuzzy +msgid "Password recovery" +msgstr "Ger-tremen" + +#: src/components/account/ProfileForm.vue:143 +#, fuzzy +msgid "Password updated" +msgstr "Treuzkas hizivaet" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "Disklotadurioù gerioù-tremen" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "Niverenn bellgomz" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "Profil" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "Profil hizivaet" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +#, fuzzy +msgid "Provider" +msgstr "Domani krouet" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +#, fuzzy +msgid "Provider created" +msgstr "Domani krouet" + +#: src/stores/providers.store.js:45 +#, fuzzy +msgid "Provider deleted" +msgstr "Domani krouet" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +#, fuzzy +msgid "Provider name" +msgstr "Domani krouet" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +#, fuzzy +msgid "Provider updated" +msgstr "Profil hizivaet" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +#, fuzzy +msgid "Providers" +msgstr "Chomlec'h postel" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "Kota" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" +"Kota evit ar voest-posteloù-mañ. Gellout a ra bezañ ezpleget e Ko, Mo " +"(diouer) pe Go c'hoazh. Termeniñ un dalvoudegezh ispisial pe implijit " +"talvoudegezh an domani. Laoskit goullo evit termeniñ un dalvoudegezh " +"divevenn (berzet evit ar verourien zomani)." + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" +"Kota rannet kenetre 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/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +#, fuzzy +msgid "Quota: " +msgstr "Kota" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "Chomlec'h dre-zegouezh" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "Ger-tremen dre-zegouezh" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "Resever(ien)" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "Reseverien" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +#, fuzzy +msgid "relaydomain" +msgstr "Domani nevez" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "Derc'hel soñj ac'hanon" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +#, fuzzy +msgid "Reopen alarm" +msgstr "Serriñ" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "Eilgwerzher" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "Mammennoù" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "Implij mammennoù" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "Rol" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "Enrollañ" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "Klask" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "Eil chomlec'h postel" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +#, fuzzy +msgid "Send only" +msgstr "Kont nevez" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +#, fuzzy +msgid "Send only account" +msgstr "Kont nevez" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "Chomlec'hioù ar c'haser" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "Skejer" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "Arventennoù" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "Diskouez an alc'hwez" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "Implijer diazez" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +#, fuzzy +msgid "Statistics" +msgstr "Statud" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "Statud" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "Kas" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "Berradenn" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "Dreist-merour" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "Balizoù" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "Hollad" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "Treuzdougen" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +#, fuzzy +msgid "Trusted sources" +msgstr "Mammennoù fizius" + +#: src/components/account/TwoFactorAuthForm.vue:6 +#, fuzzy +msgid "Two factor authentication" +msgstr "O vezañ anavezet" + +#: src/components/login/TwofaForm.vue:6 +#, fuzzy +msgid "Two-factor authentication" +msgstr "O vezañ anavezet" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "Doare" + +#: src/components/admin/domains/DomainEditForm.vue:19 +#, fuzzy +msgid "Type: " +msgstr "Doare" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "Dizanv" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "Mammennoù dizanv/Gourdrouzioù" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "divevennet" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +#, fuzzy +msgid "Unlimited" +msgstr "divevennet" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "Hizivaat" + +#: src/components/account/ProfileForm.vue:75 +#, fuzzy +msgid "Update Password" +msgstr "Ger-tremen" + +#: src/components/account/ProfileForm.vue:62 +#, fuzzy +msgid "Update settings" +msgstr "Arventennoù" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "Hizivaet" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "Implijout un dalvoudegezh domani dre-ziouer" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +#, fuzzy +msgid "User unknown." +msgstr "Dizanv" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "Anv implier" + +#: src/components/admin/identities/AccountEditForm.vue:39 +#, fuzzy +msgid "Username:" +msgstr "Anv implier" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "Degemer mat e-barzh Modoboa" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "Gant ur voest-posteloù" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" + +#~ msgid "Generate a random password for the administrator." +#~ msgstr "Genel ur ger-tremen dre-zegouezh evit ar merour." + +#, fuzzy +#~ msgid "Account not found!" +#~ msgstr "Kont krouet" + +#, fuzzy +#~ msgid "Identities deleted" +#~ msgstr "Identelezhioù" diff --git a/frontend/src/locale/cs/app.po b/frontend/src/locale/cs/app.po new file mode 100644 index 000000000..032e186ed --- /dev/null +++ b/frontend/src/locale/cs/app.po @@ -0,0 +1,1916 @@ +# Czech translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:26+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: cs\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==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +msgid "account" +msgstr "" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "" + +#: src/stores/accounts.store.js:62 +msgid "Account successfully deleted" +msgstr "" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:6 +msgid "Administrators of" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +msgid "Alarm deleted" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +msgid "alias" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +msgid "Alias already added" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +msgid "Alias successfully created" +msgstr "" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +msgid "Alias updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:124 +msgid "Aliases:" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +msgid "API token created" +msgstr "" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +msgid "Associated domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +msgid "Associated domains" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +msgid "Current password" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:80 +msgid "disabled" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +msgid "domain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +msgid "Edit provider" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "" + +#: src/components/login/LoginForm.vue:96 +msgid "Forgot password" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +msgid "Forgot password?" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +msgid "General settings" +msgstr "" + +#: src/views/account/APISetupView.vue:18 +msgid "Generate" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +msgid "Generated address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +msgid "Installed components" +msgstr "" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +msgid "Invalid password" +msgstr "" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +msgid "Latest version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:164 +msgid "Mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:157 +msgid "Mailbox:" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "" + +#: src/views/admin/monitoring/MessagesView.vue:3 +msgid "Message history" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +msgid "Migration deleted" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +msgid "Migrations" +msgstr "" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +msgid "Name:" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:16 +msgid "Name: " +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +msgid "New provider" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:165 +msgid "Number of allowed mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +msgid "Old account" +msgstr "" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +msgid "Password mismatch" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +msgid "Password recovery" +msgstr "" + +#: src/components/account/ProfileForm.vue:143 +msgid "Password updated" +msgstr "" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +msgid "Provider" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +msgid "Provider created" +msgstr "" + +#: src/stores/providers.store.js:45 +msgid "Provider deleted" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +msgid "Provider name" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +msgid "Provider updated" +msgstr "" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +msgid "Providers" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +msgid "relaydomain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +msgid "Send only" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +msgid "Send only account" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:6 +msgid "Two factor authentication" +msgstr "" + +#: src/components/login/TwofaForm.vue:6 +msgid "Two-factor authentication" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:19 +msgid "Type: " +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +msgid "Unlimited" +msgstr "" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "" + +#: src/components/account/ProfileForm.vue:75 +msgid "Update Password" +msgstr "" + +#: src/components/account/ProfileForm.vue:62 +msgid "Update settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +msgid "User unknown." +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:39 +msgid "Username:" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" diff --git a/frontend/src/locale/de/app.po b/frontend/src/locale/de/app.po new file mode 100644 index 000000000..09b4c9f65 --- /dev/null +++ b/frontend/src/locale/de/app.po @@ -0,0 +1,2016 @@ +# German translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:17+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +#, fuzzy +msgid "account" +msgstr "Konto" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "Konto" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "Konto erstellt" + +#: src/stores/accounts.store.js:62 +#, fuzzy +msgid "Account successfully deleted" +msgstr "Konto erstellt" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "Konto aktualisiert" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "Aktionen" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "Hinzufügen" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "Adresse" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "Administrierte Domains" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "Administratoren" + +#: src/components/admin/domains/DomainAdminList.vue:6 +#, fuzzy +msgid "Administrators of" +msgstr "Administratoren" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +#, fuzzy +msgid "Alarm deleted" +msgstr "Erstellungsdatum" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +#, fuzzy +msgid "alias" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "Alias" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +#, fuzzy +msgid "Alias already added" +msgstr "Alias erstellt" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +#, fuzzy +msgid "Alias successfully created" +msgstr "Alias erstellt" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +#, fuzzy +msgid "Alias updated" +msgstr "Alias erstellt" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "Aliase" + +#: src/components/admin/identities/AccountEditForm.vue:124 +#, fuzzy +msgid "Aliases:" +msgstr "Aliase" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "API" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "API Zugriff" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +#, fuzzy +msgid "API token created" +msgstr "Konto erstellt" + +#: src/views/account/APISetupView.vue:114 +#, fuzzy +msgid "API token deleted" +msgstr "Erstellungsdatum" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "Antworten" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +#, fuzzy +msgid "Associated domain" +msgstr "Administrierte Domains" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +#, fuzzy +msgid "Associated domains" +msgstr "Administrierte Domains" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "Authentifizierung" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "Gebundenes Format" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "Passwort ändern" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "Auswählen, wenn Kennwörter in Datei nicht verschlüsselt sind" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "Schließen" + +#: src/components/admin/alarms/AlarmList.vue:133 +#, fuzzy +msgid "Close alarm" +msgstr "Schließen" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "Schließen" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "Bestätigung" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" +"Glückwunsch! Die Zwei-Faktor-Authentifizierung ist nun für diesen Account " +"aktiviert." + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "Bei Fehler fortfahren" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "Domain-Administrator erstellen" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "Erzeuge Postfach für den Administrator." + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "Aliase erstellen" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "Erstellungsdatum" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "Passwörter verschlüsseln" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +#, fuzzy +msgid "Current password" +msgstr "Passwörter verschlüsseln" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "Dashboard" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "Datum" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "Tag" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "Standard Postfach Kontingent" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +msgid "" +"Default quota applied to mailboxes. Can be expressed in KB, MB (default) or " +"GB. A value of 0 means no quota." +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "Beschreibung" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "Deaktiviere 2-Faktor-Authentifizierung" + +#: src/components/admin/domains/DomainList.vue:80 +#, fuzzy +msgid "disabled" +msgstr "(deaktiviert)" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "Deaktiviert" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "DKIM Schlüssel" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "DNS" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "DNS Status" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +#, fuzzy +msgid "domain" +msgstr "Domain" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "Domain" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "Domain Administrator" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "Domain erstellt." + +#: src/components/admin/identities/AccountCreationForm.vue:124 +#, fuzzy +msgid "Domain default value" +msgstr "Standardwert der Domain verwenden" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +#, fuzzy +msgid "domain's default value" +msgstr "Standardwert der Domain verwenden" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "Domains" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +#, fuzzy +msgid "Edit account" +msgstr "Neues Konto" + +#: src/views/admin/identities/AliasEditView.vue:3 +#, fuzzy +msgid "Edit alias" +msgstr "Neuer Alias" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +#, fuzzy +msgid "Edit provider" +msgstr "E-Mail Adresse" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "E-Mail Adresse" + +#: src/layouts/dashboard/NavBar.vue:233 +#, fuzzy +msgid "Email providers" +msgstr "E-Mail Adresse" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "Aktiviere 2FA" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "Aktiviere DKIM Signierung" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "Aktiviere DNS Prüfungen" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "Aktiviert" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +#, fuzzy +msgid "Enter an email address" +msgstr "E-Mail Adresse" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "Gib den Code der per SMS zugestellt wurde" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "Läuft ab am" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "Fehlgeschlagen" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +#, fuzzy +msgid "First name" +msgstr "Vollständiger Name" + +#: src/components/login/LoginForm.vue:96 +#, fuzzy +msgid "Forgot password" +msgstr "Passwort vergessen?" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +#, fuzzy +msgid "Forgot password?" +msgstr "Passwort vergessen?" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "Weiterleiten" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "Nachricht weiterleiten und Kopie in Mailbox ablegen" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "Weiterleitung aktualisiert" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +#, fuzzy +msgid "Forwarded" +msgstr "Weiterleiten" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "Von" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "Vollständiger Name" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +#, fuzzy +msgid "Fully aligned" +msgstr "Voll zugeordnet" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "Allgemein" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +#, fuzzy +msgid "General settings" +msgstr "Allgemein" + +#: src/views/account/APISetupView.vue:18 +#, fuzzy +msgid "Generate" +msgstr "Allgemein" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +#, fuzzy +msgid "Generated address" +msgstr "Ab­sen­der­ad­res­sen " + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "Identitäten" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "Import" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "Domains importieren" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "Identitäten importieren" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "Information" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +#, fuzzy +msgid "Installed components" +msgstr "Installierte Version" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "Installierte Version" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +#, fuzzy +msgid "Invalid password" +msgstr "Zufälliges Passwort" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "Lokale Kopien behalten" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "Datum der letzten Änderung" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +#, fuzzy +msgid "Latest version" +msgstr "Installierte Version" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "Stufe" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "Logger" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "Logout" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "Postfächer" + +#: src/components/admin/identities/AccountEditForm.vue:164 +#, fuzzy +msgid "Mailbox aliases:" +msgstr "Mailboxen" + +#: src/components/admin/identities/AccountEditForm.vue:157 +#, fuzzy +msgid "Mailbox:" +msgstr "Postfächer" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "Mailboxen" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "Verwendung" + +#: src/views/admin/monitoring/MessagesView.vue:3 +#, fuzzy +msgid "Message history" +msgstr "Verwendung" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +#, fuzzy +msgid "Migration deleted" +msgstr "Erstellungsdatum" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +#, fuzzy +msgid "Migrations" +msgstr "Bestätigung" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "Verändert" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "Monat" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "Name" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +#, fuzzy +msgid "Name:" +msgstr "Name" + +#: src/components/admin/domains/DomainEditForm.vue:16 +#, fuzzy +msgid "Name: " +msgstr "Name" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "Neues Konto" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "Neuer Alias" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "Neue Domain" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +#, fuzzy +msgid "New provider" +msgstr "Neue Wiederherstellungscodes" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "Neue Wiederherstellungscodes" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "Weiter" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +#, fuzzy +msgid "No associated domains" +msgstr "Administrierte Domains" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "Nicht generiert" + +#: src/components/admin/identities/AccountEditForm.vue:165 +#, fuzzy +msgid "Number of allowed mailbox aliases:" +msgstr "Mailboxen" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +#, fuzzy +msgid "Number of associated domains:" +msgstr "Administrierte Domains" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +#, fuzzy +msgid "Old account" +msgstr "Neues Konto" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "Eine oder mehrere Aktualisierungen sind verfügbar" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "Optionen" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +#, fuzzy +msgid "Parameters updated" +msgstr "Profil aktualisiert" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "Teilweise zugeordnet" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "Passwort" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +#, fuzzy +msgid "Password mismatch" +msgstr "Passwörter stimmen nicht überein" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +#, fuzzy +msgid "Password recovery" +msgstr "Passwort" + +#: src/components/account/ProfileForm.vue:143 +#, fuzzy +msgid "Password updated" +msgstr "Weiterleitung aktualisiert" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "Passwörter stimmen nicht überein" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "Telefonnummer" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "Pincode" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "Bitte die Primäre Email-Adresse eingeben" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "Profil" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "Profil aktualisiert" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +#, fuzzy +msgid "Provider" +msgstr "Neue Wiederherstellungscodes" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +#, fuzzy +msgid "Provider created" +msgstr "Domain erstellt." + +#: src/stores/providers.store.js:45 +#, fuzzy +msgid "Provider deleted" +msgstr "Domain erstellt." + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +#, fuzzy +msgid "Provider name" +msgstr "Domain erstellt." + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +#, fuzzy +msgid "Provider updated" +msgstr "Profil aktualisiert" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +#, fuzzy +msgid "Providers" +msgstr "E-Mail Adresse" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" +"Quota dieses Postfachs. Kann in KB, MB (Voreinstellung) oder GB angegeben " +"werden. Eigenen Wert eingeben oder Voreinstellung der Domain verwenden " +"lassen. Frei lassen, um Quota auf unlimitiert zu setzen (nur Super-" +"Administratoren)." + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" +"Von Postfächern gemeinsam genutzte Quota/Speicherplatz. Kann in KB, MB " +"(Voreinstellung) oder GB angegeben werden. 0 eingeben, um keine Quota zu " +"verwenden." + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "Zufällige Adresse" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "Zufälliges Passwort" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "Empfänger" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "Empfänger" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "Registrieren" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +#, fuzzy +msgid "relaydomain" +msgstr "Neue Domain" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "An mich erinnern" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +#, fuzzy +msgid "Reopen alarm" +msgstr "Schließen" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "Reseller" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "Setze Wiederherstellungscodes zurück" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "Ressourcen" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "Ressourcen-Verbrauch" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "Rolle" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "Speichern" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "Suchen" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "Zweite E-Mail Adresse" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +#, fuzzy +msgid "Secured" +msgstr "Sicherheit" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "Sicherheit" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +#, fuzzy +msgid "Send only" +msgstr "Neues Konto" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +#, fuzzy +msgid "Send only account" +msgstr "Neues Konto" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "Ab­sen­der­ad­res­sen " + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "Separator" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "Einstellungen" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "Zeige Schlüssel" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "Normaler Benutzer" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +#, fuzzy +msgid "Statistics" +msgstr "Statistiken" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "Status" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "Abschicken" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "Zusammenfassung" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "Super-Administrator" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "Tags" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "Bis" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "Total" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +#, fuzzy +msgid "Trusted sources" +msgstr "Vertraute Quellen" + +#: src/components/account/TwoFactorAuthForm.vue:6 +#, fuzzy +msgid "Two factor authentication" +msgstr "Authentifizierung" + +#: src/components/login/TwofaForm.vue:6 +#, fuzzy +msgid "Two-factor authentication" +msgstr "Authentifizierung" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" +"Zwei-Faktor-Authentifizierung (2FA) ist noch nicht für diesen Account " +"aktiviert.\n" +"Aktiviere dieses Feature, um die Account-Sicherheit zu erhöhen." + +#: src/components/account/TwoFactorAuthForm.vue:71 +#, fuzzy +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" +"Glückwunsch! Die Zwei-Faktor-Authentifizierung ist nun für diesen Account " +"aktiviert." + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "Typ" + +#: src/components/admin/domains/DomainEditForm.vue:19 +#, fuzzy +msgid "Type: " +msgstr "Typ" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "Unbekannt" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "Unbekannte Quellen / Bedrohungen" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "unbegrenzt" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +#, fuzzy +msgid "Unlimited" +msgstr "unbegrenzt" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "Aktualisieren" + +#: src/components/account/ProfileForm.vue:75 +#, fuzzy +msgid "Update Password" +msgstr "Passwort" + +#: src/components/account/ProfileForm.vue:62 +#, fuzzy +msgid "Update settings" +msgstr "Einstellungen" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "Aktualisieren" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "Standardwert der Domain verwenden" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +#, fuzzy +msgid "User unknown." +msgstr "Unbekannt" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "Benutzername" + +#: src/components/admin/identities/AccountEditForm.vue:39 +#, fuzzy +msgid "Username:" +msgstr "Benutzername" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "Woche" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "Willkommen zu Modoboa" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "Mit einem Postfach" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "Jahr" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" + +#~ msgid "Generate a random password for the administrator." +#~ msgstr "Zufällig generiertes Passwort für den Administrator verwenden." + +#, fuzzy +#~ msgid "Account not found!" +#~ msgstr "Konto erstellt" + +#, fuzzy +#~ msgid "Identities deleted" +#~ msgstr "Identitäten" diff --git a/frontend/src/locale/el/app.po b/frontend/src/locale/el/app.po new file mode 100644 index 000000000..01ec11b44 --- /dev/null +++ b/frontend/src/locale/el/app.po @@ -0,0 +1,1916 @@ +# Greek translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:26+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +msgid "account" +msgstr "" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "" + +#: src/stores/accounts.store.js:62 +msgid "Account successfully deleted" +msgstr "" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:6 +msgid "Administrators of" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +msgid "Alarm deleted" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +msgid "alias" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +msgid "Alias already added" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +msgid "Alias successfully created" +msgstr "" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +msgid "Alias updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:124 +msgid "Aliases:" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +msgid "API token created" +msgstr "" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +msgid "Associated domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +msgid "Associated domains" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +msgid "Current password" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:80 +msgid "disabled" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +msgid "domain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +msgid "Edit provider" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "" + +#: src/components/login/LoginForm.vue:96 +msgid "Forgot password" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +msgid "Forgot password?" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +msgid "General settings" +msgstr "" + +#: src/views/account/APISetupView.vue:18 +msgid "Generate" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +msgid "Generated address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +msgid "Installed components" +msgstr "" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +msgid "Invalid password" +msgstr "" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +msgid "Latest version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:164 +msgid "Mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:157 +msgid "Mailbox:" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "" + +#: src/views/admin/monitoring/MessagesView.vue:3 +msgid "Message history" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +msgid "Migration deleted" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +msgid "Migrations" +msgstr "" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +msgid "Name:" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:16 +msgid "Name: " +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +msgid "New provider" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:165 +msgid "Number of allowed mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +msgid "Old account" +msgstr "" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +msgid "Password mismatch" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +msgid "Password recovery" +msgstr "" + +#: src/components/account/ProfileForm.vue:143 +msgid "Password updated" +msgstr "" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +msgid "Provider" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +msgid "Provider created" +msgstr "" + +#: src/stores/providers.store.js:45 +msgid "Provider deleted" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +msgid "Provider name" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +msgid "Provider updated" +msgstr "" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +msgid "Providers" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +msgid "relaydomain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +msgid "Send only" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +msgid "Send only account" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:6 +msgid "Two factor authentication" +msgstr "" + +#: src/components/login/TwofaForm.vue:6 +msgid "Two-factor authentication" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:19 +msgid "Type: " +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +msgid "Unlimited" +msgstr "" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "" + +#: src/components/account/ProfileForm.vue:75 +msgid "Update Password" +msgstr "" + +#: src/components/account/ProfileForm.vue:62 +msgid "Update settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +msgid "User unknown." +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:39 +msgid "Username:" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" diff --git a/frontend/src/locale/en/app.po b/frontend/src/locale/en/app.po new file mode 100644 index 000000000..e6ed876d8 --- /dev/null +++ b/frontend/src/locale/en/app.po @@ -0,0 +1,2020 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" +"A new key will be generated soon. Refresh the page in a moment to see it." + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "Absolute time range" + +#: src/stores/identities.store.js:67 +#, fuzzy +msgid "account" +msgstr "Account" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "Account" + +#: src/stores/accounts.store.js:51 +#, fuzzy +msgid "Account created" +msgstr "Domain created" + +#: src/stores/accounts.store.js:62 +msgid "Account successfully deleted" +msgstr "" + +#: src/stores/accounts.store.js:43 +#, fuzzy +msgid "Account updated" +msgstr "Domain updated" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "Actions" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "Add" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "Add a new domain alias" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "Add administrator" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "Add sender address" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "Address" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "Administered domains" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "Administrator added" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "Administrator name" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "Administrator removed" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "Administrators" + +#: src/components/admin/domains/DomainAdminList.vue:6 +msgid "Administrators of" +msgstr "Administrators of" + +#: src/components/admin/alarms/AlarmList.vue:188 +#, fuzzy +msgid "Alarm closed" +msgstr "Alarms" + +#: src/components/admin/alarms/AlarmList.vue:173 +#, fuzzy +msgid "Alarm deleted" +msgstr "Domain deleted" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "Alarms" + +#: src/components/admin/alarms/AlarmList.vue:180 +#, fuzzy +msgid "Alarms deleted" +msgstr "Domain alias deleted" + +#: src/stores/identities.store.js:97 +#, fuzzy +msgid "alias" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "Alias" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +msgid "Alias already added" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +msgid "Alias successfully created" +msgstr "" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +#, fuzzy +msgid "Alias updated" +msgstr "Domain alias updated" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "Aliases" + +#: src/components/admin/identities/AccountEditForm.vue:124 +#, fuzzy +msgid "Aliases:" +msgstr "Aliases" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "Alignment" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "API" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "" + +#: src/views/account/APISetupView.vue:80 +#, fuzzy +msgid "API token copied to your clipboard" +msgstr "Password copied to clipboard" + +#: src/views/account/APISetupView.vue:92 +#, fuzzy +msgid "API token created" +msgstr "Domain created" + +#: src/views/account/APISetupView.vue:114 +#, fuzzy +msgid "API token deleted" +msgstr "Domain deleted" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "Apply" + +#: src/components/admin/identities/IdentityList.vue:231 +#, fuzzy +msgid "Are you sure you want to delete this alias?" +msgstr "Do you really want to delete the domain %{ domain }?" + +#: src/components/admin/identities/IdentityList.vue:205 +#, fuzzy +msgid "Are you sure you want to delete this identity ?" +msgstr "Do you really want to delete the domain %{ domain }?" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +#, fuzzy +msgid "Associated domain" +msgstr "Administered domains" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +#, fuzzy +msgid "Associated domains" +msgstr "Administered domains" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "Audit trail" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "Authentication" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "Auto configuration" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "autoconfig record (Mozilla) not found" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "autoconfig record (Mozilla): %{ value }" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "autodiscover record (Microsoft) not found" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "autodiscover record (Microsoft): %{ value }" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "Back" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "Bind/named format. Click to copy" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "Cancel" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +#, fuzzy +msgid "Change password" +msgstr "Random password" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "Choose a domain" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +#, fuzzy +msgid "Choose a role" +msgstr "Choose a domain" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "Close" + +#: src/components/admin/alarms/AlarmList.vue:133 +#, fuzzy +msgid "Close alarm" +msgstr "Close" + +#: src/components/admin/alarms/AlarmList.vue:46 +#, fuzzy +msgid "Closed" +msgstr "Close" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "Confirm and create" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +#, fuzzy +msgid "Confirmation" +msgstr "Information" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "Connect" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "Continue on error" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "Control if this domain will be allowed to send and receive messages" + +#: src/components/admin/domains/DNSDetail.vue:114 +#, fuzzy +msgid "Copy key to clipboard" +msgstr "Copy to clipboard" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "Copy to clipboard" + +#: src/views/account/APISetupView.vue:33 +#, fuzzy +msgid "Copy token to clipboard" +msgstr "Copy to clipboard" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "Create a domain administrator" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "Create a mailbox for the administrator." + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "Create aliases" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "Create standard aliases for the domain." + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "Creation date" + +#: src/views/admin/identities/IdentitiesView.vue:81 +#, fuzzy +msgid "Crypt passwords" +msgstr "Forgot password" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "CSV seems to be badly formatted" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +#, fuzzy +msgid "Current password" +msgstr "Forgot password" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +#, fuzzy +msgid "Daily message sending limit" +msgstr "Message sending limit" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "Daily sending limit" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "Dashboard" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "Day" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "Default mailbox quota" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +msgid "" +"Default quota applied to mailboxes. Can be expressed in KB, MB (default) or " +"GB. A value of 0 means no quota." +msgstr "" +"Default quota applied to mailboxes. Can be expressed in KB, MB (default) or " +"GB. A value of 0 means no quota." + +#: src/components/admin/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "Delete" + +#: src/views/account/APISetupView.vue:43 +#, fuzzy +msgid "Delete token" +msgstr "Delete" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "Detail" + +#: src/components/account/TwoFactorAuthForm.vue:90 +#, fuzzy +msgid "Disable 2FA" +msgstr "Disabled" + +#: src/components/admin/domains/DomainList.vue:80 +#, fuzzy +msgid "disabled" +msgstr "(disabled)" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "Disabled" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "DKIM key" + +#: src/components/admin/domains/DNSDetail.vue:182 +#, fuzzy +msgid "DKIM key copied to clipboard" +msgstr "Password copied to clipboard" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "DKIM key length" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "DKIM key selector" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" +"DKIM keys already exist for this domain. Do you want to overwrite them?" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "DKIM public key for" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "DKIM record found" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "DKIM record not found" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "DKIM signing" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "DMARC" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "DMARC record found" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "DMARC record not found" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "DMARC support does not seem to be enabled for this domain." + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "DNS" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "DNS checks" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "DNS configuration for " + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "DNS configuration help" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "DNS status" + +#: src/components/admin/identities/IdentityList.vue:97 +#, fuzzy +msgid "Do not delete account folder" +msgstr "Do not delete domain folder" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "Do not delete domain folder" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "Do you really want to delete the domain %{ domain }?" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +#, fuzzy +msgid "domain" +msgstr "Domain" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "Domain" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +#, fuzzy +msgid "Domain administrator" +msgstr "Create a domain administrator" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "Domain alias created" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "Domain alias deleted" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "Domain alias updated" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "Domain created" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +#, fuzzy +msgid "Domain default value" +msgstr "Domain deleted" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "Domain deleted" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "Domain name (ex: domain.tld)" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "Domain updated" + +#: src/components/admin/identities/AccountEditForm.vue:81 +#, fuzzy +msgid "domain's default value" +msgstr "Domain deleted" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "Domains" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "Don't treat duplicated objects as errors" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "Edit" + +#: src/views/admin/identities/AccountEditView.vue:2 +#, fuzzy +msgid "Edit account" +msgstr "Account" + +#: src/views/admin/identities/AliasEditView.vue:3 +#, fuzzy +msgid "Edit alias" +msgstr "Edit domain alias" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "Edit domain" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "Edit domain alias" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +#, fuzzy +msgid "Edit provider" +msgstr "Email providers" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +#, fuzzy +msgid "Email address" +msgstr "Specify an email address" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "Email providers" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "Empty" + +#: src/components/account/TwoFactorAuthForm.vue:107 +#, fuzzy +msgid "Enable 2FA" +msgstr "Enabled" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "Enable DKIM signing" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "Enable DNS checks" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "Enabled" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +#, fuzzy +msgid "Enter an email address" +msgstr "Specify an email address" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "Export accounts and aliases to CSV" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "Export domains and aliases to CSV" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "Failed" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "Field is required" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +#, fuzzy +msgid "First name" +msgstr "Full name" + +#: src/components/login/LoginForm.vue:96 +msgid "Forgot password" +msgstr "Forgot password" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +#, fuzzy +msgid "Forgot password?" +msgstr "Forgot password" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "Forward" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" + +#: src/components/account/ForwardForm.vue:49 +#, fuzzy +msgid "Forward updated" +msgstr "Forwarded" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "Forwarded" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "Forwarders with ARC" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "From" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "Full name" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "Fullname/recipient" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "Fully aligned" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "General" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "General information" + +#: src/components/account/ProfileForm.vue:5 +#, fuzzy +msgid "General settings" +msgstr "General information" + +#: src/views/account/APISetupView.vue:18 +#, fuzzy +msgid "Generate" +msgstr "General" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "Generate a new DKIM key" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +#, fuzzy +msgid "Generated address" +msgstr "Sender addresses" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "Identification" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "Identities" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" +"If you configured it recently, please wait for the first report to be " +"received and processed." + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "IMAP Migration" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +#, fuzzy +msgid "IMAP Port" +msgstr "IMAP Migration" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "Import" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "Import accounts and aliases from CSV file" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "Import domains" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "Import domains and aliases from CSV file" + +#: src/views/admin/identities/IdentitiesView.vue:59 +#, fuzzy +msgid "Import identities" +msgstr "Identities" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "Information" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +msgid "Installed components" +msgstr "" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +#, fuzzy +msgid "Invalid password" +msgstr "Random password" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "Last login date" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "Last modification date" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +#, fuzzy +msgid "Last name" +msgstr "Last login date" + +#: src/views/admin/InformationView.vue:59 +msgid "Latest version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "Limitations" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "Logout" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +#, fuzzy +msgid "Mailbox" +msgstr "Mailboxes" + +#: src/components/admin/identities/AccountEditForm.vue:164 +#, fuzzy +msgid "Mailbox aliases:" +msgstr "Mailboxes" + +#: src/components/admin/identities/AccountEditForm.vue:157 +#, fuzzy +msgid "Mailbox:" +msgstr "Mailboxes" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "Mailboxes" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "MB" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +#, fuzzy +msgid "Message" +msgstr "Messages" + +#: src/views/admin/monitoring/MessagesView.vue:3 +#, fuzzy +msgid "Message history" +msgstr "Messages" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "Message sending limit" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "messages" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "Messages" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +#, fuzzy +msgid "Migration deleted" +msgstr "Domain deleted" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +msgid "Migrations" +msgstr "Migrations" + +#: src/plugins/rules.js:32 +#, fuzzy +msgid "Minimum length is %{ length }" +msgstr "Minimum length is 6" + +#: src/components/admin/identities/AliasSummary.vue:12 +#, fuzzy +msgid "Modified" +msgstr "Modify" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "Modify" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "Monitoring" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "Month" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "Must be a numeric value or empty" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "MX records" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "Name" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "Name of the administrator" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +#, fuzzy +msgid "Name of the domain to migrate" +msgstr "Name of the administrator" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +#, fuzzy +msgid "Name:" +msgstr "Name: " + +#: src/components/admin/domains/DomainEditForm.vue:16 +msgid "Name: " +msgstr "Name: " + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "Never logged-in" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "New" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +#, fuzzy +msgid "New account" +msgstr "Account" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +#, fuzzy +msgid "New alias" +msgstr "New domain" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "New domain" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +#, fuzzy +msgid "New provider" +msgstr "Email providers" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "Next" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "no" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "No" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "No data to export" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "No sender address defined for this account" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "No sending limit" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "Not a valid email" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "Not generated" + +#: src/components/admin/identities/AccountEditForm.vue:165 +msgid "Number of allowed mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" +"Number of messages this domain can send per day. Leave empty for no limit." + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +#, fuzzy +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" +"Number of messages this domain can send per day. Leave empty for no limit." + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "OK" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +#, fuzzy +msgid "Old account" +msgstr "Account" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "Options" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "Partially aligned" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "Partially trusted sources / Forwarders" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "Password" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "Password copied to clipboard" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +#, fuzzy +msgid "Password mismatch" +msgstr "Password" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +#, fuzzy +msgid "Password recovery" +msgstr "Password" + +#: src/components/account/ProfileForm.vue:143 +#, fuzzy +msgid "Password updated" +msgstr "Password" + +#: src/plugins/rules.js:39 +#, fuzzy +msgid "Passwords mismatch" +msgstr "Password" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "Pending" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "Period" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "Phone number" + +#: src/components/account/TwoFactorAuthForm.vue:39 +#, fuzzy +msgid "Pin code" +msgstr "Verify code" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "Problem" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "Profile" + +#: src/components/account/ProfileForm.vue:125 +#, fuzzy +msgid "Profile updated" +msgstr "Domain updated" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "Provide a CSV file where lines respect one of the following formats:" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +#, fuzzy +msgid "Provider" +msgstr "Email providers" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +#, fuzzy +msgid "Provider created" +msgstr "Domain created" + +#: src/stores/providers.store.js:45 +#, fuzzy +msgid "Provider deleted" +msgstr "Domain deleted" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +msgid "Provider name" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +#, fuzzy +msgid "Provider updated" +msgstr "Domain updated" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +#, fuzzy +msgid "Providers" +msgstr "Email providers" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "Quota" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "Quota: " + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +#, fuzzy +msgid "Random address" +msgstr "Random password" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "Random password" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "Raw format. Click to copy" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "Relative time ranges" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "Relay" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +#, fuzzy +msgid "relaydomain" +msgstr "New domain" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "Reload" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "Remember me" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "Remove this address" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "Remove this administrator" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "Resources" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "Resources usage" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "Role" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "Save" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "Secondary email" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +#, fuzzy +msgid "Secured" +msgstr "Security" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "Security" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "Select an account" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "Select file" + +#: src/components/admin/identities/AccountEditForm.vue:92 +msgid "Send only" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +#, fuzzy +msgid "Send only account" +msgstr "Select an account" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "Sender addresses" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "Sending limit" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "Sending limit: " + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "Separator" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "Service" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "Service: " + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "Settings" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "Show key" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "Specify an email address" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "SPF record found" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "SPF record not found" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "Statistics" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +#, fuzzy +msgid "Status" +msgstr "DNS status" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "Summary" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +#, fuzzy +msgid "Super administrator" +msgstr "Add administrator" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "Tags" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "To" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "Total" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "Transport" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "Trusted sources" + +#: src/components/account/TwoFactorAuthForm.vue:6 +#, fuzzy +msgid "Two factor authentication" +msgstr "Two-factor authentication" + +#: src/components/login/TwofaForm.vue:6 +msgid "Two-factor authentication" +msgstr "Two-factor authentication" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "Type" + +#: src/components/admin/domains/DomainEditForm.vue:19 +msgid "Type: " +msgstr "Type: " + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "Unknown" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "Unknown sources / Threats" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +#, fuzzy +msgid "unlimited" +msgstr "Unlimited" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +msgid "Unlimited" +msgstr "Unlimited" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "Update" + +#: src/components/account/ProfileForm.vue:75 +#, fuzzy +msgid "Update Password" +msgstr "Password" + +#: src/components/account/ProfileForm.vue:62 +#, fuzzy +msgid "Update settings" +msgstr "Settings" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "Updated" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +#, fuzzy +msgid "User unknown." +msgstr "Unknown" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "Username" + +#: src/components/admin/identities/AccountEditForm.vue:39 +#, fuzzy +msgid "Username:" +msgstr "Username" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "Valid" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "Verify code" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "warning" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "Warning" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "Week" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "With a mailbox" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "With mailbox" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "Year" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "yes" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "Yes" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "You can use a different character as separator." + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" + +#~ msgid "Generate a random password for the administrator." +#~ msgstr "Generate a random password for the administrator." diff --git a/frontend/src/locale/es/app.po b/frontend/src/locale/es/app.po new file mode 100644 index 000000000..892b8ad82 --- /dev/null +++ b/frontend/src/locale/es/app.po @@ -0,0 +1,2005 @@ +# Spanish translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:26+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +#, fuzzy +msgid "account" +msgstr "Cuenta" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "Cuenta" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "Cuenta creada" + +#: src/stores/accounts.store.js:62 +#, fuzzy +msgid "Account successfully deleted" +msgstr "Cuenta creada" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "Cuenta actualizada" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "Acciones" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "Añadir" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "Dirección" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "Dominios administrados" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "Administradores" + +#: src/components/admin/domains/DomainAdminList.vue:6 +#, fuzzy +msgid "Administrators of" +msgstr "Administradores" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +#, fuzzy +msgid "Alarm deleted" +msgstr "Fecha de creación" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +#, fuzzy +msgid "alias" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "Alias" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +#, fuzzy +msgid "Alias already added" +msgstr "Alias creado" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +#, fuzzy +msgid "Alias successfully created" +msgstr "Alias creado" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +#, fuzzy +msgid "Alias updated" +msgstr "Alias creado" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:124 +#, fuzzy +msgid "Aliases:" +msgstr "Alias" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "API" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "Acceso API" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +#, fuzzy +msgid "API token created" +msgstr "Cuenta creada" + +#: src/views/account/APISetupView.vue:114 +#, fuzzy +msgid "API token deleted" +msgstr "Fecha de creación" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "Aplicar" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +#, fuzzy +msgid "Associated domain" +msgstr "Dominios administrados" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +#, fuzzy +msgid "Associated domains" +msgstr "Dominios administrados" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "Autenticación" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "Formato inválido" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "Cambiar contraseña" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" +"Marque esta opción si las contraseñas que contiene su fichero no están " +"cifradas" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "Confirmación" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "Continúe en error." + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "Crear un administrador del dominio" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "Crear mailbox para el administrador." + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "Crear alias" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "Fecha de creación" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "Contraseñas cifradas" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +#, fuzzy +msgid "Current password" +msgstr "Contraseñas cifradas" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "Panel de Control" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "Día" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "Cuota de mailbox por defecto" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +msgid "" +"Default quota applied to mailboxes. Can be expressed in KB, MB (default) or " +"GB. A value of 0 means no quota." +msgstr "" +"Cuota de mailbox predeterminda en MB. Un valor de 0 significa ningún limite." + +#: src/components/admin/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "Descripción" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +#, fuzzy +msgid "Disable 2FA" +msgstr "Deshabilitado" + +#: src/components/admin/domains/DomainList.vue:80 +#, fuzzy +msgid "disabled" +msgstr "(deshabilitado)" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "Deshabilitado" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "Estado de DNS" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +#, fuzzy +msgid "domain" +msgstr "Dominio" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "Dominio" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "Administrador del dominio" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "Dominio creado" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +#, fuzzy +msgid "Domain default value" +msgstr "Usar el valor por defecto del dominio" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +#, fuzzy +msgid "domain's default value" +msgstr "Usar el valor por defecto del dominio" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "Dominios" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +#, fuzzy +msgid "Edit account" +msgstr "Nueva cuenta" + +#: src/views/admin/identities/AliasEditView.vue:3 +#, fuzzy +msgid "Edit alias" +msgstr "Nuevo alias" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +#, fuzzy +msgid "Edit provider" +msgstr "Dirección de email" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "Dirección de email" + +#: src/layouts/dashboard/NavBar.vue:233 +#, fuzzy +msgid "Email providers" +msgstr "Dirección de email" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +#, fuzzy +msgid "Enable 2FA" +msgstr "Activado" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "Activar comprobación de DNS" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "Activado" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +#, fuzzy +msgid "Enter an email address" +msgstr "Dirección de email" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "Caduca en" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +#, fuzzy +msgid "First name" +msgstr "Nombre completo" + +#: src/components/login/LoginForm.vue:96 +#, fuzzy +msgid "Forgot password" +msgstr "¿Ha olvidado su contraseña?" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +#, fuzzy +msgid "Forgot password?" +msgstr "¿Ha olvidado su contraseña?" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "Siguiente" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "Reenvía mensajes y guarda copias en su mailbox local" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "Reenvío actualizado" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +#, fuzzy +msgid "Forwarded" +msgstr "Siguiente" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "Nombre completo" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +#, fuzzy +msgid "Fully aligned" +msgstr "Nombre completo" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "General" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +#, fuzzy +msgid "General settings" +msgstr "General" + +#: src/views/account/APISetupView.vue:18 +#, fuzzy +msgid "Generate" +msgstr "General" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +#, fuzzy +msgid "Generated address" +msgstr "Direcciónes de remitente" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "Identidades" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "Importar" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "Importar dominios" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "Importar identidades" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "Información" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +#, fuzzy +msgid "Installed components" +msgstr "Versión instalada" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "Versión instalada" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +#, fuzzy +msgid "Invalid password" +msgstr "Dirección aleatoria" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "Mantener copias locales" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "Última fecha de modificación" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +#, fuzzy +msgid "Latest version" +msgstr "Versión instalada" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "Nivel" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "Logger" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "Salir" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "Mailboxes" + +#: src/components/admin/identities/AccountEditForm.vue:164 +#, fuzzy +msgid "Mailbox aliases:" +msgstr "Mailboxes" + +#: src/components/admin/identities/AccountEditForm.vue:157 +#, fuzzy +msgid "Mailbox:" +msgstr "Mailboxes" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "Mailboxes" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "Uso" + +#: src/views/admin/monitoring/MessagesView.vue:3 +#, fuzzy +msgid "Message history" +msgstr "Uso" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +#, fuzzy +msgid "Migration deleted" +msgstr "Fecha de creación" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +#, fuzzy +msgid "Migrations" +msgstr "Confirmación" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "Modificado" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "Mes" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "Nombre" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +#, fuzzy +msgid "Name:" +msgstr "Nombre" + +#: src/components/admin/domains/DomainEditForm.vue:16 +#, fuzzy +msgid "Name: " +msgstr "Nombre" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "Nueva cuenta" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "Nuevo alias" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "Nuevo dominio" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +#, fuzzy +msgid "New provider" +msgstr "Dirección de email" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "Siguiente" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +#, fuzzy +msgid "No associated domains" +msgstr "Dominios administrados" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "Sin definir" + +#: src/components/admin/identities/AccountEditForm.vue:165 +#, fuzzy +msgid "Number of allowed mailbox aliases:" +msgstr "Mailboxes" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +#, fuzzy +msgid "Number of associated domains:" +msgstr "Dominios administrados" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +#, fuzzy +msgid "Old account" +msgstr "Nueva cuenta" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "Una o más actualizaciones están disponibles" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "Opciones" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +#, fuzzy +msgid "Parameters updated" +msgstr "Perfil actualizado" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "Contraseña" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +#, fuzzy +msgid "Password mismatch" +msgstr "Las contraseñas no coinciden" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +#, fuzzy +msgid "Password recovery" +msgstr "Contraseña" + +#: src/components/account/ProfileForm.vue:143 +#, fuzzy +msgid "Password updated" +msgstr "Reenvío actualizado" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "Las contraseñas no coinciden" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "Numero de telefono " + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "Perfil actualizado" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +#, fuzzy +msgid "Provider" +msgstr "Dominio creado" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +#, fuzzy +msgid "Provider created" +msgstr "Dominio creado" + +#: src/stores/providers.store.js:45 +#, fuzzy +msgid "Provider deleted" +msgstr "Dominio creado" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +#, fuzzy +msgid "Provider name" +msgstr "Dominio creado" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +#, fuzzy +msgid "Provider updated" +msgstr "Perfil actualizado" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +#, fuzzy +msgid "Providers" +msgstr "Dirección de email" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" +"Cuota en MB para este mailbox. Defina un valor por defecto o use el del " +"dominio por defecto. Déjelo vacío para definir un valor ilimitado (no " +"permitido para los administradores del dominio)" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" +"Cuota de mailbox predeterminda en MB. Un valor de 0 significa ningún limite." + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "Dirección aleatoria" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "Dirección aleatoria" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "Destinatario(s)" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "Destinatarios" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +#, fuzzy +msgid "relaydomain" +msgstr "Nuevo dominio" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "Recuerdame" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "Revendedor" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "Recursos" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "Uso de recursos" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "Rol" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "Guardar" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "Buscar" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "Email secundario" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +#, fuzzy +msgid "Send only" +msgstr "Nueva cuenta" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +#, fuzzy +msgid "Send only account" +msgstr "Nueva cuenta" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "Direcciónes de remitente" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "Separador" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "Configuración" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "Usuario normal" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +#, fuzzy +msgid "Statistics" +msgstr "Estadísticas" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "Estatus" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "Enviar" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "Resumen" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "Super administrador" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "Tags" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +#, fuzzy +msgid "Trusted sources" +msgstr "Recursos" + +#: src/components/account/TwoFactorAuthForm.vue:6 +#, fuzzy +msgid "Two factor authentication" +msgstr "Autenticación" + +#: src/components/login/TwofaForm.vue:6 +#, fuzzy +msgid "Two-factor authentication" +msgstr "Autenticación" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "Tipo" + +#: src/components/admin/domains/DomainEditForm.vue:19 +#, fuzzy +msgid "Type: " +msgstr "Tipo" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "Desconocido" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "ilimitado" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +#, fuzzy +msgid "Unlimited" +msgstr "ilimitado" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "Actualizar" + +#: src/components/account/ProfileForm.vue:75 +#, fuzzy +msgid "Update Password" +msgstr "Contraseña" + +#: src/components/account/ProfileForm.vue:62 +#, fuzzy +msgid "Update settings" +msgstr "Configuración" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "Actualizado" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "Usar el valor por defecto del dominio" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +#, fuzzy +msgid "User unknown." +msgstr "Desconocido" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "Nombre de usuario" + +#: src/components/admin/identities/AccountEditForm.vue:39 +#, fuzzy +msgid "Username:" +msgstr "Nombre de usuario" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "Semana" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "Bienvenido a Modoboa" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "Con una mailbox" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "Año" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" + +#~ msgid "Generate a random password for the administrator." +#~ msgstr "Crear mailbox para el administrador." + +#, fuzzy +#~ msgid "Account not found!" +#~ msgstr "Cuenta creada" + +#, fuzzy +#~ msgid "Identities deleted" +#~ msgstr "Identidades" diff --git a/frontend/src/locale/fi/app.po b/frontend/src/locale/fi/app.po new file mode 100644 index 000000000..7b1e05ebf --- /dev/null +++ b/frontend/src/locale/fi/app.po @@ -0,0 +1,2101 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Generated-By: easygettext\n" +"X-Generator: Poedit 3.2.2\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "API:n dokumentaatio on saatavilla" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "Uusi avain luodaan pian. Päivitä sivu hetken kuluttua nähdäksesi sen." + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" +"Käyttäjä, jolla on kaikki oikeudet, voi tehdä mitä tahansa. Oletusarvoisesti " +"tällaisella käyttäjällä ei ole postilaatikkoa, joten hän ei voi käyttää " +"loppukäyttäjän ominaisuuksia." + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" +"Käyttäjä, jolla ei ole oikeuksia mutta jolla on postilaatikko. Hän saa " +"käyttää kaikkia loppukäyttäjän ominaisuuksia: webmail, kalenteri, " +"yhteystiedot, suodattimet." + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" +"Käyttäjä, jolla on oikeuksia yhdessä tai useammassa verkkotunnuksessa. " +"Hänellä on oikeus hallinnoida postilaatikoita ja hänellä voi myös olla " +"postilaatikko." + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "Määrämittainen aikaraja" + +#: src/stores/identities.store.js:67 +#, fuzzy +msgid "account" +msgstr "Tili" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "Tili" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "Tili luotu" + +#: src/stores/accounts.store.js:62 +#, fuzzy +msgid "Account successfully deleted" +msgstr "Tili luotu" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "Tili päivitetty" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "Toiminnot" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "Lisää" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "Lisää uusi verkkotunnuksen alias" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "Lisää järjestelmänvalvoja" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "Lisää lähettäjän osoite" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +#, fuzzy +msgid "Add/Remove from the domain page" +msgstr "Ylläpitäjän nimi" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "Osoite" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "Hallinnoidut verkkotunnukset" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "Järjestelmänvalvoja lisäsi" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "Järjestelmänvalvojan nimi" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "Järjestelmänvalvoja poistettu" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "Ylläpitäjät" + +#: src/components/admin/domains/DomainAdminList.vue:6 +#, fuzzy +msgid "Administrators of" +msgstr "Ylläpitäjät" + +#: src/components/admin/alarms/AlarmList.vue:188 +#, fuzzy +msgid "Alarm closed" +msgstr "Hälytykset" + +#: src/components/admin/alarms/AlarmList.vue:173 +#, fuzzy +msgid "Alarm deleted" +msgstr "Verkkotunnuksen alias poistettu" + +#: src/components/admin/alarms/AlarmList.vue:196 +#, fuzzy +msgid "Alarm re-opened" +msgstr "Verkkotunnuksen alias poistettu" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "Hälytykset" + +#: src/components/admin/alarms/AlarmList.vue:180 +#, fuzzy +msgid "Alarms deleted" +msgstr "Verkkotunnuksen alias poistettu" + +#: src/stores/identities.store.js:97 +#, fuzzy +msgid "alias" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "Alias" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +#, fuzzy +msgid "Alias already added" +msgstr "Alias luotu" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +#, fuzzy +msgid "Alias successfully created" +msgstr "Alias luotu" + +#: src/stores/aliases.store.js:61 +#, fuzzy +msgid "Alias successfully deleted" +msgstr "Verkkotunnuksen alias poistettu" + +#: src/stores/aliases.store.js:74 +msgid "Alias updated" +msgstr "Alias päivitetty" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" +"Tämän postilaatikon alias-nimet. Jos haluat luoda catchall-aliaksen, " +"kirjoita vain verkkotunnus (@domain.tld)." + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "Aliakset" + +#: src/components/admin/identities/AccountEditForm.vue:124 +#, fuzzy +msgid "Aliases:" +msgstr "Aliakset" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "API" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "API-pääsy" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "API-tunniste kopioitu leikepöydälle" + +#: src/views/account/APISetupView.vue:92 +msgid "API token created" +msgstr "API-tunniste luotu" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "API-tunniste poistettu" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "Käytä" + +#: src/components/admin/identities/IdentityList.vue:231 +#, fuzzy +msgid "Are you sure you want to delete this alias?" +msgstr "Haluatko todella poistaa aliaksen %{ alias }?" + +#: src/components/admin/identities/IdentityList.vue:205 +#, fuzzy +msgid "Are you sure you want to delete this identity ?" +msgstr "Haluatko todella poistaa aliaksen %{ alias }?" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +#, fuzzy +msgid "Associated domain" +msgstr "Hallinnoidut verkkotunnukset" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +#, fuzzy +msgid "Associated domains" +msgstr "Hallinnoidut verkkotunnukset" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "Tarkastusketju" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "Tunnistautuminen" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "Automaattinen asetusten määrittäminen" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "autoconfig-tallennetta (Mozilla) ei löydy" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "autoconfig-tietue (Mozilla): %{ value }" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "autodiscover-tietuetta (Microsoft) ei löydy" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "autodiscover-tietue (Microsoft): %{ value }" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "Takaisin" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "Bind/nimetty muoto. Kopioi klikkaamalla" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "Peruuta" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +#, fuzzy +msgid "Change password" +msgstr "Vaihda salasana" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" +"Valitse tämä vaihtoehto, jos tiedostosi sisältämiä salasanoja ei ole " +"salakirjoitettu" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "Valitse verkkotunnus" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "Valitse käyttäjätyyppisi" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "Sulje" + +#: src/components/admin/alarms/AlarmList.vue:133 +#, fuzzy +msgid "Close alarm" +msgstr "Sulje" + +#: src/components/admin/alarms/AlarmList.vue:46 +#, fuzzy +msgid "Closed" +msgstr "Suljettu" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "Vahvista ja luo" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "Vahvistus" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "Onnittelut! Kaksivaiheinen tunnistus on nyt käytössä tililläsi." + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "Yhdistä" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "Jatka virheestä" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "Määritä, saako tämä verkkotunnus lähettää ja vastaanottaa viestejä" + +#: src/components/admin/domains/DNSDetail.vue:114 +#, fuzzy +msgid "Copy key to clipboard" +msgstr "Kopioi turvatunnus leikepöydälle" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "Kopioi leikepöydälle" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "Kopioi turvatunnus leikepöydälle" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "Luo verkkotunnuksen ylläpitäjä" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "Luo ylläpitäjän postilaatikko." + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "Luo aliaksia" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "Luo verkkotunnuksen tavanomaiset aliakset." + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "Luontipäivä" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "Salakirjoita salasanat" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +msgid "Current password" +msgstr "Nykyinen salasana" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "Päivittäinen viestien lähetysraja" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "Päivittäinen lähetysraja" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "Työpöytä" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "Päivämäärä" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "Päivä" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "Oletuspostilaatikkokiintiö" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +msgid "" +"Default quota applied to mailboxes. Can be expressed in KB, MB (default) or " +"GB. A value of 0 means no quota." +msgstr "" +"Postilaatikoihin sovellettava oletuskiintiö. Voidaan ilmaista kilotavuina, " +"megatavuina (oletus) tai gigatavuina. Arvo 0 tarkoittaa, ettei kiintiötä ole." + +#: src/components/admin/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "Poista" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "Poista avain" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "Kuvaus" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "Poista kaksivaiheinen tunnistautuminen (2FA) käytöstä" + +#: src/components/admin/domains/DomainList.vue:80 +#, fuzzy +msgid "disabled" +msgstr "(ei käytössä)" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "Pois käytöstä" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "DKIM-avain" + +#: src/components/admin/domains/DNSDetail.vue:182 +#, fuzzy +msgid "DKIM key copied to clipboard" +msgstr "API-tunniste kopioitu leikepöydälle" + +#: src/components/admin/domains/DNSDetail.vue:218 +#, fuzzy +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" +"DKIM-avaimet ovat jo olemassa tälle verkkotunnukselle. Haluatko korvata ne?" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "DKIM-avaimen pituus" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "DKIM-avaimen valitsin-tietue" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" +"DKIM-avaimet ovat jo olemassa tälle verkkotunnukselle. Haluatko korvata ne?" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "DKIM julkinen avain tietueelle" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "DKIM-tietue löydetty" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "DKIM-tietuetta ei löydy" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "DKIM-allekirjoitus" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "DMARC-tietue löydetty" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "DMARC-tietuetta ei löydy" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "DNS" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "DNS-tarkistukset" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +#, fuzzy +msgid "DNS configuration for " +msgstr "DNS-määritykset" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "DNS-määritysapu" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "DNS-tila" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "Älä poista tilikansiota" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "Älä poista verkkotunnuksen kansiota" + +#: src/components/admin/domains/DomainList.vue:236 +#, fuzzy +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "Haluatko todella poistaa aliaksen %{ alias }?" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +#, fuzzy +msgid "domain" +msgstr "Verkkotunnus" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "Verkkotunnus" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "Luo verkkotunnuksen ylläpitäjä" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "Verkkotunnuksen alias luotu" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "Verkkotunnuksen alias poistettu" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "Verkkotunnuksen alias päivitetty" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "Verkkotunnus luotu" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "Verkkotunnuksen oletusarvo" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "Verkkotunnus (esim. domain.tld)" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "Verkkotunnus päivitetty" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "verkkotunnuksen oletusarvo" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "Sinulla ei ole oikeutta tuoda verkkotunnuksia" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "Älä käsittele päällekkäisiä objekteja virheinä" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "Muokkaa" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "Muokkaa tiliä" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "Muokkaa aliasta" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "Muokkaa verkkotunnusta" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "Muokkaa verkkotunnusta" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +#, fuzzy +msgid "Edit provider" +msgstr "Sähköpostiosoite" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "Sähköposti" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "Sähköpostiosoite" + +#: src/layouts/dashboard/NavBar.vue:233 +#, fuzzy +msgid "Email providers" +msgstr "Sähköpostiosoite" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "Tyhjä" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "Ota käyttöön kaksivaiheinen tunnistus (2FA)" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "Ota DKIM-allekirjoitus käyttöön" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "Ota DNS-tarkistukset käyttöön" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "Käytössä" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "Anna yksinkertainen käyttäjätunnus tai sähköpostiosoite" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "Syötä oikean muotoinen sähköpostiosoite" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" +"Syötä koodi mobiililaitteesi kaksivaiheisen tunnistuksen sovelluksesta. Jos " +"olet hukannut laitteesi, voit syöttää yhden palautuskoodeistasi." + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "Kirjoita tekstiviestillä saamasi koodi" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "Esim: 10 MB. Jätä tyhjäksi, jos et halua rajoitusta" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "Vanhenee" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "Vie tilit ja aliakset CSV-tiedostoon" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "Vie verkkotunnukset ja aliakset CSV-tiedostoon" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +#, fuzzy +msgid "Field is required" +msgstr "Tämä kenttä on pakollinen" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "Etunimi" + +#: src/components/login/LoginForm.vue:96 +#, fuzzy +msgid "Forgot password" +msgstr "Unohditko salasanasi?" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +#, fuzzy +msgid "Forgot password?" +msgstr "Unohditko salasanasi?" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "Välitä" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "Välitä viestit ja tallenna kopiot paikalliseen postilaatikkoon" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "Välitystieto päivitetty" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +#, fuzzy +msgid "Forwarded" +msgstr "Välitä" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "Lähde" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "Koko nimi" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "Koko nimi/saaja" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +#, fuzzy +msgid "Fully aligned" +msgstr "Koko nimi" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "Yleiset" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "Yleiset tiedot" + +#: src/components/account/ProfileForm.vue:5 +msgid "General settings" +msgstr "Yleiset asetukset" + +#: src/views/account/APISetupView.vue:18 +msgid "Generate" +msgstr "Luo" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "Luo uusi DKIM-avain" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +#, fuzzy +msgid "Generated address" +msgstr "Lähettäjän osoitteet" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "ohje" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" +"Tässä on esimerkki DNS-määrityksistä (bind-muodossa). Korvaa [ ]:n välissä " +"olevat arvot sopivilla arvoilla." + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "Tunniste" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "Identiteetit" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "Jos suljet tämän lomakkeen nyt, muutokset eivät tallennu. Vahvistatko?" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +#, fuzzy +msgid "IMAP Migration" +msgstr "Automaattinen asetusten määrittäminen" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +#, fuzzy +msgid "IMAP Port" +msgstr "Automaattinen asetusten määrittäminen" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "Tuonti" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "Tuo tilejä ja aliaksia CSV-tiedostosta" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "Tuo verkkotunnuksia" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "Tuo verkkotunnukset ja aliakset CSV-tiedostosta" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "Tuo identiteetit" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "Ilmoita yksi tai useampi vastaanottaja pilkulla (,) erotettuna" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +#, fuzzy +msgid "Information" +msgstr "Tiedot" + +#: src/components/account/TwoFactorAuthForm.vue:34 +#, fuzzy +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" +"Asenna soft token -autentikointiohjelma, kuten FreeOTP tai Google\n" +" Authenticator sovelluskaupasta ja käytä \n" +" sovellusta QR-koodin skannaamiseen." + +#: src/views/admin/InformationView.vue:8 +#, fuzzy +msgid "Installed components" +msgstr "Asennettu versio" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "Asennettu versio" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +msgid "Invalid password" +msgstr "Virheellinen salasana" + +#: src/plugins/rules.js:41 +#, fuzzy +msgid "Invalid port number" +msgstr "Virheellinen salasana" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "Virheellinen käyttäjätunnus ja/tai salasana" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +#, fuzzy +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" +"Esittää yhteenvedon Modoboa-palvelimesi tilasta sekä\n" +" hyödyllisiä tietoja tuotteesta." + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "Säilytä paikallisia kopioita" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "Kieli" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "Viimeisin kirjautumispäivä" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "Viimeisin muutospäivä" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "Sukunimi" + +#: src/views/admin/InformationView.vue:59 +#, fuzzy +msgid "Latest version" +msgstr "Asennettu versio" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "Jätä tyhjäksi, jos rajaa ei ole" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "Taso" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "Rajoitukset" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "Lokikirja" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "Kirjaudu ulos" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "Postilaatikko" + +#: src/components/admin/identities/AccountEditForm.vue:164 +#, fuzzy +msgid "Mailbox aliases:" +msgstr "Postilaatikot" + +#: src/components/admin/identities/AccountEditForm.vue:157 +#, fuzzy +msgid "Mailbox:" +msgstr "Postilaatikko" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "Postilaatikot" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "Viesti" + +#: src/views/admin/monitoring/MessagesView.vue:3 +msgid "Message history" +msgstr "Viestien historia" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "Viestien lähetysraja" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "viestit" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "Viestit" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +#, fuzzy +msgid "Migration deleted" +msgstr "Luontipäivä" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +#, fuzzy +msgid "Migrations" +msgstr "Rajoitukset" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "Muokattu" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "Muokkaa" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "Kuukausi" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "MX-tietueet" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "Nimi" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "Ylläpitäjän nimi" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +#, fuzzy +msgid "Name of the domain to migrate" +msgstr "Ylläpitäjän nimi" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +#, fuzzy +msgid "Name:" +msgstr "Nimi:" + +#: src/components/admin/domains/DomainEditForm.vue:16 +#, fuzzy +msgid "Name: " +msgstr "Nimi:" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "Ei koskaan kirjautunut sisään" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "Uusi" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "Uusi tili" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "Uusi alias" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "Uusi verkkotunnus" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +#, fuzzy +msgid "New provider" +msgstr "Uudet palautuskoodit" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "Uudet palautuskoodit" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "Seuraava" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "ei" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "Ei" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +#, fuzzy +msgid "No associated domains" +msgstr "Hallinnoidut verkkotunnukset" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "Tälle tilille ei ole määritelty lähettäjän osoitetta" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "Ei lähetysrajaa" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "Ei luotu" + +#: src/components/admin/identities/AccountEditForm.vue:165 +#, fuzzy +msgid "Number of allowed mailbox aliases:" +msgstr "Postilaatikot" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +#, fuzzy +msgid "Number of associated domains:" +msgstr "Hallinnoidut verkkotunnukset" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" +"Viestien määrä, jonka tämä verkkotunnus voi lähettää päivässä. Jätä " +"tyhjäksi, jos et halua rajoitusta." + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" +"Viestien määrä, jonka tämä postilaatikko voi lähettää päivässä. Jätä " +"tyhjäksi, jos et halua rajoitusta." + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "OK" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +#, fuzzy +msgid "Old account" +msgstr "Muokkaa tiliä" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "Yksi tai useampi päivitys on saatavilla" + +#: src/components/admin/alarms/AlarmList.vue:43 +#, fuzzy +msgid "Opened" +msgstr "Avattu" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "Avatut hälytykset" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "Vaihtoehdot" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "Parametrit päivitetty" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "Salasana" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "Salasana kopioitu leikepöydälle" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +#, fuzzy +msgid "Password mismatch" +msgstr "Salasanat eivät täsmää" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +#, fuzzy +msgid "Password recovery" +msgstr "Salasana" + +#: src/components/account/ProfileForm.vue:143 +msgid "Password updated" +msgstr "Salasana päivitetty" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "Salasanat eivät täsmää" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "Odottaa" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "Jakso" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "Puhelinnumero" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "Pin-koodi" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "Täytä ensisijainen sähköpostiosoitteesi" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "Ongelma" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "Jatka" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "Profiili" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "Profiili päivitetty" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "Toimita CSV-tiedosto, jonka rivit ovat jossakin seuraavista muodoista:" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +#, fuzzy +msgid "Provider" +msgstr "Etunimi" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +#, fuzzy +msgid "Provider created" +msgstr "API-tunniste luotu" + +#: src/stores/providers.store.js:45 +#, fuzzy +msgid "Provider deleted" +msgstr "API-tunniste poistettu" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +#, fuzzy +msgid "Provider name" +msgstr "Etunimi" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +#, fuzzy +msgid "Provider updated" +msgstr "Profiili päivitetty" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +#, fuzzy +msgid "Providers" +msgstr "Etunimi" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "Jonon ID" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "Verkkotunnuksen oletuskiintiö" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" +"Tämän postilaatikon kiintiö, joka voidaan ilmaista kilotavuina, megatavuina " +"(oletus) tai gigatavuina. Määritä oma arvo tai käytä toimialueen " +"oletusarvoa. Jätä tyhjäksi, jos haluat määrittää rajoittamattoman arvon (ei " +"sallittu toimialueen ylläpitäjille)." + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" +"Postilaatikoiden kesken jaettu kiintiö. Voidaan ilmaista kilotavuina (KB), " +"megatavuina (MB) (oletus) tai gigatavuina (GB). Arvo 0 tarkoittaa, ettei " +"kiintiötä ole." + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +#, fuzzy +msgid "Quota: " +msgstr "Kiintiö:" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "Satunnainen osoite" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "Satunnainen salasana" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "Raakamuoto. Kopioi napsauttamalla" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "Vastaanottaja(t)" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "Vastaanottajat" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "Rekisteröidy" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "Suhteelliset aikavälialueet" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "Välitysrele" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +#, fuzzy +msgid "relaydomain" +msgstr "Uusi verkkotunnus" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "Muista minut" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "Poista tämä osoite" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "Poista tämä ylläpitäjä" + +#: src/components/admin/alarms/AlarmList.vue:140 +#, fuzzy +msgid "Reopen alarm" +msgstr "Avatut hälytykset" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "Jälleenmyyjä" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +#, fuzzy +msgid "Reset recovery codes" +msgstr "Uudet palautuskoodit" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "Resurssit" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "Resurssien käyttö" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "Rooli" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "Tallenna" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "Hae" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "Toissijainen sähköpostiosoite" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +#, fuzzy +msgid "Secured" +msgstr "Turvallisuus" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "Turvallisuus" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "Valitse tili" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "Valitse tiedosto" + +#: src/components/admin/identities/AccountEditForm.vue:92 +#, fuzzy +msgid "Send only" +msgstr "Valitse tili" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +#, fuzzy +msgid "Send only account" +msgstr "Valitse tili" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "Lähettäjän osoitteet" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "Lähetysraja" + +#: src/components/admin/domains/DomainEditForm.vue:84 +#, fuzzy +msgid "Sending limit: " +msgstr "Lähetysraja:" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "Erotin" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "Palvelu" + +#: src/components/admin/domains/DomainEditForm.vue:116 +#, fuzzy +msgid "Service: " +msgstr "Palvelu:" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "Asetukset" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "Näytä avain" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "Yksinkertainen käyttäjä" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "Määritä sähköpostiosoite" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "SPF-tietue löydetty" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "SPF-tietuetta ei löydy" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "Aloita nimen kirjoittaminen tästä..." + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +#, fuzzy +msgid "Statistics" +msgstr "Tilastot" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "Tila" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "Lähetä" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "Yhteenveto" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "Pääylläpitäjä" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "Tunnisteet" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" +"Kunkin rivin ensimmäinen elementti on pakollinen, ja sen on oltava yhtä " +"suuri kuin jokin edellisistä arvoista." + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +#, fuzzy +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" +"Seuraavia palautuskoodeja voidaan käyttää kerran kutakin, jotta\n" +" saada tilisi takaisin, jos kadotat puhelimesi\n" +" esimerkiksi. Varmista, että tallennat ne turvalliseen paikkaan, " +"muutoin\n" +" et pääse enää käyttämään tiliäsi." + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "Tämä sivu on vielä rakenteilla." + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "Vastaanottaja" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "Siirto" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +#, fuzzy +msgid "Trusted sources" +msgstr "Resurssit" + +#: src/components/account/TwoFactorAuthForm.vue:6 +#, fuzzy +msgid "Two factor authentication" +msgstr "Kaksivaiheinent tunnistus" + +#: src/components/login/TwofaForm.vue:6 +#, fuzzy +msgid "Two-factor authentication" +msgstr "Kaksivaiheinent tunnistus" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" +"Kaksivaiheista tunnistusta (2FA) ei ole vielä aktivoitu tilillesi. Tämän " +"ominaisuuden käyttöönotto lisää tilisi turvallisuutta." + +#: src/components/account/TwoFactorAuthForm.vue:71 +#, fuzzy +msgid "Two-Factor Authentication is enabled for your account." +msgstr "Onnittelut! Kaksivaiheinen tunnistus on nyt käytössä tililläsi." + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "Tyyppi" + +#: src/components/admin/domains/DomainEditForm.vue:19 +#, fuzzy +msgid "Type: " +msgstr "Tyyppi:" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "Tuntematon" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "rajoittamaton" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +#, fuzzy +msgid "Unlimited" +msgstr "rajoittamaton" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "Päivitä" + +#: src/components/account/ProfileForm.vue:75 +msgid "Update Password" +msgstr "Vaihda salasana" + +#: src/components/account/ProfileForm.vue:62 +msgid "Update settings" +msgstr "Päivitä asetukset" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "Päivitetty" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "Käytä verkkotunnuksen oletusarvoa" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +#, fuzzy +msgid "User unknown." +msgstr "Tuntematon" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "Käyttäjätunnus" + +#: src/components/admin/identities/AccountEditForm.vue:39 +msgid "Username:" +msgstr "Käyttäjätunnus:" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "Kelvollinen" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "Tarkista koodi" + +#: src/components/admin/domains/DNSDetail.vue:217 +#, fuzzy +msgid "warning" +msgstr "Varoitus" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "Varoitus" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "Viikko" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "Tervetuloa Modoboaan" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "Postilaatikolla" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "Postilaatikolla" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "Vuosi" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "kyllä" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "Kyllä" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "Olet poistamassa API-pääsytunnistetta" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "Voit käyttää erottimena eri merkkiä." + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "API-pääsytunnistetta ei ole vielä luotu." + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "API-pääsytunnisteesi on:" + +#~ msgid "Generate a random password for the administrator." +#~ msgstr "Luo satunnainen salasana järjestelmänvalvojalle." + +#, fuzzy +#~ msgid "Account not found!" +#~ msgstr "DMARC-tietuetta ei löydy" + +#~ msgid "Address:" +#~ msgstr "Osoite:" + +#~ msgid "Administrators of {{ domain.name }}" +#~ msgstr "{{ domain.name }}:n ylläpitäjät" + +#~ msgid "hostname of your automx server" +#~ msgstr "automx-palvelimen nimi" + +#, fuzzy +#~ msgid "Identities deleted" +#~ msgstr "Identiteetit" + +#~ msgid "IP address of your Modoboa server" +#~ msgstr "Modoboa-palvelimen IP-osoite" + +#~ msgid "Sender address added" +#~ msgstr "Lähettäjän osoite lisätty" + +#~ msgid "Sender address deleted" +#~ msgstr "Lähettäjän osoite poistettu" + +#~ msgid "Settings: thislabel" +#~ msgstr "Asetukset: tämä etiketti" + +#~ msgid "" +#~ "The following recovery codes can be used one time each to\n" +#~ " let you regain access to your account, in case you lose your\n" +#~ " phone for example. Make sure to save them in a safe place,\n" +#~ " otherwise you won't be able to access your account anymore." +#~ msgstr "" +#~ "Seuraavia palautuskoodeja voidaan käyttää kerran kutakin seuraavista " +#~ "syistä\n" +#~ " jotta voit saada tilisi uudelleen käyttöön, jos menetät " +#~ "tilisi\n" +#~ " esimerkiksi puhelimesi. Muista tallentaa ne turvalliseen " +#~ "paikkaan,\n" +#~ " muuten et pääse enää tilillesi." + +#~ msgid "Two-factor authentication code" +#~ msgstr "Kaksivaiheisen tunnistuksen koodi" + +#~ msgid "Verification" +#~ msgstr "Vahvistus" + +#~ msgid "This field must be a valid number" +#~ msgstr "Tämän kentän on oltava numero" + +#~ msgid "Settings: " +#~ msgstr "Asetukset: " diff --git a/frontend/src/locale/fr/app.po b/frontend/src/locale/fr/app.po new file mode 100644 index 000000000..55c8505a2 --- /dev/null +++ b/frontend/src/locale/fr/app.po @@ -0,0 +1,2100 @@ +# +# Translators: +# Che Akycow, 2023 +# Antoine Nguyen , 2023 +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"Last-Translator: Antoine Nguyen , 2023\n" +"Language-Team: French (https://app.transifex.com/tonio/teams/13749/fr/)\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: easygettext\n" +"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % " +"1000000 == 0 ? 1 : 2;\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "Une documentation de l'API est disponible" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" +"Une nouvelle clé sera générée bientôt. Actualisez dans un moment la page " +"pour la voir." + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" +"Un utilisateur ayant tous les privilège, peut tout faire. Par défaut, il n'a " +"pas de boîte mail et ne peut donc pas accéder aux fonctionnalités d'un " +"utilisateur final." + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" +"Un utilisateur sans privilèges mais ayant une boîte mail. Il sera autorisé à " +"utiliser toutes les fonctionnalités de l'utilisateur final : webmail, " +"calendrier, contacts, filtres." + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" +"Un utilisateur avec des privilèges sur un ou plusieurs domaines. Il sera " +"autorisé à administrer les boîtes mail et il peut avoir aussi une boîte aux " +"lettres." + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "Plage de temps absolue" + +#: src/stores/identities.store.js:67 +#, fuzzy +msgid "account" +msgstr "Compte" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "Compte" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "Compte créé" + +#: src/stores/accounts.store.js:62 +#, fuzzy +msgid "Account successfully deleted" +msgstr "Compte supprimé" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "Compte mis à jour" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "Actions" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "Ajouter" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "Ajouter un nouvel alias de domaine" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "Ajouter un administrateur" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "Ajouter l'adresse de l'expéditeur" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +#, fuzzy +msgid "Add/Remove from the domain page" +msgstr "Nom du domaine à migrer" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "Adresse" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "Adresse (nom d'hôte ou IP)" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "Domaines administrés" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "L'administrateur a ajouté" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "Nom de l'administrateur" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "Administrateur supprimé" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "Administrateurs" + +#: src/components/admin/domains/DomainAdminList.vue:6 +#, fuzzy +msgid "Administrators of" +msgstr "Administrateurs" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "Alarme fermée" + +#: src/components/admin/alarms/AlarmList.vue:173 +msgid "Alarm deleted" +msgstr "Alarme supprimée" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "Alarme ré-ouverte" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "Alarmes" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "Alarmes supprimées" + +#: src/stores/identities.store.js:97 +#, fuzzy +msgid "alias" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "Alias" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +#, fuzzy +msgid "Alias already added" +msgstr "Alias créé" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +#, fuzzy +msgid "Alias successfully created" +msgstr "Alias créé" + +#: src/stores/aliases.store.js:61 +#, fuzzy +msgid "Alias successfully deleted" +msgstr "Alias supprimé" + +#: src/stores/aliases.store.js:74 +msgid "Alias updated" +msgstr "Alias mis à jour" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" +"Alias(s) de cette boîte aux lettres. Pour créer un alias fourre-tout, entrer " +"uniquement le nom du domaine (@domain.tld)." + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:124 +#, fuzzy +msgid "Aliases:" +msgstr "Alias" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "Alignement" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "API" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "Accès API" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "Jeton API copié dans votre presse-papier" + +#: src/views/account/APISetupView.vue:92 +msgid "API token created" +msgstr "Jeton API créé" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "Jeton API supprimé" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "Appliquer" + +#: src/components/admin/identities/IdentityList.vue:231 +#, fuzzy +msgid "Are you sure you want to delete this alias?" +msgstr "Voulez-vous réellement supprimer l'alias %{ alias }?" + +#: src/components/admin/identities/IdentityList.vue:205 +#, fuzzy +msgid "Are you sure you want to delete this identity ?" +msgstr "Voulez-vous vraiment supprimer les identités sélectionnées?" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +#, fuzzy +msgid "Associated domain" +msgstr "Domaines associés" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +msgid "Associated domains" +msgstr "Domaines associés" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "Journal des modifications" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "Authentification" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "Configuration automatique" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "Enregistrement autoconfig (Mozilla) introuvable" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "Enregistrement autoconfig (Mozilla) : %{ value }" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "Enregistrement autodiscover (Microsoft) non trouvé" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "Enregistrement autodiscover (Microsoft): %{ value }" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "Retour" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "Format bind/named. Cliquez pour copier" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "Annuler" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "Modifier le mot de passe" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "Vérifier la connexion :" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "Consulter la liste suivante pour trouver des composants associés" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" +"Cochez cette option si les mots de passe contenus dans votre fichier ne sont " +"pas chiffrés" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "Choisissez un domaine" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "Choisissez un rôle" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "Fermer" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "Fermer l'alarme" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "Fermé" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "Confirmer et créer" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "Confirmation" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" +"Félicitations ! l'authentification à double facteur est maintenant activée " +"sur votre compte" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "Connexion" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "Continuer en cas d'erreur" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" +"Contrôler si ce domaine sera autorisé à envoyer et recevoir des messages." + +#: src/components/admin/domains/DNSDetail.vue:114 +#, fuzzy +msgid "Copy key to clipboard" +msgstr "Copier le jeton dans la presse-papiers" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "Copier dans le presse-papiers" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "Copier le jeton dans la presse-papiers" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "Créer un administrateur de domaine" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "Créer une boite aux lettres pour l'administrateur" + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "Créer des alias" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "Créer des aliases standard pour le domaine" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "Date de création" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "Chiffrer les mots de passe" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +msgid "Current password" +msgstr "Mot de passe actuel" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "Limite quotidienne d'envoi de messages" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "Limite d'envoi quotidienne" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "Tableau de bord" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "Date" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "Jour" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "Quota par défaut pour une boîte aux lettres" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +msgid "" +"Default quota applied to mailboxes. Can be expressed in KB, MB (default) or " +"GB. A value of 0 means no quota." +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "Supprimer" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "Supprimer le jeton" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "Description" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "Détail" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "Désactiver l'authentification à double facteur" + +#: src/components/admin/domains/DomainList.vue:80 +#, fuzzy +msgid "disabled" +msgstr "(désactivé)" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "Désactivés" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "Clé DKIM" + +#: src/components/admin/domains/DNSDetail.vue:182 +#, fuzzy +msgid "DKIM key copied to clipboard" +msgstr "Jeton API copié dans votre presse-papier" + +#: src/components/admin/domains/DNSDetail.vue:218 +#, fuzzy +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "Des clés DKIM existent déjà pour ce domaine. Voulez-vous les écraser?" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "Longeur de clé DKIM" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "Sélecteur de clé DKIM" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "Des clés DKIM existent déjà pour ce domaine. Voulez-vous les écraser?" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "Clé publique DKIM pour " + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "Enregistrement DKIM trouvé" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "Enregistrement DKIM introuvable" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "Signature DKIM" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "DMARC" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "Enregistrement DMARC trouvé" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "Enregistrement DMARC introuvable" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "La support DMARC ne semble pas actif pour ce domaine." + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "DNS" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "Vérifications DNS" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +#, fuzzy +msgid "DNS configuration for " +msgstr "Configuration DNS pour" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "Aide à la configuration du DNS" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "Statut DNS" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "Ne pas supprimer le dossier du compte" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "Ne pas supprimer le dossier des domaines" + +#: src/components/admin/domains/DomainList.vue:236 +#, fuzzy +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "Voulez-vous réellement supprimer l'alias %{ alias }?" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +#, fuzzy +msgid "domain" +msgstr "Domaine" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "Domaine" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "Administrateur de domaine" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "Alias de domaine créé" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "Alias de domaine supprimé" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "Alias de domaine mise à jour" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "Domaine créé" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "Valeur du domaine par défaut" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "Supprimer le domaine" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "Nom de domaine (ex: domaine.tld)" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "Domaine mise à jour" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "La valeur par défaut du domaine" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "Domaines" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "Ne pas traiter les objets dupliqués comme des erreurs" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "Modifier" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "Modifier le compte" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "Modifier l'alias" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "Modifier le domaine" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "Modifier l'alias de domaine" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +msgid "Edit provider" +msgstr "Modifier le fournisseur" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "E-mail" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "Adresse email" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "Fournisseurs de messagerie" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "Vide" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "Activer 2FA" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "Activer la signature DKIM" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "Activer les tests DNS" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "Activé" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "Entrer un nom d'utilisateur simple ou une adresse e-mail" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "Entrer une adresse e-mail" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" +"Entrez le code de l'application à double facteur sur votre téléphone mobile. " +"Si vous avez perdu votre appareil, vous pouvez entrez l'un de vos code de " +"récupération." + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "Entrez le code que vous venez de recevoir par SMS" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "Erreur" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "Ex: 10MB. Laisser vide pour aucune limite" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "Expire le" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "Exporter les comptes et les alias au format CSV" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "Exporter les domaines et les alias au format CSV" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "Échoué" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +#, fuzzy +msgid "Field is required" +msgstr "Ce champ est requis" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "Prénom" + +#: src/components/login/LoginForm.vue:96 +#, fuzzy +msgid "Forgot password" +msgstr "Mot de passe oublié ?" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +#, fuzzy +msgid "Forgot password?" +msgstr "Mot de passe oublié ?" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "Transfert" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" +"Transférer les messages et stocker des copies dans votre boîte aux lettres " +"locale" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "Transfert mise à jour" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "Transféré" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "Transporteur avec ARC" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "De" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "Nom complet" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "Nom complet / destinataire" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "Entièrement aligné" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "Général" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "Information générale" + +#: src/components/account/ProfileForm.vue:5 +msgid "General settings" +msgstr "Paramètres généraux " + +#: src/views/account/APISetupView.vue:18 +msgid "Generate" +msgstr "Générer" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "Générer une nouvelle clé DKIM" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +#, fuzzy +msgid "Generated address" +msgstr "Adresses d'expédition" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "aide" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" +"Voici un exemplaire de configuration DNS (format bind). Remplacer les " +"valeurs entre [ ] par les valeurs appropriées." + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "Identification" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "Identités" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" +"Si vous fermez ce formulaire maintenant, vos modifications ne seront pas " +"sauvegardées. Confirmez-vous ?" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" +"Si vous l'avez récemment configuré, veuillez attendre que le premier rapport " +"soit reçu et traité. " + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "Migration IMAP" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "Port IMAP" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "Importer" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "Importation de comptes et alias à partir d'un fichier CSV" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "Importer des domaines" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "Importation de domaines et alias à partir d'un fichier CSV" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "Importer des identités" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "Indiquer un ou plusieurs destinataires séparés par une virgule (,) " + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "Information" + +#: src/components/account/TwoFactorAuthForm.vue:34 +#, fuzzy +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" +"Installez un logiciel d'authentification de jeton comme FreeOTP ou google\n" +" Authentification depuis votre magasin d'applications et " +"utilisez\n" +" cette application pour scanner ce QR code." + +#: src/views/admin/InformationView.vue:8 +msgid "Installed components" +msgstr "Composants installés" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "Version installée" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +msgid "Invalid password" +msgstr "Mot de passe incorrect" + +#: src/plugins/rules.js:41 +#, fuzzy +msgid "Invalid port number" +msgstr "Spécifier un numéro de port correct" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "Jeton de réinitialisation incorrect." + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "Nom d'utilisateur et/ou mot de passe incorrect" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" +"La connexion IMAP est-elle sécurisée via l'utilisation de SSL/TLS ou StartTLS" + +#: src/views/Dashboard.vue:9 +#, fuzzy +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" +"Il présentera un résumé du statut de votre serveur Modoboa\n" +" et quelques informations utiles sur le produit." + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "Conserver des copies locales" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "Langage" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "Date de dernière connexion" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "Date de dernière modification" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "Nom de famille" + +#: src/views/admin/InformationView.vue:59 +msgid "Latest version" +msgstr "Dernière version" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "Laisser vide pour aucune limite" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "Niveau" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "Limites" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "Domaine local (optionnel)" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "Logger" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "Déconnexion" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "Boîte aux lettres" + +#: src/components/admin/identities/AccountEditForm.vue:164 +#, fuzzy +msgid "Mailbox aliases:" +msgstr "Boîtes aux lettres" + +#: src/components/admin/identities/AccountEditForm.vue:157 +#, fuzzy +msgid "Mailbox:" +msgstr "Boîte aux lettres" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "Boîtes aux lettres" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "Message" + +#: src/views/admin/monitoring/MessagesView.vue:3 +msgid "Message history" +msgstr "Historique des messages" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "Limite d'envoi des messages" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "messages" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "Messages" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +msgid "Migration deleted" +msgstr "Migration supprimée" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +msgid "Migrations" +msgstr "Migrations" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "Modifié" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "Modifier" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "Mois" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "Enregistrements MX" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "Nom" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "Nom de l'administrateur" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "Nom du domaine à migrer" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +#, fuzzy +msgid "Name:" +msgstr "Nom :" + +#: src/components/admin/domains/DomainEditForm.vue:16 +#, fuzzy +msgid "Name: " +msgstr "Nom :" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "Jamais connecté" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "Nouvelle" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "Nouveau compte" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "Nouvel alias" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "Nouveau domaine" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +msgid "New provider" +msgstr "Nouveau fournisseur" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "Nouveaux codes de récupération" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "Suivant" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "non" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "Non" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "Aucun domaine associé" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "Aucune adresse d'expéditeur définie pour ce compte" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "Pas de limite d'envoi" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "Non générée" + +#: src/components/admin/identities/AccountEditForm.vue:165 +#, fuzzy +msgid "Number of allowed mailbox aliases:" +msgstr "Nombre de domaines associés :" + +#: src/components/admin/identities/AccountEditForm.vue:158 +#, fuzzy +msgid "Number of allowed mailboxes:" +msgstr "Nombre de domaines associés :" + +#: src/components/admin/identities/AccountEditForm.vue:125 +#, fuzzy +msgid "Number of associated alias:" +msgstr "Nombre de domaines associés :" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "Nombre de domaines associés :" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" +"Nombre de messages que ce domaine peut envoyer par jour. Laisser vide pour " +"aucune limite." + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" +"Nombre de messages que cette boîte aux lettres peut envoyer par jour. " +"Laisser vide pour aucune limite." + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "Ok" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "OK" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +msgid "Old account" +msgstr "Ancien compte" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "Une ou plusieurs mise à jour sont disponibles" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "Ouvert" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "Alarmes ouvertes" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "Options" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "Paramètres mis à jour" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "Partiellement aligné" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "Sources partiellement fiables / Transitaires" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "Mot de passe" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "Mot de passe copié dans la presse-papier" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +#, fuzzy +msgid "Password mismatch" +msgstr "Les mots de passe diffèrent" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +msgid "Password recovery" +msgstr "Récupération de mot de passe" + +#: src/components/account/ProfileForm.vue:143 +msgid "Password updated" +msgstr "Mot de passe mis à jour" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "Les mots de passe diffèrent" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "En attente" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "Période" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "Numéro de téléphone" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "Code Pin" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "Veillez renseigner votre adresse e-mail principale" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "Port" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "Problème" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "Procéder" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "Profil" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "Profil mis à jour" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" +"Fournir un fichier CSV dont les lignes respectent l'un des formats suivants:" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +msgid "Provider" +msgstr "Fournisseur" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +msgid "Provider created" +msgstr "Fournisseur créé" + +#: src/stores/providers.store.js:45 +msgid "Provider deleted" +msgstr "Fournisseur supprimé" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +msgid "Provider name" +msgstr "Nom du fournisseur" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +msgid "Provider updated" +msgstr "Fournisseur mis à jour" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +msgid "Providers" +msgstr "Fournisseurs" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "ID de file" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "Quota" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" +"Quota pour cette boite. Peut être exprimé en Ko, Mo (défaut) ou Go. Définir " +"une valeur spécifique ou utiliser la valeur par défaut du domaine. Laisser " +"vide pour définir une valeur illimitée (interdit pour les admins. de " +"domaine)." + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" +"Quota partagé entre les 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/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +#, fuzzy +msgid "Quota: " +msgstr "Quota:" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "Adresse aléatoire" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "Mot de passe aléatoire" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "Format brut. Cliquer pour copier" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "Destinataire(s)" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "Destinataires" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "Enregistrer" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "Intervalles des temps relatifs" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "Relais" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +#, fuzzy +msgid "relaydomain" +msgstr "Nouveau domaine" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "Recharger" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "Se souvenir de moi" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "Supprimer cette adresse" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "Supprimer cet administrateur" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "Ré-ouvrir l'alarme" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "Revendeur" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "Renvoyer le SMS." + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "Rénitialiser les codes de récupération" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "Ressources" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "Utilisation des ressources" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "Réessayer la rénitialisation" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "Retour à la connexion" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "Rôle" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "Enregistrer" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "Chercher" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "E-mail secondaire" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "Sécurisé" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "Sécurité" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "Sélectionner un compte" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "Sélectionner un fichier" + +#: src/components/admin/identities/AccountEditForm.vue:92 +#, fuzzy +msgid "Send only" +msgstr "Sélectionner un compte" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +#, fuzzy +msgid "Send only account" +msgstr "Sélectionner un compte" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "Adresses d'expédition" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "Limite d'envoi" + +#: src/components/admin/domains/DomainEditForm.vue:84 +#, fuzzy +msgid "Sending limit: " +msgstr "Limite d'envoi :" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "Séparateur" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "Service" + +#: src/components/admin/domains/DomainEditForm.vue:116 +#, fuzzy +msgid "Service: " +msgstr "Service :" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "Paramètres" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "Afficher la clé" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "Utilisateur simple" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "Spécifier une adresse e-mail" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "Enregistrement SPF trouvé" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "Enregistrement SPF introuvable" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "Commencer à saisir un nom ici..." + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "Statistiques" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "Statut" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "Soumettre" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "Résumé" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "Super administrateur" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "Tags" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" +"Le premier élément de chaque ligne est obligatoire et doit être égal à l'une " +"des valeurs précédentes." + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +#, fuzzy +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" +"Les codes de récupération suivants peuvent être utilisés une fois chacun " +"pour vous permettre de récupérer un accès à votre compte, au cas où vous " +"perdriez votre téléphone par exemple. Assurez-vous de les conserver dans un " +"lieu sûr, autrement vous ne serez définitivement plus en mesure d'accéder à " +"votre compte." + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "Cette page est en cours de construction." + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "A" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "Trop de tentatives sans succès, veuillez réessayer plus tard" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "Total" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "TOTP envoyé." + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "Transport" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "Déclenché" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "Sources de confiance" + +#: src/components/account/TwoFactorAuthForm.vue:6 +#, fuzzy +msgid "Two factor authentication" +msgstr "Authentification à double facteur" + +#: src/components/login/TwofaForm.vue:6 +#, fuzzy +msgid "Two-factor authentication" +msgstr "Authentification à double facteur" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" +"L'authentification à double facteur (2FA) n'est pas encore activée pour " +"votre compte. L'activation de cette fonctionnalité augmentera la sécurité de " +"votre compte." + +#: src/components/account/TwoFactorAuthForm.vue:71 +#, fuzzy +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" +"Félicitations ! l'authentification à double facteur est maintenant activée " +"sur votre compte" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "Type" + +#: src/components/admin/domains/DomainEditForm.vue:19 +#, fuzzy +msgid "Type: " +msgstr "Type :" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "Inconnu" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "Sources inconnues / Menaces" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "illimité" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +#, fuzzy +msgid "Unlimited" +msgstr "illimité" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "Mettre à jour" + +#: src/components/account/ProfileForm.vue:75 +msgid "Update Password" +msgstr "Mise à jour du mot de passe" + +#: src/components/account/ProfileForm.vue:62 +msgid "Update settings" +msgstr "Mise à jour des paramètres" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "Mis à jour" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "Utiliser la valeur par défaut du domaine" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" +"L'utilisateur semble erroné, revenez à la connexion ou redémarrer " +"réinitialisez le processus " + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +msgid "User unknown." +msgstr "Utilisateur inconnu." + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "Nom d'utilisateur" + +#: src/components/admin/identities/AccountEditForm.vue:39 +msgid "Username:" +msgstr "Nom d'utilisateur :" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "Valide" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "Vérifier le code" + +#: src/components/admin/domains/DNSDetail.vue:217 +#, fuzzy +msgid "warning" +msgstr "Avertissement" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "Avertissement" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "Semaine" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "Bienvenue dans Modoboa" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "Avec une boite aux lettres" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "Avec boîte aux lettres" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "Année" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "oui" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "Oui" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "Vous êtes sur le point de supprimer votre jeton d'accès à l'API" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "Vous pouvez utiliser autre caractère comme séparateur" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "Votre jeton API n'a pas encore été généré." + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "Votre jeton API est :" + +#~ msgid "Generate a random password for the administrator." +#~ msgstr "Générer un mot de passe aléatoire pour cet administrateur." + +#~ msgid "Account not found!" +#~ msgstr "Compte introuvable !" + +#~ msgid "Address:" +#~ msgstr "Adresse :" + +#~ msgid "Administrators of {{ domain.name }}" +#~ msgstr "Administrateur de {{ domain.name }}" + +#~ msgid "body" +#~ msgstr "Corps" + +#~ msgid "element" +#~ msgstr "élément" + +#~ msgid "err" +#~ msgstr "erreur" + +#~ msgid "hostname of your automx server" +#~ msgstr "Nom d'hôte de votre serveur automx" + +#~ msgid "Identities deleted" +#~ msgstr "Identités supprimées" + +#~ msgid "IP address of your Modoboa server" +#~ msgstr "Adresse IP de votre serveur Modoboa" + +#~ msgid "Sender address added" +#~ msgstr "Adresse d'expédition ajoutée" + +#~ msgid "Sender address deleted" +#~ msgstr "Adresse d'expédition supprimée" + +#~ msgid "Settings: thislabel" +#~ msgstr "Paramètres : thislabel" + +#~ msgid "" +#~ "The following recovery codes can be used one time each to\n" +#~ " let you regain access to your account, in case you lose your\n" +#~ " phone for example. Make sure to save them in a safe place,\n" +#~ " otherwise you won't be able to access your account anymore." +#~ msgstr "" +#~ "Le code de récupération suivant est à usage unique\n" +#~ " pour vous permettre d'accéder à votre compte, en cas de " +#~ "perte de votre\n" +#~ " téléphone par exemple. Soyez convaincu de l'avoir " +#~ "sauvegardé dans un endroit sûr,\n" +#~ " sinon vous ne pourrez plus jamais accéder à votre compte. " + +#~ msgid "title" +#~ msgstr "titre" + +#~ msgid "Two-factor authentication code" +#~ msgstr "Code d'authentification double facteur" + +#~ msgid "Verification" +#~ msgstr "Vérification" + +#~ msgid "You have one or more opened alarms" +#~ msgstr "Vous avez une ou plusieurs alarmes ouvertes" + +#~ msgid "This field must be a valid number" +#~ msgstr "Ce champ doit contenir un numéro valide" + +#~ msgid "Settings: " +#~ msgstr "Paramètres :" + +#~ msgid "You are throttled, please try later." +#~ msgstr "Votre limite est atteinte, veuillez réessayer plus tard" diff --git a/frontend/src/locale/it/app.po b/frontend/src/locale/it/app.po new file mode 100644 index 000000000..a1bd397f6 --- /dev/null +++ b/frontend/src/locale/it/app.po @@ -0,0 +1,2013 @@ +# Italian translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:26+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +#, fuzzy +msgid "account" +msgstr "Account" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "Account" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "Account creato" + +#: src/stores/accounts.store.js:62 +#, fuzzy +msgid "Account successfully deleted" +msgstr "Account creato" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "Account aggiornato" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "Azioni" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "Aggiungi" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "Indirizzo" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "Domini amministrati" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "Amministratori" + +#: src/components/admin/domains/DomainAdminList.vue:6 +#, fuzzy +msgid "Administrators of" +msgstr "Amministratori" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +#, fuzzy +msgid "Alarm deleted" +msgstr "Data di creazione" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +#, fuzzy +msgid "alias" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "Alias" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +#, fuzzy +msgid "Alias already added" +msgstr "Alias creato" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +#, fuzzy +msgid "Alias successfully created" +msgstr "Alias creato" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +#, fuzzy +msgid "Alias updated" +msgstr "Alias creato" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:124 +#, fuzzy +msgid "Aliases:" +msgstr "Alias" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "API" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "Accesso API" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +#, fuzzy +msgid "API token created" +msgstr "Account creato" + +#: src/views/account/APISetupView.vue:114 +#, fuzzy +msgid "API token deleted" +msgstr "Data di creazione" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "Applica" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +#, fuzzy +msgid "Associated domain" +msgstr "Domini amministrati" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +#, fuzzy +msgid "Associated domains" +msgstr "Domini amministrati" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "Autenticazione" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "Formato bind/named" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "Cambia password" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" +"Seleziona questa opzione se le password contenute nel file non sono criptate" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "Chiudi" + +#: src/components/admin/alarms/AlarmList.vue:133 +#, fuzzy +msgid "Close alarm" +msgstr "Chiudi" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "Chiudi" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "Conferma" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "Continuare in caso di errore" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "Crea un amministratore di dominio" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "Crea una casella di posta per l'amministratore." + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "Crea alias" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "Data di creazione" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "Cripta le password" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +#, fuzzy +msgid "Current password" +msgstr "Cripta le password" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "Giorno" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "Dimensione massima predefinita per le mailbox" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +msgid "" +"Default quota applied to mailboxes. Can be expressed in KB, MB (default) or " +"GB. A value of 0 means no quota." +msgstr "" +"Valore predefinito per lo spazio massimo confiviso tra le mailbox. Può " +"essere espresso in KB, MB (predefinito) o GB. Il valore 0 indica nessun " +"limite." + +#: src/components/admin/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "Descrizione" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +#, fuzzy +msgid "Disable 2FA" +msgstr "Disabilitato" + +#: src/components/admin/domains/DomainList.vue:80 +#, fuzzy +msgid "disabled" +msgstr "(disabilitato)" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "Disabilitato" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "Chiave DKIM" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "DNS" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "Stato del DNS" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +#, fuzzy +msgid "domain" +msgstr "Dominio" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "Dominio" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "Amministratore di dominio" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "Dominio creato" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +#, fuzzy +msgid "Domain default value" +msgstr "Usa il valore predefinito" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +#, fuzzy +msgid "domain's default value" +msgstr "Usa il valore predefinito" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "Domini" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +#, fuzzy +msgid "Edit account" +msgstr "Nuovo account" + +#: src/views/admin/identities/AliasEditView.vue:3 +#, fuzzy +msgid "Edit alias" +msgstr "Nuovo alias" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +#, fuzzy +msgid "Edit provider" +msgstr "Indirizzo email" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "Indirizzo email" + +#: src/layouts/dashboard/NavBar.vue:233 +#, fuzzy +msgid "Email providers" +msgstr "Indirizzo email" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +#, fuzzy +msgid "Enable 2FA" +msgstr "Abilitato" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "Abilita la firma DKIM" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "Abilita i controlli DNS" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "Abilitato" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +#, fuzzy +msgid "Enter an email address" +msgstr "Indirizzo email" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "Scade il" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "Fallito" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +#, fuzzy +msgid "Field is required" +msgstr "Questo campo è obbligatorio" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +#, fuzzy +msgid "First name" +msgstr "Nome completo" + +#: src/components/login/LoginForm.vue:96 +#, fuzzy +msgid "Forgot password" +msgstr "Password dimenticata?" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +#, fuzzy +msgid "Forgot password?" +msgstr "Password dimenticata?" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "Inoltra" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" +"Inoltra i messaggi e memorizza le copie nella tua casella di posta locale" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "Inoltro aggiornato" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +#, fuzzy +msgid "Forwarded" +msgstr "Inoltra" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "Nome completo" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +#, fuzzy +msgid "Fully aligned" +msgstr "Completamente allineato" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "Generale" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +#, fuzzy +msgid "General settings" +msgstr "Generale" + +#: src/views/account/APISetupView.vue:18 +#, fuzzy +msgid "Generate" +msgstr "Generale" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +#, fuzzy +msgid "Generated address" +msgstr "Indirizzi mittenti" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "Identità" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "Importa" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "Importa domini" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "Identità di importazione" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "Informazioni" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +#, fuzzy +msgid "Installed components" +msgstr "Versione installata" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "Versione installata" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +#, fuzzy +msgid "Invalid password" +msgstr "Password casuale" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "Mantieni copie locali" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "Data dell'ultima modifica" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +#, fuzzy +msgid "Latest version" +msgstr "Versione installata" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "Livello" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "Logger" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "Esci" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "Caselle di posta" + +#: src/components/admin/identities/AccountEditForm.vue:164 +#, fuzzy +msgid "Mailbox aliases:" +msgstr "Caselle di posta" + +#: src/components/admin/identities/AccountEditForm.vue:157 +#, fuzzy +msgid "Mailbox:" +msgstr "Caselle di posta" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "Caselle di posta" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "Utilizzo" + +#: src/views/admin/monitoring/MessagesView.vue:3 +#, fuzzy +msgid "Message history" +msgstr "Utilizzo" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +#, fuzzy +msgid "Migration deleted" +msgstr "Data di creazione" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +#, fuzzy +msgid "Migrations" +msgstr "Conferma" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "Modificato" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "Mese" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "Nome" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +#, fuzzy +msgid "Name:" +msgstr "Nome" + +#: src/components/admin/domains/DomainEditForm.vue:16 +#, fuzzy +msgid "Name: " +msgstr "Nome" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "Nuovo account" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "Nuovo alias" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "Nuovo dominio" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +#, fuzzy +msgid "New provider" +msgstr "Indirizzo email" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "Successivo" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +#, fuzzy +msgid "No associated domains" +msgstr "Domini amministrati" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "Non generata" + +#: src/components/admin/identities/AccountEditForm.vue:165 +#, fuzzy +msgid "Number of allowed mailbox aliases:" +msgstr "Caselle di posta" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +#, fuzzy +msgid "Number of associated domains:" +msgstr "Domini amministrati" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +#, fuzzy +msgid "Old account" +msgstr "Nuovo account" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "Sono disponibili nuovi aggiornamenti" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "Opzioni" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +#, fuzzy +msgid "Parameters updated" +msgstr "Profilo aggiornato" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "Parzialmente allineato" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "Password" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +#, fuzzy +msgid "Password mismatch" +msgstr "Le password non corrispondono" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +#, fuzzy +msgid "Password recovery" +msgstr "Password" + +#: src/components/account/ProfileForm.vue:143 +#, fuzzy +msgid "Password updated" +msgstr "Inoltro aggiornato" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "Le password non corrispondono" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "Numero di telefono" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "Profilo" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "Profilo aggiornato" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +#, fuzzy +msgid "Provider" +msgstr "Dominio creato" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +#, fuzzy +msgid "Provider created" +msgstr "Dominio creato" + +#: src/stores/providers.store.js:45 +#, fuzzy +msgid "Provider deleted" +msgstr "Dominio creato" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +#, fuzzy +msgid "Provider name" +msgstr "Dominio creato" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +#, fuzzy +msgid "Provider updated" +msgstr "Profilo aggiornato" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +#, fuzzy +msgid "Providers" +msgstr "Indirizzo email" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "Dimensione massima" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" +"Dimensione massima per questa mailbox, può essere espressa in KB, MB " +"(predefinito) o GB. Definire un valore personalizzato o utilizzare quello " +"predefinito per il dominio. Lasciare vuoto per specificare un valore non " +"limitato (non permesso per amministratori di dominio)." + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" +"Spazio massimo confiviso tra le mailbox. Può essere espresso in KB, MB " +"(predefinito) o GB. Il valore 0 indica nessun limite." + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +#, fuzzy +msgid "Quota: " +msgstr "Dimensione massima" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "Indirizzo casuale" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "Password casuale" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "Destinatario(i)" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "Destinatari" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +#, fuzzy +msgid "relaydomain" +msgstr "Nuovo dominio" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "Ricordami" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +#, fuzzy +msgid "Reopen alarm" +msgstr "Chiudi" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "Rivenditore" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "Risorse" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "Utilizzo risorse" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "Ruolo" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "Salva" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "Ricerca" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "Email secondaria" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +#, fuzzy +msgid "Send only" +msgstr "Nuovo account" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +#, fuzzy +msgid "Send only account" +msgstr "Nuovo account" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "Indirizzi mittenti" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "Separatore" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "Impostazioni" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "Visualizza chiave" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "Utente semplice" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +#, fuzzy +msgid "Statistics" +msgstr "Statistiche" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "Stato" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "Invia" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "Sommario" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "Super amministratore" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "Tag" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "Totale" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "Trasporto" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +#, fuzzy +msgid "Trusted sources" +msgstr "Fonti attendibili" + +#: src/components/account/TwoFactorAuthForm.vue:6 +#, fuzzy +msgid "Two factor authentication" +msgstr "Autenticazione" + +#: src/components/login/TwofaForm.vue:6 +#, fuzzy +msgid "Two-factor authentication" +msgstr "Autenticazione" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "Tipo" + +#: src/components/admin/domains/DomainEditForm.vue:19 +#, fuzzy +msgid "Type: " +msgstr "Tipo" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "Sconosciuto" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "Fonti sconosciute / Minaccie" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "senza limiti" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +#, fuzzy +msgid "Unlimited" +msgstr "senza limiti" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "Aggiorna" + +#: src/components/account/ProfileForm.vue:75 +#, fuzzy +msgid "Update Password" +msgstr "Password" + +#: src/components/account/ProfileForm.vue:62 +#, fuzzy +msgid "Update settings" +msgstr "Impostazioni" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "Aggiornato" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "Usa il valore predefinito" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +#, fuzzy +msgid "User unknown." +msgstr "Sconosciuto" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "Nome utente" + +#: src/components/admin/identities/AccountEditForm.vue:39 +#, fuzzy +msgid "Username:" +msgstr "Nome utente" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "Settimana" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "Benvenuti in Modoboa" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "Con una casella di posta" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "Anno" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" + +#~ msgid "Generate a random password for the administrator." +#~ msgstr "Genera una password casuale per l'amministratore." + +#, fuzzy +#~ msgid "Account not found!" +#~ msgstr "Account creato" + +#, fuzzy +#~ msgid "Identities deleted" +#~ msgstr "Identità" diff --git a/frontend/src/locale/ja/app.po b/frontend/src/locale/ja/app.po new file mode 100644 index 000000000..a61a3c694 --- /dev/null +++ b/frontend/src/locale/ja/app.po @@ -0,0 +1,1916 @@ +# Japanese translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:26+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +msgid "account" +msgstr "" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "" + +#: src/stores/accounts.store.js:62 +msgid "Account successfully deleted" +msgstr "" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:6 +msgid "Administrators of" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +msgid "Alarm deleted" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +msgid "alias" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +msgid "Alias already added" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +msgid "Alias successfully created" +msgstr "" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +msgid "Alias updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:124 +msgid "Aliases:" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +msgid "API token created" +msgstr "" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +msgid "Associated domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +msgid "Associated domains" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +msgid "Current password" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:80 +msgid "disabled" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +msgid "domain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +msgid "Edit provider" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "" + +#: src/components/login/LoginForm.vue:96 +msgid "Forgot password" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +msgid "Forgot password?" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +msgid "General settings" +msgstr "" + +#: src/views/account/APISetupView.vue:18 +msgid "Generate" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +msgid "Generated address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +msgid "Installed components" +msgstr "" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +msgid "Invalid password" +msgstr "" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +msgid "Latest version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:164 +msgid "Mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:157 +msgid "Mailbox:" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "" + +#: src/views/admin/monitoring/MessagesView.vue:3 +msgid "Message history" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +msgid "Migration deleted" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +msgid "Migrations" +msgstr "" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +msgid "Name:" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:16 +msgid "Name: " +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +msgid "New provider" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:165 +msgid "Number of allowed mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +msgid "Old account" +msgstr "" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +msgid "Password mismatch" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +msgid "Password recovery" +msgstr "" + +#: src/components/account/ProfileForm.vue:143 +msgid "Password updated" +msgstr "" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +msgid "Provider" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +msgid "Provider created" +msgstr "" + +#: src/stores/providers.store.js:45 +msgid "Provider deleted" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +msgid "Provider name" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +msgid "Provider updated" +msgstr "" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +msgid "Providers" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +msgid "relaydomain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +msgid "Send only" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +msgid "Send only account" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:6 +msgid "Two factor authentication" +msgstr "" + +#: src/components/login/TwofaForm.vue:6 +msgid "Two-factor authentication" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:19 +msgid "Type: " +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +msgid "Unlimited" +msgstr "" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "" + +#: src/components/account/ProfileForm.vue:75 +msgid "Update Password" +msgstr "" + +#: src/components/account/ProfileForm.vue:62 +msgid "Update settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +msgid "User unknown." +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:39 +msgid "Username:" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" diff --git a/frontend/src/locale/messages.pot b/frontend/src/locale/messages.pot new file mode 100644 index 000000000..6f7ccc7a2 --- /dev/null +++ b/frontend/src/locale/messages.pot @@ -0,0 +1,1864 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +msgid "account" +msgstr "" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "" + +#: src/stores/accounts.store.js:62 +msgid "Account successfully deleted" +msgstr "" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:6 +msgid "Administrators of" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +msgid "Alarm deleted" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +msgid "alias" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +msgid "Alias already added" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +msgid "Alias successfully created" +msgstr "" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +msgid "Alias updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:124 +msgid "Aliases:" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +msgid "API token created" +msgstr "" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +msgid "Associated domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +msgid "Associated domains" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +msgid "Current password" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:80 +msgid "disabled" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "DKIM key does not seem to be genrated yet or has failed. Do you want to requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +msgid "domain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +msgid "Edit provider" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "" + +#: src/components/login/TwofaForm.vue:11 +msgid "Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "" + +#: src/components/login/LoginForm.vue:96 +msgid "Forgot password" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +msgid "Forgot password?" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:284 +#: src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +msgid "General settings" +msgstr "" + +#: src/views/account/APISetupView.vue:18 +msgid "Generate" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +msgid "Generated address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "" + +#: src/components/tools/CreationForm.vue:127 +msgid "If you close this form now, your modifications won't be saved. Do you confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "If you configured it recently, please wait for the first report to be received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 +#: src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "Install a soft token authenticator like FreeOTP or Google Authenticator from your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +msgid "Installed components" +msgstr "" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +msgid "Invalid password" +msgstr "" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "It will present a summary of your Modoboa server's status and some useful information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +msgid "Latest version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:164 +msgid "Mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:157 +msgid "Mailbox:" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "" + +#: src/views/admin/monitoring/MessagesView.vue:3 +msgid "Message history" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +msgid "Migration deleted" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +msgid "Migrations" +msgstr "" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +msgid "Name:" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:16 +msgid "Name: " +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +msgid "New provider" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:165 +msgid "Number of allowed mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +msgid "Old account" +msgstr "" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +msgid "Password mismatch" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +msgid "Password recovery" +msgstr "" + +#: src/components/account/ProfileForm.vue:143 +msgid "Password updated" +msgstr "" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 +#: src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +msgid "Provider" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +msgid "Provider created" +msgstr "" + +#: src/stores/providers.store.js:45 +msgid "Provider deleted" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +msgid "Provider name" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +msgid "Provider updated" +msgstr "" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +msgid "Providers" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)." +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota." +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +msgid "relaydomain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 +#: src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +msgid "Send only" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +msgid "Send only account" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "" + +#: src/components/tools/ImportForm.vue:16 +msgid "The first element of each line is mandatory and must be equal to one of the previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "The following recovery codes can be used one time each to let you regain access to your account, in case you lose your phone for example. Make sure to save them in a safe place, otherwise you won't be able to access your account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:6 +msgid "Two factor authentication" +msgstr "" + +#: src/components/login/TwofaForm.vue:6 +msgid "Two-factor authentication" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:19 +msgid "Type: " +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +msgid "Unlimited" +msgstr "" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "" + +#: src/components/account/ProfileForm.vue:75 +msgid "Update Password" +msgstr "" + +#: src/components/account/ProfileForm.vue:62 +msgid "Update settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +msgid "User unknown." +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:39 +msgid "Username:" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" diff --git a/frontend/src/locale/nl/app.po b/frontend/src/locale/nl/app.po new file mode 100644 index 000000000..5d99c8cf1 --- /dev/null +++ b/frontend/src/locale/nl/app.po @@ -0,0 +1,1916 @@ +# Dutch translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:26+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +msgid "account" +msgstr "" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "" + +#: src/stores/accounts.store.js:62 +msgid "Account successfully deleted" +msgstr "" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:6 +msgid "Administrators of" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +msgid "Alarm deleted" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +msgid "alias" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +msgid "Alias already added" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +msgid "Alias successfully created" +msgstr "" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +msgid "Alias updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:124 +msgid "Aliases:" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +msgid "API token created" +msgstr "" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +msgid "Associated domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +msgid "Associated domains" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +msgid "Current password" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:80 +msgid "disabled" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +msgid "domain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +msgid "Edit provider" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "" + +#: src/components/login/LoginForm.vue:96 +msgid "Forgot password" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +msgid "Forgot password?" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +msgid "General settings" +msgstr "" + +#: src/views/account/APISetupView.vue:18 +msgid "Generate" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +msgid "Generated address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +msgid "Installed components" +msgstr "" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +msgid "Invalid password" +msgstr "" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +msgid "Latest version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:164 +msgid "Mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:157 +msgid "Mailbox:" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "" + +#: src/views/admin/monitoring/MessagesView.vue:3 +msgid "Message history" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +msgid "Migration deleted" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +msgid "Migrations" +msgstr "" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +msgid "Name:" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:16 +msgid "Name: " +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +msgid "New provider" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:165 +msgid "Number of allowed mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +msgid "Old account" +msgstr "" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +msgid "Password mismatch" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +msgid "Password recovery" +msgstr "" + +#: src/components/account/ProfileForm.vue:143 +msgid "Password updated" +msgstr "" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +msgid "Provider" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +msgid "Provider created" +msgstr "" + +#: src/stores/providers.store.js:45 +msgid "Provider deleted" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +msgid "Provider name" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +msgid "Provider updated" +msgstr "" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +msgid "Providers" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +msgid "relaydomain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +msgid "Send only" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +msgid "Send only account" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:6 +msgid "Two factor authentication" +msgstr "" + +#: src/components/login/TwofaForm.vue:6 +msgid "Two-factor authentication" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:19 +msgid "Type: " +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +msgid "Unlimited" +msgstr "" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "" + +#: src/components/account/ProfileForm.vue:75 +msgid "Update Password" +msgstr "" + +#: src/components/account/ProfileForm.vue:62 +msgid "Update settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +msgid "User unknown." +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:39 +msgid "Username:" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" diff --git a/frontend/src/locale/pl/app.po b/frontend/src/locale/pl/app.po new file mode 100644 index 000000000..884811147 --- /dev/null +++ b/frontend/src/locale/pl/app.po @@ -0,0 +1,1917 @@ +# Polish translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:26+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pl\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==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +msgid "account" +msgstr "" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "" + +#: src/stores/accounts.store.js:62 +msgid "Account successfully deleted" +msgstr "" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:6 +msgid "Administrators of" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +msgid "Alarm deleted" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +msgid "alias" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +msgid "Alias already added" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +msgid "Alias successfully created" +msgstr "" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +msgid "Alias updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:124 +msgid "Aliases:" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +msgid "API token created" +msgstr "" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +msgid "Associated domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +msgid "Associated domains" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +msgid "Current password" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:80 +msgid "disabled" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +msgid "domain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +msgid "Edit provider" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "" + +#: src/components/login/LoginForm.vue:96 +msgid "Forgot password" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +msgid "Forgot password?" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +msgid "General settings" +msgstr "" + +#: src/views/account/APISetupView.vue:18 +msgid "Generate" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +msgid "Generated address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +msgid "Installed components" +msgstr "" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +msgid "Invalid password" +msgstr "" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +msgid "Latest version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:164 +msgid "Mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:157 +msgid "Mailbox:" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "" + +#: src/views/admin/monitoring/MessagesView.vue:3 +msgid "Message history" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +msgid "Migration deleted" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +msgid "Migrations" +msgstr "" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +msgid "Name:" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:16 +msgid "Name: " +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +msgid "New provider" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:165 +msgid "Number of allowed mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +msgid "Old account" +msgstr "" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +msgid "Password mismatch" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +msgid "Password recovery" +msgstr "" + +#: src/components/account/ProfileForm.vue:143 +msgid "Password updated" +msgstr "" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +msgid "Provider" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +msgid "Provider created" +msgstr "" + +#: src/stores/providers.store.js:45 +msgid "Provider deleted" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +msgid "Provider name" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +msgid "Provider updated" +msgstr "" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +msgid "Providers" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +msgid "relaydomain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +msgid "Send only" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +msgid "Send only account" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:6 +msgid "Two factor authentication" +msgstr "" + +#: src/components/login/TwofaForm.vue:6 +msgid "Two-factor authentication" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:19 +msgid "Type: " +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +msgid "Unlimited" +msgstr "" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "" + +#: src/components/account/ProfileForm.vue:75 +msgid "Update Password" +msgstr "" + +#: src/components/account/ProfileForm.vue:62 +msgid "Update settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +msgid "User unknown." +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:39 +msgid "Username:" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" diff --git a/frontend/src/locale/pt/app.po b/frontend/src/locale/pt/app.po new file mode 100644 index 000000000..15c86ad27 --- /dev/null +++ b/frontend/src/locale/pt/app.po @@ -0,0 +1,1916 @@ +# Portuguese translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:26+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +msgid "account" +msgstr "" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "" + +#: src/stores/accounts.store.js:62 +msgid "Account successfully deleted" +msgstr "" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:6 +msgid "Administrators of" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +msgid "Alarm deleted" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +msgid "alias" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +msgid "Alias already added" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +msgid "Alias successfully created" +msgstr "" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +msgid "Alias updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:124 +msgid "Aliases:" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +msgid "API token created" +msgstr "" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +msgid "Associated domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +msgid "Associated domains" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +msgid "Current password" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:80 +msgid "disabled" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +msgid "domain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +msgid "Edit provider" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "" + +#: src/components/login/LoginForm.vue:96 +msgid "Forgot password" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +msgid "Forgot password?" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +msgid "General settings" +msgstr "" + +#: src/views/account/APISetupView.vue:18 +msgid "Generate" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +msgid "Generated address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +msgid "Installed components" +msgstr "" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +msgid "Invalid password" +msgstr "" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +msgid "Latest version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:164 +msgid "Mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:157 +msgid "Mailbox:" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "" + +#: src/views/admin/monitoring/MessagesView.vue:3 +msgid "Message history" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +msgid "Migration deleted" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +msgid "Migrations" +msgstr "" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +msgid "Name:" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:16 +msgid "Name: " +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +msgid "New provider" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:165 +msgid "Number of allowed mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +msgid "Old account" +msgstr "" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +msgid "Password mismatch" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +msgid "Password recovery" +msgstr "" + +#: src/components/account/ProfileForm.vue:143 +msgid "Password updated" +msgstr "" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +msgid "Provider" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +msgid "Provider created" +msgstr "" + +#: src/stores/providers.store.js:45 +msgid "Provider deleted" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +msgid "Provider name" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +msgid "Provider updated" +msgstr "" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +msgid "Providers" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +msgid "relaydomain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +msgid "Send only" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +msgid "Send only account" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:6 +msgid "Two factor authentication" +msgstr "" + +#: src/components/login/TwofaForm.vue:6 +msgid "Two-factor authentication" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:19 +msgid "Type: " +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +msgid "Unlimited" +msgstr "" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "" + +#: src/components/account/ProfileForm.vue:75 +msgid "Update Password" +msgstr "" + +#: src/components/account/ProfileForm.vue:62 +msgid "Update settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +msgid "User unknown." +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:39 +msgid "Username:" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" diff --git a/frontend/src/locale/ru/app.po b/frontend/src/locale/ru/app.po new file mode 100644 index 000000000..3d78939ca --- /dev/null +++ b/frontend/src/locale/ru/app.po @@ -0,0 +1,2004 @@ +# Russian translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:26+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\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=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +#, fuzzy +msgid "account" +msgstr "Добавить аккаунт" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "Добавить аккаунт" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "Аккаунт создан" + +#: src/stores/accounts.store.js:62 +#, fuzzy +msgid "Account successfully deleted" +msgstr "Аккаунт создан" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "аккаунт изменен" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "Действие" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "Адрес" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "Адрес" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "Список квот" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "Администраторы" + +#: src/components/admin/domains/DomainAdminList.vue:6 +#, fuzzy +msgid "Administrators of" +msgstr "Администраторы" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +#, fuzzy +msgid "Alarm deleted" +msgstr "Дата создания" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +#, fuzzy +msgid "alias" +msgstr "Синоним" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "Синоним" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +#, fuzzy +msgid "Alias already added" +msgstr "Синоним создан" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +#, fuzzy +msgid "Alias successfully created" +msgstr "Синоним создан" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +#, fuzzy +msgid "Alias updated" +msgstr "Синоним создан" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "Синоним(ы)" + +#: src/components/admin/identities/AccountEditForm.vue:124 +#, fuzzy +msgid "Aliases:" +msgstr "Синоним(ы)" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "API" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +#, fuzzy +msgid "API token created" +msgstr "Аккаунт создан" + +#: src/views/account/APISetupView.vue:114 +#, fuzzy +msgid "API token deleted" +msgstr "Дата создания" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "Применить" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +#, fuzzy +msgid "Associated domain" +msgstr "Список квот" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +#, fuzzy +msgid "Associated domains" +msgstr "Список квот" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "Аутентификация" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "Неверный формат" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "Изменить пароль" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "Выберите эту опцию если пароль в вашем файле не зашифрован " + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "Подтверждение" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "Продолжать при ошибке" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "Создание администратора домена" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "Создание администратора домена" + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "Создание синонимов" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "Дата создания" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "Шифровать пароль" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +#, fuzzy +msgid "Current password" +msgstr "Шифровать пароль" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "Приборная панель" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "День" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +#, fuzzy +msgid "Disable 2FA" +msgstr "Разрешен" + +#: src/components/admin/domains/DomainList.vue:80 +#, fuzzy +msgid "disabled" +msgstr "Разрешен" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "Разрешен" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "Статистика" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +#, fuzzy +msgid "domain" +msgstr "Домены" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "Администратор домена" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "Домен создан" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +#, fuzzy +msgid "Domain default value" +msgstr "Используются значения домена по умолчанию " + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +#, fuzzy +msgid "domain's default value" +msgstr "Используются значения домена по умолчанию " + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "Домены" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +#, fuzzy +msgid "Edit account" +msgstr "Новый аккаунт" + +#: src/views/admin/identities/AliasEditView.vue:3 +#, fuzzy +msgid "Edit alias" +msgstr "Новый синоним" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +#, fuzzy +msgid "Edit provider" +msgstr "Е-майл адрес" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "Е-майл адрес" + +#: src/layouts/dashboard/NavBar.vue:233 +#, fuzzy +msgid "Email providers" +msgstr "Е-майл адрес" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +#, fuzzy +msgid "Enable 2FA" +msgstr "Разрешено" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "Разрешено" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +#, fuzzy +msgid "Enter an email address" +msgstr "Е-майл адрес" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +#, fuzzy +msgid "First name" +msgstr "Имя файла" + +#: src/components/login/LoginForm.vue:96 +#, fuzzy +msgid "Forgot password" +msgstr "Забыли пароль?" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +#, fuzzy +msgid "Forgot password?" +msgstr "Забыли пароль?" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "Перенаправленые" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" +"Перенаправление сообщения, и сохранение копии в вашем локальном почтовом " +"ящике" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "Перенаправление обновлено" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +#, fuzzy +msgid "Forwarded" +msgstr "Перенаправленые" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "Имя файла" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +#, fuzzy +msgid "Fully aligned" +msgstr "Имя файла" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "Основные" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +#, fuzzy +msgid "General settings" +msgstr "Основные" + +#: src/views/account/APISetupView.vue:18 +#, fuzzy +msgid "Generate" +msgstr "Основные" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +#, fuzzy +msgid "Generated address" +msgstr "Ошибочный запрос" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "Пользователи" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "Импорт" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "Импорт доменов" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "Импорт информации о пользователях" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "Информация" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +#, fuzzy +msgid "Installed components" +msgstr "Установленная версия" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "Установленная версия" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +#, fuzzy +msgid "Invalid password" +msgstr "Ошибочный запрос" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "Сохранить локальную копию" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "Дата последней модификации" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +#, fuzzy +msgid "Latest version" +msgstr "Установленная версия" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "Уровень" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "Логгер" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "Завершить сеанс" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "Почтовые ящики" + +#: src/components/admin/identities/AccountEditForm.vue:164 +#, fuzzy +msgid "Mailbox aliases:" +msgstr "Почтовые ящики" + +#: src/components/admin/identities/AccountEditForm.vue:157 +#, fuzzy +msgid "Mailbox:" +msgstr "Почтовые ящики" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "Почтовые ящики" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "использование (%%)" + +#: src/views/admin/monitoring/MessagesView.vue:3 +#, fuzzy +msgid "Message history" +msgstr "использование (%%)" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +#, fuzzy +msgid "Migration deleted" +msgstr "Дата создания" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +#, fuzzy +msgid "Migrations" +msgstr "Подтверждение" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "Синоним изменен" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "Месяц" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "Логин" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +#, fuzzy +msgid "Name:" +msgstr "Логин" + +#: src/components/admin/domains/DomainEditForm.vue:16 +#, fuzzy +msgid "Name: " +msgstr "Логин" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "Новый аккаунт" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "Новый синоним" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "Новый домен" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +#, fuzzy +msgid "New provider" +msgstr "Е-майл адрес" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "Следующая" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +#, fuzzy +msgid "No associated domains" +msgstr "Список квот" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "Получатель не определен" + +#: src/components/admin/identities/AccountEditForm.vue:165 +#, fuzzy +msgid "Number of allowed mailbox aliases:" +msgstr "Почтовые ящики" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +#, fuzzy +msgid "Number of associated domains:" +msgstr "Список квот" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +#, fuzzy +msgid "Old account" +msgstr "Новый аккаунт" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "Доступны одно или более обновлений." + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "Опции" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +#, fuzzy +msgid "Parameters updated" +msgstr "Профиль обновлен" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "Пароль" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +#, fuzzy +msgid "Password mismatch" +msgstr "Пароли не совпадают" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +#, fuzzy +msgid "Password recovery" +msgstr "Пароль" + +#: src/components/account/ProfileForm.vue:143 +#, fuzzy +msgid "Password updated" +msgstr "Перенаправление обновлено" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "Пароли не совпадают" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "Профиль обновлен" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +#, fuzzy +msgid "Provider" +msgstr "Домен создан" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +#, fuzzy +msgid "Provider created" +msgstr "Домен создан" + +#: src/stores/providers.store.js:45 +#, fuzzy +msgid "Provider deleted" +msgstr "Домен создан" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +#, fuzzy +msgid "Provider name" +msgstr "Домен создан" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +#, fuzzy +msgid "Provider updated" +msgstr "Профиль обновлен" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +#, fuzzy +msgid "Providers" +msgstr "Е-майл адрес" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" +"Квота в мегабайтах для этого почтового ящика. Определите собственное " +"значение или используйте значение по умолчанию для родительского домена. " +"Оставьте пустым для неограниченного значения. (Не разрешено администраторам " +"домена)" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "Ошибочный запрос" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "Ошибочный запрос" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "Получатели" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "Получатели" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +#, fuzzy +msgid "relaydomain" +msgstr "Новый домен" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "Запомнить меня" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "Реселлер" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "Ресурсы" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "Использование ресурсов" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "Роль" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "Сохранить" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "Поиск" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +#, fuzzy +msgid "Send only" +msgstr "Новый аккаунт" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +#, fuzzy +msgid "Send only account" +msgstr "Новый аккаунт" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "Ошибочный запрос" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "Разделитель" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "Настройки" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "Обычный пользователь" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +#, fuzzy +msgid "Statistics" +msgstr "Статистика" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "Статистика" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "Подтвердить" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "Супер администратор" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "Теги" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +#, fuzzy +msgid "Trusted sources" +msgstr "Ресурсы" + +#: src/components/account/TwoFactorAuthForm.vue:6 +#, fuzzy +msgid "Two factor authentication" +msgstr "Аутентификация" + +#: src/components/login/TwofaForm.vue:6 +#, fuzzy +msgid "Two-factor authentication" +msgstr "Аутентификация" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:19 +msgid "Type: " +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "Неизвестное" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "Не лимитировано" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +#, fuzzy +msgid "Unlimited" +msgstr "Не лимитировано" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "Обновление" + +#: src/components/account/ProfileForm.vue:75 +#, fuzzy +msgid "Update Password" +msgstr "Пароль" + +#: src/components/account/ProfileForm.vue:62 +#, fuzzy +msgid "Update settings" +msgstr "Настройки" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "Обновление" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "Используются значения домена по умолчанию " + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +#, fuzzy +msgid "User unknown." +msgstr "Неизвестное" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "Логин пользователя" + +#: src/components/admin/identities/AccountEditForm.vue:39 +#, fuzzy +msgid "Username:" +msgstr "Логин пользователя" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "Неделя" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "Добро пожаловать в Modoboa!" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "Год" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" + +#~ msgid "Generate a random password for the administrator." +#~ msgstr "Создание администратора домена" + +#, fuzzy +#~ msgid "Account not found!" +#~ msgstr "Аккаунт создан" + +#, fuzzy +#~ msgid "Identities deleted" +#~ msgstr "Пользователи" diff --git a/frontend/src/locale/sv/app.po b/frontend/src/locale/sv/app.po new file mode 100644 index 000000000..ef8397721 --- /dev/null +++ b/frontend/src/locale/sv/app.po @@ -0,0 +1,2080 @@ +# +# Translators: +# Olle Gustafsson , 2023 +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"Last-Translator: Olle Gustafsson , 2023\n" +"Language-Team: Swedish (https://app.transifex.com/tonio/teams/13749/sv/)\n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: easygettext\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "Dokumentation av API är tillgänglig" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" +"En ny nyckel kommer snart att skapas. Ladda om sidan om en stund för att se " +"den." + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" +"Användare med alla rättigheter som kan göra allt. Som standard har en sån " +"här användare ingen brevlåda så den kan inte komma åt slutanvändarfunktioner." + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" +"Användare utan privilegier men som har en en brevlåda. Den kommer att kunna " +"använda alla slutanvändarfunktioner: webbmail, kalender, kontakter, filter." + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" +"Användare med rättigheter på en eller flera domäner. Den kan administrera " +"brevlådor och han kan även ha en brevlåda." + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "Absolut tidsintervall" + +#: src/stores/identities.store.js:67 +#, fuzzy +msgid "account" +msgstr "Konto" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "Konto" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "Konto skapat" + +#: src/stores/accounts.store.js:62 +#, fuzzy +msgid "Account successfully deleted" +msgstr "Konto raderat" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "Konto uppdaterat" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "Åtgärder" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "Lägg till" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "Lägg till nytt domän alias" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "Lägg till administratör" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "Lägg till avsändaradress" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +#, fuzzy +msgid "Add/Remove from the domain page" +msgstr "Namn på domänen att migrera" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "Adress" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "Adress (värdnamn eller IP)" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "Administrerade domäner" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "Administratör tillagd" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "Administratörs namn" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "Administratör raderad" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "Administratörer" + +#: src/components/admin/domains/DomainAdminList.vue:6 +#, fuzzy +msgid "Administrators of" +msgstr "Administratörer" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "Larm stängt" + +#: src/components/admin/alarms/AlarmList.vue:173 +msgid "Alarm deleted" +msgstr "Larm raderat" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "Larm öppnat på nytt" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "Larm" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "Larm raderade" + +#: src/stores/identities.store.js:97 +#, fuzzy +msgid "alias" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "Alias" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +#, fuzzy +msgid "Alias already added" +msgstr "Alias skapat" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +#, fuzzy +msgid "Alias successfully created" +msgstr "Alias skapat" + +#: src/stores/aliases.store.js:61 +#, fuzzy +msgid "Alias successfully deleted" +msgstr "Alias raderat" + +#: src/stores/aliases.store.js:74 +msgid "Alias updated" +msgstr "Alias uppdaterat" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" +"Alias för denna brevlåda. För att skapa ett catchall-alias anger du bara " +"domännamnet (@domain.tld)." + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "Alias" + +#: src/components/admin/identities/AccountEditForm.vue:124 +#, fuzzy +msgid "Aliases:" +msgstr "Alias" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "Placering" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "API" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "API åtkomst" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "API token kopierat till urklipp" + +#: src/views/account/APISetupView.vue:92 +msgid "API token created" +msgstr "API token skapat" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "API token raderat" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "Tillämpa" + +#: src/components/admin/identities/IdentityList.vue:231 +#, fuzzy +msgid "Are you sure you want to delete this alias?" +msgstr "Vill du verkligen ta bort aliaset %{ alias }?" + +#: src/components/admin/identities/IdentityList.vue:205 +#, fuzzy +msgid "Are you sure you want to delete this identity ?" +msgstr "Vill du verkligen ta bort de valda identiteterna?" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +#, fuzzy +msgid "Associated domain" +msgstr "Associerade domäner" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +msgid "Associated domains" +msgstr "Associerade domäner" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "Verifieringskedja" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "Autentisering" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "Automatisk konfiguration" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "autoconfig-posten (Mozilla) hittades inte" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "\"autoconfig-post (Mozilla): %{ value }\"" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "autodiscover-post (Microsoft) hittades inte" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "autodiscover-post (Microsoft): %{ value }" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "Tillbaka" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "Bind/named formatterat. Klicka för att kopiera" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "Avbryt" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "Ändra lösenord" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "Kontrollera anslutning:" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "Kolla in följande lista för att hitta relaterade komponenter" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" +"Markera det här alternativet om lösenorden i din fil inte är krypterade" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "Välj en domän" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "Välj en roll" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "Stäng" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "Stäng alarm" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "Stängd" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "Bekräfta och skapa" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "Bekräftelse" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "Grattis! Tvåfaktorsautentisering är nu aktiverad för ditt konto." + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "Anslut" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "Fortsätt vid fel" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" +"Kontrollera om den här domänen ska tillåtas skicka och ta emot meddelanden" + +#: src/components/admin/domains/DNSDetail.vue:114 +#, fuzzy +msgid "Copy key to clipboard" +msgstr "Kopiera token till urklipp" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "Kopiera till urklipp" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "Kopiera token till urklipp" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "Kunde inte spara parametrar" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "Skapa en domänadministratör" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "Skapa en brevlåda för administratören." + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "Skapa alias" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "Skapa standardalias för domänen." + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "Datum skapad" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "Kryptera lösenord" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +msgid "Current password" +msgstr "Nuvarande lösenord" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "Daglig sändningsgräns för meddelanden" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "Daglig sändningsgräns" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "Instrumentbräda" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "Datum" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "Dag" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "Standard brevlådekvota" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +msgid "" +"Default quota applied to mailboxes. Can be expressed in KB, MB (default) or " +"GB. A value of 0 means no quota." +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "Radera" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "Radera token" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "Beskrivning" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "Detalj" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "Inaktivear 2FA" + +#: src/components/admin/domains/DomainList.vue:80 +#, fuzzy +msgid "disabled" +msgstr "(inaktiverad)" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "Inaktiverad" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "DKIM nyckel" + +#: src/components/admin/domains/DNSDetail.vue:182 +#, fuzzy +msgid "DKIM key copied to clipboard" +msgstr "API token kopierat till urklipp" + +#: src/components/admin/domains/DNSDetail.vue:218 +#, fuzzy +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "DKIM-nycklar finns redan för den här domänen. Vill du skriva över dem?" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "DKIM nyckellängd" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "DKIM nyckel väljare" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "DKIM-nycklar finns redan för den här domänen. Vill du skriva över dem?" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "DKIM publik nyckel för" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "DKIM-post hittades" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "DKIM-posten hittades inte" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "DKIM signering" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "DMARC" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "DMARC post hittad" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "DMARC post ej hittad" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "DMARC-stöd verkar inte vara aktiverat för den här domänen." + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "DNS" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "DNS kontroller" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +#, fuzzy +msgid "DNS configuration for " +msgstr "DNS konfigurering för" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "DNS konfigurering hjälp" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "DNS status" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "Ta inte bort kontomappen" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "Ta inte bort domänmappen" + +#: src/components/admin/domains/DomainList.vue:236 +#, fuzzy +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "Vill du verkligen ta bort aliaset %{ alias }?" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +#, fuzzy +msgid "domain" +msgstr "Domän" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "Domän" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "Domänadministratör" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "Domän alias skapat" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "Domänalias raderat" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "Domänalias uppdaterat" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "Domän skapad" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "Domän standardvärde" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "Domän raderad" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "Domännamn (ex: domain.tld)" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "Domän uppdaterad" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "domänens standardvärde" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "Domäner" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "Behandla inte duplicerade objekt som fel" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "Redigera" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "Redigera konto" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "Redigera alias" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "Redigera domän" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "Redigera domänalias" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +msgid "Edit provider" +msgstr "Redigera leverantör" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "E-post" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "E-postadress" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "E-postleverantörer" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "Tom" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "Aktivera 2FA" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "Aktivera DKIM signering" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "Aktivera DNS kontroller" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "Aktiverad" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "Ange ett enkelt användarnamn eller en e-postadress" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "Ange en e-postadress" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"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." + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "Ange koden du precis har fått via SMS" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "Fel" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "Ex: 10MB. Lämna tomt för ingen gräns" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "Utgår kl" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "Exportera konton och alias till CSV" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "Exportera domäner och alias till CSV" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "Misslyckades" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +#, fuzzy +msgid "Field is required" +msgstr "Detta fält krävs" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "Förnamn" + +#: src/components/login/LoginForm.vue:96 +#, fuzzy +msgid "Forgot password" +msgstr "Glömt lösenord?" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +#, fuzzy +msgid "Forgot password?" +msgstr "Glömt lösenord?" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "Vidarebefordra" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "Vidarebefordra meddelanden och lagra kopior i din lokala brevlåda" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "Vidarebefordring uppdaterad" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "Vidarebefordrad" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "Vidarebefordrare med ARC" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "Från" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "Komplett namn" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "Komplett namn/mottagare" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "Helt inriktad" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "Allmän" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "Allmänn information" + +#: src/components/account/ProfileForm.vue:5 +msgid "General settings" +msgstr "Allmänna inställningar" + +#: src/views/account/APISetupView.vue:18 +msgid "Generate" +msgstr "Generera" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "Generera en ny DKIM nyckel" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +#, fuzzy +msgid "Generated address" +msgstr "Avsändaradresser" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "hjälp" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" +"Här är ett exempel på DNS-konfiguration (bind-format). Ersätt värdena mellan " +"[ ] med de lämpliga värdena." + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "Identifikation" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "Identiteter" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" +"Om du stänger formuläret nu kommer dina ändringar inte att sparas. Bekräftar " +"du?" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" +"Om du konfigurerade det nyligen, vänta tills den första rapporten tas emot " +"och behandlas." + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "IMAP migrering" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "IMAP port" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "Importera" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "Importera konton och alias från CSV-fil" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "Importera domäner" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "Importera domäner och alias från CSV-fil" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "Importera identiteter" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "Ange en eller flera mottagare separerade med kommatecken (,)" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "Information" + +#: src/components/account/TwoFactorAuthForm.vue:34 +#, fuzzy +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" +"Installera en mjuk tokenskyddare som FreeOTP eller Google\n" +"Authenticator från din applikationsbutik och använd den appen\n" +"för att skanna denna QR-kod." + +#: src/views/admin/InformationView.vue:8 +msgid "Installed components" +msgstr "Installerade komponenter" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "Installerad version" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +msgid "Invalid password" +msgstr "Ogiltigt lösenord" + +#: src/plugins/rules.js:41 +#, fuzzy +msgid "Invalid port number" +msgstr "Ange ett giltigt portnummer" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "Ogiltigt återställningstoken." + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "Ogiltigt användarnamn och/eller lösenord" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "Är IMAP-anslutningen säker med SSL/TLS eller StartTLS" + +#: src/views/Dashboard.vue:9 +#, fuzzy +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" +"Den kommer att presentera en sammanfattning av din Modoboa-servers status " +"och\n" +"lite användbar information om produkten." + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "Behåll lokala kopior" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "Språk" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "Senaste inloggning" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "Senaste ändrad datum" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "Efternamn" + +#: src/views/admin/InformationView.vue:59 +msgid "Latest version" +msgstr "Senaste version" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "Lämna tomt för ingen gräns" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "Nivå" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "Gränser" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "Lokal domän (valfritt)§" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "Logger" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "Logga ut" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "Brevlåda" + +#: src/components/admin/identities/AccountEditForm.vue:164 +#, fuzzy +msgid "Mailbox aliases:" +msgstr "Brevlådor" + +#: src/components/admin/identities/AccountEditForm.vue:157 +#, fuzzy +msgid "Mailbox:" +msgstr "Brevlåda" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "Brevlådor" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "MB" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "Meddelande" + +#: src/views/admin/monitoring/MessagesView.vue:3 +msgid "Message history" +msgstr "Meddelande historik" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "Begränsning för meddelandesändning" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "meddelanden" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "Meddelanden" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +msgid "Migration deleted" +msgstr "Migrering raderad" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +msgid "Migrations" +msgstr "Migreringar" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "Ändrad" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "Ändra" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "Månad" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "MX poster" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "Namn" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "Namn på administratören" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "Namn på domänen att migrera" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +#, fuzzy +msgid "Name:" +msgstr "Namn:" + +#: src/components/admin/domains/DomainEditForm.vue:16 +#, fuzzy +msgid "Name: " +msgstr "Namn:" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "Aldrig inloggad" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "Ny" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "Nytt konto" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "Nytt alias" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "Ny domän" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +msgid "New provider" +msgstr "Ny leverantör" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "Nya återställningskoder" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "Nästa" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "nej" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "Nej" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "Inga associerade domäner" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "Inge avsändaradress agedd för detta konto" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "Ingen sändningsbegränsning" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "Ej genererad" + +#: src/components/admin/identities/AccountEditForm.vue:165 +#, fuzzy +msgid "Number of allowed mailbox aliases:" +msgstr "Antal associerade domäner:" + +#: src/components/admin/identities/AccountEditForm.vue:158 +#, fuzzy +msgid "Number of allowed mailboxes:" +msgstr "Antal associerade domäner:" + +#: src/components/admin/identities/AccountEditForm.vue:125 +#, fuzzy +msgid "Number of associated alias:" +msgstr "Antal associerade domäner:" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "Antal associerade domäner:" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" +"Antal meddelanden som denna domän kan skicka per dag. Lämna tomt för ingen " +"begränsning." + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" +"Antal meddelanden som denna brevlåda kan skicka per dag. Lämna tomt för " +"ingen begränsning." + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "Ok" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "OK" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +msgid "Old account" +msgstr "Gammalt konto" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "En eller flera uppdateringar tillgängliga" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "Öppnad" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "Öppnade alarm" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "Alternativ" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "Parametrar uppdaterade" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "Delvis justerad" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "Delvis pålitliga källor / speditörer" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "Lösenord" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "Lösenord kopierat till urklipp" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +#, fuzzy +msgid "Password mismatch" +msgstr "Lösenord matchar ej" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +msgid "Password recovery" +msgstr "Lösenordsåterställning" + +#: src/components/account/ProfileForm.vue:143 +msgid "Password updated" +msgstr "Lösenord uppdaterat" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "Lösenord matchar ej" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "Väntande" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "Period" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "Telefonnummer" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "Pinkod" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "Var vänlig fyll i din primära e-postadress" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "Port" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "Problem" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "Fortsätt" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "Profil" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "Profil uppdaterad" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "Ange en CSV-fil där raderna respekterar ett av följande format:" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +msgid "Provider" +msgstr "Leverantör" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +msgid "Provider created" +msgstr "Leverantör skapad" + +#: src/stores/providers.store.js:45 +msgid "Provider deleted" +msgstr "Leverantör raderad" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +msgid "Provider name" +msgstr "Leverantörsnamn" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +msgid "Provider updated" +msgstr "Leverantör uppdaterad" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +msgid "Providers" +msgstr "Leverantörer" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "Kö ID" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "Kvota" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" +"Kvot för denna brevlåda, kan anges i KB, MB (standard) eller GB. Ange ett " +"anpassat värde eller använd domänens standardvärde. Lämna tomt för att ange " +"ett obegränsat värde (inte tillåtet för domänadministratörer)." + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" +"Kvot delad mellan brevlådor. Kan anges i KB, MB (standard) eller GB. Ett " +"värde av 0 innebär ingen kvot." + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +#, fuzzy +msgid "Quota: " +msgstr "Kvota:" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "Slumpmässig adress" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "Slumpmässigt lösenord" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "Råformat. Klicka för att kopiera" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "Mottagare" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "Mottagare" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "Register" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "Relativa tidsintervall" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "Relä" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +#, fuzzy +msgid "relaydomain" +msgstr "Ny domän" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "Ladda om" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "Kom ihåg mig" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "Radera denna adress" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "Radera denna administratör" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "Återöppna larmet" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "Återförsäljare" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "Skicka SMS på nytt." + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "Återställ återställningskoder" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "Resurser" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "Resursanvändning" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "Försök återställning igen" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "Återgå till inloggning" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "Roll" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "Spara" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "Sök" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "Sekundär e-post" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "Säkrad" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "Säkerhet" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "Välj ett konto" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "Välj fil" + +#: src/components/admin/identities/AccountEditForm.vue:92 +#, fuzzy +msgid "Send only" +msgstr "Välj ett konto" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +#, fuzzy +msgid "Send only account" +msgstr "Välj ett konto" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "Avsändaradresser" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "Sändningsgräns" + +#: src/components/admin/domains/DomainEditForm.vue:84 +#, fuzzy +msgid "Sending limit: " +msgstr "Sändningsgräns:" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "Avgränsare" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "Tjänst" + +#: src/components/admin/domains/DomainEditForm.vue:116 +#, fuzzy +msgid "Service: " +msgstr "Tjänst:" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "Inställningar" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "Visa nyckel" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "Enkel användare" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "Ange en e-postadress" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "SPF post hittad" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "SPF post saknas" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "Börja skriva ett namn här..." + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "Statistik" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "Status" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "Skicka" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "Sammanfattning" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "Superadministratör" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "Taggar" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" +"Det första elementet i varje rad är obligatoriskt och måste vara lika med " +"ett av de tidigare värdena." + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +#, fuzzy +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" +"Följande återställningskoder kan användas en gång var för att hyra ut\n" +"du återfår åtkomst till ditt konto, om du tappar bort din telefon\n" +"till exempel. Se till att spara dem på ett säkert ställe, annars\n" +"du kommer inte längre kunna komma åt ditt konto." + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "Denna sida är fortfarande under konstruktion." + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "Till" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "För många misslyckade försök, försök igen senare." + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "Totalt" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "TOTP skickat igen." + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "Transport" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "Triggad" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "Pålitliga källor" + +#: src/components/account/TwoFactorAuthForm.vue:6 +#, fuzzy +msgid "Two factor authentication" +msgstr "Tvåfaktorsautentisering" + +#: src/components/login/TwofaForm.vue:6 +#, fuzzy +msgid "Two-factor authentication" +msgstr "Tvåfaktorsautentisering" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" +"Tvåfaktorsautentisering (2FA) är ännu inte aktiverad för ditt konto. Om du " +"aktiverar den här funktionen ökar ditt kontos säkerhet." + +#: src/components/account/TwoFactorAuthForm.vue:71 +#, fuzzy +msgid "Two-Factor Authentication is enabled for your account." +msgstr "Grattis! Tvåfaktorsautentisering är nu aktiverad för ditt konto." + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "Typ" + +#: src/components/admin/domains/DomainEditForm.vue:19 +#, fuzzy +msgid "Type: " +msgstr "Typ:" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "Okänd" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "Okända källor / hot" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "obegränsat" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +#, fuzzy +msgid "Unlimited" +msgstr "obegränsat" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "Uppdatera" + +#: src/components/account/ProfileForm.vue:75 +msgid "Update Password" +msgstr "Uppdatera lösenord" + +#: src/components/account/ProfileForm.vue:62 +msgid "Update settings" +msgstr "Uppdatera inställningar" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "Uppdaterad" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "Använd domänens standardvärde" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" +"Användare verkar felaktig, återgå till inloggning eller börja om " +"återsällningsprocessen?" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +msgid "User unknown." +msgstr "Okänd användare." + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "Användarnamn" + +#: src/components/admin/identities/AccountEditForm.vue:39 +msgid "Username:" +msgstr "Användarnamn:" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "Giltig" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "Verifikationskod" + +#: src/components/admin/domains/DNSDetail.vue:217 +#, fuzzy +msgid "warning" +msgstr "Varning" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "Varning" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "Vecka" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "Välkommen till Modoboa" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "Med en brevlåda" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "Med brevlåda" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "År" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "ja" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "Ja" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "Du håller på att radera din API-åtkomsttoken" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "Du kan använda ett annat tecken som avgränsare." + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "Ditt API token har ännu ej genererats." + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "Ditt API token är:" + +#~ msgid "Generate a random password for the administrator." +#~ msgstr "Generera ett slumpmässigt lösenord for administratören." + +#~ msgid "Account not found!" +#~ msgstr "Konto hittades ej!" + +#~ msgid "Address:" +#~ msgstr "Adress:" + +#~ msgid "Administrators of {{ domain.name }}" +#~ msgstr "Administratörer av {{ domain.name }}" + +#~ msgid "body" +#~ msgstr "kropp" + +#~ msgid "element" +#~ msgstr "element" + +#~ msgid "err" +#~ msgstr "fel" + +#~ msgid "hostname of your automx server" +#~ msgstr "Värdnamnet för din automx-server" + +#~ msgid "Identities deleted" +#~ msgstr "Identiteter raderade" + +#~ msgid "IP address of your Modoboa server" +#~ msgstr "IP adress för din Modoboa server" + +#~ msgid "Sender address added" +#~ msgstr "Avsändaradress tillagd" + +#~ msgid "Sender address deleted" +#~ msgstr "Avsändaradress raderad" + +#~ msgid "Settings: thislabel" +#~ msgstr "Inställningar: thislabel" + +#~ msgid "" +#~ "The following recovery codes can be used one time each to\n" +#~ " let you regain access to your account, in case you lose your\n" +#~ " phone for example. Make sure to save them in a safe place,\n" +#~ " otherwise you won't be able to access your account anymore." +#~ msgstr "" +#~ "Följande återställningskoder kan användas en gång var för att\n" +#~ "låter dig återfå åtkomst till ditt konto, ifall du förlorar ditt\n" +#~ "telefon till exempel. Se till att spara dem på en säker plats,\n" +#~ "annars kommer du inte längre komma åt ditt konto." + +#~ msgid "title" +#~ msgstr "titel" + +#~ msgid "Two-factor authentication code" +#~ msgstr "Tvåfaktors autentiseringskod" + +#~ msgid "Verification" +#~ msgstr "Verifikation" + +#~ msgid "You have one or more opened alarms" +#~ msgstr "Du har ett eller flera öppna alarm" + +#~ msgid "This field must be a valid number" +#~ msgstr "Detta fält måste vara ett nummer" + +#~ msgid "Settings: " +#~ msgstr "Inställningar:" + +#~ msgid "You are throttled, please try later." +#~ msgstr "Du är strypt, försök senare." diff --git a/frontend/src/locale/tr/app.po b/frontend/src/locale/tr/app.po new file mode 100644 index 000000000..084cba161 --- /dev/null +++ b/frontend/src/locale/tr/app.po @@ -0,0 +1,1967 @@ +# Turkish translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:26+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +msgid "account" +msgstr "" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "" + +#: src/stores/accounts.store.js:62 +msgid "Account successfully deleted" +msgstr "" + +#: src/stores/accounts.store.js:43 +#, fuzzy +msgid "Account updated" +msgstr "Profil güncellendi" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:6 +#, fuzzy +msgid "Administrators of" +msgstr "Süper Yönetici" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +msgid "Alarm deleted" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +msgid "alias" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +msgid "Alias already added" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +msgid "Alias successfully created" +msgstr "" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +#, fuzzy +msgid "Alias updated" +msgstr "Profil güncellendi" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:124 +msgid "Aliases:" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "API" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "API erişimi" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +#, fuzzy +msgid "API token created" +msgstr "Profil güncellendi" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +msgid "Associated domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +msgid "Associated domains" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "Kimlik Doğrulama" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "Parolayı değiştirin" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "Kapat" + +#: src/components/admin/alarms/AlarmList.vue:133 +#, fuzzy +msgid "Close alarm" +msgstr "Kapat" + +#: src/components/admin/alarms/AlarmList.vue:46 +#, fuzzy +msgid "Closed" +msgstr "Kapat" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "Onayla" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" +"Tebrikler! Artık hesabınız için İki Faktörlü Kimlik Doğrulama " +"etkinleştirildi." + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:81 +#, fuzzy +msgid "Crypt passwords" +msgstr "Parolanızı mı unuttunuz?" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +#, fuzzy +msgid "Current password" +msgstr "Parolanızı mı unuttunuz?" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "Gösterge Paneli" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "Tarih" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "Tanım" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "2FA'yı devre dışı bırak" + +#: src/components/admin/domains/DomainList.vue:80 +#, fuzzy +msgid "disabled" +msgstr "2FA'yı devre dışı bırak" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +msgid "domain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "Alan adı Yöneticisi" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +#, fuzzy +msgid "Edit provider" +msgstr "Yeni kurtarma kodları" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "2FA'yı etkinleştir" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "Az önce SMS ile aldığınız kodu giriniz" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +#, fuzzy +msgid "Field is required" +msgstr "Bu alan gerekli" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "" + +#: src/components/login/LoginForm.vue:96 +#, fuzzy +msgid "Forgot password" +msgstr "Parolanızı mı unuttunuz?" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +#, fuzzy +msgid "Forgot password?" +msgstr "Parolanızı mı unuttunuz?" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" + +#: src/components/account/ForwardForm.vue:49 +#, fuzzy +msgid "Forward updated" +msgstr "Profil güncellendi" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "Kimden" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "Genel" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +#, fuzzy +msgid "General settings" +msgstr "Genel" + +#: src/views/account/APISetupView.vue:18 +#, fuzzy +msgid "Generate" +msgstr "Genel" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +msgid "Generated address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "Bilgi" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +#, fuzzy +msgid "Installed components" +msgstr "Kurulu sürüm" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "Kurulu sürüm" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +#, fuzzy +msgid "Invalid password" +msgstr "Parolayı değiştirin" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +#, fuzzy +msgid "Latest version" +msgstr "Kurulu sürüm" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "Seviye" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "Kayıtçı" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "Çıkış Yapın" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:164 +msgid "Mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:157 +msgid "Mailbox:" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "İleti" + +#: src/views/admin/monitoring/MessagesView.vue:3 +#, fuzzy +msgid "Message history" +msgstr "İleti" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +#, fuzzy +msgid "Migration deleted" +msgstr "Onayla" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +#, fuzzy +msgid "Migrations" +msgstr "Onayla" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "İsim" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +#, fuzzy +msgid "Name:" +msgstr "İsim" + +#: src/components/admin/domains/DomainEditForm.vue:16 +#, fuzzy +msgid "Name: " +msgstr "İsim" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +#, fuzzy +msgid "New provider" +msgstr "Yeni kurtarma kodları" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "Yeni kurtarma kodları" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "Sonraki" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "Hayır" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:165 +msgid "Number of allowed mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +msgid "Old account" +msgstr "" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "Bir veya daha fazla güncelleme mevcut" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +#, fuzzy +msgid "Parameters updated" +msgstr "Profil güncellendi" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "Parola" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +#, fuzzy +msgid "Password mismatch" +msgstr "Parolalar uyuşmuyor" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +#, fuzzy +msgid "Password recovery" +msgstr "Parola" + +#: src/components/account/ProfileForm.vue:143 +#, fuzzy +msgid "Password updated" +msgstr "Profil güncellendi" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "Parolalar uyuşmuyor" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "Telefon numarası" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "Pin kodu" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "Lütfen birincil e-posta adresinizi girin" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "Profil" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "Profil güncellendi" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +#, fuzzy +msgid "Provider" +msgstr "Yeni kurtarma kodları" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +#, fuzzy +msgid "Provider created" +msgstr "Profil güncellendi" + +#: src/stores/providers.store.js:45 +#, fuzzy +msgid "Provider deleted" +msgstr "Profil güncellendi" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +#, fuzzy +msgid "Provider name" +msgstr "Profil güncellendi" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +#, fuzzy +msgid "Provider updated" +msgstr "Profil güncellendi" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +#, fuzzy +msgid "Providers" +msgstr "Yeni kurtarma kodları" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "Kayıt ol" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +msgid "relaydomain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "Beni hatırla" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +#, fuzzy +msgid "Reopen alarm" +msgstr "Kapat" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "Bayii" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "Kurtarma kodlarını sıfırla" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "Rol" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "Kaydet" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "İkincil e-posta" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +#, fuzzy +msgid "Secured" +msgstr "Güvenlik" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "Güvenlik" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +msgid "Send only" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +msgid "Send only account" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "Ayarlar" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "Basit kullanıcı" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "Gönder" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +#, fuzzy +msgid "Super administrator" +msgstr "Alan adı Yöneticisi" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "Kime" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:6 +#, fuzzy +msgid "Two factor authentication" +msgstr "Kimlik Doğrulama" + +#: src/components/login/TwofaForm.vue:6 +#, fuzzy +msgid "Two-factor authentication" +msgstr "Kimlik Doğrulama" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" +"Hesabınız için İki Faktörlü Kimlik Doğrulama (2FA) henüz etkinleştirilmedi. " +"Bu özelliği etkinleştirmek hesabınızın güvenliğini artıracaktır." + +#: src/components/account/TwoFactorAuthForm.vue:71 +#, fuzzy +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" +"Tebrikler! Artık hesabınız için İki Faktörlü Kimlik Doğrulama " +"etkinleştirildi." + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:19 +msgid "Type: " +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "Bilinmeyen" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +msgid "Unlimited" +msgstr "" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "Güncelle" + +#: src/components/account/ProfileForm.vue:75 +#, fuzzy +msgid "Update Password" +msgstr "Parola" + +#: src/components/account/ProfileForm.vue:62 +#, fuzzy +msgid "Update settings" +msgstr "Ayarlar" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +#, fuzzy +msgid "User unknown." +msgstr "Bilinmeyen" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "Kullanıcı adı" + +#: src/components/admin/identities/AccountEditForm.vue:39 +#, fuzzy +msgid "Username:" +msgstr "Kullanıcı adı" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "Modoboa'ya hoş geldiniz" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "Evet" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" diff --git a/frontend/src/locale/translations.json b/frontend/src/locale/translations.json new file mode 100644 index 000000000..547ba536e --- /dev/null +++ b/frontend/src/locale/translations.json @@ -0,0 +1 @@ +{"en":{"A new key will be generated soon. Refresh the page in a moment to see it.":"A new key will be generated soon. Refresh the page in a moment to see it.","Absolute time range":"Absolute time range","Account":"Account","Actions":"Actions","Add":"Add","Add a new domain alias":"Add a new domain alias","Add administrator":"Add administrator","Add sender address":"Add sender address","Address":"Address","Administered domains":"Administered domains","Administrator added":"Administrator added","Administrator name":"Administrator name","Administrator removed":"Administrator removed","Administrators":"Administrators","Administrators of":"Administrators of","Alarms":"Alarms","Alias":"Alias","Aliases":"Aliases","Alignment":"Alignment","API":"API","Apply":"Apply","Audit trail":"Audit trail","Authentication":"Authentication","Auto configuration":"Auto configuration","autoconfig record (Mozilla) not found":"autoconfig record (Mozilla) not found","autoconfig record (Mozilla): %{ value }":"autoconfig record (Mozilla): %{ value }","autodiscover record (Microsoft) not found":"autodiscover record (Microsoft) not found","autodiscover record (Microsoft): %{ value }":"autodiscover record (Microsoft): %{ value }","Back":"Back","Bind/named format. Click to copy":"Bind/named format. Click to copy","Cancel":"Cancel","Choose a domain":"Choose a domain","Close":"Close","Confirm and create":"Confirm and create","Connect":"Connect","Continue on error":"Continue on error","Control if this domain will be allowed to send and receive messages":"Control if this domain will be allowed to send and receive messages","Copy to clipboard":"Copy to clipboard","Create a domain administrator":"Create a domain administrator","Create a mailbox for the administrator.":"Create a mailbox for the administrator.","Create aliases":"Create aliases","Create standard aliases for the domain.":"Create standard aliases for the domain.","Creation date":"Creation date","CSV seems to be badly formatted":"CSV seems to be badly formatted","Daily sending limit":"Daily sending limit","Dashboard":"Dashboard","Day":"Day","Default mailbox quota":"Default mailbox quota","Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.","Delete":"Delete","Detail":"Detail","Disabled":"Disabled","DKIM key":"DKIM key","DKIM key does not seem to be genrated yet or has failed. Do you want to requeue the job?":"DKIM key does not seem to be genrated yet or has failed. Do you want to requeue the job?","DKIM key length":"DKIM key length","DKIM key selector":"DKIM key selector","DKIM keys already exist for this domain. Do you want to overwrite them?":"DKIM keys already exist for this domain. Do you want to overwrite them?","DKIM public key for":"DKIM public key for","DKIM record found":"DKIM record found","DKIM record not found":"DKIM record not found","DKIM signing":"DKIM signing","DMARC":"DMARC","DMARC record found":"DMARC record found","DMARC record not found":"DMARC record not found","DMARC support does not seem to be enabled for this domain.":"DMARC support does not seem to be enabled for this domain.","DNS":"DNS","DNS checks":"DNS checks","DNS configuration for ":"DNS configuration for ","DNS configuration help":"DNS configuration help","DNS status":"DNS status","Do not delete domain folder":"Do not delete domain folder","Do you really want to delete the domain %{ domain }?":"Do you really want to delete the domain %{ domain }?","Domain":"Domain","Domain alias created":"Domain alias created","Domain alias deleted":"Domain alias deleted","Domain alias updated":"Domain alias updated","Domain created":"Domain created","Domain deleted":"Domain deleted","Domain name (ex: domain.tld)":"Domain name (ex: domain.tld)","Domain updated":"Domain updated","Domains":"Domains","Don't treat duplicated objects as errors":"Don't treat duplicated objects as errors","Edit":"Edit","Edit domain":"Edit domain","Edit domain alias":"Edit domain alias","Email providers":"Email providers","Empty":"Empty","Enable DKIM signing":"Enable DKIM signing","Enable DNS checks":"Enable DNS checks","Enabled":"Enabled","Enter the code from the two-factor app on your mobile device. If you have 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 have lost your device, you may enter one of your recovery codes.","Export accounts and aliases to CSV":"Export accounts and aliases to CSV","Export domains and aliases to CSV":"Export domains and aliases to CSV","Failed":"Failed","Field is required":"Field is required","Forgot password":"Forgot password","Forward":"Forward","Forwarded":"Forwarded","Forwarders with ARC":"Forwarders with ARC","From":"From","Full name":"Full name","Fullname/recipient":"Fullname/recipient","Fully aligned":"Fully aligned","General":"General","General information":"General information","Generate a new DKIM key":"Generate a new DKIM key","Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones.":"Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones.","Identification":"Identification","Identities":"Identities","If you close this form now, your modifications won't be saved. Do you confirm?":"If you close this form now, your modifications won't be saved. Do you confirm?","If you configured it recently, please wait for the first report to be received and processed.":"If you configured it recently, please wait for the first report to be received and processed.","IMAP Migration":"IMAP Migration","Import":"Import","Import accounts and aliases from CSV file":"Import accounts and aliases from CSV file","Import domains":"Import domains","Import domains and aliases from CSV file":"Import domains and aliases from CSV file","Information":"Information","Last login date":"Last login date","Last modification date":"Last modification date","Limitations":"Limitations","Logout":"Logout","Mailboxes":"Mailboxes","MB":"MB","Message sending limit":"Message sending limit","messages":"messages","Messages":"Messages","Migrations":"Migrations","Modify":"Modify","Monitoring":"Monitoring","Month":"Month","Must be a numeric value or empty":"Must be a numeric value or empty","MX records":"MX records","Name":"Name","Name of the administrator":"Name of the administrator","Name: ":"Name: ","Never logged-in":"Never logged-in","New":"New","New domain":"New domain","Next":"Next","no":"no","No":"No","No data to export":"No data to export","No sender address defined for this account":"No sender address defined for this account","No sending limit":"No sending limit","Not a valid email":"Not a valid email","Not generated":"Not generated","Number of messages this domain can send per day. Leave empty for no limit.":"Number of messages this domain can send per day. Leave empty for no limit.","OK":"OK","Options":"Options","Partially aligned":"Partially aligned","Partially trusted sources / Forwarders":"Partially trusted sources / Forwarders","Password":"Password","Password copied to clipboard":"Password copied to clipboard","Pending":"Pending","Period":"Period","Phone number":"Phone number","Problem":"Problem","Profile":"Profile","Provide a CSV file where lines respect one of the following formats:":"Provide a CSV file where lines respect one of the following formats:","Quota":"Quota","Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.","Quota: ":"Quota: ","Random password":"Random password","Raw format. Click to copy":"Raw format. Click to copy","Relative time ranges":"Relative time ranges","Relay":"Relay","Reload":"Reload","Remember me":"Remember me","Remove this address":"Remove this address","Remove this administrator":"Remove this administrator","Resources":"Resources","Resources usage":"Resources usage","Role":"Role","Save":"Save","Secondary email":"Secondary email","Security":"Security","Select an account":"Select an account","Select file":"Select file","Sender addresses":"Sender addresses","Sending limit":"Sending limit","Sending limit: ":"Sending limit: ","Separator":"Separator","Service":"Service","Service: ":"Service: ","Settings":"Settings","Show key":"Show key","Specify an email address":"Specify an email address","SPF record found":"SPF record found","SPF record not found":"SPF record not found","Statistics":"Statistics","Summary":"Summary","Tags":"Tags","The first element of each line is mandatory and must be equal to one of the previous values.":"The first element of each line is mandatory and must be equal to one of the previous values.","To":"To","Total":"Total","Transport":"Transport","Trusted sources":"Trusted sources","Two-factor authentication":"Two-factor authentication","Type":"Type","Type: ":"Type: ","Unknown":"Unknown","Unknown sources / Threats":"Unknown sources / Threats","Unlimited":"Unlimited","Update":"Update","Updated":"Updated","Username":"Username","Valid":"Valid","Verify code":"Verify code","warning":"warning","Warning":"Warning","Week":"Week","With a mailbox":"With a mailbox","With mailbox":"With mailbox","Year":"Year","yes":"yes","Yes":"Yes","You can use a different character as separator.":"You can use a different character as separator."},"de":{"Account":"Konto","Account created":"Konto erstellt","Account updated":"Konto aktualisiert","Actions":"Aktionen","Add":"Hinzufügen","Address":"Adresse","Administered domains":"Administrierte Domains","Administrators":"Administratoren","Alias":"Alias","Aliases":"Aliase","API":"API","API access":"API Zugriff","Apply":"Antworten","Authentication":"Authentifizierung","Bind/named format. Click to copy":"Gebundenes Format","Change password":"Passwort ändern","Check this option if passwords contained in your file are not crypted":"Auswählen, wenn Kennwörter in Datei nicht verschlüsselt sind","Close":"Schließen","Closed":"Schließen","Confirmation":"Bestätigung","Congratulations! Two-Factor Authentication is now enabled for your account.":"Glückwunsch! Die Zwei-Faktor-Authentifizierung ist nun für diesen Account aktiviert.","Continue on error":"Bei Fehler fortfahren","Create a domain administrator":"Domain-Administrator erstellen","Create a mailbox for the administrator.":"Erzeuge Postfach für den Administrator.","Create aliases":"Aliase erstellen","Creation date":"Erstellungsdatum","Crypt passwords":"Passwörter verschlüsseln","Dashboard":"Dashboard","Date":"Datum","Day":"Tag","Default mailbox quota":"Standard Postfach Kontingent","Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Auf Postfächer angewendete Quota. Kann in KB, MB (Voreinstellung) oder GB angegeben werden. 0 eingeben, um keine Quota zu verwenden.","Description":"Beschreibung","Disable 2FA":"Deaktiviere 2-Faktor-Authentifizierung","Disabled":"Deaktiviert","DKIM key":"DKIM Schlüssel","DNS":"DNS","DNS status":"DNS Status","Domain":"Domain","Domain administrator":"Domain Administrator","Domain created":"Domain erstellt.","Domains":"Domains","Email address":"E-Mail Adresse","Enable 2FA":"Aktiviere 2FA","Enable DKIM signing":"Aktiviere DKIM Signierung","Enable DNS checks":"Aktiviere DNS Prüfungen","Enabled":"Aktiviert","Enter the code you've just received by SMS":"Gib den Code der per SMS zugestellt wurde","Expire at":"Läuft ab am","Failed":"Fehlgeschlagen","Forward":"Weiterleiten","Forward messages and store copies into your local mailbox":"Nachricht weiterleiten und Kopie in Mailbox ablegen","Forward updated":"Weiterleitung aktualisiert","From":"Von","Full name":"Vollständiger Name","General":"Allgemein","Identities":"Identitäten","Import":"Import","Import domains":"Domains importieren","Import identities":"Identitäten importieren","Information":"Information","Installed version":"Installierte Version","Keep local copies":"Lokale Kopien behalten","Last modification date":"Datum der letzten Änderung","Level":"Stufe","Logger":"Logger","Logout":"Logout","Mailbox":"Postfächer","Mailboxes":"Mailboxen","Message":"Verwendung","Modified":"Verändert","Month":"Monat","Name":"Name","New account":"Neues Konto","New alias":"Neuer Alias","New domain":"Neue Domain","New recovery codes":"Neue Wiederherstellungscodes","Next":"Weiter","Not generated":"Nicht generiert","One or more updates are available":"Eine oder mehrere Aktualisierungen sind verfügbar","Options":"Optionen","Partially aligned":"Teilweise zugeordnet","Password":"Passwort","Passwords mismatch":"Passwörter stimmen nicht überein","Phone number":"Telefonnummer","Pin code":"Pincode","Please fill-in your primary email address":"Bitte die Primäre Email-Adresse eingeben","Profile":"Profil","Profile updated":"Profil aktualisiert","Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators).":"Quota dieses Postfachs. Kann in KB, MB (Voreinstellung) oder GB angegeben werden. Eigenen Wert eingeben oder Voreinstellung der Domain verwenden lassen. Frei lassen, um Quota auf unlimitiert zu setzen (nur Super-Administratoren).","Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Von Postfächern gemeinsam genutzte Quota/Speicherplatz. Kann in KB, MB (Voreinstellung) oder GB angegeben werden. 0 eingeben, um keine Quota zu verwenden.","Random address":"Zufällige Adresse","Random password":"Zufälliges Passwort","Recipient(s)":"Empfänger","Recipients":"Empfänger","Register":"Registrieren","Remember me":"An mich erinnern","Reseller":"Reseller","Reset recovery codes":"Setze Wiederherstellungscodes zurück","Resources":"Ressourcen","Resources usage":"Ressourcen-Verbrauch","Role":"Rolle","Save":"Speichern","Search":"Suchen","Secondary email":"Zweite E-Mail Adresse","Security":"Sicherheit","Sender addresses":"Ab­sen­der­ad­res­sen ","Separator":"Separator","Settings":"Einstellungen","Show key":"Zeige Schlüssel","Simple user":"Normaler Benutzer","Status":"Status","Submit":"Abschicken","Summary":"Zusammenfassung","Super administrator":"Super-Administrator","Tags":"Tags","To":"Bis","Total":"Total","Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security.":"Zwei-Faktor-Authentifizierung (2FA) ist noch nicht für diesen Account aktiviert.\nAktiviere dieses Feature, um die Account-Sicherheit zu erhöhen.","Type":"Typ","Unknown":"Unbekannt","Unknown sources / Threats":"Unbekannte Quellen / Bedrohungen","unlimited":"unbegrenzt","Update":"Aktualisieren","Updated":"Aktualisieren","Use domain default value":"Standardwert der Domain verwenden","Username":"Benutzername","Week":"Woche","Welcome to Modoboa":"Willkommen zu Modoboa","With a mailbox":"Mit einem Postfach","Year":"Jahr"},"el":{},"br":{"Account":"Kont","Account created":"Kont krouet","Account updated":"Kont hizivaet","Actions":"Oberioù","Add":"Ouzhpennañ","Address":"Chomlec'h","Administered domains":"Domanioù meret","Administrators":"Merourien","Alias":"Alias","Aliases":"Aliasoù","API":"API","API access":"API moned","Authentication":"O vezañ anavezet","Bind/named format. Click to copy":"Stumm Ereet/anvet","Change password":"Cheñch ger-tremen","Check this option if passwords contained in your file are not crypted":"Kochit an dibarzh ma ne vez ket kriptet ar gerioù-tremen endalc'het en ho restr","Close":"Serriñ","Closed":"Serriñ","Confirmation":"Kadarnadur","Continue on error":"Kenderc'hel war ar fazi","Create a domain administrator":"Krouit ur merour domani","Create a mailbox for the administrator.":"Krouiñ ur voest-posteloù evit ar merour.","Create aliases":"Krouiñ aliasoù","Creation date":"Deiziad krouidigezh","Crypt passwords":"Kriptañ ar gerioù-tremen","Dashboard":"Taolenn-stur","Default mailbox quota":"Kota boest-posteloù dre-ziouer","Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"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.","Description":"Deskrivadur","Disabled":"Lazhet","DKIM key":"Alc'hwez DKIM","DNS":"DNS","DNS status":"Statud DNS","Domain":"Domani","Domain administrator":"Merour an domani","Domain created":"Domani krouet","Domains":"Domanioù","Email address":"Chomlec'h postel","Enable DKIM signing":"Enaouiñ ar sinadur DKIM","Enable DNS checks":"Enaouiñ ar gwiriañ DNS","Enabled":"Enaouet","Expire at":"Diamzeriet da","Failed":"C'hwitet","Forward":"Treuzkas","Forward messages and store copies into your local mailbox":"Treuzkas kemennadennoù ha stokiñ eiladennoù e-barzh ar voest-posteloù lec'hel","Forward updated":"Treuzkas hizivaet","Full name":"Anv klok","General":"Hollek","Identities":"Identelezhioù","Import":"Emporzhiañ","Import domains":"Emporzhiañ domanioù","Import identities":"Emporzhiañ identelezhioù","Information":"Titouroù","Installed version":"Stumm staliet","Keep local copies":"Mirout eiladennoù lec'hel","Last modification date":"Deiziad aozañ diwezhañ","Level":"Live","Logger":"Enroller","Logout":"Digevreañ","Mailbox":"Boest-posteloù","Mailboxes":"Boest-posteloù","Message":"Implij","Modified":"Aozet","Name":"Anv","New account":"Kont nevez","New alias":"Alias nevez","New domain":"Domani nevez","Next":"Da-heul","Not generated":"Neket ganet","One or more updates are available":"Hegerz ez eus un hizivadenn pe muioc'h","Options":"Dibarzhioù","Partially aligned":"Linennet dre an hanter","Password":"Ger-tremen","Passwords mismatch":"Disklotadurioù gerioù-tremen","Phone number":"Niverenn bellgomz","Profile":"Profil","Profile updated":"Profil hizivaet","Quota":"Kota","Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators).":"Kota evit ar voest-posteloù-mañ. Gellout a ra bezañ ezpleget e Ko, Mo (diouer) pe Go c'hoazh. Termeniñ un dalvoudegezh ispisial pe implijit talvoudegezh an domani. Laoskit goullo evit termeniñ un dalvoudegezh divevenn (berzet evit ar verourien zomani).","Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Kota rannet kenetre ar boestoù-postel. Gellout a ra bezañ ezpleget e Ko, Mo (diouer) pe Go c'hoazh. Un dalvoudegezh \"0\" a dalvez kota ebet.","Random address":"Chomlec'h dre-zegouezh","Random password":"Ger-tremen dre-zegouezh","Recipient(s)":"Resever(ien)","Recipients":"Reseverien","Remember me":"Derc'hel soñj ac'hanon","Reseller":"Eilgwerzher","Resources":"Mammennoù","Resources usage":"Implij mammennoù","Role":"Rol","Save":"Enrollañ","Search":"Klask","Secondary email":"Eil chomlec'h postel","Sender addresses":"Chomlec'hioù ar c'haser","Separator":"Skejer","Settings":"Arventennoù","Show key":"Diskouez an alc'hwez","Simple user":"Implijer diazez","Status":"Statud","Submit":"Kas","Summary":"Berradenn","Super administrator":"Dreist-merour","Tags":"Balizoù","Total":"Hollad","Transport":"Treuzdougen","Type":"Doare","Unknown":"Dizanv","Unknown sources / Threats":"Mammennoù dizanv/Gourdrouzioù","unlimited":"divevennet","Update":"Hizivaat","Updated":"Hizivaet","Use domain default value":"Implijout un dalvoudegezh domani dre-ziouer","Username":"Anv implier","Welcome to Modoboa":"Degemer mat e-barzh Modoboa","With a mailbox":"Gant ur voest-posteloù"},"cs":{},"es":{"Account":"Cuenta","Account created":"Cuenta creada","Account updated":"Cuenta actualizada","Actions":"Acciones","Add":"Añadir","Address":"Dirección","Administered domains":"Dominios administrados","Administrators":"Administradores","Alias":"Alias","Aliases":"Alias","API":"API","API access":"Acceso API","Apply":"Aplicar","Authentication":"Autenticación","Bind/named format. Click to copy":"Formato inválido","Change password":"Cambiar contraseña","Check this option if passwords contained in your file are not crypted":"Marque esta opción si las contraseñas que contiene su fichero no están cifradas","Confirmation":"Confirmación","Continue on error":"Continúe en error.","Create a domain administrator":"Crear un administrador del dominio","Create a mailbox for the administrator.":"Crear mailbox para el administrador.","Create aliases":"Crear alias","Creation date":"Fecha de creación","Crypt passwords":"Contraseñas cifradas","Dashboard":"Panel de Control","Day":"Día","Default mailbox quota":"Cuota de mailbox por defecto","Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Cuota de mailbox predeterminda en MB. Un valor de 0 significa ningún limite.","Description":"Descripción","Disabled":"Deshabilitado","DNS status":"Estado de DNS","Domain":"Dominio","Domain administrator":"Administrador del dominio","Domain created":"Dominio creado","Domains":"Dominios","Email address":"Dirección de email","Enable DNS checks":"Activar comprobación de DNS","Enabled":"Activado","Expire at":"Caduca en","Forward":"Siguiente","Forward messages and store copies into your local mailbox":"Reenvía mensajes y guarda copias en su mailbox local","Forward updated":"Reenvío actualizado","Full name":"Nombre completo","General":"General","Identities":"Identidades","Import":"Importar","Import domains":"Importar dominios","Import identities":"Importar identidades","Information":"Información","Installed version":"Versión instalada","Keep local copies":"Mantener copias locales","Last modification date":"Última fecha de modificación","Level":"Nivel","Logger":"Logger","Logout":"Salir","Mailbox":"Mailboxes","Mailboxes":"Mailboxes","Message":"Uso","Modified":"Modificado","Month":"Mes","Name":"Nombre","New account":"Nueva cuenta","New alias":"Nuevo alias","New domain":"Nuevo dominio","Next":"Siguiente","Not generated":"Sin definir","One or more updates are available":"Una o más actualizaciones están disponibles","Options":"Opciones","Password":"Contraseña","Passwords mismatch":"Las contraseñas no coinciden","Phone number":"Numero de telefono ","Profile updated":"Perfil actualizado","Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators).":"Cuota en MB para este mailbox. Defina un valor por defecto o use el del dominio por defecto. Déjelo vacío para definir un valor ilimitado (no permitido para los administradores del dominio)","Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Cuota de mailbox predeterminda en MB. Un valor de 0 significa ningún limite.","Random address":"Dirección aleatoria","Random password":"Dirección aleatoria","Recipient(s)":"Destinatario(s)","Recipients":"Destinatarios","Remember me":"Recuerdame","Reseller":"Revendedor","Resources":"Recursos","Resources usage":"Uso de recursos","Role":"Rol","Save":"Guardar","Search":"Buscar","Secondary email":"Email secundario","Sender addresses":"Direcciónes de remitente","Separator":"Separador","Settings":"Configuración","Simple user":"Usuario normal","Status":"Estatus","Submit":"Enviar","Summary":"Resumen","Super administrator":"Super administrador","Tags":"Tags","Type":"Tipo","Unknown":"Desconocido","unlimited":"ilimitado","Update":"Actualizar","Updated":"Actualizado","Use domain default value":"Usar el valor por defecto del dominio","Username":"Nombre de usuario","Week":"Semana","Welcome to Modoboa":"Bienvenido a Modoboa","With a mailbox":"Con una mailbox","Year":"Año"},"fi":{"A documentation of the API is available":"API:n dokumentaatio on saatavilla","A new key will be generated soon. Refresh the page in a moment to see it.":"Uusi avain luodaan pian. Päivitä sivu hetken kuluttua nähdäksesi sen.","A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features.":"Käyttäjä, jolla on kaikki oikeudet, voi tehdä mitä tahansa. Oletusarvoisesti tällaisella käyttäjällä ei ole postilaatikkoa, joten hän ei voi käyttää loppukäyttäjän ominaisuuksia.","A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters.":"Käyttäjä, jolla ei ole oikeuksia mutta jolla on postilaatikko. Hän saa käyttää kaikkia loppukäyttäjän ominaisuuksia: webmail, kalenteri, yhteystiedot, suodattimet.","A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox.":"Käyttäjä, jolla on oikeuksia yhdessä tai useammassa verkkotunnuksessa. Hänellä on oikeus hallinnoida postilaatikoita ja hänellä voi myös olla postilaatikko.","Absolute time range":"Määrämittainen aikaraja","Account":"Tili","Account created":"Tili luotu","Account updated":"Tili päivitetty","Actions":"Toiminnot","Add":"Lisää","Add a new domain alias":"Lisää uusi verkkotunnuksen alias","Add administrator":"Lisää järjestelmänvalvoja","Add sender address":"Lisää lähettäjän osoite","Address":"Osoite","Administered domains":"Hallinnoidut verkkotunnukset","Administrator added":"Järjestelmänvalvoja lisäsi","Administrator name":"Järjestelmänvalvojan nimi","Administrator removed":"Järjestelmänvalvoja poistettu","Administrators":"Ylläpitäjät","Alarms":"Hälytykset","Alias":"Alias","Alias updated":"Alias päivitetty","Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld).":"Tämän postilaatikon alias-nimet. Jos haluat luoda catchall-aliaksen, kirjoita vain verkkotunnus (@domain.tld).","Aliases":"Aliakset","API":"API","API access":"API-pääsy","API token copied to your clipboard":"API-tunniste kopioitu leikepöydälle","API token created":"API-tunniste luotu","API token deleted":"API-tunniste poistettu","Apply":"Käytä","Audit trail":"Tarkastusketju","Authentication":"Tunnistautuminen","Auto configuration":"Automaattinen asetusten määrittäminen","autoconfig record (Mozilla) not found":"autoconfig-tallennetta (Mozilla) ei löydy","autoconfig record (Mozilla): %{ value }":"autoconfig-tietue (Mozilla): %{ value }","autodiscover record (Microsoft) not found":"autodiscover-tietuetta (Microsoft) ei löydy","autodiscover record (Microsoft): %{ value }":"autodiscover-tietue (Microsoft): %{ value }","Back":"Takaisin","Bind/named format. Click to copy":"Bind/nimetty muoto. Kopioi klikkaamalla","Cancel":"Peruuta","Check this option if passwords contained in your file are not crypted":"Valitse tämä vaihtoehto, jos tiedostosi sisältämiä salasanoja ei ole salakirjoitettu","Choose a domain":"Valitse verkkotunnus","Choose a role":"Valitse käyttäjätyyppisi","Close":"Sulje","Confirm and create":"Vahvista ja luo","Confirmation":"Vahvistus","Congratulations! Two-Factor Authentication is now enabled for your account.":"Onnittelut! Kaksivaiheinen tunnistus on nyt käytössä tililläsi.","Connect":"Yhdistä","Continue on error":"Jatka virheestä","Control if this domain will be allowed to send and receive messages":"Määritä, saako tämä verkkotunnus lähettää ja vastaanottaa viestejä","Copy to clipboard":"Kopioi leikepöydälle","Copy token to clipboard":"Kopioi turvatunnus leikepöydälle","Create a domain administrator":"Luo verkkotunnuksen ylläpitäjä","Create a mailbox for the administrator.":"Luo ylläpitäjän postilaatikko.","Create aliases":"Luo aliaksia","Create standard aliases for the domain.":"Luo verkkotunnuksen tavanomaiset aliakset.","Creation date":"Luontipäivä","Crypt passwords":"Salakirjoita salasanat","Current password":"Nykyinen salasana","Daily message sending limit":"Päivittäinen viestien lähetysraja","Daily sending limit":"Päivittäinen lähetysraja","Dashboard":"Työpöytä","Date":"Päivämäärä","Day":"Päivä","Default mailbox quota":"Oletuspostilaatikkokiintiö","Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Postilaatikoihin sovellettava oletuskiintiö. Voidaan ilmaista kilotavuina, megatavuina (oletus) tai gigatavuina. Arvo 0 tarkoittaa, ettei kiintiötä ole.","Delete":"Poista","Delete token":"Poista avain","Description":"Kuvaus","Disable 2FA":"Poista kaksivaiheinen tunnistautuminen (2FA) käytöstä","Disabled":"Pois käytöstä","DKIM key":"DKIM-avain","DKIM key length":"DKIM-avaimen pituus","DKIM key selector":"DKIM-avaimen valitsin-tietue","DKIM keys already exist for this domain. Do you want to overwrite them?":"DKIM-avaimet ovat jo olemassa tälle verkkotunnukselle. Haluatko korvata ne?","DKIM public key for":"DKIM julkinen avain tietueelle","DKIM record found":"DKIM-tietue löydetty","DKIM record not found":"DKIM-tietuetta ei löydy","DKIM signing":"DKIM-allekirjoitus","DMARC record found":"DMARC-tietue löydetty","DMARC record not found":"DMARC-tietuetta ei löydy","DNS":"DNS","DNS checks":"DNS-tarkistukset","DNS configuration help":"DNS-määritysapu","DNS status":"DNS-tila","Do not delete account folder":"Älä poista tilikansiota","Do not delete domain folder":"Älä poista verkkotunnuksen kansiota","Domain":"Verkkotunnus","Domain administrator":"Luo verkkotunnuksen ylläpitäjä","Domain alias created":"Verkkotunnuksen alias luotu","Domain alias deleted":"Verkkotunnuksen alias poistettu","Domain alias updated":"Verkkotunnuksen alias päivitetty","Domain created":"Verkkotunnus luotu","Domain default value":"Verkkotunnuksen oletusarvo","Domain name (ex: domain.tld)":"Verkkotunnus (esim. domain.tld)","Domain updated":"Verkkotunnus päivitetty","domain's default value":"verkkotunnuksen oletusarvo","Domains":"Sinulla ei ole oikeutta tuoda verkkotunnuksia","Don't treat duplicated objects as errors":"Älä käsittele päällekkäisiä objekteja virheinä","Edit":"Muokkaa","Edit account":"Muokkaa tiliä","Edit alias":"Muokkaa aliasta","Edit domain":"Muokkaa verkkotunnusta","Edit domain alias":"Muokkaa verkkotunnusta","Email":"Sähköposti","Email address":"Sähköpostiosoite","Empty":"Tyhjä","Enable 2FA":"Ota käyttöön kaksivaiheinen tunnistus (2FA)","Enable DKIM signing":"Ota DKIM-allekirjoitus käyttöön","Enable DNS checks":"Ota DNS-tarkistukset käyttöön","Enabled":"Käytössä","Enter a simple username or an email address":"Anna yksinkertainen käyttäjätunnus tai sähköpostiosoite","Enter an email address":"Syötä oikean muotoinen sähköpostiosoite","Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes.":"Syötä koodi mobiililaitteesi kaksivaiheisen tunnistuksen sovelluksesta. Jos olet hukannut laitteesi, voit syöttää yhden palautuskoodeistasi.","Enter the code you've just received by SMS":"Kirjoita tekstiviestillä saamasi koodi","Ex: 10MB. Leave empty for no limit":"Esim: 10 MB. Jätä tyhjäksi, jos et halua rajoitusta","Expire at":"Vanhenee","Export accounts and aliases to CSV":"Vie tilit ja aliakset CSV-tiedostoon","Export domains and aliases to CSV":"Vie verkkotunnukset ja aliakset CSV-tiedostoon","First name":"Etunimi","Forward":"Välitä","Forward messages and store copies into your local mailbox":"Välitä viestit ja tallenna kopiot paikalliseen postilaatikkoon","Forward updated":"Välitystieto päivitetty","From":"Lähde","Full name":"Koko nimi","Fullname/recipient":"Koko nimi/saaja","General":"Yleiset","General information":"Yleiset tiedot","General settings":"Yleiset asetukset","Generate":"Luo","Generate a new DKIM key":"Luo uusi DKIM-avain","help":"ohje","Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones.":"Tässä on esimerkki DNS-määrityksistä (bind-muodossa). Korvaa [ ]:n välissä olevat arvot sopivilla arvoilla.","Identification":"Tunniste","Identities":"Identiteetit","If you close this form now, your modifications won't be saved. Do you confirm?":"Jos suljet tämän lomakkeen nyt, muutokset eivät tallennu. Vahvistatko?","Import":"Tuonti","Import accounts and aliases from CSV file":"Tuo tilejä ja aliaksia CSV-tiedostosta","Import domains":"Tuo verkkotunnuksia","Import domains and aliases from CSV file":"Tuo verkkotunnukset ja aliakset CSV-tiedostosta","Import identities":"Tuo identiteetit","Indicate one or more recipients separated by a comma (,)":"Ilmoita yksi tai useampi vastaanottaja pilkulla (,) erotettuna","Installed version":"Asennettu versio","Invalid password":"Virheellinen salasana","Invalid username and/or password":"Virheellinen käyttäjätunnus ja/tai salasana","Keep local copies":"Säilytä paikallisia kopioita","Language":"Kieli","Last login date":"Viimeisin kirjautumispäivä","Last modification date":"Viimeisin muutospäivä","Last name":"Sukunimi","Leave empty for no limit":"Jätä tyhjäksi, jos rajaa ei ole","Level":"Taso","Limitations":"Rajoitukset","Logger":"Lokikirja","Logout":"Kirjaudu ulos","Mailbox":"Postilaatikko","Mailboxes":"Postilaatikot","Message":"Viesti","Message history":"Viestien historia","Message sending limit":"Viestien lähetysraja","messages":"viestit","Messages":"Viestit","Modified":"Muokattu","Modify":"Muokkaa","Month":"Kuukausi","MX records":"MX-tietueet","Name":"Nimi","Name of the administrator":"Ylläpitäjän nimi","Never logged-in":"Ei koskaan kirjautunut sisään","New":"Uusi","New account":"Uusi tili","New alias":"Uusi alias","New domain":"Uusi verkkotunnus","New recovery codes":"Uudet palautuskoodit","Next":"Seuraava","no":"ei","No":"Ei","No sender address defined for this account":"Tälle tilille ei ole määritelty lähettäjän osoitetta","No sending limit":"Ei lähetysrajaa","Not generated":"Ei luotu","Number of messages this domain can send per day. Leave empty for no limit.":"Viestien määrä, jonka tämä verkkotunnus voi lähettää päivässä. Jätä tyhjäksi, jos et halua rajoitusta.","Number of messages this mailbox can send per day. Leave empty for no limit.":"Viestien määrä, jonka tämä postilaatikko voi lähettää päivässä. Jätä tyhjäksi, jos et halua rajoitusta.","OK":"OK","One or more updates are available":"Yksi tai useampi päivitys on saatavilla","Opened alarms":"Avatut hälytykset","Options":"Vaihtoehdot","Parameters updated":"Parametrit päivitetty","Password":"Salasana","Password copied to clipboard":"Salasana kopioitu leikepöydälle","Password updated":"Salasana päivitetty","Passwords mismatch":"Salasanat eivät täsmää","Pending":"Odottaa","Period":"Jakso","Phone number":"Puhelinnumero","Pin code":"Pin-koodi","Please fill-in your primary email address":"Täytä ensisijainen sähköpostiosoitteesi","Problem":"Ongelma","Proceed":"Jatka","Profile":"Profiili","Profile updated":"Profiili päivitetty","Provide a CSV file where lines respect one of the following formats:":"Toimita CSV-tiedosto, jonka rivit ovat jossakin seuraavista muodoista:","Queue ID":"Jonon ID","Quota":"Verkkotunnuksen oletuskiintiö","Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators).":"Tämän postilaatikon kiintiö, joka voidaan ilmaista kilotavuina, megatavuina (oletus) tai gigatavuina. Määritä oma arvo tai käytä toimialueen oletusarvoa. Jätä tyhjäksi, jos haluat määrittää rajoittamattoman arvon (ei sallittu toimialueen ylläpitäjille).","Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Postilaatikoiden kesken jaettu kiintiö. Voidaan ilmaista kilotavuina (KB), megatavuina (MB) (oletus) tai gigatavuina (GB). Arvo 0 tarkoittaa, ettei kiintiötä ole.","Random address":"Satunnainen osoite","Random password":"Satunnainen salasana","Raw format. Click to copy":"Raakamuoto. Kopioi napsauttamalla","Recipient(s)":"Vastaanottaja(t)","Recipients":"Vastaanottajat","Register":"Rekisteröidy","Relative time ranges":"Suhteelliset aikavälialueet","Relay":"Välitysrele","Remember me":"Muista minut","Remove this address":"Poista tämä osoite","Remove this administrator":"Poista tämä ylläpitäjä","Reseller":"Jälleenmyyjä","Resources":"Resurssit","Resources usage":"Resurssien käyttö","Role":"Rooli","Save":"Tallenna","Search":"Hae","Secondary email":"Toissijainen sähköpostiosoite","Security":"Turvallisuus","Select an account":"Valitse tili","Select file":"Valitse tiedosto","Sender addresses":"Lähettäjän osoitteet","Sending limit":"Lähetysraja","Separator":"Erotin","Service":"Palvelu","Settings":"Asetukset","Show key":"Näytä avain","Simple user":"Yksinkertainen käyttäjä","Specify an email address":"Määritä sähköpostiosoite","SPF record found":"SPF-tietue löydetty","SPF record not found":"SPF-tietuetta ei löydy","Start typing a name here...":"Aloita nimen kirjoittaminen tästä...","Status":"Tila","Submit":"Lähetä","Summary":"Yhteenveto","Super administrator":"Pääylläpitäjä","Tags":"Tunnisteet","The first element of each line is mandatory and must be equal to one of the previous values.":"Kunkin rivin ensimmäinen elementti on pakollinen, ja sen on oltava yhtä suuri kuin jokin edellisistä arvoista.","This page is still under construction.":"Tämä sivu on vielä rakenteilla.","To":"Vastaanottaja","Transport":"Siirto","Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security.":"Kaksivaiheista tunnistusta (2FA) ei ole vielä aktivoitu tilillesi. Tämän ominaisuuden käyttöönotto lisää tilisi turvallisuutta.","Type":"Tyyppi","Unknown":"Tuntematon","unlimited":"rajoittamaton","Update":"Päivitä","Update Password":"Vaihda salasana","Update settings":"Päivitä asetukset","Updated":"Päivitetty","Use domain default value":"Käytä verkkotunnuksen oletusarvoa","Username":"Käyttäjätunnus","Username:":"Käyttäjätunnus:","Valid":"Kelvollinen","Verify code":"Tarkista koodi","Warning":"Varoitus","Week":"Viikko","Welcome to Modoboa":"Tervetuloa Modoboaan","With a mailbox":"Postilaatikolla","With mailbox":"Postilaatikolla","Year":"Vuosi","yes":"kyllä","Yes":"Kyllä","You are about to delete your API access token":"Olet poistamassa API-pääsytunnistetta","You can use a different character as separator.":"Voit käyttää erottimena eri merkkiä.","Your API token has not been generated yet.":"API-pääsytunnistetta ei ole vielä luotu.","Your API token is:":"API-pääsytunnisteesi on:"},"it":{"Account":"Account","Account created":"Account creato","Account updated":"Account aggiornato","Actions":"Azioni","Add":"Aggiungi","Address":"Indirizzo","Administered domains":"Domini amministrati","Administrators":"Amministratori","Alias":"Alias","Aliases":"Alias","API":"API","API access":"Accesso API","Apply":"Applica","Authentication":"Autenticazione","Bind/named format. Click to copy":"Formato bind/named","Change password":"Cambia password","Check this option if passwords contained in your file are not crypted":"Seleziona questa opzione se le password contenute nel file non sono criptate","Close":"Chiudi","Closed":"Chiudi","Confirmation":"Conferma","Continue on error":"Continuare in caso di errore","Create a domain administrator":"Crea un amministratore di dominio","Create a mailbox for the administrator.":"Crea una casella di posta per l'amministratore.","Create aliases":"Crea alias","Creation date":"Data di creazione","Crypt passwords":"Cripta le password","Day":"Giorno","Default mailbox quota":"Dimensione massima predefinita per le mailbox","Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Valore predefinito per lo spazio massimo confiviso tra le mailbox. Può essere espresso in KB, MB (predefinito) o GB. Il valore 0 indica nessun limite.","Description":"Descrizione","Disabled":"Disabilitato","DKIM key":"Chiave DKIM","DNS":"DNS","DNS status":"Stato del DNS","Domain":"Dominio","Domain administrator":"Amministratore di dominio","Domain created":"Dominio creato","Domains":"Domini","Email address":"Indirizzo email","Enable DKIM signing":"Abilita la firma DKIM","Enable DNS checks":"Abilita i controlli DNS","Enabled":"Abilitato","Expire at":"Scade il","Failed":"Fallito","Forward":"Inoltra","Forward messages and store copies into your local mailbox":"Inoltra i messaggi e memorizza le copie nella tua casella di posta locale","Forward updated":"Inoltro aggiornato","Full name":"Nome completo","General":"Generale","Identities":"Identità","Import":"Importa","Import domains":"Importa domini","Import identities":"Identità di importazione","Information":"Informazioni","Installed version":"Versione installata","Keep local copies":"Mantieni copie locali","Last modification date":"Data dell'ultima modifica","Level":"Livello","Logger":"Logger","Logout":"Esci","Mailbox":"Caselle di posta","Mailboxes":"Caselle di posta","Message":"Utilizzo","Modified":"Modificato","Month":"Mese","Name":"Nome","New account":"Nuovo account","New alias":"Nuovo alias","New domain":"Nuovo dominio","Next":"Successivo","Not generated":"Non generata","One or more updates are available":"Sono disponibili nuovi aggiornamenti","Options":"Opzioni","Partially aligned":"Parzialmente allineato","Password":"Password","Passwords mismatch":"Le password non corrispondono","Phone number":"Numero di telefono","Profile":"Profilo","Profile updated":"Profilo aggiornato","Quota":"Dimensione massima","Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators).":"Dimensione massima per questa mailbox, può essere espressa in KB, MB (predefinito) o GB. Definire un valore personalizzato o utilizzare quello predefinito per il dominio. Lasciare vuoto per specificare un valore non limitato (non permesso per amministratori di dominio).","Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Spazio massimo confiviso tra le mailbox. Può essere espresso in KB, MB (predefinito) o GB. Il valore 0 indica nessun limite.","Random address":"Indirizzo casuale","Random password":"Password casuale","Recipient(s)":"Destinatario(i)","Recipients":"Destinatari","Remember me":"Ricordami","Reseller":"Rivenditore","Resources":"Risorse","Resources usage":"Utilizzo risorse","Role":"Ruolo","Save":"Salva","Search":"Ricerca","Secondary email":"Email secondaria","Sender addresses":"Indirizzi mittenti","Separator":"Separatore","Settings":"Impostazioni","Show key":"Visualizza chiave","Simple user":"Utente semplice","Status":"Stato","Submit":"Invia","Summary":"Sommario","Super administrator":"Super amministratore","Tags":"Tag","Total":"Totale","Transport":"Trasporto","Type":"Tipo","Unknown":"Sconosciuto","Unknown sources / Threats":"Fonti sconosciute / Minaccie","unlimited":"senza limiti","Update":"Aggiorna","Updated":"Aggiornato","Use domain default value":"Usa il valore predefinito","Username":"Nome utente","Week":"Settimana","Welcome to Modoboa":"Benvenuti in Modoboa","With a mailbox":"Con una casella di posta","Year":"Anno"},"fr":{"A documentation of the API is available":"Une documentation de l'API est disponible","A new key will be generated soon. Refresh the page in a moment to see it.":"Une nouvelle clé sera générée bientôt. Actualisez dans un moment la page pour la voir.","A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features.":"Un utilisateur ayant tous les privilège, peut tout faire. Par défaut, il n'a pas de boîte mail et ne peut donc pas accéder aux fonctionnalités d'un utilisateur final.","A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters.":"Un utilisateur sans privilèges mais ayant une boîte mail. Il sera autorisé à utiliser toutes les fonctionnalités de l'utilisateur final : webmail, calendrier, contacts, filtres.","A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox.":"Un utilisateur avec des privilèges sur un ou plusieurs domaines. Il sera autorisé à administrer les boîtes mail et il peut avoir aussi une boîte aux lettres.","Absolute time range":"Plage de temps absolue","Account":"Compte","Account created":"Compte créé","Account updated":"Compte mis à jour","Actions":"Actions","Add":"Ajouter","Add a new domain alias":"Ajouter un nouvel alias de domaine","Add administrator":"Ajouter un administrateur","Add sender address":"Ajouter l'adresse de l'expéditeur","Address":"Adresse","Address (hostname or IP)":"Adresse (nom d'hôte ou IP)","Administered domains":"Domaines administrés","Administrator added":"L'administrateur a ajouté","Administrator name":"Nom de l'administrateur","Administrator removed":"Administrateur supprimé","Administrators":"Administrateurs","Alarm closed":"Alarme fermée","Alarm deleted":"Alarme supprimée","Alarm re-opened":"Alarme ré-ouverte","Alarms":"Alarmes","Alarms deleted":"Alarmes supprimées","Alias":"Alias","Alias updated":"Alias mis à jour","Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld).":"Alias(s) de cette boîte aux lettres. Pour créer un alias fourre-tout, entrer uniquement le nom du domaine (@domain.tld).","Aliases":"Alias","Alignment":"Alignement","API":"API","API access":"Accès API","API token copied to your clipboard":"Jeton API copié dans votre presse-papier","API token created":"Jeton API créé","API token deleted":"Jeton API supprimé","Apply":"Appliquer","Associated domains":"Domaines associés","Audit trail":"Journal des modifications","Authentication":"Authentification","Auto configuration":"Configuration automatique","autoconfig record (Mozilla) not found":"Enregistrement autoconfig (Mozilla) introuvable","autoconfig record (Mozilla): %{ value }":"Enregistrement autoconfig (Mozilla) : %{ value }","autodiscover record (Microsoft) not found":"Enregistrement autodiscover (Microsoft) non trouvé","autodiscover record (Microsoft): %{ value }":"Enregistrement autodiscover (Microsoft): %{ value }","Back":"Retour","Bind/named format. Click to copy":"Format bind/named. Cliquez pour copier","Cancel":"Annuler","Change password":"Modifier le mot de passe","Check connection:":"Vérifier la connexion :","Check out the following list to find related components":"Consulter la liste suivante pour trouver des composants associés","Check this option if passwords contained in your file are not crypted":"Cochez cette option si les mots de passe contenus dans votre fichier ne sont pas chiffrés","Choose a domain":"Choisissez un domaine","Choose a role":"Choisissez un rôle","Close":"Fermer","Close alarm":"Fermer l'alarme","Closed":"Fermé","Confirm and create":"Confirmer et créer","Confirmation":"Confirmation","Congratulations! Two-Factor Authentication is now enabled for your account.":"Félicitations ! l'authentification à double facteur est maintenant activée sur votre compte","Connect":"Connexion","Continue on error":"Continuer en cas d'erreur","Control if this domain will be allowed to send and receive messages":"Contrôler si ce domaine sera autorisé à envoyer et recevoir des messages.","Copy to clipboard":"Copier dans le presse-papiers","Copy token to clipboard":"Copier le jeton dans la presse-papiers","Create a domain administrator":"Créer un administrateur de domaine","Create a mailbox for the administrator.":"Créer une boite aux lettres pour l'administrateur","Create aliases":"Créer des alias","Create standard aliases for the domain.":"Créer des aliases standard pour le domaine","Creation date":"Date de création","Crypt passwords":"Chiffrer les mots de passe","Current password":"Mot de passe actuel","Daily message sending limit":"Limite quotidienne d'envoi de messages","Daily sending limit":"Limite d'envoi quotidienne","Dashboard":"Tableau de bord","Date":"Date","Day":"Jour","Default mailbox quota":"Quota par défaut pour une boîte aux lettres","Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"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.","Delete":"Supprimer","Delete token":"Supprimer le jeton","Description":"Description","Detail":"Détail","Disable 2FA":"Désactiver l'authentification à double facteur","Disabled":"Désactivés","DKIM key":"Clé DKIM","DKIM key length":"Longeur de clé DKIM","DKIM key selector":"Sélecteur de clé DKIM","DKIM keys already exist for this domain. Do you want to overwrite them?":"Des clés DKIM existent déjà pour ce domaine. Voulez-vous les écraser?","DKIM public key for":"Clé publique DKIM pour ","DKIM record found":"Enregistrement DKIM trouvé","DKIM record not found":"Enregistrement DKIM introuvable","DKIM signing":"Signature DKIM","DMARC":"DMARC","DMARC record found":"Enregistrement DMARC trouvé","DMARC record not found":"Enregistrement DMARC introuvable","DMARC support does not seem to be enabled for this domain.":"La support DMARC ne semble pas actif pour ce domaine.","DNS":"DNS","DNS checks":"Vérifications DNS","DNS configuration help":"Aide à la configuration du DNS","DNS status":"Statut DNS","Do not delete account folder":"Ne pas supprimer le dossier du compte","Do not delete domain folder":"Ne pas supprimer le dossier des domaines","Domain":"Domaine","Domain administrator":"Administrateur de domaine","Domain alias created":"Alias de domaine créé","Domain alias deleted":"Alias de domaine supprimé","Domain alias updated":"Alias de domaine mise à jour","Domain created":"Domaine créé","Domain default value":"Valeur du domaine par défaut","Domain deleted":"Supprimer le domaine","Domain name (ex: domain.tld)":"Nom de domaine (ex: domaine.tld)","Domain updated":"Domaine mise à jour","domain's default value":"La valeur par défaut du domaine","Domains":"Domaines","Don't treat duplicated objects as errors":"Ne pas traiter les objets dupliqués comme des erreurs","Edit":"Modifier","Edit account":"Modifier le compte","Edit alias":"Modifier l'alias","Edit domain":"Modifier le domaine","Edit domain alias":"Modifier l'alias de domaine","Edit provider":"Modifier le fournisseur","Email":"E-mail","Email address":"Adresse email","Email providers":"Fournisseurs de messagerie","Empty":"Vide","Enable 2FA":"Activer 2FA","Enable DKIM signing":"Activer la signature DKIM","Enable DNS checks":"Activer les tests DNS","Enabled":"Activé","Enter a simple username or an email address":"Entrer un nom d'utilisateur simple ou une adresse e-mail","Enter an email address":"Entrer une adresse e-mail","Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes.":"Entrez le code de l'application à double facteur sur votre téléphone mobile. Si vous avez perdu votre appareil, vous pouvez entrez l'un de vos code de récupération.","Enter the code you've just received by SMS":"Entrez le code que vous venez de recevoir par SMS","Error":"Erreur","Ex: 10MB. Leave empty for no limit":"Ex: 10MB. Laisser vide pour aucune limite","Expire at":"Expire le","Export accounts and aliases to CSV":"Exporter les comptes et les alias au format CSV","Export domains and aliases to CSV":"Exporter les domaines et les alias au format CSV","Failed":"Échoué","First name":"Prénom","Forward":"Transfert","Forward messages and store copies into your local mailbox":"Transférer les messages et stocker des copies dans votre boîte aux lettres locale","Forward updated":"Transfert mise à jour","Forwarded":"Transféré","Forwarders with ARC":"Transporteur avec ARC","From":"De","Full name":"Nom complet","Fullname/recipient":"Nom complet / destinataire","Fully aligned":"Entièrement aligné","General":"Général","General information":"Information générale","General settings":"Paramètres généraux ","Generate":"Générer","Generate a new DKIM key":"Générer une nouvelle clé DKIM","help":"aide","Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones.":"Voici un exemplaire de configuration DNS (format bind). Remplacer les valeurs entre [ ] par les valeurs appropriées.","Identification":"Identification","Identities":"Identités","If you close this form now, your modifications won't be saved. Do you confirm?":"Si vous fermez ce formulaire maintenant, vos modifications ne seront pas sauvegardées. Confirmez-vous ?","If you configured it recently, please wait for the first report to be received and processed.":"Si vous l'avez récemment configuré, veuillez attendre que le premier rapport soit reçu et traité. ","IMAP Migration":"Migration IMAP","IMAP Port":"Port IMAP","Import":"Importer","Import accounts and aliases from CSV file":"Importation de comptes et alias à partir d'un fichier CSV","Import domains":"Importer des domaines","Import domains and aliases from CSV file":"Importation de domaines et alias à partir d'un fichier CSV","Import identities":"Importer des identités","Indicate one or more recipients separated by a comma (,)":"Indiquer un ou plusieurs destinataires séparés par une virgule (,) ","Information":"Information","Installed components":"Composants installés","Installed version":"Version installée","Invalid password":"Mot de passe incorrect","Invalid reset token.":"Jeton de réinitialisation incorrect.","Invalid username and/or password":"Nom d'utilisateur et/ou mot de passe incorrect","Is the IMAP connection secured using SSL/TLS or StartTLS":"La connexion IMAP est-elle sécurisée via l'utilisation de SSL/TLS ou StartTLS","Keep local copies":"Conserver des copies locales","Language":"Langage","Last login date":"Date de dernière connexion","Last modification date":"Date de dernière modification","Last name":"Nom de famille","Latest version":"Dernière version","Leave empty for no limit":"Laisser vide pour aucune limite","Level":"Niveau","Limitations":"Limites","Local domain (optional)":"Domaine local (optionnel)","Logger":"Logger","Logout":"Déconnexion","Mailbox":"Boîte aux lettres","Mailboxes":"Boîtes aux lettres","Message":"Message","Message history":"Historique des messages","Message sending limit":"Limite d'envoi des messages","messages":"messages","Messages":"Messages","Migration deleted":"Migration supprimée","Migrations":"Migrations","Modified":"Modifié","Modify":"Modifier","Month":"Mois","MX records":"Enregistrements MX","Name":"Nom","Name of the administrator":"Nom de l'administrateur","Name of the domain to migrate":"Nom du domaine à migrer","Never logged-in":"Jamais connecté","New":"Nouvelle","New account":"Nouveau compte","New alias":"Nouvel alias","New domain":"Nouveau domaine","New provider":"Nouveau fournisseur","New recovery codes":"Nouveaux codes de récupération","Next":"Suivant","no":"non","No":"Non","No associated domains":"Aucun domaine associé","No sender address defined for this account":"Aucune adresse d'expéditeur définie pour ce compte","No sending limit":"Pas de limite d'envoi","Not generated":"Non générée","Number of associated domains:":"Nombre de domaines associés :","Number of messages this domain can send per day. Leave empty for no limit.":"Nombre de messages que ce domaine peut envoyer par jour. Laisser vide pour aucune limite.","Number of messages this mailbox can send per day. Leave empty for no limit.":"Nombre de messages que cette boîte aux lettres peut envoyer par jour. Laisser vide pour aucune limite.","Ok":"Ok","OK":"OK","Old account":"Ancien compte","One or more updates are available":"Une ou plusieurs mise à jour sont disponibles","Opened":"Ouvert","Opened alarms":"Alarmes ouvertes","Options":"Options","Parameters updated":"Paramètres mis à jour","Partially aligned":"Partiellement aligné","Partially trusted sources / Forwarders":"Sources partiellement fiables / Transitaires","Password":"Mot de passe","Password copied to clipboard":"Mot de passe copié dans la presse-papier","Password recovery":"Récupération de mot de passe","Password updated":"Mot de passe mis à jour","Passwords mismatch":"Les mots de passe diffèrent","Pending":"En attente","Period":"Période","Phone number":"Numéro de téléphone","Pin code":"Code Pin","Please fill-in your primary email address":"Veillez renseigner votre adresse e-mail principale","Port":"Port","Problem":"Problème","Proceed":"Procéder","Profile":"Profil","Profile updated":"Profil mis à jour","Provide a CSV file where lines respect one of the following formats:":"Fournir un fichier CSV dont les lignes respectent l'un des formats suivants:","Provider":"Fournisseur","Provider created":"Fournisseur créé","Provider deleted":"Fournisseur supprimé","Provider name":"Nom du fournisseur","Provider updated":"Fournisseur mis à jour","Providers":"Fournisseurs","Queue ID":"ID de file","Quota":"Quota","Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators).":"Quota pour cette boite. Peut être exprimé en Ko, Mo (défaut) ou Go. Définir une valeur spécifique ou utiliser la valeur par défaut du domaine. Laisser vide pour définir une valeur illimitée (interdit pour les admins. de domaine).","Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Quota partagé entre les boîtes aux lettres. Peut être exprimé en Ko, Mo (défaut) ou Go. Une valeur à 0 signifie pas de quota.","Random address":"Adresse aléatoire","Random password":"Mot de passe aléatoire","Raw format. Click to copy":"Format brut. Cliquer pour copier","Recipient(s)":"Destinataire(s)","Recipients":"Destinataires","Register":"Enregistrer","Relative time ranges":"Intervalles des temps relatifs","Relay":"Relais","Reload":"Recharger","Remember me":"Se souvenir de moi","Remove this address":"Supprimer cette adresse","Remove this administrator":"Supprimer cet administrateur","Reopen alarm":"Ré-ouvrir l'alarme","Reseller":"Revendeur","Resend SMS.":"Renvoyer le SMS.","Reset recovery codes":"Rénitialiser les codes de récupération","Resources":"Ressources","Resources usage":"Utilisation des ressources","Retry reset":"Réessayer la rénitialisation","Return to login":"Retour à la connexion","Role":"Rôle","Save":"Enregistrer","Search":"Chercher","Secondary email":"E-mail secondaire","Secured":"Sécurisé","Security":"Sécurité","Select an account":"Sélectionner un compte","Select file":"Sélectionner un fichier","Sender addresses":"Adresses d'expédition","Sending limit":"Limite d'envoi","Separator":"Séparateur","Service":"Service","Settings":"Paramètres","Show key":"Afficher la clé","Simple user":"Utilisateur simple","Specify an email address":"Spécifier une adresse e-mail","SPF record found":"Enregistrement SPF trouvé","SPF record not found":"Enregistrement SPF introuvable","Start typing a name here...":"Commencer à saisir un nom ici...","Statistics":"Statistiques","Status":"Statut","Submit":"Soumettre","Summary":"Résumé","Super administrator":"Super administrateur","Tags":"Tags","The first element of each line is mandatory and must be equal to one of the previous values.":"Le premier élément de chaque ligne est obligatoire et doit être égal à l'une des valeurs précédentes.","This page is still under construction.":"Cette page est en cours de construction.","To":"A","Too many unsuccessful attempts, please try later.":"Trop de tentatives sans succès, veuillez réessayer plus tard","Total":"Total","TOTP resent.":"TOTP envoyé.","Transport":"Transport","Triggered":"Déclenché","Trusted sources":"Sources de confiance","Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security.":"L'authentification à double facteur (2FA) n'est pas encore activée pour votre compte. L'activation de cette fonctionnalité augmentera la sécurité de votre compte.","Type":"Type","Unknown":"Inconnu","Unknown sources / Threats":"Sources inconnues / Menaces","unlimited":"illimité","Update":"Mettre à jour","Update Password":"Mise à jour du mot de passe","Update settings":"Mise à jour des paramètres","Updated":"Mis à jour","Use domain default value":"Utiliser la valeur par défaut du domaine","User seems wrong, return to login or restart reset the process?":"L'utilisateur semble erroné, revenez à la connexion ou redémarrer réinitialisez le processus ","User unknown.":"Utilisateur inconnu.","Username":"Nom d'utilisateur","Username:":"Nom d'utilisateur :","Valid":"Valide","Verify code":"Vérifier le code","Warning":"Avertissement","Week":"Semaine","Welcome to Modoboa":"Bienvenue dans Modoboa","With a mailbox":"Avec une boite aux lettres","With mailbox":"Avec boîte aux lettres","Year":"Année","yes":"oui","Yes":"Oui","You are about to delete your API access token":"Vous êtes sur le point de supprimer votre jeton d'accès à l'API","You can use a different character as separator.":"Vous pouvez utiliser autre caractère comme séparateur","Your API token has not been generated yet.":"Votre jeton API n'a pas encore été généré.","Your API token is:":"Votre jeton API est :"},"nl":{},"ja":{},"pl":{},"pt":{},"ru":{"Account":"Добавить аккаунт","Account created":"Аккаунт создан","Account updated":"аккаунт изменен","Actions":"Действие","Add":"Адрес","Address":"Адрес","Administered domains":"Список квот","Administrators":"Администраторы","Alias":"Синоним","Aliases":"Синоним(ы)","API":"API","Apply":"Применить","Authentication":"Аутентификация","Bind/named format. Click to copy":"Неверный формат","Change password":"Изменить пароль","Check this option if passwords contained in your file are not crypted":"Выберите эту опцию если пароль в вашем файле не зашифрован ","Confirmation":"Подтверждение","Continue on error":"Продолжать при ошибке","Create a domain administrator":"Создание администратора домена","Create a mailbox for the administrator.":"Создание администратора домена","Create aliases":"Создание синонимов","Creation date":"Дата создания","Crypt passwords":"Шифровать пароль","Dashboard":"Приборная панель","Day":"День","Disabled":"Разрешен","DNS status":"Статистика","Domain administrator":"Администратор домена","Domain created":"Домен создан","Domains":"Домены","Email address":"Е-майл адрес","Enabled":"Разрешено","Forward":"Перенаправленые","Forward messages and store copies into your local mailbox":"Перенаправление сообщения, и сохранение копии в вашем локальном почтовом ящике","Forward updated":"Перенаправление обновлено","Full name":"Имя файла","General":"Основные","Identities":"Пользователи","Import":"Импорт","Import domains":"Импорт доменов","Import identities":"Импорт информации о пользователях","Information":"Информация","Installed version":"Установленная версия","Keep local copies":"Сохранить локальную копию","Last modification date":"Дата последней модификации","Level":"Уровень","Logger":"Логгер","Logout":"Завершить сеанс","Mailbox":"Почтовые ящики","Mailboxes":"Почтовые ящики","Message":"использование (%%)","Modified":"Синоним изменен","Month":"Месяц","Name":"Логин","New account":"Новый аккаунт","New alias":"Новый синоним","New domain":"Новый домен","Next":"Следующая","Not generated":"Получатель не определен","One or more updates are available":"Доступны одно или более обновлений.","Options":"Опции","Password":"Пароль","Passwords mismatch":"Пароли не совпадают","Profile updated":"Профиль обновлен","Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators).":"Квота в мегабайтах для этого почтового ящика. Определите собственное значение или используйте значение по умолчанию для родительского домена. Оставьте пустым для неограниченного значения. (Не разрешено администраторам домена)","Random address":"Ошибочный запрос","Random password":"Ошибочный запрос","Recipient(s)":"Получатели","Recipients":"Получатели","Remember me":"Запомнить меня","Reseller":"Реселлер","Resources":"Ресурсы","Resources usage":"Использование ресурсов","Role":"Роль","Save":"Сохранить","Search":"Поиск","Sender addresses":"Ошибочный запрос","Separator":"Разделитель","Settings":"Настройки","Simple user":"Обычный пользователь","Status":"Статистика","Submit":"Подтвердить","Super administrator":"Супер администратор","Tags":"Теги","Unknown":"Неизвестное","unlimited":"Не лимитировано","Update":"Обновление","Updated":"Обновление","Use domain default value":"Используются значения домена по умолчанию ","Username":"Логин пользователя","Week":"Неделя","Welcome to Modoboa":"Добро пожаловать в Modoboa!","Year":"Год"},"sv":{"A documentation of the API is available":"Dokumentation av API är tillgänglig","A new key will be generated soon. Refresh the page in a moment to see it.":"En ny nyckel kommer snart att skapas. Ladda om sidan om en stund för att se den.","A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features.":"Användare med alla rättigheter som kan göra allt. Som standard har en sån här användare ingen brevlåda så den kan inte komma åt slutanvändarfunktioner.","A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters.":"Användare utan privilegier men som har en en brevlåda. Den kommer att kunna använda alla slutanvändarfunktioner: webbmail, kalender, kontakter, filter.","A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox.":"Användare med rättigheter på en eller flera domäner. Den kan administrera brevlådor och han kan även ha en brevlåda.","Absolute time range":"Absolut tidsintervall","Account":"Konto","Account created":"Konto skapat","Account updated":"Konto uppdaterat","Actions":"Åtgärder","Add":"Lägg till","Add a new domain alias":"Lägg till nytt domän alias","Add administrator":"Lägg till administratör","Add sender address":"Lägg till avsändaradress","Address":"Adress","Address (hostname or IP)":"Adress (värdnamn eller IP)","Administered domains":"Administrerade domäner","Administrator added":"Administratör tillagd","Administrator name":"Administratörs namn","Administrator removed":"Administratör raderad","Administrators":"Administratörer","Alarm closed":"Larm stängt","Alarm deleted":"Larm raderat","Alarm re-opened":"Larm öppnat på nytt","Alarms":"Larm","Alarms deleted":"Larm raderade","Alias":"Alias","Alias updated":"Alias uppdaterat","Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld).":"Alias för denna brevlåda. För att skapa ett catchall-alias anger du bara domännamnet (@domain.tld).","Aliases":"Alias","Alignment":"Placering","API":"API","API access":"API åtkomst","API token copied to your clipboard":"API token kopierat till urklipp","API token created":"API token skapat","API token deleted":"API token raderat","Apply":"Tillämpa","Associated domains":"Associerade domäner","Audit trail":"Verifieringskedja","Authentication":"Autentisering","Auto configuration":"Automatisk konfiguration","autoconfig record (Mozilla) not found":"autoconfig-posten (Mozilla) hittades inte","autoconfig record (Mozilla): %{ value }":"\"autoconfig-post (Mozilla): %{ value }\"","autodiscover record (Microsoft) not found":"autodiscover-post (Microsoft) hittades inte","autodiscover record (Microsoft): %{ value }":"autodiscover-post (Microsoft): %{ value }","Back":"Tillbaka","Bind/named format. Click to copy":"Bind/named formatterat. Klicka för att kopiera","Cancel":"Avbryt","Change password":"Ändra lösenord","Check connection:":"Kontrollera anslutning:","Check out the following list to find related components":"Kolla in följande lista för att hitta relaterade komponenter","Check this option if passwords contained in your file are not crypted":"Markera det här alternativet om lösenorden i din fil inte är krypterade","Choose a domain":"Välj en domän","Choose a role":"Välj en roll","Close":"Stäng","Close alarm":"Stäng alarm","Closed":"Stängd","Confirm and create":"Bekräfta och skapa","Confirmation":"Bekräftelse","Congratulations! Two-Factor Authentication is now enabled for your account.":"Grattis! Tvåfaktorsautentisering är nu aktiverad för ditt konto.","Connect":"Anslut","Continue on error":"Fortsätt vid fel","Control if this domain will be allowed to send and receive messages":"Kontrollera om den här domänen ska tillåtas skicka och ta emot meddelanden","Copy to clipboard":"Kopiera till urklipp","Copy token to clipboard":"Kopiera token till urklipp","Could not save parameters":"Kunde inte spara parametrar","Create a domain administrator":"Skapa en domänadministratör","Create a mailbox for the administrator.":"Skapa en brevlåda för administratören.","Create aliases":"Skapa alias","Create standard aliases for the domain.":"Skapa standardalias för domänen.","Creation date":"Datum skapad","Crypt passwords":"Kryptera lösenord","Current password":"Nuvarande lösenord","Daily message sending limit":"Daglig sändningsgräns för meddelanden","Daily sending limit":"Daglig sändningsgräns","Dashboard":"Instrumentbräda","Date":"Datum","Day":"Dag","Default mailbox quota":"Standard brevlådekvota","Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Standardkvot tillämpas på postlådor. Kan uttryckas i KB, MB (standard) eller GB. Ett värde på 0 betyder ingen kvot.","Delete":"Radera","Delete token":"Radera token","Description":"Beskrivning","Detail":"Detalj","Disable 2FA":"Inaktivear 2FA","Disabled":"Inaktiverad","DKIM key":"DKIM nyckel","DKIM key length":"DKIM nyckellängd","DKIM key selector":"DKIM nyckel väljare","DKIM keys already exist for this domain. Do you want to overwrite them?":"DKIM-nycklar finns redan för den här domänen. Vill du skriva över dem?","DKIM public key for":"DKIM publik nyckel för","DKIM record found":"DKIM-post hittades","DKIM record not found":"DKIM-posten hittades inte","DKIM signing":"DKIM signering","DMARC":"DMARC","DMARC record found":"DMARC post hittad","DMARC record not found":"DMARC post ej hittad","DMARC support does not seem to be enabled for this domain.":"DMARC-stöd verkar inte vara aktiverat för den här domänen.","DNS":"DNS","DNS checks":"DNS kontroller","DNS configuration help":"DNS konfigurering hjälp","DNS status":"DNS status","Do not delete account folder":"Ta inte bort kontomappen","Do not delete domain folder":"Ta inte bort domänmappen","Domain":"Domän","Domain administrator":"Domänadministratör","Domain alias created":"Domän alias skapat","Domain alias deleted":"Domänalias raderat","Domain alias updated":"Domänalias uppdaterat","Domain created":"Domän skapad","Domain default value":"Domän standardvärde","Domain deleted":"Domän raderad","Domain name (ex: domain.tld)":"Domännamn (ex: domain.tld)","Domain updated":"Domän uppdaterad","domain's default value":"domänens standardvärde","Domains":"Domäner","Don't treat duplicated objects as errors":"Behandla inte duplicerade objekt som fel","Edit":"Redigera","Edit account":"Redigera konto","Edit alias":"Redigera alias","Edit domain":"Redigera domän","Edit domain alias":"Redigera domänalias","Edit provider":"Redigera leverantör","Email":"E-post","Email address":"E-postadress","Email providers":"E-postleverantörer","Empty":"Tom","Enable 2FA":"Aktivera 2FA","Enable DKIM signing":"Aktivera DKIM signering","Enable DNS checks":"Aktivera DNS kontroller","Enabled":"Aktiverad","Enter a simple username or an email address":"Ange ett enkelt användarnamn eller en e-postadress","Enter an email address":"Ange en e-postadress","Enter the code from the two-factor app on your mobile device. If you have lost your device, you may enter one of your recovery codes.":"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.","Enter the code you've just received by SMS":"Ange koden du precis har fått via SMS","Error":"Fel","Ex: 10MB. Leave empty for no limit":"Ex: 10MB. Lämna tomt för ingen gräns","Expire at":"Utgår kl","Export accounts and aliases to CSV":"Exportera konton och alias till CSV","Export domains and aliases to CSV":"Exportera domäner och alias till CSV","Failed":"Misslyckades","First name":"Förnamn","Forward":"Vidarebefordra","Forward messages and store copies into your local mailbox":"Vidarebefordra meddelanden och lagra kopior i din lokala brevlåda","Forward updated":"Vidarebefordring uppdaterad","Forwarded":"Vidarebefordrad","Forwarders with ARC":"Vidarebefordrare med ARC","From":"Från","Full name":"Komplett namn","Fullname/recipient":"Komplett namn/mottagare","Fully aligned":"Helt inriktad","General":"Allmän","General information":"Allmänn information","General settings":"Allmänna inställningar","Generate":"Generera","Generate a new DKIM key":"Generera en ny DKIM nyckel","help":"hjälp","Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones.":"Här är ett exempel på DNS-konfiguration (bind-format). Ersätt värdena mellan [ ] med de lämpliga värdena.","Identification":"Identifikation","Identities":"Identiteter","If you close this form now, your modifications won't be saved. Do you confirm?":"Om du stänger formuläret nu kommer dina ändringar inte att sparas. Bekräftar du?","If you configured it recently, please wait for the first report to be received and processed.":"Om du konfigurerade det nyligen, vänta tills den första rapporten tas emot och behandlas.","IMAP Migration":"IMAP migrering","IMAP Port":"IMAP port","Import":"Importera","Import accounts and aliases from CSV file":"Importera konton och alias från CSV-fil","Import domains":"Importera domäner","Import domains and aliases from CSV file":"Importera domäner och alias från CSV-fil","Import identities":"Importera identiteter","Indicate one or more recipients separated by a comma (,)":"Ange en eller flera mottagare separerade med kommatecken (,)","Information":"Information","Installed components":"Installerade komponenter","Installed version":"Installerad version","Invalid password":"Ogiltigt lösenord","Invalid reset token.":"Ogiltigt återställningstoken.","Invalid username and/or password":"Ogiltigt användarnamn och/eller lösenord","Is the IMAP connection secured using SSL/TLS or StartTLS":"Är IMAP-anslutningen säker med SSL/TLS eller StartTLS","Keep local copies":"Behåll lokala kopior","Language":"Språk","Last login date":"Senaste inloggning","Last modification date":"Senaste ändrad datum","Last name":"Efternamn","Latest version":"Senaste version","Leave empty for no limit":"Lämna tomt för ingen gräns","Level":"Nivå","Limitations":"Gränser","Local domain (optional)":"Lokal domän (valfritt)§","Logger":"Logger","Logout":"Logga ut","Mailbox":"Brevlåda","Mailboxes":"Brevlådor","MB":"MB","Message":"Meddelande","Message history":"Meddelande historik","Message sending limit":"Begränsning för meddelandesändning","messages":"meddelanden","Messages":"Meddelanden","Migration deleted":"Migrering raderad","Migrations":"Migreringar","Modified":"Ändrad","Modify":"Ändra","Month":"Månad","MX records":"MX poster","Name":"Namn","Name of the administrator":"Namn på administratören","Name of the domain to migrate":"Namn på domänen att migrera","Never logged-in":"Aldrig inloggad","New":"Ny","New account":"Nytt konto","New alias":"Nytt alias","New domain":"Ny domän","New provider":"Ny leverantör","New recovery codes":"Nya återställningskoder","Next":"Nästa","no":"nej","No":"Nej","No associated domains":"Inga associerade domäner","No sender address defined for this account":"Inge avsändaradress agedd för detta konto","No sending limit":"Ingen sändningsbegränsning","Not generated":"Ej genererad","Number of associated domains:":"Antal associerade domäner:","Number of messages this domain can send per day. Leave empty for no limit.":"Antal meddelanden som denna domän kan skicka per dag. Lämna tomt för ingen begränsning.","Number of messages this mailbox can send per day. Leave empty for no limit.":"Antal meddelanden som denna brevlåda kan skicka per dag. Lämna tomt för ingen begränsning.","Ok":"Ok","OK":"OK","Old account":"Gammalt konto","One or more updates are available":"En eller flera uppdateringar tillgängliga","Opened":"Öppnad","Opened alarms":"Öppnade alarm","Options":"Alternativ","Parameters updated":"Parametrar uppdaterade","Partially aligned":"Delvis justerad","Partially trusted sources / Forwarders":"Delvis pålitliga källor / speditörer","Password":"Lösenord","Password copied to clipboard":"Lösenord kopierat till urklipp","Password recovery":"Lösenordsåterställning","Password updated":"Lösenord uppdaterat","Passwords mismatch":"Lösenord matchar ej","Pending":"Väntande","Period":"Period","Phone number":"Telefonnummer","Pin code":"Pinkod","Please fill-in your primary email address":"Var vänlig fyll i din primära e-postadress","Port":"Port","Problem":"Problem","Proceed":"Fortsätt","Profile":"Profil","Profile updated":"Profil uppdaterad","Provide a CSV file where lines respect one of the following formats:":"Ange en CSV-fil där raderna respekterar ett av följande format:","Provider":"Leverantör","Provider created":"Leverantör skapad","Provider deleted":"Leverantör raderad","Provider name":"Leverantörsnamn","Provider updated":"Leverantör uppdaterad","Providers":"Leverantörer","Queue ID":"Kö ID","Quota":"Kvota","Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators).":"Kvot för denna brevlåda, kan anges i KB, MB (standard) eller GB. Ange ett anpassat värde eller använd domänens standardvärde. Lämna tomt för att ange ett obegränsat värde (inte tillåtet för domänadministratörer).","Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota.":"Kvot delad mellan brevlådor. Kan anges i KB, MB (standard) eller GB. Ett värde av 0 innebär ingen kvot.","Random address":"Slumpmässig adress","Random password":"Slumpmässigt lösenord","Raw format. Click to copy":"Råformat. Klicka för att kopiera","Recipient(s)":"Mottagare","Recipients":"Mottagare","Register":"Register","Relative time ranges":"Relativa tidsintervall","Relay":"Relä","Reload":"Ladda om","Remember me":"Kom ihåg mig","Remove this address":"Radera denna adress","Remove this administrator":"Radera denna administratör","Reopen alarm":"Återöppna larmet","Reseller":"Återförsäljare","Resend SMS.":"Skicka SMS på nytt.","Reset recovery codes":"Återställ återställningskoder","Resources":"Resurser","Resources usage":"Resursanvändning","Retry reset":"Försök återställning igen","Return to login":"Återgå till inloggning","Role":"Roll","Save":"Spara","Search":"Sök","Secondary email":"Sekundär e-post","Secured":"Säkrad","Security":"Säkerhet","Select an account":"Välj ett konto","Select file":"Välj fil","Sender addresses":"Avsändaradresser","Sending limit":"Sändningsgräns","Separator":"Avgränsare","Service":"Tjänst","Settings":"Inställningar","Show key":"Visa nyckel","Simple user":"Enkel användare","Specify an email address":"Ange en e-postadress","SPF record found":"SPF post hittad","SPF record not found":"SPF post saknas","Start typing a name here...":"Börja skriva ett namn här...","Statistics":"Statistik","Status":"Status","Submit":"Skicka","Summary":"Sammanfattning","Super administrator":"Superadministratör","Tags":"Taggar","The first element of each line is mandatory and must be equal to one of the previous values.":"Det första elementet i varje rad är obligatoriskt och måste vara lika med ett av de tidigare värdena.","This page is still under construction.":"Denna sida är fortfarande under konstruktion.","To":"Till","Too many unsuccessful attempts, please try later.":"För många misslyckade försök, försök igen senare.","Total":"Totalt","TOTP resent.":"TOTP skickat igen.","Transport":"Transport","Triggered":"Triggad","Trusted sources":"Pålitliga källor","Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security.":"Tvåfaktorsautentisering (2FA) är ännu inte aktiverad för ditt konto. Om du aktiverar den här funktionen ökar ditt kontos säkerhet.","Type":"Typ","Unknown":"Okänd","Unknown sources / Threats":"Okända källor / hot","unlimited":"obegränsat","Update":"Uppdatera","Update Password":"Uppdatera lösenord","Update settings":"Uppdatera inställningar","Updated":"Uppdaterad","Use domain default value":"Använd domänens standardvärde","User seems wrong, return to login or restart reset the process?":"Användare verkar felaktig, återgå till inloggning eller börja om återsällningsprocessen?","User unknown.":"Okänd användare.","Username":"Användarnamn","Username:":"Användarnamn:","Valid":"Giltig","Verify code":"Verifikationskod","Warning":"Varning","Week":"Vecka","Welcome to Modoboa":"Välkommen till Modoboa","With a mailbox":"Med en brevlåda","With mailbox":"Med brevlåda","Year":"År","yes":"ja","Yes":"Ja","You are about to delete your API access token":"Du håller på att radera din API-åtkomsttoken","You can use a different character as separator.":"Du kan använda ett annat tecken som avgränsare.","Your API token has not been generated yet.":"Ditt API token har ännu ej genererats.","Your API token is:":"Ditt API token är:"},"tr":{"API":"API","API access":"API erişimi","Authentication":"Kimlik Doğrulama","Change password":"Parolayı değiştirin","Close":"Kapat","Confirmation":"Onayla","Congratulations! Two-Factor Authentication is now enabled for your account.":"Tebrikler! Artık hesabınız için İki Faktörlü Kimlik Doğrulama etkinleştirildi.","Dashboard":"Gösterge Paneli","Date":"Tarih","Description":"Tanım","Disable 2FA":"2FA'yı devre dışı bırak","Domain administrator":"Alan adı Yöneticisi","Enable 2FA":"2FA'yı etkinleştir","Enter the code you've just received by SMS":"Az önce SMS ile aldığınız kodu giriniz","From":"Kimden","General":"Genel","Information":"Bilgi","Installed version":"Kurulu sürüm","Level":"Seviye","Logger":"Kayıtçı","Logout":"Çıkış Yapın","Message":"İleti","Name":"İsim","New recovery codes":"Yeni kurtarma kodları","Next":"Sonraki","No":"Hayır","One or more updates are available":"Bir veya daha fazla güncelleme mevcut","Password":"Parola","Passwords mismatch":"Parolalar uyuşmuyor","Phone number":"Telefon numarası","Pin code":"Pin kodu","Please fill-in your primary email address":"Lütfen birincil e-posta adresinizi girin","Profile":"Profil","Profile updated":"Profil güncellendi","Register":"Kayıt ol","Remember me":"Beni hatırla","Reseller":"Bayii","Reset recovery codes":"Kurtarma kodlarını sıfırla","Role":"Rol","Save":"Kaydet","Secondary email":"İkincil e-posta","Security":"Güvenlik","Settings":"Ayarlar","Simple user":"Basit kullanıcı","Submit":"Gönder","To":"Kime","Two-Factor Authentication (2FA) is not yet activated for your account. Enabling this feature will increase your account's security.":"Hesabınız için İki Faktörlü Kimlik Doğrulama (2FA) henüz etkinleştirilmedi. Bu özelliği etkinleştirmek hesabınızın güvenliğini artıracaktır.","Unknown":"Bilinmeyen","Update":"Güncelle","Username":"Kullanıcı adı","Welcome to Modoboa":"Modoboa'ya hoş geldiniz","Yes":"Evet"},"zh":{}} \ No newline at end of file diff --git a/frontend/src/locale/zh/app.po b/frontend/src/locale/zh/app.po new file mode 100644 index 000000000..ab995530f --- /dev/null +++ b/frontend/src/locale/zh/app.po @@ -0,0 +1,1915 @@ +# Language zh-hant translations for Modoboa package. +# Copyright (C) 2023 THE Modoboa'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Modoboa package. +# Automatically generated, 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: Modoboa 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 14:58+0100\n" +"PO-Revision-Date: 2023-02-23 11:26+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: zh\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:41 +msgid "(the domain will be created locally)" +msgstr "" + +#: src/views/account/APISetupView.vue:50 +msgid "A documentation of the API is available" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:195 +msgid "" +"A new key will be generated soon. Refresh the page in a moment to see it." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:108 +msgid "" +"A user with all privileges, can do anything. By default, such a user does " +"not have a mailbox so he can't access end-user features." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:82 +msgid "" +"A user with no privileges but with a mailbox. He will be allowed to use all " +"end-user features: webmail, calendar, contacts, filters." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:92 +msgid "" +"A user with privileges on one or more domain. He will be allowed to " +"administer mailboxes and he can also have a mailbox." +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:17 +msgid "Absolute time range" +msgstr "" + +#: src/stores/identities.store.js:67 +msgid "account" +msgstr "" + +#: src/views/admin/identities/AccountView.vue:4 +#: src/views/admin/identities/IdentitiesView.vue:33 +msgid "Account" +msgstr "" + +#: src/stores/accounts.store.js:51 +msgid "Account created" +msgstr "" + +#: src/stores/accounts.store.js:62 +msgid "Account successfully deleted" +msgstr "" + +#: src/stores/accounts.store.js:43 +msgid "Account updated" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:20 +#: src/components/admin/alarms/AlarmList.vue:98 +#: src/components/admin/domains/DomainList.vue:206 +#: src/components/admin/domains/DomainList.vue:24 +#: src/components/admin/identities/IdentityList.vue:122 +#: src/components/admin/identities/IdentityList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:23 +#: src/components/admin/imap_migration/MigrationsList.vue:80 +#: src/components/admin/imap_migration/ProvidersList.vue:102 +#: src/components/admin/imap_migration/ProvidersList.vue:25 +msgid "Actions" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Add" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:74 +msgid "Add a new domain alias" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:65 +msgid "Add administrator" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:53 +msgid "Add sender address" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:16 +msgid "Add/Remove from the domain page" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:171 +#: src/components/admin/identities/AccountSenderAddresses.vue:73 +#: src/components/admin/identities/AliasCreationForm.vue:60 +#: src/components/admin/identities/AliasEditForm.vue:16 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:54 +#: src/components/admin/imap_migration/ProvidersList.vue:97 +msgid "Address" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:11 +msgid "Address (hostname or IP)" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:4 +msgid "Administered domains" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:147 +msgid "Administrator added" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:247 +msgid "Administrator name" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:155 +msgid "Administrator removed" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:9 +#: src/components/admin/domains/DomainList.vue:284 +msgid "Administrators" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:6 +msgid "Administrators of" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:188 +msgid "Alarm closed" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:173 +msgid "Alarm deleted" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:196 +msgid "Alarm re-opened" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:302 +#: src/layouts/dashboard/NavBar.vue:201 +msgid "Alarms" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:180 +msgid "Alarms deleted" +msgstr "" + +#: src/stores/identities.store.js:97 +msgid "alias" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:115 +#: src/views/admin/domains/DomainsView.vue:36 +#: src/views/admin/identities/AliasView.vue:5 +#: src/views/admin/identities/IdentitiesView.vue:36 +msgid "Alias" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:50 +msgid "Alias already added" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:130 +msgid "Alias already exists, redirecting to edit page" +msgstr "" + +#: src/stores/aliases.store.js:48 +msgid "Alias successfully created" +msgstr "" + +#: src/stores/aliases.store.js:61 +msgid "Alias successfully deleted" +msgstr "" + +#: src/stores/aliases.store.js:74 +msgid "Alias updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:8 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:8 +msgid "" +"Alias(es) of this mailbox. To create a catchall alias, just enter the domain " +"name (@domain.tld)." +msgstr "" + +#: src/components/admin/domains/DomainList.vue:201 +#: src/components/admin/domains/DomainSummary.vue:40 +#: src/components/admin/identities/AccountAliases.vue:4 +#: src/components/admin/identities/AccountCreationForm.vue:139 +#: src/components/admin/identities/AccountCreationForm.vue:142 +#: src/components/admin/identities/AccountCreationForm.vue:172 +msgid "Aliases" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:124 +msgid "Aliases:" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:5 +msgid "Alignment" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:260 +msgid "API" +msgstr "" + +#: src/views/account/APISetupView.vue:4 +msgid "API access" +msgstr "" + +#: src/views/account/APISetupView.vue:80 +msgid "API token copied to your clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:92 +msgid "API token created" +msgstr "" + +#: src/views/account/APISetupView.vue:114 +msgid "API token deleted" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:22 +msgid "Apply" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:231 +msgid "Are you sure you want to delete this alias?" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:205 +msgid "Are you sure you want to delete this identity ?" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:42 +msgid "Associated domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:64 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:72 +#: src/components/admin/imap_migration/ProviderForm.vue:29 +#: src/components/admin/imap_migration/ProvidersList.vue:100 +msgid "Associated domains" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:216 +#: src/views/admin/monitoring/AuditTrailView.vue:3 +msgid "Audit trail" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:72 +msgid "Authentication" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:35 +#: src/components/admin/domains/DomainDNSConfig.vue:71 +msgid "Auto configuration" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:56 +msgid "autoconfig record (Mozilla) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:50 +msgid "autoconfig record (Mozilla): %{ value }" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:68 +msgid "autodiscover record (Microsoft) not found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:62 +msgid "autodiscover record (Microsoft): %{ value }" +msgstr "" + +#: src/components/tools/CreationForm.vue:61 +msgid "Back" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:23 +msgid "Bind/named format. Click to copy" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:155 +#: src/components/admin/identities/AccountEditForm.vue:185 +#: src/components/admin/identities/AliasEditForm.vue:66 +#: src/components/admin/imap_migration/ProviderForm.vue:57 +#: src/components/tools/ConfirmDialog.vue:47 +#: src/views/account/APISetupView.vue:105 +msgid "Cancel" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:15 +msgid "Change password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:33 +msgid "Check connection:" +msgstr "" + +#: src/views/admin/InformationView.vue:21 +msgid "Check out the following list to find related components" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:85 +msgid "Check this option if passwords contained in your file are not crypted" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:15 +msgid "Choose a domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:7 +msgid "Choose a role" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:24 +msgid "Click here to copy the key" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:23 +#: src/components/admin/domains/DomainAdminList.vue:70 +#: src/components/admin/domains/DomainAliasForm.vue:31 +#: src/components/admin/domains/DomainDKIMKey.vue:37 +#: src/components/admin/domains/DomainDNSConfig.vue:80 +#: src/components/tools/ImportForm.vue:51 +#: src/layouts/dashboard/DashboardLayout.vue:14 +msgid "Close" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:133 +msgid "Close alarm" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:46 +msgid "Closed" +msgstr "" + +#: src/components/tools/CreationForm.vue:89 +msgid "Confirm and create" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:63 +msgid "Confirmation" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:50 +msgid "" +"Congratulations! Two-Factor Authentication is now enabled for your account." +msgstr "" + +#: src/components/login/LoginForm.vue:87 +msgid "Connect" +msgstr "" + +#: src/components/tools/ImportForm.vue:40 +msgid "Continue on error" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:22 +msgid "Control if this domain will be allowed to send and receive messages" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:114 +msgid "Copy key to clipboard" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:54 +#: src/components/admin/identities/AccountCreationForm.vue:43 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:42 +msgid "Copy to clipboard" +msgstr "" + +#: src/views/account/APISetupView.vue:33 +msgid "Copy token to clipboard" +msgstr "" + +#: src/views/admin/ParametersView.vue:158 +msgid "Could not save parameters" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:238 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:5 +msgid "Create a domain administrator" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:27 +msgid "Create a mailbox for the administrator." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:262 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:33 +msgid "Create aliases" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:35 +msgid "Create standard aliases for the domain." +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:8 +#: src/components/admin/identities/AccountSummary.vue:8 +#: src/components/admin/identities/AliasSummary.vue:8 +msgid "Creation date" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:81 +msgid "Crypt passwords" +msgstr "" + +#: src/mixins/importExport.js:39 +msgid "CSV seems to be badly formatted" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:4 +msgid "Current password" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:23 +msgid "Daily message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:30 +#: src/components/admin/identities/AccountSummary.vue:55 +msgid "Daily sending limit" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:183 +msgid "Dashboard" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:49 +#: src/components/admin/logs/MessageList.vue:43 +msgid "Date" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:108 +msgid "Day" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:192 +#: src/components/admin/domains/DomainSummary.vue:23 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19 +msgid "Default mailbox quota" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:21 +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/alarms/AlarmList.vue:109 +#: src/components/admin/alarms/AlarmList.vue:126 +#: src/components/admin/domains/DomainAliasForm.vue:38 +#: src/components/admin/domains/DomainList.vue:294 +#: src/components/admin/identities/IdentityList.vue:164 +#: src/components/admin/identities/IdentityList.vue:176 +#: src/components/admin/identities/IdentityList.vue:189 +#: src/components/admin/imap_migration/MigrationsList.vue:120 +#: src/components/admin/imap_migration/ProvidersList.vue:124 +msgid "Delete" +msgstr "" + +#: src/views/account/APISetupView.vue:43 +msgid "Delete token" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:72 +#: src/components/admin/identities/AliasSummary.vue:20 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:57 +#: src/views/admin/InformationView.vue:60 +msgid "Description" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:45 +msgid "Detail" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:90 +msgid "Disable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:80 +msgid "disabled" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:18 +msgid "Disabled" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:103 +msgid "DKIM key" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:182 +msgid "DKIM key copied to clipboard" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:218 +msgid "" +"DKIM key does not seem to be genrated yet or has failed. Do you want to " +"requeue the job?" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:208 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:22 +msgid "DKIM key length" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:204 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:16 +msgid "DKIM key selector" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:238 +msgid "DKIM keys already exist for this domain. Do you want to overwrite them?" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:5 +msgid "DKIM public key for" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:84 +msgid "DKIM record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:87 +msgid "DKIM record not found" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:50 +msgid "DKIM signing" +msgstr "" + +#: src/views/admin/domains/DomainView.vue:27 +msgid "DMARC" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:92 +msgid "DMARC record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:95 +msgid "DMARC record not found" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:89 +msgid "DMARC support does not seem to be enabled for this domain." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:143 +#: src/components/admin/domains/DomainCreationForm.vue:149 +#: src/components/admin/domains/DomainCreationForm.vue:173 +#: src/components/admin/domains/DomainEditForm.vue:34 +msgid "DNS" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:41 +msgid "DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:4 +msgid "DNS configuration for " +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:8 +msgid "DNS configuration help" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:202 +msgid "DNS status" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:97 +msgid "Do not delete account folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:158 +msgid "Do not delete domain folder" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:236 +msgid "Do you really want to delete the domain %{ domain }?" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:55 +msgid "domain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:94 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:21 +#: src/views/admin/domains/DomainsView.vue:33 +#: src/views/admin/domains/DomainView.vue:5 +msgid "Domain" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:90 +msgid "Domain administrator" +msgstr "" + +#: src/stores/domains.store.js:84 +msgid "Domain alias created" +msgstr "" + +#: src/stores/domains.store.js:106 +msgid "Domain alias deleted" +msgstr "" + +#: src/stores/domains.store.js:121 +msgid "Domain alias updated" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:313 +msgid "Domain created" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:124 +msgid "Domain default value" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:250 +msgid "Domain deleted" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:5 +msgid "Domain name (ex: domain.tld)" +msgstr "" + +#: src/stores/domains.store.js:56 +msgid "Domain updated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:81 +msgid "domain's default value" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:189 +#: src/views/admin/domains/DomainsView.vue:4 +msgid "Domains" +msgstr "" + +#: src/components/tools/ImportForm.vue:43 +msgid "Don't treat duplicated objects as errors" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:289 +#: src/components/admin/identities/IdentityList.vue:159 +#: src/components/admin/identities/IdentityList.vue:171 +#: src/components/admin/imap_migration/ProvidersList.vue:130 +msgid "Edit" +msgstr "" + +#: src/views/admin/identities/AccountEditView.vue:2 +msgid "Edit account" +msgstr "" + +#: src/views/admin/identities/AliasEditView.vue:3 +msgid "Edit alias" +msgstr "" + +#: src/views/admin/domains/DomainEditView.vue:3 +msgid "Edit domain" +msgstr "" + +#: src/components/admin/domains/DomainAliasForm.vue:73 +msgid "Edit domain alias" +msgstr "" + +#: src/views/admin/imap_migration/ProviderEditView.vue:3 +msgid "Edit provider" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:120 +msgid "Email" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:10 +msgid "Email address" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:233 +msgid "Email providers" +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:104 +#: src/views/login/PasswordRecoveryForm.vue:103 +msgid "Email sent, please check your inbox" +msgstr "" + +#: src/components/tools/CreationSummary.vue:45 +msgid "Empty" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:107 +msgid "Enable 2FA" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:181 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:11 +msgid "Enable DKIM signing" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:176 +#: src/components/admin/domains/form_steps/DomainDNSForm.vue:6 +msgid "Enable DNS checks" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:166 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:20 +#: src/components/admin/identities/AccountCreationForm.vue:108 +#: src/components/admin/identities/AccountEditForm.vue:44 +#: src/components/admin/identities/AliasEditForm.vue:19 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:42 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:52 +msgid "Enabled" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:71 +msgid "Enter a simple username or an email address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:69 +msgid "Enter an email address" +msgstr "" + +#: src/components/login/TwofaForm.vue:11 +msgid "" +"Enter the code from the two-factor app on your mobile device. If you have " +"lost your device, you may enter one of your recovery codes." +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:16 +msgid "Enter the code you've just received by SMS" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:70 +#: src/views/login/PasswordRecoveryForm.vue:121 +msgid "Error" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:13 +msgid "Ex: 10MB. Leave empty for no limit" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:66 +#: src/components/admin/identities/AliasSummary.vue:16 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:55 +msgid "Expire at" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:15 +msgid "Export accounts and aliases to CSV" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:15 +msgid "Export domains and aliases to CSV" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:130 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:152 +msgid "Failed" +msgstr "" + +#: src/components/account/ProfileForm.vue:24 +msgid "Feel free to improve the translations" +msgstr "" + +#: src/plugins/rules.js:27 +msgid "Field is required" +msgstr "" + +#: src/components/account/ProfileForm.vue:9 +#: src/components/admin/identities/AccountCreationForm.vue:99 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:18 +msgid "First name" +msgstr "" + +#: src/components/login/LoginForm.vue:96 +msgid "Forgot password" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:11 +#: src/components/login/PasswordRecoveryForm.vue:12 +#: src/views/login/PasswordRecoveryForm.vue:17 +msgid "Forgot password?" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:284 src/views/account/ForwardView.vue:3 +msgid "Forward" +msgstr "" + +#: src/components/account/ForwardForm.vue:18 +msgid "Forward messages and store copies into your local mailbox" +msgstr "" + +#: src/components/account/ForwardForm.vue:49 +msgid "Forward updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:129 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:151 +msgid "Forwarded" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:61 +msgid "Forwarders with ARC" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:46 +#: src/components/tools/TimeSerieChart.vue:19 +msgid "From" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:19 +msgid "Full name" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:119 +msgid "Fullname/recipient" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:127 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:143 +msgid "Fully aligned" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:142 +#: src/components/admin/domains/DomainCreationForm.vue:148 +#: src/components/admin/domains/DomainCreationForm.vue:161 +#: src/components/admin/domains/DomainEditForm.vue:9 +#: src/components/admin/identities/AliasCreationForm.vue:53 +#: src/components/admin/identities/AliasCreationForm.vue:93 +#: src/components/admin/identities/AliasEditForm.vue:9 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:51 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:71 +#: src/components/admin/imap_migration/ProviderForm.vue:7 +#: src/views/admin/domains/DomainView.vue:21 +msgid "General" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:4 +#: src/components/admin/identities/AccountSummary.vue:4 +#: src/components/admin/identities/AliasSummary.vue:4 +msgid "General information" +msgstr "" + +#: src/components/account/ProfileForm.vue:5 +msgid "General settings" +msgstr "" + +#: src/views/account/APISetupView.vue:18 +msgid "Generate" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:119 +msgid "Generate a new DKIM key" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:38 +msgid "Generated address" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:101 +msgid "help" +msgstr "" + +#: src/components/account/ProfileForm.vue:28 +#: src/views/account/APISetupView.vue:51 +msgid "here" +msgstr "" + +#: src/components/admin/domains/DomainDNSConfig.vue:9 +msgid "" +"Here is an example of DNS configuration (bind format). Replace values " +"between [ ] by the appropriate ones." +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:161 +#: src/components/admin/identities/AccountCreationForm.vue:96 +#: src/components/admin/identities/AccountEditForm.vue:31 +#: src/components/login/LoginForm.vue:56 +msgid "Identification" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:195 +#: src/views/admin/identities/IdentitiesView.vue:4 +msgid "Identities" +msgstr "" + +#: src/components/tools/CreationForm.vue:127 +msgid "" +"If you close this form now, your modifications won't be saved. Do you " +"confirm?" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:94 +msgid "" +"If you configured it recently, please wait for the first report to be " +"received and processed." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:229 +msgid "IMAP Migration" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:17 +msgid "IMAP Port" +msgstr "" + +#: src/components/tools/ImportForm.vue:54 +msgid "Import" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:8 +msgid "Import accounts and aliases from CSV file" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:53 +msgid "Import domains" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:8 +msgid "Import domains and aliases from CSV file" +msgstr "" + +#: src/views/admin/identities/IdentitiesView.vue:59 +msgid "Import identities" +msgstr "" + +#: src/components/account/ForwardForm.vue:8 +msgid "Indicate one or more recipients separated by a comma (,)" +msgstr "" + +#: src/views/login/PasswordRecoveryForm.vue:102 +msgid "Info" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:252 src/views/admin/InformationView.vue:4 +msgid "Information" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:34 +msgid "" +"Install a soft token authenticator like FreeOTP or Google Authenticator from " +"your application repository and use that app to scan this QR code." +msgstr "" + +#: src/views/admin/InformationView.vue:8 +msgid "Installed components" +msgstr "" + +#: src/views/admin/InformationView.vue:58 +msgid "Installed version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:126 +msgid "Invalid password" +msgstr "" + +#: src/plugins/rules.js:41 +msgid "Invalid port number" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:115 +msgid "Invalid reset token." +msgstr "" + +#: src/components/login/LoginForm.vue:41 +msgid "Invalid username and/or password" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:27 +msgid "Is the IMAP connection secured using SSL/TLS or StartTLS" +msgstr "" + +#: src/views/Dashboard.vue:9 +msgid "" +"It will present a summary of your Modoboa server's status and some useful " +"information about the product." +msgstr "" + +#: src/components/account/ForwardForm.vue:16 +msgid "Keep local copies" +msgstr "" + +#: src/components/account/ProfileForm.vue:22 +msgid "Language" +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:12 +msgid "Last login date" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:12 +msgid "Last modification date" +msgstr "" + +#: src/components/account/ProfileForm.vue:15 +#: src/components/admin/identities/AccountCreationForm.vue:100 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:25 +msgid "Last name" +msgstr "" + +#: src/views/admin/InformationView.vue:59 +msgid "Latest version" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26 +msgid "Leave empty for no limit" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:50 +msgid "Level" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:144 +#: src/components/admin/domains/DomainCreationForm.vue:150 +#: src/components/admin/domains/DomainCreationForm.vue:188 +#: src/components/admin/domains/DomainEditForm.vue:71 +msgid "Limitations" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:13 +msgid "Local domain (optional)" +msgstr "" + +#: src/components/admin/logs/AuditTrailList.vue:51 +msgid "Logger" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:300 +msgid "Logout" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:95 +#: src/components/admin/identities/AccountCreationForm.vue:118 +#: src/components/admin/identities/AccountCreationForm.vue:168 +#: src/components/admin/identities/AccountEditForm.vue:68 +msgid "Mailbox" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:164 +msgid "Mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:157 +msgid "Mailbox:" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:36 +msgid "Mailboxes" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:20 +#: src/components/admin/identities/AccountSummary.vue:49 +msgid "MB" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:96 +#: src/components/admin/logs/AuditTrailList.vue:52 +msgid "Message" +msgstr "" + +#: src/views/admin/monitoring/MessagesView.vue:3 +msgid "Message history" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:196 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32 +#: src/components/admin/identities/AccountCreationForm.vue:128 +msgid "Message sending limit" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:32 +msgid "messages" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:221 +msgid "Messages" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:95 +msgid "Migration deleted" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:238 +#: src/views/admin/imap_migration/MigrationsView.vue:4 +msgid "Migrations" +msgstr "" + +#: src/plugins/rules.js:32 +msgid "Minimum length is %{ length }" +msgstr "" + +#: src/components/admin/identities/AliasSummary.vue:12 +msgid "Modified" +msgstr "" + +#: src/components/tools/CreationSummary.vue:10 +msgid "Modify" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:207 +msgid "Monitoring" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:110 +msgid "Month" +msgstr "" + +#: src/plugins/rules.js:37 +msgid "Must be a numeric value or empty" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:15 +msgid "MX records" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:170 +#: src/components/admin/domains/DomainAdminList.vue:106 +#: src/components/admin/domains/DomainAliasForm.vue:8 +#: src/components/admin/domains/DomainCreationForm.vue:163 +#: src/components/admin/domains/DomainList.vue:200 +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:11 +#: src/components/admin/identities/IdentityList.vue:118 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:53 +#: src/components/admin/imap_migration/ProvidersList.vue:96 +#: src/views/admin/InformationView.vue:57 +msgid "Name" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:12 +msgid "Name of the administrator" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:6 +msgid "Name of the domain to migrate" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:14 +msgid "Name:" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:16 +msgid "Name: " +msgstr "" + +#: src/components/admin/identities/AccountSummary.vue:16 +msgid "Never logged-in" +msgstr "" + +#: src/views/admin/domains/DomainsView.vue:28 +#: src/views/admin/identities/IdentitiesView.vue:28 +#: src/views/admin/imap_migration/ProvidersView.vue:12 +msgid "New" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:4 +#: src/components/admin/imap_migration/MigrationsList.vue:78 +msgid "New account" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:4 +msgid "New alias" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:4 +msgid "New domain" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:4 +msgid "New provider" +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:4 +msgid "New recovery codes" +msgstr "" + +#: src/components/tools/CreationForm.vue:68 +msgid "Next" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "no" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:223 +#: src/components/admin/domains/DNSDetail.vue:243 +#: src/components/admin/domains/DomainList.vue:241 +#: src/components/admin/identities/IdentityList.vue:209 +#: src/components/admin/identities/IdentityList.vue:235 +#: src/components/tools/CreationForm.vue:133 +msgid "No" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:40 +msgid "No associated domains" +msgstr "" + +#: src/mixins/importExport.js:8 +msgid "No data to export" +msgstr "" + +#: src/components/admin/identities/DomainAdminDomains.vue:13 +msgid "No domain managed" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:11 +msgid "No sender address defined for this account" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:89 +msgid "No sending limit" +msgstr "" + +#: src/plugins/rules.js:7 +msgid "Not a valid email" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:126 +msgid "Not generated" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:165 +msgid "Number of allowed mailbox aliases:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:158 +msgid "Number of allowed mailboxes:" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:125 +msgid "Number of associated alias:" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:36 +msgid "Number of associated domains:" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:34 +msgid "" +"Number of messages this domain can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:28 +msgid "" +"Number of messages this mailbox can send per day. Leave empty for no limit." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:76 +#: src/views/login/PasswordRecoveryForm.vue:75 +msgid "Ok" +msgstr "" + +#: src/components/tools/ConfirmDialog.vue:48 +msgid "OK" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:77 +msgid "Old account" +msgstr "" + +#: src/views/admin/InformationView.vue:18 +msgid "One or more updates are available" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:43 +msgid "Opened" +msgstr "" + +#: src/views/admin/alarms/AlarmsView.vue:3 +msgid "Opened alarms" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:145 +#: src/components/admin/domains/DomainCreationForm.vue:235 +msgid "Options" +msgstr "" + +#: src/components/account/ProfileForm.vue:30 +msgid "or suggest a new language" +msgstr "" + +#: src/views/admin/ParametersView.vue:150 +msgid "Parameters updated" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:128 +#: src/components/admin/dmarc/DmarcAligmentChart.vue:148 +msgid "Partially aligned" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:54 +msgid "Partially trusted sources / Forwarders" +msgstr "" + +#: src/components/account/ProfileForm.vue:69 +#: src/components/account/TwoFactorAuthForm.vue:75 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:52 +#: src/components/login/LoginForm.vue:70 +msgid "Password" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:280 +#: src/components/admin/identities/AccountCreationForm.vue:205 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:105 +msgid "Password copied to clipboard" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:100 +msgid "Password mismatch" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:12 +msgid "Password recovery" +msgstr "" + +#: src/components/account/ProfileForm.vue:143 +msgid "Password updated" +msgstr "" + +#: src/plugins/rules.js:39 +msgid "Passwords mismatch" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:20 +#: src/components/admin/domains/DNSDetail.vue:40 +#: src/components/admin/domains/DNSStatusChip.vue:21 +msgid "Pending" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:9 +msgid "Period" +msgstr "" + +#: src/components/account/ProfileForm.vue:47 +#: src/components/account/ProfileForm.vue:50 +#: src/components/admin/identities/AccountSummary.vue:31 +msgid "Phone number" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:39 +msgid "Pin code" +msgstr "" + +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:62 +msgid "Please add at least one recipient." +msgstr "" + +#: src/components/login/PasswordRecoveryForm.vue:16 +#: src/views/login/PasswordRecoveryForm.vue:21 +msgid "Please fill-in your primary email address" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:55 +#: src/components/admin/imap_migration/ProvidersList.vue:98 +msgid "Port" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:24 +msgid "Problem" +msgstr "" + +#: src/views/account/APISetupView.vue:106 +msgid "Proceed" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:267 src/layouts/dashboard/NavBar.vue:294 +#: src/views/account/ProfileView.vue:4 +msgid "Profile" +msgstr "" + +#: src/components/account/ProfileForm.vue:125 +msgid "Profile updated" +msgstr "" + +#: src/components/tools/ImportForm.vue:10 +msgid "Provide a CSV file where lines respect one of the following formats:" +msgstr "" + +#: src/components/admin/imap_migration/MigrationsList.vue:76 +msgid "Provider" +msgstr "" + +#: src/components/admin/imap_migration/ProviderCreationForm.vue:127 +msgid "Provider created" +msgstr "" + +#: src/stores/providers.store.js:45 +msgid "Provider deleted" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:5 +msgid "Provider name" +msgstr "" + +#: src/components/admin/imap_migration/ProviderForm.vue:133 +msgid "Provider updated" +msgstr "" + +#: src/views/admin/imap_migration/ProvidersView.vue:4 +msgid "Providers" +msgstr "" + +#: src/components/admin/logs/MessageList.vue:42 +msgid "Queue ID" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:190 +#: src/components/admin/domains/DomainList.vue:204 +#: src/components/admin/domains/DomainSummary.vue:16 +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:5 +#: src/components/admin/identities/AccountCreationForm.vue:122 +#: src/components/admin/identities/AccountSummary.vue:36 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:3 +msgid "Quota" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:15 +msgid "" +"Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a " +"custom value or use domain's default one. Leave empty to define an unlimited " +"value (not allowed for domain administrators)." +msgstr "" + +#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:7 +msgid "" +"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. " +"A value of 0 means no quota." +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:79 +#: src/components/admin/identities/AccountEditForm.vue:80 +#: src/components/admin/identities/AccountEditForm.vue:86 +msgid "Quota: " +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:56 +#: src/components/admin/identities/form_steps/AliasGeneralForm.vue:6 +msgid "Random address" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:252 +#: src/components/admin/identities/AccountCreationForm.vue:103 +#: src/components/admin/identities/form_steps/AccountPasswordSubForm.vue:19 +msgid "Random password" +msgstr "" + +#: src/components/admin/domains/DomainDKIMKey.vue:9 +msgid "Raw format. Click to copy" +msgstr "" + +#: src/components/account/ForwardForm.vue:4 +msgid "Recipient(s)" +msgstr "" + +#: src/components/admin/identities/AliasCreationForm.vue:77 +#: src/components/admin/identities/AliasCreationForm.vue:80 +#: src/components/admin/identities/AliasCreationForm.vue:97 +#: src/components/admin/identities/AliasEditForm.vue:38 +#: src/components/admin/identities/AliasRecipientsSummary.vue:4 +msgid "Recipients" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:42 +msgid "Register" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:27 +msgid "Relative time ranges" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:77 +msgid "Relay" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:60 +msgid "relaydomain" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:116 +msgid "Reload" +msgstr "" + +#: src/components/login/LoginForm.vue:77 +msgid "Remember me" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:37 +msgid "Remove this address" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:47 +msgid "Remove this administrator" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:140 +msgid "Reopen alarm" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:99 +msgid "Reseller" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:39 +msgid "Resend SMS." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:93 +msgid "Reset recovery codes" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:144 +#: src/components/admin/identities/AccountEditForm.vue:143 +msgid "Resources" +msgstr "" + +#: src/components/tools/ResourcesView.vue:4 +msgid "Resources usage" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:73 +msgid "Retry reset" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:45 +#: src/components/login/PasswordRecoveryForm.vue:38 +#: src/components/login/PasswordRecoveryForm.vue:77 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:44 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:72 +#: src/views/login/PasswordRecoveryForm.vue:43 +#: src/views/login/PasswordRecoveryForm.vue:76 +msgid "Return to login" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:157 +#: src/components/admin/identities/AccountCreationForm.vue:92 +#: src/components/admin/identities/AccountCreationForm.vue:93 +#: src/components/admin/identities/AccountEditForm.vue:9 +#: src/components/admin/identities/AccountSummary.vue:23 +msgid "Role" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:163 +#: src/components/admin/identities/AccountEditForm.vue:193 +#: src/components/admin/identities/AliasEditForm.vue:74 +#: src/components/admin/imap_migration/ProviderForm.vue:60 +msgid "Save" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:38 +#: src/components/admin/identities/IdentityList.vue:39 +#: src/components/admin/imap_migration/ProvidersList.vue:39 +#: src/components/admin/logs/AuditTrailList.vue:17 +#: src/components/admin/logs/MessageList.vue:17 +msgid "Search" +msgstr "" + +#: src/components/account/ProfileForm.vue:54 +#: src/components/admin/identities/AccountSummary.vue:27 +msgid "Secondary email" +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderGeneralForm.vue:24 +#: src/components/admin/imap_migration/ProviderCreationForm.vue:57 +#: src/components/admin/imap_migration/ProvidersList.vue:99 +msgid "Secured" +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:273 src/views/account/SecurityView.vue:4 +msgid "Security" +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:20 +msgid "Select an account" +msgstr "" + +#: src/components/tools/ImportForm.vue:22 +msgid "Select file" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:92 +msgid "Send only" +msgstr "" + +#: src/components/admin/identities/AccountCreationForm.vue:132 +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:40 +msgid "Send only account" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:5 +msgid "Sender addresses" +msgstr "" + +#: src/components/admin/domains/DomainList.vue:203 +msgid "Sending limit" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:84 +msgid "Sending limit: " +msgstr "" + +#: src/components/tools/ImportForm.vue:31 +msgid "Separator" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:216 +#: src/components/admin/domains/form_steps/DomainTransportForm.vue:3 +msgid "Service" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:116 +msgid "Service: " +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:246 +msgid "Settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:108 +msgid "Show key" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:80 +msgid "Simple user" +msgstr "" + +#: src/components/admin/identities/AccountSenderAddresses.vue:18 +msgid "Specify an email address" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:76 +msgid "SPF record found" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:79 +msgid "SPF record not found" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountAliasForm.vue:6 +#: src/components/admin/identities/form_steps/AliasRecipientForm.vue:6 +msgid "Start typing a name here..." +msgstr "" + +#: src/layouts/dashboard/NavBar.vue:211 +#: src/views/admin/domains/DomainView.vue:24 +#: src/views/admin/monitoring/StatisticsView.vue:3 +msgid "Statistics" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:93 +#: src/components/admin/logs/MessageList.vue:44 +msgid "Status" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:40 +#: src/components/login/PasswordRecoveryForm.vue:33 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:34 +#: src/views/login/PasswordRecoveryForm.vue:38 +msgid "Submit" +msgstr "" + +#: src/components/tools/CreationForm.vue:20 +#: src/components/tools/CreationForm.vue:73 +msgid "Summary" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountRoleForm.vue:106 +msgid "Super administrator" +msgstr "" + +#: src/components/tools/EmailField.vue:58 +msgid "SuperAdmins cannot own a mailbox" +msgstr "" + +#: src/components/admin/identities/IdentityList.vue:120 +msgid "Tags" +msgstr "" + +#: src/components/tools/ImportForm.vue:16 +msgid "" +"The first element of each line is mandatory and must be equal to one of the " +"previous values." +msgstr "" + +#: src/components/account/RecoveryCodesResetDialog.vue:9 +#: src/components/account/TwoFactorAuthForm.vue:57 +msgid "" +"The following recovery codes can be used one time each to let you regain " +"access to your account, in case you lose your phone for example. Make sure " +"to save them in a safe place, otherwise you won't be able to access your " +"account anymore." +msgstr "" + +#: src/components/account/ProfileForm.vue:34 +msgid "there" +msgstr "" + +#: src/views/Dashboard.vue:6 +msgid "This page is still under construction." +msgstr "" + +#: src/components/admin/logs/MessageList.vue:45 +#: src/components/tools/TimeSerieChart.vue:20 +msgid "To" +msgstr "" + +#: src/components/login/LoginForm.vue:44 +#: src/components/login/PasswordRecoveryChangeForm.vue:126 +#: src/components/login/PasswordRecoveryForm.vue:125 +#: src/components/login/PasswordRecoverySmsTotpForm.vue:103 +#: src/views/login/PasswordRecoveryForm.vue:124 +msgid "Too many unsuccessful attempts, please try later." +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:140 +#: src/components/admin/dmarc/DmarcSourceTable.vue:11 +msgid "Total" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:89 +msgid "TOTP resent." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:151 +#: src/components/admin/domains/DomainCreationForm.vue:214 +#: src/components/admin/domains/DomainEditForm.vue:108 +msgid "Transport" +msgstr "" + +#: src/components/admin/alarms/AlarmList.vue:92 +msgid "Triggered" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:48 +msgid "Trusted sources" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:6 +msgid "Two factor authentication" +msgstr "" + +#: src/components/login/TwofaForm.vue:6 +msgid "Two-factor authentication" +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:101 +msgid "" +"Two-Factor Authentication (2FA) is not yet activated for your account. " +"Enabling this feature will increase your account's security." +msgstr "" + +#: src/components/account/TwoFactorAuthForm.vue:71 +msgid "Two-Factor Authentication is enabled for your account." +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:164 +#: src/components/admin/domains/form_steps/DomainGeneralForm.vue:13 +msgid "Type" +msgstr "" + +#: src/components/admin/domains/DomainEditForm.vue:19 +msgid "Type: " +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:29 +msgid "Unknown" +msgstr "" + +#: src/components/admin/dmarc/DmarcAligmentChart.vue:68 +msgid "Unknown sources / Threats" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:109 +msgid "unlimited" +msgstr "" + +#: src/components/admin/domains/DomainSummary.vue:18 +#: src/components/admin/domains/DomainSummary.vue:25 +#: src/components/admin/identities/AccountSummary.vue:38 +msgid "Unlimited" +msgstr "" + +#: src/components/account/ForwardForm.vue:25 +#: src/components/admin/domains/DomainAliasForm.vue:68 +msgid "Update" +msgstr "" + +#: src/components/account/ProfileForm.vue:75 +msgid "Update Password" +msgstr "" + +#: src/components/account/ProfileForm.vue:62 +msgid "Update settings" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:172 +msgid "Updated" +msgstr "" + +#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:106 +msgid "Use domain default value" +msgstr "" + +#: src/components/login/PasswordRecoverySmsTotpForm.vue:97 +msgid "User seems wrong, return to login or restart reset the process?" +msgstr "" + +#: src/components/login/PasswordRecoveryChangeForm.vue:117 +msgid "User unknown." +msgstr "" + +#: src/components/admin/domains/DomainAdminList.vue:105 +#: src/components/admin/identities/AccountCreationForm.vue:98 +#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3 +#: src/components/login/LoginForm.vue:62 +msgid "Username" +msgstr "" + +#: src/components/admin/identities/AccountEditForm.vue:39 +msgid "Username:" +msgstr "" + +#: src/components/admin/domains/DNSStatusChip.vue:27 +msgid "Valid" +msgstr "" + +#: src/components/login/TwofaForm.vue:31 +msgid "Verify code" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:217 +msgid "warning" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:237 +#: src/components/admin/domains/DomainList.vue:235 +#: src/components/admin/identities/IdentityList.vue:204 +#: src/components/admin/identities/IdentityList.vue:230 +#: src/components/tools/CreationForm.vue:126 +#: src/views/account/APISetupView.vue:101 +msgid "Warning" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:109 +msgid "Week" +msgstr "" + +#: src/views/Dashboard.vue:3 +msgid "Welcome to Modoboa" +msgstr "" + +#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25 +msgid "With a mailbox" +msgstr "" + +#: src/components/admin/domains/DomainCreationForm.vue:257 +msgid "With mailbox" +msgstr "" + +#: src/components/tools/TimeSerieChart.vue:111 +msgid "Year" +msgstr "" + +#: src/plugins/filters.js:9 +msgid "yes" +msgstr "" + +#: src/components/admin/domains/DNSDetail.vue:224 +#: src/components/admin/domains/DNSDetail.vue:244 +#: src/components/admin/domains/DomainList.vue:242 +#: src/components/admin/identities/IdentityList.vue:208 +#: src/components/admin/identities/IdentityList.vue:234 +#: src/components/tools/CreationForm.vue:132 +msgid "Yes" +msgstr "" + +#: src/views/account/APISetupView.vue:102 +msgid "You are about to delete your API access token" +msgstr "" + +#: src/components/tools/ImportForm.vue:20 +msgid "You can use a different character as separator." +msgstr "" + +#: src/components/admin/imap_migration/form_steps/ProviderAssociatedForm.vue:115 +msgid "You need to bind at least one domain to the provider." +msgstr "" + +#: src/views/account/APISetupView.vue:9 +msgid "Your API token has not been generated yet." +msgstr "" + +#: src/views/account/APISetupView.vue:25 +msgid "Your API token is:" +msgstr "" diff --git a/frontend/src/main.js b/frontend/src/main.js index 8493baa0f..ca186bb61 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -1,33 +1,34 @@ -import Vue from 'vue' -import './plugins/vee-validate' -import './plugins/vue-cookie' -import './plugins/vue-gettext' -import './filters' +/** + * main.js + * + * Bootstraps Vuetify and other plugins then mounts the App` + */ + +// Plugins +import { registerPlugins } from '@/plugins' + +// Components import App from './App.vue' -import router from './router' -import store from './store' -import vuetify from './plugins/vuetify' -import sassStyles from './styles/global.scss' // eslint-disable-line no-unused-vars -import repository from './api/repository' -Vue.config.productionTip = false +// Composables +import { createApp } from 'vue' -export const bus = new Vue() +//api +import repository from '@/api/repository.js' -fetch(process.env.BASE_URL + 'config.json').then(resp => { +fetch(import.meta.env.BASE_URL + 'config.json').then((resp) => { resp.json().then((config) => { if (!config.API_BASE_URL) { throw Error('API_BASE_URL is not defined in config.json') } repository.defaults.baseURL = config.API_BASE_URL - Vue.prototype.$config = config + const app = createApp(App) - new Vue({ - router, - store, - vuetify, - render: h => h(App) - }).$mount('#app') + registerPlugins(app) + + app.mount('#app') + + app.provide('$config', config) }) }) diff --git a/frontend/src/mixins/importExport.js b/frontend/src/mixins/importExport.js index 202751635..e7c97f1ae 100644 --- a/frontend/src/mixins/importExport.js +++ b/frontend/src/mixins/importExport.js @@ -1,29 +1,45 @@ -import { bus } from '@/main' +import { useBusStore } from '@/stores' -export const importExportMixin = { - methods: { - exportContent (content, name) { - const blob = new Blob([content], { type: 'text/csv' }) - const link = document.createElement('a') - link.href = URL.createObjectURL(blob) - link.download = `modoboa-${name}.csv` - link.click() - URL.revokeObjectURL(link.href) - }, - importContent (api, data) { - api.importFromCSV(data).then(resp => { +export const importExportMixin = () => { + function exportContent(content, name, $gettext) { + if (!content && !content.length) { + const busStore = useBusStore() + busStore.displayNotification({ + msg: $gettext('No data to export'), + type: 'warning', + }) + return + } + const blob = new Blob([content], { type: 'text/csv' }) + const link = document.createElement('a') + link.href = URL.createObjectURL(blob) + link.download = `modoboa-${name}.csv` + link.click() + URL.revokeObjectURL(link.href) + } + + function importContent(api, data, importForm, $gettext) { + api + .importFromCSV(data) + .then((resp) => { + const busStore = useBusStore() if (resp.data.status) { - bus.$emit('notification', { msg: resp.data.message }) - this.$refs.importForm.close() + busStore.displayNotification({ msg: resp.data.message }) + importForm.value.close() } else { - bus.$emit('notification', { msg: resp.data.message, type: 'error' }) + busStore.displayNotification({ + msg: resp.data.message, + type: 'error', + }) } - }).catch(() => { - bus.$emit('notification', { - msg: this.$gettext('CSV seems to be badly formatted'), - type: 'error' + }) + .catch(() => { + const busStore = useBusStore() + busStore.displayNotification({ + msg: $gettext('CSV seems to be badly formatted'), + type: 'error', }) }) - } } + return { exportContent, importContent } } diff --git a/frontend/src/plugins/filters.js b/frontend/src/plugins/filters.js new file mode 100644 index 000000000..4caeaa4e5 --- /dev/null +++ b/frontend/src/plugins/filters.js @@ -0,0 +1,21 @@ +import gettext from './gettext' +import { DateTime } from 'luxon' + +const { $gettext } = gettext + +export default { + install: (app) => { + app.config.globalProperties.$yesno = (value) => { + return value ? $gettext('yes') : $gettext('no') + } + app.config.globalProperties.$date = (value) => { + return DateTime.fromISO(value) + .setLocale('en') + .toLocaleString(DateTime.DATETIME_MED) + } + app.config.globalProperties.$truncate = (value, length, clamp) => { + clamp = clamp || '...' + return value.length > length ? value.slice(0, length) + clamp : value + } + }, +} diff --git a/frontend/src/plugins/gettext.js b/frontend/src/plugins/gettext.js new file mode 100644 index 000000000..b01f8c85b --- /dev/null +++ b/frontend/src/plugins/gettext.js @@ -0,0 +1,27 @@ +import { createGettext } from 'vue3-gettext' +import translations from '@/locale/translations.json' + +export default createGettext({ + availableLanguages: { + en: 'English', + cs: 'Czech', + de: 'German', + br: 'Breton', + el: 'Greek', + es: 'Spain', + fi: 'Finnish', + fr: 'French', + it: 'Italian', + ja: 'Japanese', + nl: 'Dutch', + pl: 'Polish', + pt: 'Portuguese', + ru: 'Russian', + sv: 'Swedish', + tr: 'tr', + zh: 'Chinese', + }, + defaultLanguage: 'en', + translations: translations, + silent: true, // stop warnings +}) diff --git a/frontend/src/plugins/index.js b/frontend/src/plugins/index.js new file mode 100644 index 000000000..af0f19c3f --- /dev/null +++ b/frontend/src/plugins/index.js @@ -0,0 +1,23 @@ +/** + * plugins/index.js + * + * Automatically included in `./src/main.js` + */ + +// Plugins +import vuetify from './vuetify' +import router from '../router' +import gettext from './gettext' +import filters from './filters' +import pinia from '@/stores' +import VueApexCharts from 'vue3-apexcharts' + +export function registerPlugins(app) { + app + .use(gettext) + .use(vuetify) + .use(pinia) + .use(router) + .use(filters) + .use(VueApexCharts) +} diff --git a/frontend/src/plugins/rules.js b/frontend/src/plugins/rules.js new file mode 100644 index 000000000..e9c804b87 --- /dev/null +++ b/frontend/src/plugins/rules.js @@ -0,0 +1,42 @@ +import gettext from './gettext' + +const { $gettext } = gettext + +function validateEmail(email) { + if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { + return $gettext('Not a valid email') + } else { + return true + } +} + +function validateNumeric(value) { + if (isNaN(value)) { + return false + } + var x = parseFloat(value) + return (x | 0) === x +} + +function samePassword(value, confirmation) { + return value === confirmation +} + +export default { + required: (value) => + (value !== '' && value != null) || $gettext('Field is required'), + email: (value) => validateEmail(value), + emailOrNull: (value) => value != null || value !== '' || validateEmail(value), + minLength: (len) => (value) => + value.length > len || + $gettext('Minimum length is %{ length }', { length: len }), + numericOrNull: (value) => + value == null || + value === '' || + validateNumeric(value) || + $gettext('Must be a numeric value or empty'), + samePassword: (value, confirmation) => + samePassword(value, confirmation) || $gettext('Passwords mismatch'), + portNumber: (value) => + (value > 0 && value < 65536) || $gettext('Invalid port number'), +} diff --git a/frontend/src/plugins/vee-validate.js b/frontend/src/plugins/vee-validate.js deleted file mode 100644 index bf78b912b..000000000 --- a/frontend/src/plugins/vee-validate.js +++ /dev/null @@ -1,58 +0,0 @@ -import Vue from 'vue' -import { ValidationObserver, ValidationProvider, extend } from 'vee-validate' -import { confirmed, email, numeric, required } from 'vee-validate/dist/rules' -import { translate } from 'vue-gettext' -import account from '@/api/account' - -const { gettext: $gettext } = translate - -// Declare builtin rules here -extend('samePassword', { - ...confirmed, - message: () => $gettext('Passwords mismatch') -}) -extend('numeric', { - ...numeric, - message: () => $gettext('This field must be a valid number') -}) -extend('minmax', { - validate: async (value, args) => { - return value.length >= args.length && value.length <= args.length - }, - params: ['length'], - message: $gettext('This field must have a length of {length} characters') -}) -extend('required', { - ...required, - message: () => $gettext('This field is required') -}) -extend('email', { - ...email, - message: () => $gettext('Specify an email address') -}) - -// Add custom rules here -extend('validPassword', { - validate: async (value) => { - try { - await account.checkPassword(value) - return true - } catch (error) { - return false - } - }, - message: $gettext('Invalid password') -}) -extend('portNumber', { - validate: async (value) => { - if (value < 0 || value > 65535) { - return false - } - return true - }, - message: $gettext('Specify a valid port number') -}) - -// Register components globally -Vue.component('ValidationObserver', ValidationObserver) -Vue.component('ValidationProvider', ValidationProvider) diff --git a/frontend/src/plugins/vue-cookie.js b/frontend/src/plugins/vue-cookie.js deleted file mode 100644 index ad6b8acca..000000000 --- a/frontend/src/plugins/vue-cookie.js +++ /dev/null @@ -1,4 +0,0 @@ -import Vue from 'vue' -import VueCookie from 'vue-cookie' - -Vue.use(VueCookie) diff --git a/frontend/src/plugins/vue-gettext.js b/frontend/src/plugins/vue-gettext.js deleted file mode 100644 index 371eee090..000000000 --- a/frontend/src/plugins/vue-gettext.js +++ /dev/null @@ -1,16 +0,0 @@ -import Vue from 'vue' -import GetTextPlugin from 'vue-gettext' -import translations from '@/translations.json' - -Vue.use(GetTextPlugin, { - autoAddKeyAttributes: true, - availableLanguages: { - en: 'English', - fr: 'Français' - }, - translations: translations -}) - -Vue.filter('translate', value => { - return !value ? '' : Vue.prototype.$gettext(value.toString()) -}) diff --git a/frontend/src/plugins/vuetify.js b/frontend/src/plugins/vuetify.js index c8df96438..2a2881f39 100644 --- a/frontend/src/plugins/vuetify.js +++ b/frontend/src/plugins/vuetify.js @@ -1,20 +1,36 @@ +/** + * plugins/vuetify.js + * + * Framework documentation: https://vuetifyjs.com` + */ + +// Styles import '@mdi/font/css/materialdesignicons.css' -import Vue from 'vue' -import Vuetify from 'vuetify/lib' +import 'vuetify/styles' -Vue.use(Vuetify) +// Composables +import { createVuetify } from 'vuetify' -export default new Vuetify({ +// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides +export default createVuetify({ theme: { - options: { - customProperties: true - }, themes: { light: { - primary: '#046BF8', - secondary: '#F18429', - label: '#616161' - } - } - } + colors: { + primary: '#046BF8', + 'primary-lighten-1': '#3688F9', + 'primary-darken-1': '#0350BA', + secondary: '#F18429', + label: '#616161', + }, + }, + }, + }, + styles: { configFile: 'src/styles/settings.scss' }, + defaults: { + VCard: { + class: 'pa-2', + VCardTitle: { class: 'd-flex', style: 'align-items: center;' }, + }, + }, }) diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index a91738e8a..665c64fa7 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -1,264 +1,319 @@ -import Vue from 'vue' -import VueRouter from 'vue-router' - -import store from '@/store' - -import ParametersForm from '@/components/parameters/ParametersForm' - -Vue.use(VueRouter) +// Composables +import { createRouter, createWebHistory } from 'vue-router' +import { useAuthStore } from '@/stores' const routes = [ - { - path: '/', - name: 'Dashboard', - component: () => import(/* webpackChunkName: "dashboard" */ '../views/Dashboard.vue'), - meta: { - requiresAuth: true - } - }, { path: '/login', - name: 'Login', - // route level code-splitting - // this generates a separate chunk (about.[hash].js) for this route - // which is lazy-loaded when the route is visited. - component: () => import(/* webpackChunkName: "about" */ '../views/Login.vue'), - meta: { - layoutTemplate: 'empty' - } + component: () => import('@/layouts/default/DefaultLayout.vue'), + children: [ + { + path: '', + name: 'Login', + component: () => import('@/views/login/LoginView.vue'), + }, + { + path: 'twofa', + name: 'TwoFA', + component: () => import('@/views/login/TwoFA.vue'), + }, + { + path: 'password_recovery', + name: 'PasswordRecovery', + component: () => import('../views/login/PasswordRecoveryView.vue'), + }, + { + path: 'password_recovery/confirm/:id?/:token?/', + name: 'PasswordRecoveryChangeForm', + component: () => + import('../views/login/PasswordRecoveryChangeView.vue'), + }, + { + path: 'password_recovery/sms_confirm', + name: 'PasswordRecoverySms', + component: () => + import('../views/login/PasswordRecoverySmsTotpView.vue'), + }, + ], }, { - path: '/twofa', - name: 'TwoFA', - component: () => import('../views/TwoFA.vue'), - meta: { - layoutTemplate: 'empty' - } + path: '/admin', + component: () => import('@/layouts/dashboard/DashboardLayout.vue'), + children: [ + { + path: '', + name: 'Dashboard', + component: () => import('@/views/Dashboard.vue'), + meta: { + requiresAuth: true, + }, + }, + { + path: 'domains', + component: () => import('@/layouts/default/DefaultLayout.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'], + }, + children: [ + { + path: '', + name: 'DomainList', + component: () => import('@/views/admin/domains/DomainsView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'], + }, + }, + { + path: ':id', + name: 'DomainDetail', + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'], + }, + component: () => import('@/views/admin/domains/DomainView.vue'), + }, + { + path: ':id/edit', + name: 'DomainEdit', + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'], + }, + component: () => import('@/views/admin/domains/DomainEditView.vue'), + }, + ], + }, + { + path: 'imap_migration', + component: () => import('@/layouts/default/DefaultLayout.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'], + }, + children: [ + { + path: 'migrations', + name: 'MigrationsList', + component: () => + import('@/views/admin/imap_migration/MigrationsView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['Resellers', 'SuperAdmins'], + }, + }, + { + path: 'providers', + component: () => import('@/layouts/default/DefaultLayout.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['Resellers', 'SuperAdmins'], + }, + children: [ + { + path: '', + name: 'ProvidersList', + component: () => + import('@/views/admin/imap_migration/ProvidersView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['Resellers', 'SuperAdmins'], + }, + }, + { + path: 'providers/:id/edit', + name: 'ProviderEdit', + component: () => + import('@/views/admin/imap_migration/ProviderEditView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['Resellers', 'SuperAdmins'], + }, + }, + ], + }, + ], + }, + { + path: 'identities', + component: () => import('@/layouts/default/DefaultLayout.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'], + }, + children: [ + { + path: '', + name: 'Identities', + component: () => + import('@/views/admin/identities/IdentitiesView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'], + }, + }, + { + path: 'accounts/:id', + name: 'AccountDetail', + component: () => import('@/views/admin/identities/AccountView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'], + }, + }, + { + path: 'accounts/:id/edit', + name: 'AccountEdit', + component: () => + import('@/views/admin/identities/AccountEditView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'], + }, + }, + { + path: 'aliases/:id', + name: 'AliasDetail', + component: () => import('@/views/admin/identities/AliasView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'], + }, + }, + { + path: 'aliases/:id/edit', + name: 'AliasEdit', + component: () => + import('@/views/admin/identities/AliasEditView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'], + }, + }, + ], + }, + { + path: 'parameters/:app', + name: 'ParametersEdit', + component: () => import('@/views/admin/ParametersView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['SuperAdmins'], + }, + }, + { + path: 'alarms', + name: 'Alarms', + component: () => import('@/views/admin/alarms/AlarmsView.vue'), + meta: { + requiresAuth: true, + }, + }, + { + path: 'monitoring/statistics', + name: 'Statistics', + component: () => import('@/views/admin/monitoring/StatisticsView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['SuperAdmins'], + }, + }, + { + path: 'monitoring/audit_trail', + name: 'AuditTrail', + component: () => import('@/views/admin/monitoring/AuditTrailView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['SuperAdmins'], + }, + }, + { + path: 'monitoring/messages', + name: 'MessageLog', + component: () => import('@/views/admin/monitoring/MessagesView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['DomainAdmins', 'SuperAdmins'], + }, + }, + { + path: 'information', + name: 'Information', + component: () => import('@/views/admin/InformationView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['SuperAdmins'], + }, + }, + ], }, { - path: '/domains', - name: 'DomainList', - component: () => import('../views/domains/Domains.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'] - } + path: '/account', + component: () => import('@/layouts/dashboard/DashboardLayout.vue'), + meta: { layout: 'account' }, + children: [ + { + path: 'api', + name: 'APISetup', + component: () => import('@/views/account/APISetupView.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['SuperAdmins'], + }, + }, + { + path: 'profile', + name: 'UserProfile', + component: () => import('@/views/account/ProfileView.vue'), + meta: { + requiresAuth: true, + }, + }, + { + path: 'security', + name: 'UserSecurity', + component: () => import('@/views/account/SecurityView.vue'), + meta: { + requiresAuth: true, + }, + }, + { + path: 'forward', + name: 'UserForward', + component: () => import('@/views/account/ForwardView.vue'), + meta: { + requiresAuth: true, + }, + }, + ], }, { - path: '/domains/:id', - name: 'DomainDetail', - component: () => import('../views/domains/Domain.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'] - } + path: '/:pathMatch(.*)*', + name: 'NotFound', + redirect: { name: 'Dashboard', params: {} }, }, - { - path: '/domains/:id/edit', - name: 'DomainEdit', - component: () => import('../views/domains/DomainEdit.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'] - } - }, - { - path: '/imap_migration/migrations', - name: 'MigrationsList', - component: () => import('../components/imap_migration/MigrationsList.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['Resellers', 'SuperAdmins'] - } - }, - { - path: '/imap_migration/providers', - name: 'ProvidersList', - component: () => import('../views/imap_migration/Providers.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['Resellers', 'SuperAdmins'] - } - }, - { - path: '/imap_migration/providers/:id/edit', - name: 'ProviderEdit', - component: () => import('../views/imap_migration/ProviderEdit.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['Resellers', 'SuperAdmins'] - } - }, - { - path: '/identities', - name: 'Identities', - component: () => import('../views/identities/Identities.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'] - } - }, - { - path: '/identities/accounts/:id', - name: 'AccountDetail', - component: () => import('../views/identities/Account.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'] - } - }, - { - path: '/identities/accounts/:id/edit', - name: 'AccountEdit', - component: () => import('../views/identities/AccountEdit.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'] - } - }, - { - path: '/identities/aliases/:id', - name: 'AliasDetail', - component: () => import('../views/identities/Alias.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'] - } - }, - { - path: '/identities/aliases/:id/edit', - name: 'AliasEdit', - component: () => import('../views/identities/AliasEdit.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['DomainAdmins', 'Resellers', 'SuperAdmins'] - } - }, - { - path: '/parameters/:app', - name: 'ParametersEdit', - component: ParametersForm, - meta: { - requiresAuth: true, - allowedRoles: ['SuperAdmins'] - } - }, - { - path: '/alarms', - name: 'Alarms', - component: () => import('../views/alarms/Alarms.vue'), - meta: { - requiresAuth: true - } - }, - { - path: '/monitoring/statistics', - name: 'Statistics', - component: () => import('../views/monitoring/Statistics.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['SuperAdmins'] - } - }, - { - path: '/monitoring/audit_trail', - name: 'AuditTrail', - component: () => import('../views/monitoring/AuditTrail.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['SuperAdmins'] - } - }, - { - path: '/monitoring/messages', - name: 'MessageLog', - component: () => import('../views/monitoring/Messages.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['DomainAdmins', 'SuperAdmins'] - } - }, - { - path: '/information', - name: 'Information', - component: () => import('../views/admin/Information.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['SuperAdmins'] - } - }, - { - path: '/user/api', - name: 'APISetup', - component: () => import('../views/user/APISetup.vue'), - meta: { - requiresAuth: true, - allowedRoles: ['SuperAdmins'], - layout: 'user' - } - }, - { - path: '/user/profile', - name: 'UserProfile', - component: () => import('../views/user/Profile.vue'), - meta: { - requiresAuth: true, - layout: 'user' - } - }, - { - path: '/user/security', - name: 'UserSecurity', - component: () => import('../views/user/Security.vue'), - meta: { - requiresAuth: true, - layout: 'user' - } - }, - { - path: '/user/forward', - name: 'UserForward', - component: () => import('../views/user/Forward.vue'), - meta: { - requiresAuth: true, - layout: 'user' - } - }, - { - path: '/password_recovery', - name: 'PasswordRecoveryForm', - component: () => import('../views/user/PasswordRecoveryForm.vue') - }, - { - path: '/password_recovery/confirm/:id?/:token?/', - name: 'PasswordRecoveryChangeForm', - component: () => import('../views/user/PasswordRecoveryChangeForm.vue') - }, - { - path: '/password_recovery/sms_confirm', - name: 'PasswordRecoverySms', - component: () => import('../views/user/PasswordRecoverySmsTotpForm.vue') - } ] -const router = new VueRouter({ - mode: 'history', - base: process.env.BASE_URL, - routes +const router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes, }) router.beforeEach((to, from, next) => { - if (to.matched.some(record => record.meta.requiresAuth)) { - store.dispatch('auth/initialize').then(() => { - if (!store.getters['auth/isAuthenticated']) { + if (to.meta.requiresAuth !== undefined) { + const authStore = useAuthStore() + authStore.initialize().then(() => { + if (!authStore.isAuthenticated) { next({ name: 'Login' }) } else { + /* if (to.meta.allowedRoles !== undefined) { - if (to.meta.allowedRoles.indexOf(store.getters['auth/authUser'].role) === -1) { + if (to.meta.allowedRoles.indexOf(authStore.authUser.role) === -1) { next({ name: 'Dashboard' }) return } - } + }*/ next() } }) diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js deleted file mode 100644 index f4241e4b1..000000000 --- a/frontend/src/store/index.js +++ /dev/null @@ -1,19 +0,0 @@ -import Vue from 'vue' -import Vuex from 'vuex' - -import auth from '@/store/modules/auth' -import domains from '@/store/modules/domains' -import identities from '@/store/modules/identities' -import providers from '@/store/modules/providers' - -Vue.use(Vuex) - -export default new Vuex.Store({ - modules: { - auth, - domains, - identities, - providers - }, - strict: process.env.NODE_ENV !== 'production' -}) diff --git a/frontend/src/store/modules/auth.js b/frontend/src/store/modules/auth.js deleted file mode 100644 index 1d4243697..000000000 --- a/frontend/src/store/modules/auth.js +++ /dev/null @@ -1,65 +0,0 @@ -import Cookies from 'js-cookie' -import Vue from 'vue' - -import repository from '@/api/repository' -import account from '@/api/account' - -function setupAxios (token) { - repository.defaults.headers.common.Authorization = `Bearer ${token}` - repository.defaults.headers.post['Content-Type'] = 'application/json' -} - -const state = () => ({ - authUser: {}, - isAuthenticated: false -}) - -const getters = { - isAuthenticated: state => state.isAuthenticated, - authUser: state => state.authUser -} - -const mutations = { - SET_AUTH_USER (state, { authUser, isAuthenticated }) { - state.authUser = authUser - state.isAuthenticated = isAuthenticated - Vue.config.language = authUser.language - }, - LOGOUT_USER (state) { - state.authUser = null - state.isAuthenticated = false - } -} - -const actions = { - fetchUser ({ commit }) { - return account.getMe().then(resp => { - commit('SET_AUTH_USER', { authUser: resp.data, isAuthenticated: true }) - }) - }, - initialize ({ commit, dispatch, state }) { - const token = Cookies.get('token') - if (!token) { - return - } - setupAxios(token) - return dispatch('fetchUser') - }, - logout ({ commit }) { - return new Promise((resolve, reject) => { - delete repository.defaults.headers.common.Authorization - Cookies.remove('token') - Cookies.remove('refreshToken') - commit('LOGOUT_USER') - resolve() - }) - } -} - -export default { - namespaced: true, - state, - getters, - mutations, - actions -} diff --git a/frontend/src/store/modules/domains.js b/frontend/src/store/modules/domains.js deleted file mode 100644 index b5d0df93b..000000000 --- a/frontend/src/store/modules/domains.js +++ /dev/null @@ -1,86 +0,0 @@ -import Vue from 'vue' -import domainApi from '@/api/domains' - -// mutation types -const SET_DOMAINS = 'SET_DOMAINS' -const ADD_DOMAIN = 'ADD_DOMAIN' -const UPDATE_DOMAIN = 'UPDATE_DOMAIN' -const DELETE_DOMAIN = 'DELETE_DOMAIN' - -// initial state -const state = { - domainsLoaded: false, - domains: [] -} - -// getters -const getters = { - domains: state => state.domains, - domainsLoaded: state => state.domainsLoaded, - getDomainByPk: state => pk => { - for (const domain of state.domains) { - if (domain.pk === parseInt(pk, 10)) { - return domain - } - } - return null - } -} - -// actions -const actions = { - getDomains ({ commit }) { - return domainApi.getDomains().then(response => { - commit(SET_DOMAINS, { domains: response.data }) - }) - }, - createDomain ({ commit }, data) { - return new Promise((resolve, reject) => { - domainApi.createDomain(data).then(response => { - commit(ADD_DOMAIN, { domain: response.data }) - resolve(response) - }).catch(error => { - reject(error) - }) - }) - }, - updateDomain ({ commit }, data) { - return domainApi.updateDomain(data.pk, data).then(response => { - commit(UPDATE_DOMAIN, { domain: response.data }) - }) - }, - deleteDomain ({ commit }, { id, data }) { - return domainApi.deleteDomain(id, data).then(resp => { - commit(DELETE_DOMAIN, id) - }) - } -} - -// mutations -const mutations = { - [SET_DOMAINS] (state, { domains }) { - state.domainsLoaded = true - state.domains = domains - }, - [ADD_DOMAIN] (state, { domain }) { - state.domains.push(domain) - }, - [UPDATE_DOMAIN] (state, { domain }) { - state.domains.forEach(function (item, pos) { - if (item.pk === domain.pk) { - Vue.set(state.domains, pos, domain) - } - }) - }, - [DELETE_DOMAIN] (state, domainId) { - state.domains = state.domains.filter(item => item.pk !== domainId) - } -} - -export default { - namespaced: true, - state, - getters, - actions, - mutations -} diff --git a/frontend/src/store/modules/identities.js b/frontend/src/store/modules/identities.js deleted file mode 100644 index 1cfb25b34..000000000 --- a/frontend/src/store/modules/identities.js +++ /dev/null @@ -1,34 +0,0 @@ -import domainApi from '@/api/domains' - -const state = { - domains: [] -} - -const getters = { - domains: state => state.domains, - getDomainByName: state => name => { - return state.domains.find(domain => domain.name === name) - } -} - -const mutations = { - SET_DOMAINS (state, domains) { - state.domains = domains - } -} - -const actions = { - fetchDomains ({ commit }) { - domainApi.getDomains().then(resp => { - commit('SET_DOMAINS', resp.data) - }) - } -} - -export default { - namespaced: true, - state, - getters, - actions, - mutations -} diff --git a/frontend/src/store/modules/providers.js b/frontend/src/store/modules/providers.js deleted file mode 100644 index 127c42bb5..000000000 --- a/frontend/src/store/modules/providers.js +++ /dev/null @@ -1,73 +0,0 @@ -import Vue from 'vue' -import providerApi from '@/api/imap_migration/providers' - -// mutation types -export const ADD_PROVIDER = 'ADD_PROVIDER' -export const UPDATE_PROVIDER = 'SET_PROVIDER' -export const SET_PROVIDERS = 'SET_PROVIDERS' -export const DELETE_PROVIDER = 'DELETE_PROVIDER' - -const state = { - providersLoaded: false, - providers: [] -} - -const getters = { - providers: state => state.providers -} - -const actions = { - getProviders ({ commit }, params) { - return providerApi.getProviders(params).then(response => { - commit(SET_PROVIDERS, { providers: response.data }) - }) - }, - createProvider ({ commit }, data) { - return new Promise((resolve, reject) => { - providerApi.createProvider(data).then(response => { - commit(ADD_PROVIDER, { provider: response.data }) - resolve(response) - }).catch(error => { - reject(error) - }) - }) - }, - updateProvider ({ commit }, data) { - return providerApi.updateProvider(data.id, data).then(response => { - commit(UPDATE_PROVIDER, { provider: response.data }) - }) - }, - deleteProvider ({ commit }, data) { - return providerApi.deleteProvider(data.id).then(response => { - commit(DELETE_PROVIDER, data) - }) - } -} - -const mutations = { - [SET_PROVIDERS] (state, { providers }) { - state.providersLoaded = true - state.providers = providers - }, - [ADD_PROVIDER] (state, { provider }) { - state.providers.push(provider) - }, - [UPDATE_PROVIDER] (state, { provider }) { - state.providers.forEach(function (item, pos) { - if (item.pk === provider.pk) { - Vue.set(state.providers, pos, provider) - } - }) - }, - [DELETE_PROVIDER] (state, data) { - state.providers = state.providers.filter(item => item.id !== data.id) - } -} - -export default { - namespaced: true, - state, - getters, - actions, - mutations -} diff --git a/frontend/src/stores/accounts.store.js b/frontend/src/stores/accounts.store.js new file mode 100644 index 000000000..7af49f1fa --- /dev/null +++ b/frontend/src/stores/accounts.store.js @@ -0,0 +1,77 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' + +import { useBusStore } from './bus.store' + +import accountsApi from '@/api/accounts' +import gettext from '@/plugins/gettext' + +export const useAccountsStore = defineStore('accounts', () => { + const busStore = useBusStore() + + const { $gettext } = gettext + + const accounts = ref({}) + const accountsLoaded = ref(false) + + async function getAll() { + accounts.value = {} + return accountsApi.getAll().then((response) => { + for (const account of response.data) { + accounts.value[account.pk] = account + } + return response + }) + } + + async function getAccount(pk) { + accountsLoaded.value = false + return accountsApi + .get(pk) + .then((response) => { + accounts.value[pk] = response.data + return response + }) + .finally(() => { + accountsLoaded.value = true + }) + } + + async function updateAccount(data) { + return accountsApi.patch(data.pk, data).then((response) => { + accounts.value[data.pk] = response.data + busStore.displayNotification({ msg: $gettext('Account updated') }) + return response + }) + } + + async function createAccount(data) { + return accountsApi.create(data).then((response) => { + accounts.value[response.data.pk] = response.data + busStore.displayNotification({ msg: $gettext('Account created') }) + return response + }) + } + + async function deleteAccount(pk, options) { + accountsLoaded.value = false + return accountsApi + .delete(pk, options) + .then((response) => { + busStore.displayNotification({ + msg: $gettext('Account successfully deleted'), + }) + return response + }) + .finally(() => (accountsLoaded.value = true)) + } + return { + accounts, + accountsLoaded, + getAll, + getAccount, + updateAccount, + createAccount, + deleteAccount, + } +}) diff --git a/frontend/src/stores/aliases.store.js b/frontend/src/stores/aliases.store.js new file mode 100644 index 000000000..83ea1c8ab --- /dev/null +++ b/frontend/src/stores/aliases.store.js @@ -0,0 +1,89 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import aliasesApi from '@/api/aliases' +import { useBusStore } from './bus.store' + +import gettext from '@/plugins/gettext' + +export const useAliasesStore = defineStore('aliases', () => { + const busStore = useBusStore() + const { $gettext } = gettext + + const aliases = ref({}) + + const aliasesLoaded = ref(false) + + async function getAll() { + aliasesLoaded.value = false + return aliasesApi + .getAll() + .then((response) => { + aliases.value = {} + for (const account of response.data) { + aliases.value[account.pk] = account + } + return response + }) + .finally(() => (aliasesLoaded.value = true)) + } + + async function getAlias(pk) { + aliasesLoaded.value = false + return aliasesApi + .get(pk) + .then((response) => { + aliases.value[pk] = response.data + return response + }) + .finally(() => (aliasesLoaded.value = true)) + } + + async function createAlias(data) { + aliasesLoaded.value = false + return aliasesApi + .create(data) + .then((response) => { + aliases.value[response.data.pk] = response.data + busStore.displayNotification({ + msg: $gettext('Alias successfully created'), + }) + return response + }) + .finally(() => (aliasesLoaded.value = true)) + } + + async function deleteAlias(pk) { + aliasesLoaded.value = false + return aliasesApi + .delete(pk) + .then((response) => { + busStore.displayNotification({ + msg: $gettext('Alias successfully deleted'), + }) + return response + }) + .finally(() => (aliasesLoaded.value = true)) + } + + async function updateAlias(data) { + aliasesLoaded.value = false + return aliasesApi + .patch(data.pk, data) + .then((response) => { + aliases.value[data.pk] = response.data + busStore.displayNotification({ msg: $gettext('Alias updated') }) + return response + }) + .finally(() => (aliasesLoaded.value = true)) + } + + return { + aliases, + aliasesLoaded, + getAll, + getAlias, + createAlias, + deleteAlias, + updateAlias, + } +}) diff --git a/frontend/src/stores/auth.store.js b/frontend/src/stores/auth.store.js new file mode 100644 index 000000000..d49aea138 --- /dev/null +++ b/frontend/src/stores/auth.store.js @@ -0,0 +1,91 @@ +import Cookies from 'js-cookie' + +import { defineStore } from 'pinia' +import { ref } from 'vue' +import gettext from '@/plugins/gettext' + +import repository from '@/api/repository' +import accountApi from '@/api/account' +import accountsApi from '@/api/accounts' +import authApi from '@/api/auth' + +export const useAuthStore = defineStore('auth', () => { + const authUser = ref({}) + const isAuthenticated = ref(false) + + async function fetchUser() { + return accountApi.getMe().then((resp) => { + gettext.current = resp.data.language + authUser.value = resp.data + isAuthenticated.value = true + }) + } + + async function initialize() { + const token = Cookies.get('token') + if (!token) { + return + } + repository.defaults.headers.common.Authorization = `Bearer ${token}` + repository.defaults.headers.post['Content-Type'] = 'application/json' + return fetchUser() + } + + async function login(payload) { + const resp = await authApi.requestToken(payload) + const cookiesAttributes = { sameSite: 'strict' } + if (payload.rememberMe) { + cookiesAttributes.expires = 90 + } + + const cookie = Cookies.withAttributes(cookiesAttributes) + cookie.set('token', resp.data.access) + cookie.set('refreshToken', resp.data.refresh) + initialize() + } + async function $reset() { + delete repository.defaults.headers.common.Authorization + Cookies.remove('token') + Cookies.remove('refreshToken') + authUser.value = {} + isAuthenticated.value = false + } + + async function updateAccount(data) { + return accountsApi.patch(authUser.value.pk, data).then((response) => { + if ( + response.data.language != authUser.value.language && + response.data.language in gettext.available + ) { + gettext.current = response.data.language + } + const newAuthUser = { ...authUser.value, ...response.data } + delete newAuthUser.password + authUser.value = { ...newAuthUser } + }) + } + + async function finalizeTFASetup(pinCode) { + return accountApi + .finalizeTFASetup(pinCode) + .then((response) => { + const cookie = Cookies.withAttributes({ sameSite: 'strict' }) + cookie.set('token', response.data.access) + cookie.set('refreshToken', response.data.refresh) + initialize() + return response + }) + .catch((error) => error) + } + + return { + authUser, + isAuthenticated, + fetchUser, + initialize, + login, + $reset, + updateAccount, + finalizeTFASetup, + } +}) diff --git a/frontend/src/stores/bus.store.js b/frontend/src/stores/bus.store.js new file mode 100644 index 000000000..d1d88de7d --- /dev/null +++ b/frontend/src/stores/bus.store.js @@ -0,0 +1,18 @@ +// Simple bus to handle global events like sending notifications to the user +import { defineStore } from 'pinia' +import { ref } from 'vue' + +export const useBusStore = defineStore('bus', () => { + const notification = ref({}) + const notificationColor = ref('') + + function displayNotification(options) { + notification.value = options.msg + notificationColor.value = options.type ? options.type : 'success' + } + return { + notification, + notificationColor, + displayNotification, + } +}) diff --git a/frontend/src/stores/domains.store.js b/frontend/src/stores/domains.store.js new file mode 100644 index 000000000..86288e165 --- /dev/null +++ b/frontend/src/stores/domains.store.js @@ -0,0 +1,148 @@ +import { defineStore } from 'pinia' +import { useBusStore } from './bus.store' +import { ref } from 'vue' +import gettext from '@/plugins/gettext' + +import domainApi from '@/api/domains' + +export const useDomainsStore = defineStore('domains', () => { + const busStore = useBusStore() + const { $gettext } = gettext + const domainsLoaded = ref(false) + const domains = ref({}) + const domainAliases = ref({}) + + async function getDomains() { + domainsLoaded.value = false + return domainApi.getDomains().then((response) => { + domains.value = {} + const _domains = {} + response.data.forEach(function (domain) { + _domains[domain.pk] = domain + }) + domains.value = _domains + domainsLoaded.value = true + return response + }) + } + + async function getDomain(pk) { + domainsLoaded.value = false + return domainApi.getDomain(pk).then((response) => { + domains.value[pk] = response.data + domainsLoaded.value = true + return response + }) + } + + function getDomainByName(name) { + for (const domain of Object.values(domains.value)) { + if (domain.name === name) { + return domain + } + } + } + + async function createDomain(data) { + return domainApi.createDomain(data).then((response) => { + domains.value[response.data.pk] = response.data + return response + }) + } + + async function updateDomain(data) { + return domainApi.updateDomain(data.pk, data).then((response) => { + domains.value[data.pk] = response.data + busStore.displayNotification({ msg: $gettext('Domain updated') }) + return response + }) + } + + async function deleteDomain({ id, data }) { + return domainApi.deleteDomain(id, data).then((response) => { + delete domains.value[id] + return response + }) + } + + async function getAliases(name) { + return domainApi.getDomainAliases(name).then((response) => { + domainAliases.value[name] = response.data + return response + }) + } + + async function _filterAlias(domainName, pk) { + if (domainAliases.value[domainName] !== undefined) { + return domainAliases.value[domainName].filter((al) => al.pk != pk) + } + } + + async function createAlias(data) { + return domainApi.createDomainAlias(data).then((response) => { + busStore.displayNotification({ + msg: $gettext('Domain alias created'), + }) + if (domains.value[data.target] != null) { + const domain = domains.value[data.target] + if (domainAliases.value[domain.name] !== undefined) { + domainAliases.value[domain.name].push(response.data) + } else { + domainAliases.value[domain.name] = response.data + } + domain.domainalias_count++ + } + return response + }) + } + + async function deleteAlias(alias) { + const domain = domains.value[alias.target] + const apiRequest = domainApi.deleteDomainAlias(alias.pk) + const filter = _filterAlias(domain.name, alias.pk) + Promise.all([filter, apiRequest]).then((results) => { + const newList = results[0] + busStore.displayNotification({ + msg: $gettext('Domain alias deleted'), + }) + if (newList != null) { + domainAliases.value[domain.name] = newList + } + domain.domainalias_count-- + }) + } + + async function updateAlias(data) { + const domain = domains.value[data.target] + const filter = _filterAlias(domain.name, data.pk) + const apiRequest = domainApi.updateDomainAlias(data.pk, data) + Promise.all([filter, apiRequest]).then((results) => { + busStore.displayNotification({ + msg: $gettext('Domain alias updated'), + }) + const newList = results[0] + const response = results[1] + if (newList != null) { + domainAliases.value[domain.name] = newList + domainAliases.value[domain.name].push(response.data) + } else { + domainAliases.value[domain.name] = response.data + } + }) + } + return { + domainsLoaded, + domains, + domainAliases, + getDomain, + getDomainByName, + getDomains, + createDomain, + updateDomain, + deleteDomain, + createAlias, + getAliases, + deleteAlias, + updateAlias, + } +}) diff --git a/frontend/src/stores/identities.store.js b/frontend/src/stores/identities.store.js new file mode 100644 index 000000000..0d98295fd --- /dev/null +++ b/frontend/src/stores/identities.store.js @@ -0,0 +1,172 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' + +import { useAccountsStore } from './accounts.store' +import { useAliasesStore } from './aliases.store' + +import identitiesApi from '@/api/identities' + +import gettext from '@/plugins/gettext' + +export const useIdentitiesStore = defineStore('identities', () => { + const aliasesStore = useAliasesStore() + const accountsStore = useAccountsStore() + + const { $gettext } = gettext + + const identitiesLoaded = ref(false) + const identities = ref([]) + + async function _getIndexByPk(type, pk) { + for (let i = 0; i < identities.value.length; i++) { + if (identities.value[i].pk === pk && identities.value[i].type === type) { + return i + } + } + } + + async function _deleteIdByPkAndType(type, pk) { + _getIndexByPk(type, pk).then((index) => { + if (index !== null) { + identities.value.splice(index, 1) + } + }) + } + + async function getIdentities() { + identitiesLoaded.value = false + return identitiesApi.getAll().then((response) => { + identities.value = response.data + identitiesLoaded.value = true + return response + }) + } + + async function _accountToId(data, update = false) { + const account = data + let indexSearcher = null + if (update) { + indexSearcher = _getIndexByPk('account', data.pk) + } + let name_or_rcpt = '---' + if (account.first_name !== '') { + name_or_rcpt = account.first_name + } + if (account.last_name !== '') { + name_or_rcpt = + name_or_rcpt === '' + ? account.last_name + : `${name_or_rcpt} ${account.last_name}` + } + const newIdentity = { + pk: account.pk, + type: account.type, + identity: account.username, + name_or_rcpt: name_or_rcpt, + tags: [ + { name: 'account', label: $gettext('account'), type: 'idt' }, + { name: account.role, label: $gettext(account.role), type: 'grp' }, + ], + possible_actions: [], + } + + if (update) { + indexSearcher.then((index) => { + identities.value[index] = newIdentity + return + }) + } + identities.value.push(newIdentity) + } + + async function _aliasToId(data, update = false) { + let indexSearcher = null + const alias = data + if (update) { + indexSearcher = _getIndexByPk('alias', data.pk) + } + const name_or_rcpt = + alias.recipients.length > 1 + ? `${alias.recipients[0]}, ...` + : alias.recipients[0] + const newIdentity = { + pk: alias.pk, + type: alias.type, + identity: alias.address, + name_or_rcpt: name_or_rcpt, + tags: [{ name: 'alias', label: $gettext('alias'), type: 'idt' }], + possible_actions: [], + } + if (update) { + indexSearcher.then((index) => { + identities.value[index] = newIdentity + return + }) + } + identities.value.push(newIdentity) + } + + async function createIdentity(type, data) { + identitiesLoaded.value = false + if (type === 'alias') { + return aliasesStore.createAlias(data).then((response) => { + _aliasToId(response.data) + identitiesLoaded.value = true + return response + }) + } else if (type === 'account') { + return accountsStore.createAccount(data).then((response) => { + _accountToId(response.data) + identitiesLoaded.value = true + return response + }) + } + } + + async function updateIdentity(type, data) { + identitiesLoaded.value = false + if (type === 'alias') { + return aliasesStore + .updateAlias(data) + .then((response) => { + _aliasToId(response.data, true) + return response + }) + .finally(() => (identitiesLoaded.value = true)) + } else if (type === 'account') { + return accountsStore + .updateAccount(data) + .then((response) => { + _accountToId(response.data, true) + return response + }) + .finally(() => (identitiesLoaded.value = true)) + } + } + + async function deleteIdentity(type, pk, options) { + identitiesLoaded.value = false + if (type === 'alias') { + return aliasesStore.deleteAlias(pk).then((response) => { + _deleteIdByPkAndType(type, pk) + identitiesLoaded.value = true + return response + }) + } else if (type === 'account') { + return accountsStore.deleteAccount(pk, options).then((response) => { + _deleteIdByPkAndType(type, pk) + identitiesLoaded.value = true + return response + }) + } + } + + return { + identities, + getIdentities, + identitiesLoaded, + deleteIdentity, + createIdentity, + updateIdentity, + } +}) diff --git a/frontend/src/stores/index.js b/frontend/src/stores/index.js new file mode 100644 index 000000000..6759ecca6 --- /dev/null +++ b/frontend/src/stores/index.js @@ -0,0 +1,12 @@ +import { createPinia } from 'pinia' + +export * from './auth.store' +export * from './bus.store' +export * from './domains.store' +export * from './accounts.store' +export * from './aliases.store' +export * from './identities.store' +export * from './parameters.store' +export * from './providers.store' + +export default createPinia() diff --git a/frontend/src/stores/parameters.store.js b/frontend/src/stores/parameters.store.js new file mode 100644 index 000000000..5961bad05 --- /dev/null +++ b/frontend/src/stores/parameters.store.js @@ -0,0 +1,8 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' + +export const useParametersStore = defineStore('parameters', () => { + const imapMigrationEnabled = ref(null) + + return { imapMigrationEnabled } +}) diff --git a/frontend/src/stores/providers.store.js b/frontend/src/stores/providers.store.js new file mode 100644 index 000000000..8c308effd --- /dev/null +++ b/frontend/src/stores/providers.store.js @@ -0,0 +1,58 @@ +import { defineStore } from 'pinia' +import { useBusStore } from './bus.store' +import { ref } from 'vue' +import gettext from '@/plugins/gettext' + +import providersApi from '@/api/imap_migration/providers' + +export const useProvidersStore = defineStore('providers', () => { + const busStore = useBusStore() + const providersLoaded = ref(false) + const providers = ref({}) + const { $gettext } = gettext + + async function getProviders() { + providers.value = {} + providersLoaded.value = false + return providersApi + .getProviders() + .then((response) => { + for (const provider of response.data) { + providers.value[provider.id] = provider + } + return response + }) + .finally(() => (providersLoaded.value = true)) + } + + async function createProvider(data) { + providersLoaded.value = false + return providersApi + .createProvider(data) + .then((response) => { + providers.value[response.data.id] = response.data + return response + }) + .finally(() => (providersLoaded.value = true)) + } + + async function deleteProvider(id) { + providersLoaded.value = false + return providersApi + .deleteProvider({ id: id }) + .then((response) => { + delete providers.value[id] + busStore.displayNotification({ msg: $gettext('Provider deleted') }) + return response + }) + .finally(() => (providersLoaded.value = true)) + } + + return { + providersLoaded, + providers, + getProviders, + createProvider, + deleteProvider, + } +}) diff --git a/frontend/src/styles/global.scss b/frontend/src/styles/global.scss deleted file mode 100644 index 67d87bb78..000000000 --- a/frontend/src/styles/global.scss +++ /dev/null @@ -1,18 +0,0 @@ -// Rubik Font - -@import "~@fontsource/rubik/300.css"; -@import "~@fontsource/rubik/300-italic.css"; -@import "~@fontsource/rubik/400.css"; -@import "~@fontsource/rubik/400-italic.css"; -@import "~@fontsource/rubik/500.css"; -@import "~@fontsource/rubik/500-italic.css"; -@import "~@fontsource/rubik/700.css"; -@import "~@fontsource/rubik/700-italic.css"; - -// Global styles - -.m-label { - display: block; - margin-bottom: 4px; - color: var(--v-label-base); -} diff --git a/frontend/src/styles/main.scss b/frontend/src/styles/main.scss new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/src/styles/settings.scss b/frontend/src/styles/settings.scss new file mode 100644 index 000000000..be2078af9 --- /dev/null +++ b/frontend/src/styles/settings.scss @@ -0,0 +1,14 @@ +/** + * src/styles/settings.scss + * + * Configures SASS variables and Vuetify overwrites + */ + +// https://vuetifyjs.com/features/sass-variables/` +// @use 'vuetify/settings' with ( +// $color-pack: false +// ); + +@use 'vuetify/settings' with ( + $card-title-flex: 1 0 auto +); diff --git a/frontend/src/styles/variables.scss b/frontend/src/styles/variables.scss deleted file mode 100644 index 056f6cbb3..000000000 --- a/frontend/src/styles/variables.scss +++ /dev/null @@ -1,4 +0,0 @@ -// Vuetify variables -// see: ../node_modules/vuetify/src/styles/settings/_variables.scss - -$body-font-family: "Rubik", sans-serif; diff --git a/frontend/src/views/Dashboard.vue b/frontend/src/views/Dashboard.vue index 545f275d7..a49f60dfa 100644 --- a/frontend/src/views/Dashboard.vue +++ b/frontend/src/views/Dashboard.vue @@ -1,25 +1,32 @@ + + diff --git a/frontend/src/views/Login.vue b/frontend/src/views/Login.vue deleted file mode 100644 index 77a927dc0..000000000 --- a/frontend/src/views/Login.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - diff --git a/frontend/src/views/TwoFA.vue b/frontend/src/views/TwoFA.vue deleted file mode 100644 index 90d9c62de..000000000 --- a/frontend/src/views/TwoFA.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - diff --git a/frontend/src/views/account/APISetupView.vue b/frontend/src/views/account/APISetupView.vue new file mode 100644 index 000000000..c1cc75d1e --- /dev/null +++ b/frontend/src/views/account/APISetupView.vue @@ -0,0 +1,131 @@ + + + + + diff --git a/frontend/src/views/account/ForwardView.vue b/frontend/src/views/account/ForwardView.vue new file mode 100644 index 000000000..0c34331c0 --- /dev/null +++ b/frontend/src/views/account/ForwardView.vue @@ -0,0 +1,18 @@ + + + + + diff --git a/frontend/src/views/account/ProfileView.vue b/frontend/src/views/account/ProfileView.vue new file mode 100644 index 000000000..89b5bdd5c --- /dev/null +++ b/frontend/src/views/account/ProfileView.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/frontend/src/views/account/SecurityView.vue b/frontend/src/views/account/SecurityView.vue new file mode 100644 index 000000000..dddfd6085 --- /dev/null +++ b/frontend/src/views/account/SecurityView.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/frontend/src/views/admin/Information.vue b/frontend/src/views/admin/Information.vue deleted file mode 100644 index e088b62eb..000000000 --- a/frontend/src/views/admin/Information.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/frontend/src/views/admin/InformationView.vue b/frontend/src/views/admin/InformationView.vue new file mode 100644 index 000000000..bad06c251 --- /dev/null +++ b/frontend/src/views/admin/InformationView.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/frontend/src/views/admin/ParametersView.vue b/frontend/src/views/admin/ParametersView.vue new file mode 100644 index 000000000..cc670db15 --- /dev/null +++ b/frontend/src/views/admin/ParametersView.vue @@ -0,0 +1,193 @@ + + + + + diff --git a/frontend/src/views/admin/alarms/AlarmsView.vue b/frontend/src/views/admin/alarms/AlarmsView.vue new file mode 100644 index 000000000..4f471f8f0 --- /dev/null +++ b/frontend/src/views/admin/alarms/AlarmsView.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/frontend/src/views/admin/domains/DomainEditView.vue b/frontend/src/views/admin/domains/DomainEditView.vue new file mode 100644 index 000000000..41068a340 --- /dev/null +++ b/frontend/src/views/admin/domains/DomainEditView.vue @@ -0,0 +1,25 @@ + + + diff --git a/frontend/src/views/admin/domains/DomainView.vue b/frontend/src/views/admin/domains/DomainView.vue new file mode 100644 index 000000000..5d873dc11 --- /dev/null +++ b/frontend/src/views/admin/domains/DomainView.vue @@ -0,0 +1,119 @@ + + + + + diff --git a/frontend/src/views/admin/domains/DomainsView.vue b/frontend/src/views/admin/domains/DomainsView.vue new file mode 100644 index 000000000..58c5eb8eb --- /dev/null +++ b/frontend/src/views/admin/domains/DomainsView.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/frontend/src/views/admin/identities/AccountEditView.vue b/frontend/src/views/admin/identities/AccountEditView.vue new file mode 100644 index 000000000..3b9869e7a --- /dev/null +++ b/frontend/src/views/admin/identities/AccountEditView.vue @@ -0,0 +1,12 @@ + + + diff --git a/frontend/src/views/admin/identities/AccountView.vue b/frontend/src/views/admin/identities/AccountView.vue new file mode 100644 index 000000000..4e7b17701 --- /dev/null +++ b/frontend/src/views/admin/identities/AccountView.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/frontend/src/views/admin/identities/AliasEditView.vue b/frontend/src/views/admin/identities/AliasEditView.vue new file mode 100644 index 000000000..31ba106b6 --- /dev/null +++ b/frontend/src/views/admin/identities/AliasEditView.vue @@ -0,0 +1,14 @@ + + + diff --git a/frontend/src/views/admin/identities/AliasView.vue b/frontend/src/views/admin/identities/AliasView.vue new file mode 100644 index 000000000..b3ef8321d --- /dev/null +++ b/frontend/src/views/admin/identities/AliasView.vue @@ -0,0 +1,52 @@ + + + + + diff --git a/frontend/src/views/admin/identities/IdentitiesView.vue b/frontend/src/views/admin/identities/IdentitiesView.vue new file mode 100644 index 000000000..e1abf89b1 --- /dev/null +++ b/frontend/src/views/admin/identities/IdentitiesView.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/frontend/src/views/admin/imap_migration/MigrationsView.vue b/frontend/src/views/admin/imap_migration/MigrationsView.vue new file mode 100644 index 000000000..e00845824 --- /dev/null +++ b/frontend/src/views/admin/imap_migration/MigrationsView.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/frontend/src/views/admin/imap_migration/ProviderEditView.vue b/frontend/src/views/admin/imap_migration/ProviderEditView.vue new file mode 100644 index 000000000..c9be0ca31 --- /dev/null +++ b/frontend/src/views/admin/imap_migration/ProviderEditView.vue @@ -0,0 +1,24 @@ + + + diff --git a/frontend/src/views/admin/imap_migration/ProvidersView.vue b/frontend/src/views/admin/imap_migration/ProvidersView.vue new file mode 100644 index 000000000..1f6bb45e0 --- /dev/null +++ b/frontend/src/views/admin/imap_migration/ProvidersView.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/frontend/src/views/admin/monitoring/AuditTrailView.vue b/frontend/src/views/admin/monitoring/AuditTrailView.vue new file mode 100644 index 000000000..e13edb660 --- /dev/null +++ b/frontend/src/views/admin/monitoring/AuditTrailView.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/frontend/src/views/admin/monitoring/MessagesView.vue b/frontend/src/views/admin/monitoring/MessagesView.vue new file mode 100644 index 000000000..77034f624 --- /dev/null +++ b/frontend/src/views/admin/monitoring/MessagesView.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/frontend/src/views/monitoring/Statistics.vue b/frontend/src/views/admin/monitoring/StatisticsView.vue similarity index 63% rename from frontend/src/views/monitoring/Statistics.vue rename to frontend/src/views/admin/monitoring/StatisticsView.vue index 1254604e1..20c224297 100644 --- a/frontend/src/views/monitoring/Statistics.vue +++ b/frontend/src/views/admin/monitoring/StatisticsView.vue @@ -1,41 +1,33 @@ - diff --git a/frontend/src/views/domains/Domain.vue b/frontend/src/views/domains/Domain.vue deleted file mode 100644 index a4fe69da1..000000000 --- a/frontend/src/views/domains/Domain.vue +++ /dev/null @@ -1,135 +0,0 @@ - - - - - diff --git a/frontend/src/views/domains/DomainEdit.vue b/frontend/src/views/domains/DomainEdit.vue deleted file mode 100644 index 537e0d34a..000000000 --- a/frontend/src/views/domains/DomainEdit.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/frontend/src/views/domains/Domains.vue b/frontend/src/views/domains/Domains.vue deleted file mode 100644 index 0068a4b45..000000000 --- a/frontend/src/views/domains/Domains.vue +++ /dev/null @@ -1,114 +0,0 @@ - - - - - diff --git a/frontend/src/views/identities/Account.vue b/frontend/src/views/identities/Account.vue deleted file mode 100644 index d0e841a61..000000000 --- a/frontend/src/views/identities/Account.vue +++ /dev/null @@ -1,79 +0,0 @@ - - - - - diff --git a/frontend/src/views/identities/AccountEdit.vue b/frontend/src/views/identities/AccountEdit.vue deleted file mode 100644 index c64692bb8..000000000 --- a/frontend/src/views/identities/AccountEdit.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/frontend/src/views/identities/Alias.vue b/frontend/src/views/identities/Alias.vue deleted file mode 100644 index 2c62672b7..000000000 --- a/frontend/src/views/identities/Alias.vue +++ /dev/null @@ -1,45 +0,0 @@ - - - - - diff --git a/frontend/src/views/identities/AliasEdit.vue b/frontend/src/views/identities/AliasEdit.vue deleted file mode 100644 index 54d26ed41..000000000 --- a/frontend/src/views/identities/AliasEdit.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/frontend/src/views/identities/Identities.vue b/frontend/src/views/identities/Identities.vue deleted file mode 100644 index 226abdb9a..000000000 --- a/frontend/src/views/identities/Identities.vue +++ /dev/null @@ -1,146 +0,0 @@ - - - - - diff --git a/frontend/src/views/imap_migration/ProviderEdit.vue b/frontend/src/views/imap_migration/ProviderEdit.vue deleted file mode 100644 index 518b9b665..000000000 --- a/frontend/src/views/imap_migration/ProviderEdit.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/frontend/src/views/imap_migration/Providers.vue b/frontend/src/views/imap_migration/Providers.vue deleted file mode 100644 index f229388c2..000000000 --- a/frontend/src/views/imap_migration/Providers.vue +++ /dev/null @@ -1,56 +0,0 @@ - - - - - diff --git a/frontend/src/views/login/LoginView.vue b/frontend/src/views/login/LoginView.vue new file mode 100644 index 000000000..8350fbe8c --- /dev/null +++ b/frontend/src/views/login/LoginView.vue @@ -0,0 +1,26 @@ + + + diff --git a/frontend/src/views/login/PasswordRecoveryChangeView.vue b/frontend/src/views/login/PasswordRecoveryChangeView.vue new file mode 100644 index 000000000..1aa56e03f --- /dev/null +++ b/frontend/src/views/login/PasswordRecoveryChangeView.vue @@ -0,0 +1,26 @@ + + + diff --git a/frontend/src/views/login/PasswordRecoveryForm.vue b/frontend/src/views/login/PasswordRecoveryForm.vue new file mode 100644 index 000000000..b405d81f3 --- /dev/null +++ b/frontend/src/views/login/PasswordRecoveryForm.vue @@ -0,0 +1,129 @@ + + + diff --git a/frontend/src/views/login/PasswordRecoverySmsTotpView.vue b/frontend/src/views/login/PasswordRecoverySmsTotpView.vue new file mode 100644 index 000000000..88cef341a --- /dev/null +++ b/frontend/src/views/login/PasswordRecoverySmsTotpView.vue @@ -0,0 +1,26 @@ + + + diff --git a/frontend/src/views/login/PasswordRecoveryView.vue b/frontend/src/views/login/PasswordRecoveryView.vue new file mode 100644 index 000000000..ccf11a50b --- /dev/null +++ b/frontend/src/views/login/PasswordRecoveryView.vue @@ -0,0 +1,26 @@ + + + diff --git a/frontend/src/views/login/TwoFA.vue b/frontend/src/views/login/TwoFA.vue new file mode 100644 index 000000000..462146614 --- /dev/null +++ b/frontend/src/views/login/TwoFA.vue @@ -0,0 +1,26 @@ + + + diff --git a/frontend/src/views/monitoring/AuditTrail.vue b/frontend/src/views/monitoring/AuditTrail.vue deleted file mode 100644 index 08ba34ac1..000000000 --- a/frontend/src/views/monitoring/AuditTrail.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/frontend/src/views/monitoring/Messages.vue b/frontend/src/views/monitoring/Messages.vue deleted file mode 100644 index aa012226b..000000000 --- a/frontend/src/views/monitoring/Messages.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/frontend/src/views/user/APISetup.vue b/frontend/src/views/user/APISetup.vue deleted file mode 100644 index ff00afd3b..000000000 --- a/frontend/src/views/user/APISetup.vue +++ /dev/null @@ -1,114 +0,0 @@ - - - - - diff --git a/frontend/src/views/user/Forward.vue b/frontend/src/views/user/Forward.vue deleted file mode 100644 index 6a3420e30..000000000 --- a/frontend/src/views/user/Forward.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - - - diff --git a/frontend/src/views/user/PasswordRecoveryChangeForm.vue b/frontend/src/views/user/PasswordRecoveryChangeForm.vue deleted file mode 100644 index a50b26505..000000000 --- a/frontend/src/views/user/PasswordRecoveryChangeForm.vue +++ /dev/null @@ -1,138 +0,0 @@ - - - - - diff --git a/frontend/src/views/user/PasswordRecoveryForm.vue b/frontend/src/views/user/PasswordRecoveryForm.vue deleted file mode 100644 index e59b05099..000000000 --- a/frontend/src/views/user/PasswordRecoveryForm.vue +++ /dev/null @@ -1,125 +0,0 @@ - - - - - diff --git a/frontend/src/views/user/PasswordRecoverySmsTotpForm.vue b/frontend/src/views/user/PasswordRecoverySmsTotpForm.vue deleted file mode 100644 index 163632f47..000000000 --- a/frontend/src/views/user/PasswordRecoverySmsTotpForm.vue +++ /dev/null @@ -1,131 +0,0 @@ - - - - - diff --git a/frontend/src/views/user/Profile.vue b/frontend/src/views/user/Profile.vue deleted file mode 100644 index a3bc5964b..000000000 --- a/frontend/src/views/user/Profile.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - - - diff --git a/frontend/src/views/user/Security.vue b/frontend/src/views/user/Security.vue deleted file mode 100644 index 234c2e3c2..000000000 --- a/frontend/src/views/user/Security.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - - - diff --git a/frontend/tests/unit/example.spec.js b/frontend/tests/unit/example.spec.js deleted file mode 100644 index c585ea333..000000000 --- a/frontend/tests/unit/example.spec.js +++ /dev/null @@ -1,13 +0,0 @@ -import { expect } from 'chai' -import { shallowMount } from '@vue/test-utils' -import HelloWorld from '@/components/HelloWorld.vue' - -describe('HelloWorld.vue', () => { - it('renders props.msg when passed', () => { - const msg = 'new message' - const wrapper = shallowMount(HelloWorld, { - propsData: { msg } - }) - expect(wrapper.text()).to.include(msg) - }) -}) diff --git a/frontend/vite.config.js b/frontend/vite.config.js new file mode 100644 index 000000000..b5d3d6fb1 --- /dev/null +++ b/frontend/vite.config.js @@ -0,0 +1,51 @@ +// Plugins +import vue from '@vitejs/plugin-vue' +import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify' +import ViteFonts from 'unplugin-fonts/vite' + +// Utilities +import { defineConfig } from 'vite' +import { fileURLToPath, URL } from 'node:url' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + vue({ + template: { transformAssetUrls }, + }), + // https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin#readme + vuetify({ + autoImport: true, + styles: { + configFile: 'src/styles/settings.scss', + }, + }), + ViteFonts({ + google: { + families: [ + { + name: 'Roboto', + styles: 'wght@100;300;400;500;700;900', + }, + ], + }, + }), + ], + base: process.env.NODE_ENV === 'production' ? '/new-admin/' : '/', + define: { 'process.env': {}, __VUE_OPTIONS_API__: false }, + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)), + }, + extensions: ['.js', '.json', '.jsx', '.mjs', '.ts', '.tsx', '.vue'], + }, + server: { + port: 3000, + proxy: { + '/api': + process.env.DOCKER == 'yes' + ? 'http://api:8000' + : 'http://127.0.0.1:8000', + }, + }, +}) diff --git a/frontend/vue.config.js b/frontend/vue.config.js deleted file mode 100644 index c0e75e1bc..000000000 --- a/frontend/vue.config.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - devServer: { - proxy: { - "/api": { - target: - process.env.DOCKER == "yes" - ? "http://api:8000/" - : "http://127.0.0.1:8000", - }, - }, - }, - transpileDependencies: ["vuetify"], - publicPath: process.env.NODE_ENV === "production" ? "/new-admin/" : "/", - outputDir: "../modoboa/frontend_dist", -}; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 485ee1808..066ffd824 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2,1199 +2,213 @@ # yarn lockfile v1 -"@achrinza/node-ipc@^9.2.5": - version "9.2.5" - resolved "https://registry.npmmirror.com/@achrinza/node-ipc/-/node-ipc-9.2.5.tgz#29788e608ff41121f0543491da723b243266ac28" - integrity sha512-kBX7Ay911iXZ3VZ1pYltj3Rfu7Ow9H7sK4H4RSfWIfWR2JKNB40K808wppoRIEzE2j2hXLU+r6TJgCAliCGhyQ== - dependencies: - "@node-ipc/js-queue" "2.0.3" - event-pubsub "4.3.0" - js-message "1.0.7" +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== +"@babel/code-frame@^7.0.0": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== dependencies: - "@jridgewell/gen-mapping" "^0.1.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/code-frame@^7.22.13": - version "7.22.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" - integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== - dependencies: - "@babel/highlight" "^7.22.13" + "@babel/highlight" "^7.23.4" chalk "^2.4.2" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.1.tgz#72d647b4ff6a4f82878d184613353af1dd0290f9" - integrity sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg== - -"@babel/core@^7.11.6", "@babel/core@^7.12.16": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.1.tgz#c8fa615c5e88e272564ace3d42fbc8b17bfeb22b" - integrity sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.0" - "@babel/helper-compilation-targets" "^7.19.1" - "@babel/helper-module-transforms" "^7.19.0" - "@babel/helpers" "^7.19.0" - "@babel/parser" "^7.19.1" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.1" - "@babel/types" "^7.19.0" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" - -"@babel/eslint-parser@^7.12.16": - version "7.19.1" - resolved "https://registry.npmmirror.com/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz#4f68f6b0825489e00a24b41b6a1ae35414ecd2f4" - integrity sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ== - dependencies: - "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" - eslint-visitor-keys "^2.1.0" - semver "^6.3.0" - -"@babel/generator@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.0.tgz#785596c06425e59334df2ccee63ab166b738419a" - integrity sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg== - dependencies: - "@babel/types" "^7.19.0" - "@jridgewell/gen-mapping" "^0.3.2" - jsesc "^2.5.1" - -"@babel/generator@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" - integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== - dependencies: - "@babel/types" "^7.23.0" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/helper-annotate-as-pure@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" - integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" - integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.18.6" - "@babel/types" "^7.18.9" - -"@babel/helper-compilation-targets@^7.12.16", "@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0", "@babel/helper-compilation-targets@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz#7f630911d83b408b76fe584831c98e5395d7a17c" - integrity sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg== - dependencies: - "@babel/compat-data" "^7.19.1" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.21.3" - semver "^6.3.0" - -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz#bfd6904620df4e46470bae4850d66be1054c404b" - integrity sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-member-expression-to-functions" "^7.18.9" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.9" - "@babel/helper-split-export-declaration" "^7.18.6" - -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b" - integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - regexpu-core "^5.1.0" - -"@babel/helper-define-polyfill-provider@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" - integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== - dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" - -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== - -"@babel/helper-environment-visitor@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" - integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== - -"@babel/helper-explode-assignable-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" - integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== - dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" - -"@babel/helper-function-name@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" - integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== - dependencies: - "@babel/template" "^7.22.15" - "@babel/types" "^7.23.0" - -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-hoist-variables@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" - integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-member-expression-to-functions@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" - integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== - dependencies: - "@babel/types" "^7.18.9" - -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30" - integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.18.6" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" - -"@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" - integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf" - integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== - -"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" - integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-wrap-function" "^7.18.9" - "@babel/types" "^7.18.9" - -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9", "@babel/helper-replace-supers@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78" - integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.18.9" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/traverse" "^7.19.1" - "@babel/types" "^7.19.0" - -"@babel/helper-simple-access@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" - integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" - integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw== - dependencies: - "@babel/types" "^7.18.9" - -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-split-export-declaration@^7.22.6": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" - integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-string-parser@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" - integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== - -"@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== - -"@babel/helper-validator-identifier@^7.18.6": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== - -"@babel/helper-wrap-function@^7.18.9": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz#89f18335cff1152373222f76a4b37799636ae8b1" - integrity sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg== - dependencies: - "@babel/helper-function-name" "^7.19.0" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" - -"@babel/helpers@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18" - integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg== - dependencies: - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" - -"@babel/highlight@^7.10.4", "@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/highlight@^7.22.13": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" - integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== dependencies: "@babel/helper-validator-identifier" "^7.22.20" chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/parser@^7.16.4", "@babel/parser@^7.18.10", "@babel/parser@^7.18.4", "@babel/parser@^7.19.1", "@babel/parser@^7.6.0", "@babel/parser@^7.9.6": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.1.tgz#6f6d6c2e621aad19a92544cc217ed13f1aac5b4c" - integrity sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A== - -"@babel/parser@^7.22.15", "@babel/parser@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" - integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== - -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" - integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50" - integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" - -"@babel/plugin-proposal-async-generator-functions@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz#34f6f5174b688529342288cd264f80c9ea9fb4a7" - integrity sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-remap-async-to-generator" "^7.18.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@^7.12.13", "@babel/plugin-proposal-class-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.npmmirror.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" - integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-proposal-class-static-block@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" - integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-proposal-decorators@^7.12.13": - version "7.19.1" - resolved "https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.1.tgz#4bab3e7afe894fdbf47ffa86701266104fcb6ecc" - integrity sha512-LfIKNBBY7Q1OX5C4xAgRQffOg2OnhAo9fnbcOHgOC9Yytm2Sw+4XqHufRYU86tHomzepxtvuVaNO+3EVKR4ivw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-replace-supers" "^7.19.1" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/plugin-syntax-decorators" "^7.19.0" - -"@babel/plugin-proposal-dynamic-import@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" - integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" - integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-json-strings@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" - integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23" - integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" - integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-proposal-numeric-separator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" - integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7" - integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q== - dependencies: - "@babel/compat-data" "^7.18.8" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.18.8" - -"@babel/plugin-proposal-optional-catch-binding@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" - integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993" - integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-proposal-private-methods@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" - integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-proposal-private-property-in-object@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz#a64137b232f0aca3733a67eb1a144c192389c503" - integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" - integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" - integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-decorators@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz#5f13d1d8fce96951bea01a10424463c9a5b3a599" - integrity sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ== - dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - -"@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-import-assertions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz#cd6190500a4fa2fe31990a963ffab4b63e4505e4" - integrity sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.12.13", "@babel/plugin-syntax-jsx@^7.2.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" - integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" - integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-top-level-await@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-arrow-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" - integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-async-to-generator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" - integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== - dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-remap-async-to-generator" "^7.18.6" - -"@babel/plugin-transform-block-scoped-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" - integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-block-scoping@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d" - integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-classes@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz#0e61ec257fba409c41372175e7c1e606dc79bb20" - integrity sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.19.0" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-replace-supers" "^7.18.9" - "@babel/helper-split-export-declaration" "^7.18.6" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" - integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-destructuring@^7.18.13": - version "7.18.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz#9e03bc4a94475d62b7f4114938e6c5c33372cbf5" - integrity sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" - integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-duplicate-keys@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" - integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-exponentiation-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" - integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-for-of@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" - integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" - integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== - dependencies: - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" - integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-member-expression-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" - integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-modules-amd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz#8c91f8c5115d2202f277549848874027d7172d21" - integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg== - dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-commonjs@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" - integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== - dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-simple-access" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-systemjs@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz#5f20b471284430f02d9c5059d9b9a16d4b085a1f" - integrity sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A== - dependencies: - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-validator-identifier" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-umd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" - integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== - dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz#ec7455bab6cd8fb05c525a94876f435a48128888" - integrity sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" - -"@babel/plugin-transform-new-target@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" - integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-object-super@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" - integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.6" - -"@babel/plugin-transform-parameters@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a" - integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-property-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" - integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-regenerator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz#585c66cb84d4b4bf72519a34cfce761b8676ca73" - integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - regenerator-transform "^0.15.0" - -"@babel/plugin-transform-reserved-words@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" - integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-runtime@^7.12.15": - version "7.19.1" - resolved "https://registry.npmmirror.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.1.tgz#a3df2d7312eea624c7889a2dcd37fd1dfd25b2c6" - integrity sha512-2nJjTUFIzBMP/f/miLxEK9vxwW/KUXsdvN4sR//TmuDhe6yU2h57WmIOE12Gng3MDP/xpjUV/ToZRdcf8Yj4fA== - dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - semver "^6.3.0" - -"@babel/plugin-transform-shorthand-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" - integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-spread@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6" - integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w== - dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" - -"@babel/plugin-transform-sticky-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" - integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-template-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" - integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-typeof-symbol@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" - integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-unicode-escapes@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246" - integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - -"@babel/plugin-transform-unicode-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" - integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/preset-env@^7.12.16": - version "7.19.1" - resolved "https://registry.npmmirror.com/@babel/preset-env/-/preset-env-7.19.1.tgz#9f04c916f9c0205a48ebe5cc1be7768eb1983f67" - integrity sha512-c8B2c6D16Lp+Nt6HcD+nHl0VbPKVnNPTpszahuxJJnurfMtKeZ80A+qUv48Y7wqvS+dTFuLuaM9oYxyNHbCLWA== - dependencies: - "@babel/compat-data" "^7.19.1" - "@babel/helper-compilation-targets" "^7.19.1" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-async-generator-functions" "^7.19.1" - "@babel/plugin-proposal-class-properties" "^7.18.6" - "@babel/plugin-proposal-class-static-block" "^7.18.6" - "@babel/plugin-proposal-dynamic-import" "^7.18.6" - "@babel/plugin-proposal-export-namespace-from" "^7.18.9" - "@babel/plugin-proposal-json-strings" "^7.18.6" - "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" - "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.18.9" - "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-private-methods" "^7.18.6" - "@babel/plugin-proposal-private-property-in-object" "^7.18.6" - "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.18.6" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.18.6" - "@babel/plugin-transform-async-to-generator" "^7.18.6" - "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.18.9" - "@babel/plugin-transform-classes" "^7.19.0" - "@babel/plugin-transform-computed-properties" "^7.18.9" - "@babel/plugin-transform-destructuring" "^7.18.13" - "@babel/plugin-transform-dotall-regex" "^7.18.6" - "@babel/plugin-transform-duplicate-keys" "^7.18.9" - "@babel/plugin-transform-exponentiation-operator" "^7.18.6" - "@babel/plugin-transform-for-of" "^7.18.8" - "@babel/plugin-transform-function-name" "^7.18.9" - "@babel/plugin-transform-literals" "^7.18.9" - "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.18.6" - "@babel/plugin-transform-modules-commonjs" "^7.18.6" - "@babel/plugin-transform-modules-systemjs" "^7.19.0" - "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" - "@babel/plugin-transform-new-target" "^7.18.6" - "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.18.8" - "@babel/plugin-transform-property-literals" "^7.18.6" - "@babel/plugin-transform-regenerator" "^7.18.6" - "@babel/plugin-transform-reserved-words" "^7.18.6" - "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.19.0" - "@babel/plugin-transform-sticky-regex" "^7.18.6" - "@babel/plugin-transform-template-literals" "^7.18.9" - "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.18.10" - "@babel/plugin-transform-unicode-regex" "^7.18.6" - "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.19.0" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - core-js-compat "^3.25.1" - semver "^6.3.0" - -"@babel/preset-modules@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" - integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - -"@babel/runtime-corejs2@^7.0.0": - version "7.19.2" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.19.2.tgz#73121693f93ccd8847f790f4250dd8a74e892c4b" - integrity sha512-XofFIUXoVSuIabaED6ZNzvQ5iFzwQ3rnflnJTlMfmaZ9MHi+fmPk0iAwA6J6+8tC2UVshfyWPxIDmTKR+fRofA== - dependencies: - core-js "^2.6.12" - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.12.13", "@babel/runtime@^7.8.4": - version "7.19.0" - resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" - integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.0.0", "@babel/template@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" - integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.10" - "@babel/types" "^7.18.10" - -"@babel/template@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" - integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/parser" "^7.22.15" - "@babel/types" "^7.22.15" - -"@babel/traverse@^7.0.0", "@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" - integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.0" - "@babel/types" "^7.23.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.4.4", "@babel/types@^7.6.1", "@babel/types@^7.9.6": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600" - integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA== - dependencies: - "@babel/helper-string-parser" "^7.18.10" - "@babel/helper-validator-identifier" "^7.18.6" - to-fast-properties "^2.0.0" - -"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" - integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== - dependencies: - "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@eslint/eslintrc@^0.4.3": - version "0.4.3" - resolved "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" - integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== +"@babel/parser@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.9.tgz#7b903b6149b0f8fa7ad564af646c4c38a77fc44b" + integrity sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA== + +"@esbuild/aix-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" + integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== + +"@esbuild/android-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" + integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== + +"@esbuild/android-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" + integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== + +"@esbuild/android-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" + integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== + +"@esbuild/darwin-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e" + integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== + +"@esbuild/darwin-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" + integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== + +"@esbuild/freebsd-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" + integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== + +"@esbuild/freebsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" + integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== + +"@esbuild/linux-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" + integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== + +"@esbuild/linux-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" + integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== + +"@esbuild/linux-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" + integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== + +"@esbuild/linux-loong64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" + integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== + +"@esbuild/linux-mips64el@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" + integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== + +"@esbuild/linux-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" + integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== + +"@esbuild/linux-riscv64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" + integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== + +"@esbuild/linux-s390x@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" + integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== + +"@esbuild/linux-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" + integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== + +"@esbuild/netbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" + integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== + +"@esbuild/openbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" + integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== + +"@esbuild/sunos-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" + integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== + +"@esbuild/win32-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" + integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== + +"@esbuild/win32-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" + integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== + +"@esbuild/win32-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae" + integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA== + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.6.1": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== + +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== dependencies: ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^13.9.0" - ignore "^4.0.6" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" + js-yaml "^4.1.0" + minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@fontsource/rubik@^4.5.0": - version "4.5.11" - resolved "https://registry.yarnpkg.com/@fontsource/rubik/-/rubik-4.5.11.tgz#e2d06b840ba5c2111b269bea2842f570848af070" - integrity sha512-m0/4GKOqJjF9cB4wuLgDhRdRVt35WzqI5n7SgddRjRD+yzsO0eEq/ak0ezgfbR3+f91ydDCek1+RuOVB8dNYwg== +"@eslint/js@8.56.0": + version "8.56.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" + integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== -"@hapi/hoek@^9.0.0": - version "9.3.0" - resolved "https://registry.npmmirror.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" - integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== - -"@hapi/topo@^5.0.0": - version "5.1.0" - resolved "https://registry.npmmirror.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" - integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== +"@humanwhocodes/config-array@^0.11.13": + version "0.11.14" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" + integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== dependencies: - "@hapi/hoek" "^9.0.0" + "@humanwhocodes/object-schema" "^2.0.2" + debug "^4.3.1" + minimatch "^3.0.5" -"@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== - dependencies: - "@humanwhocodes/object-schema" "^1.2.0" - debug "^4.1.1" - minimatch "^3.0.4" +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^1.2.0": - version "1.2.1" - resolved "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@humanwhocodes/object-schema@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" + integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@^3.0.3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/sourcemap-codec@^1.4.14": +"@jridgewell/sourcemap-codec@^1.4.15": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.15" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" - integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/trace-mapping@^0.3.17": - version "0.3.20" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" - integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@leichtgewicht/ip-codec@^2.0.1": - version "2.0.4" - resolved "https://registry.npmmirror.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" - integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== - -"@mdi/font@^5.9.55": - version "5.9.55" - resolved "https://registry.yarnpkg.com/@mdi/font/-/font-5.9.55.tgz#41acd50b88073ded7095fc3029d8712b6e12f38e" - integrity sha512-jswRF6q3eq8NWpWiqct6q+6Fg/I7nUhrxYJfiEM8JJpap0wVJLQdbKtyS65GdlK7S7Ytnx3TTi/bmw+tBhkGmg== - -"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": - version "5.1.1-v1" - resolved "https://registry.npmmirror.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" - integrity sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg== - dependencies: - eslint-scope "5.1.1" - -"@node-ipc/js-queue@2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@node-ipc/js-queue/-/js-queue-2.0.3.tgz#ac7fe33d766fa53e233ef8fedaf3443a01c5a4cd" - integrity sha512-fL1wpr8hhD5gT2dA1qifeVaoDFlQR5es8tFuKqjHX+kdOtdNHnxkVZbtIrR2rxnMFvehkjaZRNV2H/gPXlb0hw== - dependencies: - easy-stack "1.0.1" +"@mdi/font@^7.3.67": + version "7.4.47" + resolved "https://registry.yarnpkg.com/@mdi/font/-/font-7.4.47.tgz#2ae522867da3a5c88b738d54b403eb91471903af" + integrity sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1209,7 +223,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.walk@^1.2.3": +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -1217,129 +231,77 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@polka/url@^1.0.0-next.20": - version "1.0.0-next.21" - resolved "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" - integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== +"@rollup/rollup-android-arm-eabi@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.11.0.tgz#78693f843483a511bce6ce1d8a153a49f4cbab87" + integrity sha512-BV+u2QSfK3i1o6FucqJh5IK9cjAU6icjFFhvknzFgu472jzl0bBojfDAkJLBEsHFMo+YZg6rthBvBBt8z12IBQ== -"@sideway/address@^4.1.3": - version "4.1.4" - resolved "https://registry.npmmirror.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" - integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw== - dependencies: - "@hapi/hoek" "^9.0.0" +"@rollup/rollup-android-arm64@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.11.0.tgz#772cb1856f720863d982c17f25d3fbb930c946d3" + integrity sha512-0ij3iw7sT5jbcdXofWO2NqDNjSVVsf6itcAkV2I6Xsq4+6wjW1A8rViVB67TfBEan7PV2kbLzT8rhOVWLI2YXw== -"@sideway/formula@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" - integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== +"@rollup/rollup-darwin-arm64@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.11.0.tgz#cac4aac05432ac684a6c6c5788e8db738e047a22" + integrity sha512-yPLs6RbbBMupArf6qv1UDk6dzZvlH66z6NLYEwqTU0VHtss1wkI4UYeeMS7TVj5QRVvaNAWYKP0TD/MOeZ76Zg== -"@sideway/pinpoint@^2.0.0": - version "2.0.0" - resolved "https://registry.npmmirror.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" - integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== +"@rollup/rollup-darwin-x64@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.11.0.tgz#e36d66c6b2d4d716c94926a375d6865b0c0c9c02" + integrity sha512-OvqIgwaGAwnASzXaZEeoJY3RltOFg+WUbdkdfoluh2iqatd090UeOG3A/h0wNZmE93dDew9tAtXgm3/+U/B6bw== -"@soda/friendly-errors-webpack-plugin@^1.8.0": - version "1.8.1" - resolved "https://registry.npmmirror.com/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz#4d4fbb1108993aaa362116247c3d18188a2c6c85" - integrity sha512-h2ooWqP8XuFqTXT+NyAFbrArzfQA7R6HTezADrvD9Re8fxMLTPPniLdqVTdDaO0eIoLaAwKT+d6w+5GeTk7Vbg== - dependencies: - chalk "^3.0.0" - error-stack-parser "^2.0.6" - string-width "^4.2.3" - strip-ansi "^6.0.1" +"@rollup/rollup-linux-arm-gnueabihf@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.11.0.tgz#f7cc62debb348fb109724c882b99adc5c3f73e31" + integrity sha512-X17s4hZK3QbRmdAuLd2EE+qwwxL8JxyVupEqAkxKPa/IgX49ZO+vf0ka69gIKsaYeo6c1CuwY3k8trfDtZ9dFg== -"@soda/get-current-script@^1.0.2": - version "1.0.2" - resolved "https://registry.npmmirror.com/@soda/get-current-script/-/get-current-script-1.0.2.tgz#a53515db25d8038374381b73af20bb4f2e508d87" - integrity sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w== +"@rollup/rollup-linux-arm64-gnu@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.11.0.tgz#ed398c7434734101e77a1fd0b05682b2c2027ecd" + integrity sha512-673Lu9EJwxVB9NfYeA4AdNu0FOHz7g9t6N1DmT7bZPn1u6bTF+oZjj+fuxUcrfxWXE0r2jxl5QYMa9cUOj9NFg== -"@tootallnate/once@2": - version "2.0.0" - resolved "https://registry.npmmirror.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" - integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@rollup/rollup-linux-arm64-musl@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.11.0.tgz#4860560d18d9f18568859a800b1e79fe3b85df9e" + integrity sha512-yFW2msTAQNpPJaMmh2NpRalr1KXI7ZUjlN6dY/FhWlOclMrZezm5GIhy3cP4Ts2rIAC+IPLAjNibjp1BsxCVGg== -"@trysound/sax@0.2.0": - version "0.2.0" - resolved "https://registry.npmmirror.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" - integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== +"@rollup/rollup-linux-riscv64-gnu@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.11.0.tgz#25bc0e9dbd5feab0b6fa68b2b87ce5f28a8a7c19" + integrity sha512-kKT9XIuhbvYgiA3cPAGntvrBgzhWkGpBMzuk1V12Xuoqg7CI41chye4HU0vLJnGf9MiZzfNh4I7StPeOzOWJfA== -"@types/body-parser@*": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" - integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" +"@rollup/rollup-linux-x64-gnu@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.11.0.tgz#8c318d9c33a89cf9f917a1be90b0d8c75e0ab3ba" + integrity sha512-6q4ESWlyTO+erp1PSCmASac+ixaDv11dBk1fqyIuvIUc/CmRAX2Zk+2qK1FGo5q7kyDcjHCFVwgGFCGIZGVwCA== -"@types/bonjour@^3.5.9": - version "3.5.10" - resolved "https://registry.npmmirror.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" - integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== - dependencies: - "@types/node" "*" +"@rollup/rollup-linux-x64-musl@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.11.0.tgz#132cf0787c966b3b22cf4475706fc4cb08ec880c" + integrity sha512-vIAQUmXeMLmaDN78HSE4Kh6xqof2e3TJUKr+LPqXWU4NYNON0MDN9h2+t4KHrPAQNmU3w1GxBQ/n01PaWFwa5w== -"@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.npmmirror.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" +"@rollup/rollup-win32-arm64-msvc@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.11.0.tgz#18e49376786def75843e605bdc8059a301c11dad" + integrity sha512-LVXo9dDTGPr0nezMdqa1hK4JeoMZ02nstUxGYY/sMIDtTYlli1ZxTXBYAz3vzuuvKO4X6NBETciIh7N9+abT1g== -"@types/connect@*": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== - dependencies: - "@types/node" "*" +"@rollup/rollup-win32-ia32-msvc@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.11.0.tgz#ff9281d8b189436b7c234a52e7e0b635631c8667" + integrity sha512-xZVt6K70Gr3I7nUhug2dN6VRR1ibot3rXqXS3wo+8JP64t7djc3lBFyqO4GiVrhNaAIhUCJtwQ/20dr0h0thmQ== -"@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.npmmirror.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" +"@rollup/rollup-win32-x64-msvc@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.11.0.tgz#a59158f78d07cd3ac15092ffca2f0319f3bb69f6" + integrity sha512-f3I7h9oTg79UitEco9/2bzwdciYkWr8pITs3meSDSlr1TdvQ7IxkQaaYN2YqZXX5uZhiYL+VuYDmHwNzhx+HOg== -"@types/eslint@*", "@types/eslint@^7.29.0 || ^8.4.1": - version "8.4.6" - resolved "https://registry.npmmirror.com/@types/eslint/-/eslint-8.4.6.tgz#7976f054c1bccfcf514bff0564c0c41df5c08207" - integrity sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" +"@types/estree@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== -"@types/estree@*": - version "1.0.0" - resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== - -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.npmmirror.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== - -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": - version "4.17.31" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f" - integrity sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - -"@types/express@*", "@types/express@^4.17.13": - version "4.17.14" - resolved "https://registry.npmmirror.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c" - integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.18" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/glob@^7.1.1": +"@types/glob@5 - 7": version "7.2.0" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== @@ -1347,730 +309,140 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/html-minifier-terser@^6.0.0": - version "6.1.0" - resolved "https://registry.npmmirror.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" - integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== - -"@types/http-proxy@^1.17.8": - version "1.17.9" - resolved "https://registry.npmmirror.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" - integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw== - dependencies: - "@types/node" "*" - -"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/mime@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" - integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== - "@types/minimatch@*": version "5.1.2" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== -"@types/minimist@^1.2.0": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" - integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== - "@types/node@*": - version "18.7.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.18.tgz#633184f55c322e4fb08612307c274ee6d5ed3154" - integrity sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg== - -"@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== - -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - -"@types/qs@*": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - -"@types/range-parser@*": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== - -"@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.npmmirror.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== - -"@types/serve-index@^1.9.1": - version "1.9.1" - resolved "https://registry.npmmirror.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" - integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + version "20.11.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.19.tgz#b466de054e9cb5b3831bee38938de64ac7f81195" + integrity sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ== dependencies: - "@types/express" "*" + undici-types "~5.26.4" -"@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.0" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" - integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== - dependencies: - "@types/mime" "*" - "@types/node" "*" +"@types/parse5@^5": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" + integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== -"@types/sockjs@^0.3.33": - version "0.3.33" - resolved "https://registry.npmmirror.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" - integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== - dependencies: - "@types/node" "*" - -"@types/ws@^8.5.1": - version "8.5.3" - resolved "https://registry.npmmirror.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" - integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== - dependencies: - "@types/node" "*" - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.npmmirror.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -"@vue/babel-helper-vue-jsx-merge-props@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz#8d53a1e21347db8edbe54d339902583176de09f2" - integrity sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA== - -"@vue/babel-helper-vue-transform-on@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz#9b9c691cd06fc855221a2475c3cc831d774bc7dc" - integrity sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA== - -"@vue/babel-plugin-jsx@^1.0.3": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.1.tgz#0c5bac27880d23f89894cd036a37b55ef61ddfc1" - integrity sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" - "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - "@vue/babel-helper-vue-transform-on" "^1.0.2" - camelcase "^6.0.0" - html-tags "^3.1.0" - svg-tags "^1.0.0" - -"@vue/babel-plugin-transform-vue-jsx@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.4.0.tgz#4d4b3d46a39ea62b7467dd6e26ce47f7ceafb2fe" - integrity sha512-Fmastxw4MMx0vlgLS4XBX0XiBbUFzoMGeVXuMV08wyOfXdikAFqBTuYPR0tlk+XskL19EzHc39SgjrPGY23JnA== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-helper-vue-jsx-merge-props" "^1.4.0" - html-tags "^2.0.0" - lodash.kebabcase "^4.1.1" - svg-tags "^1.0.0" - -"@vue/babel-preset-app@^5.0.8": - version "5.0.8" - resolved "https://registry.npmmirror.com/@vue/babel-preset-app/-/babel-preset-app-5.0.8.tgz#ce38f76314f5265d62a89756ef264c21f1d351a1" - integrity sha512-yl+5qhpjd8e1G4cMXfORkkBlvtPCIgmRf3IYCWYDKIQ7m+PPa5iTm4feiNmCMD6yGqQWMhhK/7M3oWGL9boKwg== - dependencies: - "@babel/core" "^7.12.16" - "@babel/helper-compilation-targets" "^7.12.16" - "@babel/helper-module-imports" "^7.12.13" - "@babel/plugin-proposal-class-properties" "^7.12.13" - "@babel/plugin-proposal-decorators" "^7.12.13" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-jsx" "^7.12.13" - "@babel/plugin-transform-runtime" "^7.12.15" - "@babel/preset-env" "^7.12.16" - "@babel/runtime" "^7.12.13" - "@vue/babel-plugin-jsx" "^1.0.3" - "@vue/babel-preset-jsx" "^1.1.2" - babel-plugin-dynamic-import-node "^2.3.3" - core-js "^3.8.3" - core-js-compat "^3.8.3" - semver "^7.3.4" - -"@vue/babel-preset-jsx@^1.1.2": - version "1.4.0" - resolved "https://registry.npmmirror.com/@vue/babel-preset-jsx/-/babel-preset-jsx-1.4.0.tgz#f4914ba314235ab097bc4372ed67473c0780bfcc" - integrity sha512-QmfRpssBOPZWL5xw7fOuHNifCQcNQC1PrOo/4fu6xlhlKJJKSA3HqX92Nvgyx8fqHZTUGMPHmFA+IDqwXlqkSA== - dependencies: - "@vue/babel-helper-vue-jsx-merge-props" "^1.4.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.4.0" - "@vue/babel-sugar-composition-api-inject-h" "^1.4.0" - "@vue/babel-sugar-composition-api-render-instance" "^1.4.0" - "@vue/babel-sugar-functional-vue" "^1.4.0" - "@vue/babel-sugar-inject-h" "^1.4.0" - "@vue/babel-sugar-v-model" "^1.4.0" - "@vue/babel-sugar-v-on" "^1.4.0" - -"@vue/babel-sugar-composition-api-inject-h@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.4.0.tgz#187e1389f8871d89ece743bb50aed713be9d6c85" - integrity sha512-VQq6zEddJHctnG4w3TfmlVp5FzDavUSut/DwR0xVoe/mJKXyMcsIibL42wPntozITEoY90aBV0/1d2KjxHU52g== - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - -"@vue/babel-sugar-composition-api-render-instance@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.4.0.tgz#2c1607ae6dffdab47e785bc01fa45ba756e992c1" - integrity sha512-6ZDAzcxvy7VcnCjNdHJ59mwK02ZFuP5CnucloidqlZwVQv5CQLijc3lGpR7MD3TWFi78J7+a8J56YxbCtHgT9Q== - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - -"@vue/babel-sugar-functional-vue@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.4.0.tgz#60da31068567082287c7337c66ef4df04e0a1029" - integrity sha512-lTEB4WUFNzYt2In6JsoF9sAYVTo84wC4e+PoZWSgM6FUtqRJz7wMylaEhSRgG71YF+wfLD6cc9nqVeXN2rwBvw== - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - -"@vue/babel-sugar-inject-h@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.4.0.tgz#bf39aa6631fb1d0399b1c49b4c59e1c8899b4363" - integrity sha512-muwWrPKli77uO2fFM7eA3G1lAGnERuSz2NgAxuOLzrsTlQl8W4G+wwbM4nB6iewlKbwKRae3nL03UaF5ffAPMA== - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - -"@vue/babel-sugar-v-model@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.4.0.tgz#a51d986609f430c4f70ada3a93cc560a2970f720" - integrity sha512-0t4HGgXb7WHYLBciZzN5s0Hzqan4Ue+p/3FdQdcaHAb7s5D9WZFGoSxEZHrR1TFVZlAPu1bejTKGeAzaaG3NCQ== - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-helper-vue-jsx-merge-props" "^1.4.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.4.0" - camelcase "^5.0.0" - html-tags "^2.0.0" - svg-tags "^1.0.0" - -"@vue/babel-sugar-v-on@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.4.0.tgz#43b7106a9672d8cbeefc0eb8afe1d376edc6166e" - integrity sha512-m+zud4wKLzSKgQrWwhqRObWzmTuyzl6vOP7024lrpeJM4x2UhQtRDLgYjXAw9xBXjCwS0pP9kXjg91F9ZNo9JA== - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.4.0" - camelcase "^5.0.0" - -"@vue/cli-overlay@^5.0.8": - version "5.0.8" - resolved "https://registry.npmmirror.com/@vue/cli-overlay/-/cli-overlay-5.0.8.tgz#b61477acdc43bbd42fce6326d228471201ecdcdd" - integrity sha512-KmtievE/B4kcXp6SuM2gzsnSd8WebkQpg3XaB6GmFh1BJGRqa1UiW9up7L/Q67uOdTigHxr5Ar2lZms4RcDjwQ== - -"@vue/cli-plugin-babel@~5.0.8": - version "5.0.8" - resolved "https://registry.npmmirror.com/@vue/cli-plugin-babel/-/cli-plugin-babel-5.0.8.tgz#54f9a07900f29baff54803dcfa916c602894feb7" - integrity sha512-a4qqkml3FAJ3auqB2kN2EMPocb/iu0ykeELwed+9B1c1nQ1HKgslKMHMPavYx3Cd/QAx2mBD4hwKBqZXEI/CsQ== - dependencies: - "@babel/core" "^7.12.16" - "@vue/babel-preset-app" "^5.0.8" - "@vue/cli-shared-utils" "^5.0.8" - babel-loader "^8.2.2" - thread-loader "^3.0.0" - webpack "^5.54.0" - -"@vue/cli-plugin-eslint@~5.0.8": - version "5.0.8" - resolved "https://registry.npmmirror.com/@vue/cli-plugin-eslint/-/cli-plugin-eslint-5.0.8.tgz#754939265c2c5b746fa36c7d7705a89138e193bf" - integrity sha512-d11+I5ONYaAPW1KyZj9GlrV/E6HZePq5L5eAF5GgoVdu6sxr6bDgEoxzhcS1Pk2eh8rn1MxG/FyyR+eCBj/CNg== - dependencies: - "@vue/cli-shared-utils" "^5.0.8" - eslint-webpack-plugin "^3.1.0" - globby "^11.0.2" - webpack "^5.54.0" - yorkie "^2.0.0" - -"@vue/cli-plugin-router@^5.0.8", "@vue/cli-plugin-router@~5.0.8": - version "5.0.8" - resolved "https://registry.npmmirror.com/@vue/cli-plugin-router/-/cli-plugin-router-5.0.8.tgz#a113ec626f3d4216d20496c42d35533bce9e889f" - integrity sha512-Gmv4dsGdAsWPqVijz3Ux2OS2HkMrWi1ENj2cYL75nUeL+Xj5HEstSqdtfZ0b1q9NCce+BFB6QnHfTBXc/fCvMg== - dependencies: - "@vue/cli-shared-utils" "^5.0.8" - -"@vue/cli-plugin-unit-mocha@~5.0.8": - version "5.0.8" - resolved "https://registry.npmmirror.com/@vue/cli-plugin-unit-mocha/-/cli-plugin-unit-mocha-5.0.8.tgz#cad35462c5aa525131c8660a4e155d51f15ed9ca" - integrity sha512-t8eN1ttbSkHg+U7AjCKwpuhpV2OBsP35RjBkdSrcAPjoX3MxVwoWyqGPeYI+jWbPGX3tFxM/uMQwN0U3lmzH7A== - dependencies: - "@vue/cli-shared-utils" "^5.0.8" - jsdom "^18.0.1" - jsdom-global "^3.0.2" - mocha "^8.3.0" - mochapack "^2.1.0" - -"@vue/cli-plugin-vuex@^5.0.8", "@vue/cli-plugin-vuex@~5.0.8": - version "5.0.8" - resolved "https://registry.npmmirror.com/@vue/cli-plugin-vuex/-/cli-plugin-vuex-5.0.8.tgz#0d4cb3020f9102bea9288d750729dde176c66ccd" - integrity sha512-HSYWPqrunRE5ZZs8kVwiY6oWcn95qf/OQabwLfprhdpFWAGtLStShjsGED2aDpSSeGAskQETrtR/5h7VqgIlBA== - -"@vue/cli-service@~5.0.8": - version "5.0.8" - resolved "https://registry.npmmirror.com/@vue/cli-service/-/cli-service-5.0.8.tgz#cf3f6f1b7bf0fba9cdab86b6bec4f9897f982dac" - integrity sha512-nV7tYQLe7YsTtzFrfOMIHc5N2hp5lHG2rpYr0aNja9rNljdgcPZLyQRb2YRivTHqTv7lI962UXFURcpStHgyFw== - dependencies: - "@babel/helper-compilation-targets" "^7.12.16" - "@soda/friendly-errors-webpack-plugin" "^1.8.0" - "@soda/get-current-script" "^1.0.2" - "@types/minimist" "^1.2.0" - "@vue/cli-overlay" "^5.0.8" - "@vue/cli-plugin-router" "^5.0.8" - "@vue/cli-plugin-vuex" "^5.0.8" - "@vue/cli-shared-utils" "^5.0.8" - "@vue/component-compiler-utils" "^3.3.0" - "@vue/vue-loader-v15" "npm:vue-loader@^15.9.7" - "@vue/web-component-wrapper" "^1.3.0" - acorn "^8.0.5" - acorn-walk "^8.0.2" - address "^1.1.2" - autoprefixer "^10.2.4" - browserslist "^4.16.3" - case-sensitive-paths-webpack-plugin "^2.3.0" - cli-highlight "^2.1.10" - clipboardy "^2.3.0" - cliui "^7.0.4" - copy-webpack-plugin "^9.0.1" - css-loader "^6.5.0" - css-minimizer-webpack-plugin "^3.0.2" - cssnano "^5.0.0" - debug "^4.1.1" - default-gateway "^6.0.3" - dotenv "^10.0.0" - dotenv-expand "^5.1.0" - fs-extra "^9.1.0" - globby "^11.0.2" - hash-sum "^2.0.0" - html-webpack-plugin "^5.1.0" - is-file-esm "^1.0.0" - launch-editor-middleware "^2.2.1" - lodash.defaultsdeep "^4.6.1" - lodash.mapvalues "^4.6.0" - mini-css-extract-plugin "^2.5.3" - minimist "^1.2.5" - module-alias "^2.2.2" - portfinder "^1.0.26" - postcss "^8.2.6" - postcss-loader "^6.1.1" - progress-webpack-plugin "^1.0.12" - ssri "^8.0.1" - terser-webpack-plugin "^5.1.1" - thread-loader "^3.0.0" - vue-loader "^17.0.0" - vue-style-loader "^4.1.3" - webpack "^5.54.0" - webpack-bundle-analyzer "^4.4.0" - webpack-chain "^6.5.1" - webpack-dev-server "^4.7.3" - webpack-merge "^5.7.3" - webpack-virtual-modules "^0.4.2" - whatwg-fetch "^3.6.2" - -"@vue/cli-shared-utils@^5.0.8": - version "5.0.8" - resolved "https://registry.npmmirror.com/@vue/cli-shared-utils/-/cli-shared-utils-5.0.8.tgz#75fc96528eba2b1c7e33cb7e989a984ddef99c8a" - integrity sha512-uK2YB7bBVuQhjOJF+O52P9yFMXeJVj7ozqJkwYE9PlMHL1LMHjtCYm4cSdOebuPzyP+/9p0BimM/OqxsevIopQ== - dependencies: - "@achrinza/node-ipc" "^9.2.5" - chalk "^4.1.2" - execa "^1.0.0" - joi "^17.4.0" - launch-editor "^2.2.1" - lru-cache "^6.0.0" - node-fetch "^2.6.7" - open "^8.0.2" - ora "^5.3.0" - read-pkg "^5.1.1" - semver "^7.3.4" - strip-ansi "^6.0.0" - -"@vue/compiler-core@3.2.39": - version "3.2.39" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.39.tgz#0d77e635f4bdb918326669155a2dc977c053943e" - integrity sha512-mf/36OWXqWn0wsC40nwRRGheR/qoID+lZXbIuLnr4/AngM0ov8Xvv8GHunC0rKRIkh60bTqydlqTeBo49rlbqw== - dependencies: - "@babel/parser" "^7.16.4" - "@vue/shared" "3.2.39" - estree-walker "^2.0.2" - source-map "^0.6.1" - -"@vue/compiler-dom@3.2.39": - version "3.2.39" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.39.tgz#bd69d35c1a48fe2cea4ab9e96d2a3a735d146fdf" - integrity sha512-HMFI25Be1C8vLEEv1hgEO1dWwG9QQ8LTTPmCkblVJY/O3OvWx6r1+zsox5mKPMGvqYEZa6l8j+xgOfUspgo7hw== - dependencies: - "@vue/compiler-core" "3.2.39" - "@vue/shared" "3.2.39" - -"@vue/compiler-sfc@2.7.10": - version "2.7.10" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-2.7.10.tgz#3fe08e780053a3bbf41328c65ae5dfdee0385206" - integrity sha512-55Shns6WPxlYsz4WX7q9ZJBL77sKE1ZAYNYStLs6GbhIOMrNtjMvzcob6gu3cGlfpCR4bT7NXgyJ3tly2+Hx8Q== - dependencies: - "@babel/parser" "^7.18.4" - postcss "^8.4.14" - source-map "^0.6.1" - -"@vue/compiler-sfc@^3.0.0": - version "3.2.39" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.39.tgz#8fe29990f672805b7c5a2ecfa5b05e681c862ea2" - integrity sha512-fqAQgFs1/BxTUZkd0Vakn3teKUt//J3c420BgnYgEOoVdTwYpBTSXCMJ88GOBCylmUBbtquGPli9tVs7LzsWIA== - dependencies: - "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.39" - "@vue/compiler-dom" "3.2.39" - "@vue/compiler-ssr" "3.2.39" - "@vue/reactivity-transform" "3.2.39" - "@vue/shared" "3.2.39" - estree-walker "^2.0.2" - magic-string "^0.25.7" - postcss "^8.1.10" - source-map "^0.6.1" - -"@vue/compiler-ssr@3.2.39": - version "3.2.39" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.39.tgz#4f3bfb535cb98b764bee45e078700e03ccc60633" - integrity sha512-EoGCJ6lincKOZGW+0Ky4WOKsSmqL7hp1ZYgen8M7u/mlvvEQUaO9tKKOy7K43M9U2aA3tPv0TuYYQFrEbK2eFQ== - dependencies: - "@vue/compiler-dom" "3.2.39" - "@vue/shared" "3.2.39" - -"@vue/component-compiler-utils@^3.1.0", "@vue/component-compiler-utils@^3.3.0": - version "3.3.0" - resolved "https://registry.npmmirror.com/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz#f9f5fb53464b0c37b2c8d2f3fbfe44df60f61dc9" - integrity sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ== - dependencies: - consolidate "^0.15.1" - hash-sum "^1.0.2" - lru-cache "^4.1.2" - merge-source-map "^1.1.0" - postcss "^7.0.36" - postcss-selector-parser "^6.0.2" - source-map "~0.6.1" - vue-template-es2015-compiler "^1.9.0" - optionalDependencies: - prettier "^1.18.2 || ^2.0.0" - -"@vue/eslint-config-standard@^6.1.0": - version "6.1.0" - resolved "https://registry.npmmirror.com/@vue/eslint-config-standard/-/eslint-config-standard-6.1.0.tgz#b362ba67c86caa4e7b44481c2303c9dccc2dc037" - integrity sha512-9+hrEyflDzsGdlBDl9jPV5DIYUx1TOU5OSQqRDKCrNumrxRj5HRWKuk+ocXWnha6uoNRtLC24mY7d/MwqvBCNw== - dependencies: - eslint-config-standard "^16.0.3" - eslint-import-resolver-node "^0.3.4" - eslint-import-resolver-webpack "^0.13.1" - -"@vue/reactivity-transform@3.2.39": - version "3.2.39" - resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.39.tgz#da6ae6c8fd77791b9ae21976720d116591e1c4aa" - integrity sha512-HGuWu864zStiWs9wBC6JYOP1E00UjMdDWIG5W+FpUx28hV3uz9ODOKVNm/vdOy/Pvzg8+OcANxAVC85WFBbl3A== - dependencies: - "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.39" - "@vue/shared" "3.2.39" - estree-walker "^2.0.2" - magic-string "^0.25.7" - -"@vue/shared@3.2.39": - version "3.2.39" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.39.tgz#302df167559a1a5156da162d8cc6760cef67f8e3" - integrity sha512-D3dl2ZB9qE6mTuWPk9RlhDeP1dgNRUKC3NJxji74A4yL8M2MwlhLKUC/49WHjrNzSPug58fWx/yFbaTzGAQSBw== - -"@vue/test-utils@^1.0.3": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.3.0.tgz#d563decdcd9c68a7bca151d4179a2bfd6d5c3e15" - integrity sha512-Xk2Xiyj2k5dFb8eYUKkcN9PzqZSppTlx7LaQWBbdA8tqh3jHr/KHX2/YLhNFc/xwDrgeLybqd+4ZCPJSGPIqeA== - dependencies: - dom-event-types "^1.0.0" - lodash "^4.17.15" - pretty "^2.0.0" - -"@vue/vue-loader-v15@npm:vue-loader@^15.9.7": - version "15.10.0" - resolved "https://registry.npmmirror.com/vue-loader/-/vue-loader-15.10.0.tgz#2a12695c421a2a2cc2138f05a949d04ed086e38b" - integrity sha512-VU6tuO8eKajrFeBzMssFUP9SvakEeeSi1BxdTH5o3+1yUyrldp8IERkSdXlMI2t4kxF2sqYUDsQY+WJBxzBmZg== - dependencies: - "@vue/component-compiler-utils" "^3.1.0" - hash-sum "^1.0.2" - loader-utils "^1.1.0" - vue-hot-reload-api "^2.3.0" - vue-style-loader "^4.1.0" - -"@vue/web-component-wrapper@^1.3.0": - version "1.3.0" - resolved "https://registry.npmmirror.com/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz#b6b40a7625429d2bd7c2281ddba601ed05dc7f1a" - integrity sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA== - -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== - -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== - -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== - -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== - -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.npmmirror.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": +"@ungap/structured-clone@^1.2.0": version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +"@vitejs/plugin-vue@^5.0.4": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz#508d6a0f2440f86945835d903fcc0d95d1bb8a37" + integrity sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ== -abab@^2.0.5, abab@^2.0.6: - version "2.0.6" - resolved "https://registry.npmmirror.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" - integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== - -abbrev@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== +"@vue/compiler-core@3.4.19": + version "3.4.19" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.19.tgz#3161b1ede69da00f3ce8155dfab907a3eaa0515e" + integrity sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w== dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" + "@babel/parser" "^7.23.9" + "@vue/shared" "3.4.19" + entities "^4.5.0" + estree-walker "^2.0.2" + source-map-js "^1.0.2" -acorn-class-fields@^0.3.7: - version "0.3.7" - resolved "https://registry.yarnpkg.com/acorn-class-fields/-/acorn-class-fields-0.3.7.tgz#a35122f3cc6ad2bb33b1857e79215677fcfdd720" - integrity sha512-jdUWSFce0fuADUljmExz4TWpPkxmRW/ZCPRqeeUzbGf0vFUcpQYbyq52l75qGd0oSwwtAepeL6hgb/naRgvcKQ== +"@vue/compiler-dom@3.4.19": + version "3.4.19" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz#2457e57e978f431e3b5fd11fc50a3e92d5816f9a" + integrity sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA== dependencies: - acorn-private-class-elements "^0.2.7" + "@vue/compiler-core" "3.4.19" + "@vue/shared" "3.4.19" -acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.npmmirror.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== +"@vue/compiler-sfc@3.4.19": + version "3.4.19" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz#33b238ded6d63e51f6a7048b742626f6007df129" + integrity sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg== dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" + "@babel/parser" "^7.23.9" + "@vue/compiler-core" "3.4.19" + "@vue/compiler-dom" "3.4.19" + "@vue/compiler-ssr" "3.4.19" + "@vue/shared" "3.4.19" + estree-walker "^2.0.2" + magic-string "^0.30.6" + postcss "^8.4.33" + source-map-js "^1.0.2" -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.npmmirror.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +"@vue/compiler-ssr@3.4.19": + version "3.4.19" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz#1f8ee06005ebbaa354f8783fad84e9f7ea4a69c2" + integrity sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw== + dependencies: + "@vue/compiler-dom" "3.4.19" + "@vue/shared" "3.4.19" -acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: +"@vue/devtools-api@^6.5.0": + version "6.6.1" + resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.1.tgz#7c14346383751d9f6ad4bea0963245b30220ef83" + integrity sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA== + +"@vue/reactivity@3.4.19": + version "3.4.19" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.19.tgz#8cf335d97d07881d8184cb23289289dc18b03f60" + integrity sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA== + dependencies: + "@vue/shared" "3.4.19" + +"@vue/runtime-core@3.4.19": + version "3.4.19" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.19.tgz#ef10357fdf3afdf68523b55424541000105e2aeb" + integrity sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw== + dependencies: + "@vue/reactivity" "3.4.19" + "@vue/shared" "3.4.19" + +"@vue/runtime-dom@3.4.19": + version "3.4.19" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.19.tgz#079141e31d9f47515b9595f29843d51011f88739" + integrity sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g== + dependencies: + "@vue/runtime-core" "3.4.19" + "@vue/shared" "3.4.19" + csstype "^3.1.3" + +"@vue/server-renderer@3.4.19": + version "3.4.19" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.19.tgz#e6f8ff5268d0758766ca9835375218924d5f0eb6" + integrity sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw== + dependencies: + "@vue/compiler-ssr" "3.4.19" + "@vue/shared" "3.4.19" + +"@vue/shared@3.4.19": + version "3.4.19" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.19.tgz#28105147811bcf1e6612bf1c9ab0c6d91ada019c" + integrity sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw== + +"@vuetify/loader-shared@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@vuetify/loader-shared/-/loader-shared-2.0.1.tgz#4bb50ce6455b1c37958a58a63cc32e4ae6829287" + integrity sha512-zy5/ohEO7RcJaWYu2Xiy8TBEOkTb42XvWvSAJwXAtY8OlwqyGhzzBp9OvMVjLGIuFXumBpXKlsaVIkeN0OWWSw== + dependencies: + upath "^2.0.1" + +"@yr/monotone-cubic-spline@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz#7272d89f8e4f6fb7a1600c28c378cc18d3b577b9" + integrity sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA== + +acorn-jsx@^5.3.2: version "5.3.2" - resolved "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-private-class-elements@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/acorn-private-class-elements/-/acorn-private-class-elements-0.2.7.tgz#b14902c705bcff267adede1c9f61c1a317ef95d2" - integrity sha512-+GZH2wOKNZOBI4OOPmzpo4cs6mW297sn6fgIk1dUI08jGjhAaEwvC39mN2gJAg2lmAQJ1rBkFqKWonL3Zz6PVA== +acorn@^8.11.3, acorn@^8.9.0: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== -acorn-private-methods@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/acorn-private-methods/-/acorn-private-methods-0.3.3.tgz#724414ce5b2fec733089d73a5cbba8f7beff75b1" - integrity sha512-46oeEol3YFvLSah5m9hGMlNpxDBCEkdceJgf01AjqKYTK9r6HexKs2rgSbLK81pYjZZMonhftuUReGMlbbv05w== - dependencies: - acorn-private-class-elements "^0.2.7" - -acorn-stage3@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/acorn-stage3/-/acorn-stage3-4.0.0.tgz#e8b98ae2a9991be0ba1745b5b626211086b435a8" - integrity sha512-BR+LaADtA6GTB5prkNqWmlmCLYmkyW0whvSxdHhbupTaro2qBJ95fJDEiRLPUmiACGHPaYyeH9xmNJWdGfXRQw== - dependencies: - acorn-class-fields "^0.3.7" - acorn-private-methods "^0.3.3" - acorn-static-class-features "^0.2.4" - -acorn-static-class-features@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/acorn-static-class-features/-/acorn-static-class-features-0.2.4.tgz#a0f5261dd483f25196716854f2d7652a1deb39ee" - integrity sha512-5X4mpYq5J3pdndLmIB0+WtFd/mKWnNYpuTlTzj32wUu/PMmEGOiayQ5UrqgwdBNiaZBtDDh5kddpP7Yg2QaQYA== - dependencies: - acorn-private-class-elements "^0.2.7" - -acorn-walk@^7.1.1: - version "7.2.0" - resolved "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" - integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== - -acorn-walk@^8.0.0, acorn-walk@^8.0.2, acorn-walk@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^7.1.1, acorn@^7.4.0: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -acorn@^8.0.4, acorn@^8.0.5, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== - -address@^1.1.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.1.tgz#25bb61095b7522d65b357baa11bc05492d4c8acd" - integrity sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA== - -agent-base@6: - version "6.0.2" - resolved "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv-keywords@^5.0.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - -ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2080,83 +452,39 @@ ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.0.1, ajv@^8.8.0: - version "8.11.0" - resolved "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-escapes@^3.0.0: - version "3.2.0" - resolved "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - -ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.npmmirror.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - -ansi-regex@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" - integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== - -ansi-regex@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" - integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0, ansi-styles@^4.1.0: +ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== - -anymatch@~3.1.1, anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" -apexcharts@^3.25.0: - version "3.35.5" - resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.35.5.tgz#c5a950f6f7be35ff4f4509b2179ff538d366c6ec" - integrity sha512-Bi3aq35xWntI71JlywXTBBAOhuKTbB4wijKw4ClkIAFV904YDkHPIJ8N9LcZq9fvVb0VX1AEmyOFBOB2Vwsuew== +apexcharts@^3.45.2: + version "3.45.2" + resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.45.2.tgz#18a6343da122c12d71ac9f35260aacd31b16fbfb" + integrity sha512-PpuM4sJWy70sUh5U1IFn1m1p45MdHSChLUNnqEoUUUHSU2IHZugFrsVNhov1S8Q0cvfdrCRCvdBtHGSs6PSAWQ== dependencies: + "@yr/monotone-cubic-spline" "^1.0.3" svg.draggable.js "^2.2.2" svg.easing.js "^2.0.0" svg.filter.js "^2.0.2" @@ -2164,237 +492,40 @@ apexcharts@^3.25.0: svg.resize.js "^1.4.3" svg.select.js "^3.0.1" -arch@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" - integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - argparse@^2.0.1: version "2.0.1" - resolved "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -array-find@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-find/-/array-find-1.0.0.tgz#6c8e286d11ed768327f8e62ecee87353ca3e78b8" - integrity sha512-kO/vVCacW9mnpn3WPWbTVlEnOabK2L7LWi2HViURtCM46y1zb6I8UMjx4LgbiqadTgHnLInUronwn3ampNTJtQ== - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.npmmirror.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - -array-includes@^3.1.4: - version "3.1.5" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb" - integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - get-intrinsic "^1.1.1" - is-string "^1.0.7" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array.prototype.flat@^1.2.5: - version "1.3.0" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" - integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.2" - es-shim-unscopables "^1.0.0" - -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== - -assert-never@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe" - integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw== - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -async@^2.6.4: - version "2.6.4" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" - integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== - dependencies: - lodash "^4.17.14" +array-back@^3.0.1, array-back@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - -autoprefixer@^10.2.4: - version "10.4.12" - resolved "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.12.tgz#183f30bf0b0722af54ee5ef257f7d4320bb33129" - integrity sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q== +axios@^1.6.7: + version "1.6.7" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7" + integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA== dependencies: - browserslist "^4.21.4" - caniuse-lite "^1.0.30001407" - fraction.js "^4.2.0" - normalize-range "^0.1.2" - picocolors "^1.0.0" - postcss-value-parser "^4.2.0" - -axios@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.0.tgz#f1e5292f26b2fd5c2e66876adc5b06cdbd7d2102" - integrity sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg== - dependencies: - follow-redirects "^1.15.0" + follow-redirects "^1.15.4" form-data "^4.0.0" proxy-from-env "^1.1.0" -babel-loader@^8.2.2: - version "8.2.5" - resolved "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e" - integrity sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ== - dependencies: - find-cache-dir "^3.3.1" - loader-utils "^2.0.0" - make-dir "^3.1.0" - schema-utils "^2.6.5" - -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - -babel-plugin-polyfill-corejs2@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" - integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== - dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.3" - semver "^6.1.1" - -babel-plugin-polyfill-corejs3@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" - integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - core-js-compat "^3.25.1" - -babel-plugin-polyfill-regenerator@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" - integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - -babel-walk@3.0.0-canary-5: - version "3.0.0-canary-5" - resolved "https://registry.yarnpkg.com/babel-walk/-/babel-walk-3.0.0-canary-5.tgz#f66ecd7298357aee44955f235a6ef54219104b11" - integrity sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw== - dependencies: - "@babel/types" "^7.9.6" - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bl@^4.1.0: - version "4.1.0" - resolved "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -bluebird@^3.1.1: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -body-parser@1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" - integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.10.3" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - -bonjour-service@^1.0.11: - version "1.0.14" - resolved "https://registry.npmmirror.com/bonjour-service/-/bonjour-service-1.0.14.tgz#c346f5bc84e87802d08f8d5a60b93f758e514ee7" - integrity sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ== - dependencies: - array-flatten "^2.1.2" - dns-equal "^1.0.0" - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -2408,13 +539,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -2422,124 +546,12 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.3, browserslist@^4.16.6, browserslist@^4.20.3, browserslist@^4.21.3, browserslist@^4.21.4: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== - dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -buntis@0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/buntis/-/buntis-0.2.1.tgz#a043aabc7d64f2243bfaa53e34e999c2dd790e82" - integrity sha512-5wszfQlsqJmZrfxpPkO5yQcEoBAmfUYlXxXU/IM6PhPZ8DMnMMJQ9rvAHfe5WZmnB6E1IoJYylFfTaf1e2FJbQ== - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsite@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" - integrity sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ== - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camel-case@^4.1.2: - version "4.1.2" - resolved "https://registry.npmmirror.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" - integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== - dependencies: - pascal-case "^3.1.2" - tslib "^2.0.3" - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-api@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" - integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== - dependencies: - browserslist "^4.0.0" - caniuse-lite "^1.0.0" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001407: - version "1.0.30001553" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001553.tgz" - integrity sha512-N0ttd6TrFfuqKNi+pMgWJTb9qrdJu4JSpgPFLe/lrD19ugC6fZgF0pUewRowDwzdDnb9V41mFcdlYgl/PyKf4A== - -case-sensitive-paths-webpack-plugin@^2.3.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" - integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== - -chai@^4.1.2: - version "4.3.6" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c" - integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - loupe "^2.3.1" - pathval "^1.1.1" - type-detect "^4.0.5" - -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.2: +chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2548,15 +560,7 @@ chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2564,62 +568,10 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -character-parser@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" - integrity sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw== - dependencies: - is-regex "^1.0.3" - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== - -cheerio-select@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" - integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== - dependencies: - boolbase "^1.0.0" - css-select "^5.1.0" - css-what "^6.1.0" - domelementtype "^2.3.0" - domhandler "^5.0.3" - domutils "^3.0.1" - -cheerio@^1.0.0-rc.3: - version "1.0.0-rc.12" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" - integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== - dependencies: - cheerio-select "^2.1.0" - dom-serializer "^2.0.0" - domhandler "^5.0.3" - domutils "^3.0.1" - htmlparser2 "^8.0.1" - parse5 "^7.0.0" - parse5-htmlparser2-tree-adapter "^7.0.0" - -chokidar@3.5.1: - version "3.5.1" - resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.5.0" - optionalDependencies: - fsevents "~2.3.1" - -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.2, chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== dependencies: anymatch "~3.1.2" braces "~3.0.2" @@ -2631,95 +583,6 @@ chokidar@3.5.1: optionalDependencies: fsevents "~2.3.2" -chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== - -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== - -clean-css@^5.2.2: - version "5.3.1" - resolved "https://registry.npmmirror.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32" - integrity sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg== - dependencies: - source-map "~0.6.0" - -cli-cursor@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw== - dependencies: - restore-cursor "^2.0.0" - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-highlight@^2.1.10: - version "2.1.11" - resolved "https://registry.npmmirror.com/cli-highlight/-/cli-highlight-2.1.11.tgz#49736fa452f0aaf4fae580e30acb26828d2dc1bf" - integrity sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg== - dependencies: - chalk "^4.0.0" - highlight.js "^10.7.1" - mz "^2.4.0" - parse5 "^5.1.1" - parse5-htmlparser2-tree-adapter "^6.0.0" - yargs "^16.0.0" - -cli-spinners@^2.5.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a" - integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw== - -clipboardy@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-2.3.0.tgz#3c2903650c68e46a91b388985bc2774287dba290" - integrity sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ== - dependencies: - arch "^2.1.1" - execa "^1.0.0" - is-wsl "^2.1.1" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -cliui@^7.0.2, cliui@^7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== - color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -2744,526 +607,89 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -colord@^2.9.1: - version "2.9.3" - resolved "https://registry.npmmirror.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" - integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== - -colorette@^2.0.10: - version "2.0.19" - resolved "https://registry.npmmirror.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" - integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== - combined-stream@^1.0.8: version "1.0.8" - resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" -commander@^2.19.0, commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^7.2.0: - version "7.2.0" - resolved "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -commander@^8.3.0: - version "8.3.0" - resolved "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== +command-line-args@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" + integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" + array-back "^3.1.0" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -condense-newlines@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/condense-newlines/-/condense-newlines-0.2.1.tgz#3de985553139475d32502c83b02f60684d24c55f" - integrity sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg== +core-js@^3.29.0: + version "3.36.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.36.0.tgz#e752fa0b0b462a0787d56e9d73f80b0f7c0dde68" + integrity sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw== + +cosmiconfig@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz#34c3fc58287b915f3ae905ab6dc3de258b55ad9d" + integrity sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg== dependencies: - extend-shallow "^2.0.1" - is-whitespace "^0.3.0" - kind-of "^3.0.2" + env-paths "^2.2.1" + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" -config-chain@^1.1.13: - version "1.1.13" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" - integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - -connect-history-api-fallback@^2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" - integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== - -consolidate@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" - integrity sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw== - dependencies: - bluebird "^3.1.1" - -constantinople@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-4.0.1.tgz#0def113fa0e4dc8de83331a5cf79c8b325213151" - integrity sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw== - dependencies: - "@babel/parser" "^7.6.0" - "@babel/types" "^7.6.1" - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - -copy-webpack-plugin@^9.0.1: - version "9.1.0" - resolved "https://registry.npmmirror.com/copy-webpack-plugin/-/copy-webpack-plugin-9.1.0.tgz#2d2c460c4c4695ec0a58afb2801a1205256c4e6b" - integrity sha512-rxnR7PaGigJzhqETHGmAcxKnLZSR5u1Y3/bcIv/1FnqXedcL/E2ewK7ZCNrArJKCiSv8yVXhTqetJh8inDvfsA== - dependencies: - fast-glob "^3.2.7" - glob-parent "^6.0.1" - globby "^11.0.3" - normalize-path "^3.0.0" - schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - -core-js-compat@^3.25.1, core-js-compat@^3.8.3: - version "3.25.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.2.tgz#7875573586809909c69e03ef310810c1969ee138" - integrity sha512-TxfyECD4smdn3/CjWxczVtJqVLEEC2up7/82t7vC0AzNogr+4nQ8vyF7abxAuTXWvjTClSbvGhU0RgqA4ToQaQ== - dependencies: - browserslist "^4.21.4" - -core-js@^2.6.12: - version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - -core-js@^3.6.5, core-js@^3.8.3: - version "3.25.2" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.25.2.tgz#2d3670c1455432b53fa780300a6fc1bd8304932c" - integrity sha512-YB4IAT1bjEfxTJ1XYy11hJAKskO+qmhuDBM8/guIfMz4JvdsAQAqvyb97zXX7JgSrfPLG5mRGFWJwJD39ruq2A== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cosmiconfig@^7.0.0: - version "7.0.1" - resolved "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" - integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A== - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.0: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.2: version "7.0.3" - resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" which "^2.0.1" -css-declaration-sorter@^6.3.0: - version "6.3.1" - resolved "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz#be5e1d71b7a992433fb1c542c7a1b835e45682ec" - integrity sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w== - -css-loader@^6.5.0: - version "6.7.1" - resolved "https://registry.npmmirror.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" - integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== - dependencies: - icss-utils "^5.1.0" - postcss "^8.4.7" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.2.0" - semver "^7.3.5" - -css-minimizer-webpack-plugin@^3.0.2: - version "3.4.1" - resolved "https://registry.npmmirror.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz#ab78f781ced9181992fe7b6e4f3422e76429878f" - integrity sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q== - dependencies: - cssnano "^5.0.6" - jest-worker "^27.0.2" - postcss "^8.3.5" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" - source-map "^0.6.1" - -css-select@^4.1.3: - version "4.3.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" - integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== - dependencies: - boolbase "^1.0.0" - css-what "^6.0.1" - domhandler "^4.3.1" - domutils "^2.8.0" - nth-check "^2.0.1" - -css-select@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" - integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== - dependencies: - boolbase "^1.0.0" - css-what "^6.1.0" - domhandler "^5.0.2" - domutils "^3.0.1" - nth-check "^2.0.1" - -css-tree@^1.1.2, css-tree@^1.1.3: - version "1.1.3" - resolved "https://registry.npmmirror.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" - integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== - dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" - -css-what@^6.0.1, css-what@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== +css-selector-parser@^1.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-1.4.1.tgz#03f9cb8a81c3e5ab2c51684557d5aaf6d2569759" + integrity sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g== cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^5.2.12: - version "5.2.12" - resolved "https://registry.npmmirror.com/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz#ebe6596ec7030e62c3eb2b3c09f533c0644a9a97" - integrity sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew== - dependencies: - css-declaration-sorter "^6.3.0" - cssnano-utils "^3.1.0" - postcss-calc "^8.2.3" - postcss-colormin "^5.3.0" - postcss-convert-values "^5.1.2" - postcss-discard-comments "^5.1.2" - postcss-discard-duplicates "^5.1.0" - postcss-discard-empty "^5.1.1" - postcss-discard-overridden "^5.1.0" - postcss-merge-longhand "^5.1.6" - postcss-merge-rules "^5.1.2" - postcss-minify-font-values "^5.1.0" - postcss-minify-gradients "^5.1.1" - postcss-minify-params "^5.1.3" - postcss-minify-selectors "^5.2.1" - postcss-normalize-charset "^5.1.0" - postcss-normalize-display-values "^5.1.0" - postcss-normalize-positions "^5.1.1" - postcss-normalize-repeat-style "^5.1.1" - postcss-normalize-string "^5.1.0" - postcss-normalize-timing-functions "^5.1.0" - postcss-normalize-unicode "^5.1.0" - postcss-normalize-url "^5.1.0" - postcss-normalize-whitespace "^5.1.1" - postcss-ordered-values "^5.1.3" - postcss-reduce-initial "^5.1.0" - postcss-reduce-transforms "^5.1.0" - postcss-svgo "^5.1.0" - postcss-unique-selectors "^5.1.1" +csstype@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== -cssnano-utils@^3.1.0: - version "3.1.0" - resolved "https://registry.npmmirror.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" - integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== +debounce@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-2.0.0.tgz#b2f914518a1481466f4edaee0b063e4d473ad549" + integrity sha512-xRetU6gL1VJbs85Mc4FoEGSjQxzpdxRyFhe3lmWFyy2EzydIcD4xzUvRJMD+NPDfMwKNhxa3PvsIOU32luIWeA== -cssnano@^5.0.0, cssnano@^5.0.6: - version "5.1.13" - resolved "https://registry.npmmirror.com/cssnano/-/cssnano-5.1.13.tgz#83d0926e72955332dc4802a7070296e6258efc0a" - integrity sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ== - dependencies: - cssnano-preset-default "^5.2.12" - lilconfig "^2.0.3" - yaml "^1.10.2" - -csso@^4.2.0: - version "4.2.0" - resolved "https://registry.npmmirror.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" - integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== - dependencies: - css-tree "^1.1.2" - -cssom@^0.5.0: - version "0.5.0" - resolved "https://registry.npmmirror.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" - integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== - -cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^2.3.0: - version "2.3.0" - resolved "https://registry.npmmirror.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== - dependencies: - cssom "~0.3.6" - -csstype@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" - integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== - -data-urls@^3.0.1: - version "3.0.2" - resolved "https://registry.npmmirror.com/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143" - integrity sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ== - dependencies: - abab "^2.0.6" - whatwg-mimetype "^3.0.0" - whatwg-url "^11.0.0" - -de-indent@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" - integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg== - -debounce@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" - integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== - -debug@2.6.9, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: +debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@4.3.1: - version "4.3.1" - resolved "https://registry.npmmirror.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decache@^4.6.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/decache/-/decache-4.6.1.tgz#5928bfab97a6fcf22a65047a3d07999af36efaf0" - integrity sha512-ohApBM8u9ygepJCjgBrEZSSxPjc0T/PJkD+uNyxXPkqudyUpdXpwJYp0VISm2WrPVzASU6DZyIi6BWdyw7uJ2Q== - dependencies: - callsite "^1.0.0" - -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -decimal.js@^10.3.1: - version "10.4.1" - resolved "https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.1.tgz#be75eeac4a2281aace80c1a8753587c27ef053e7" - integrity sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw== - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - -deep-is@^0.1.3, deep-is@~0.1.3: +deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -deepmerge@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" - integrity sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ== - -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.npmmirror.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - -defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA== - dependencies: - clone "^1.0.2" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.npmmirror.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== - -dns-packet@^5.2.2: - version "5.4.0" - resolved "https://registry.npmmirror.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" - integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -3271,219 +697,15 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -doctypes@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" - integrity sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ== +entities@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== -dom-converter@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" - integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== - dependencies: - utila "~0.4" - -dom-event-types@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/dom-event-types/-/dom-event-types-1.1.0.tgz#120c1f92ddea7758db1ccee0a100a33c39f4701b" - integrity sha512-jNCX+uNJ3v38BKvPbpki6j5ItVlnSqVV6vDWGS6rExzCMjsc39frLjm1n91o6YaKK6AZl0wLloItW6C6mr61BQ== - -dom-serializer@^1.0.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" - integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.0" - entities "^2.0.0" - -dom-serializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" - integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.2" - entities "^4.2.0" - -domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domexception@^4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" - integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== - dependencies: - webidl-conversions "^7.0.0" - -domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" - integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== - dependencies: - domelementtype "^2.2.0" - -domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" - integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== - dependencies: - domelementtype "^2.3.0" - -domutils@^2.5.2, domutils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" - integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - -domutils@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c" - integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== - dependencies: - dom-serializer "^2.0.0" - domelementtype "^2.3.0" - domhandler "^5.0.1" - -dot-case@^3.0.4: - version "3.0.4" - resolved "https://registry.npmmirror.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" - integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -dotenv-expand@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" - integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== - -dotenv@^10.0.0: - version "10.0.0" - resolved "https://registry.npmmirror.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" - integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== - -duplexer@^0.1.2: - version "0.1.2" - resolved "https://registry.npmmirror.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" - integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== - -easy-stack@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/easy-stack/-/easy-stack-1.0.1.tgz#8afe4264626988cabb11f3c704ccd0c835411066" - integrity sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w== - -easygettext@^2.15.0: - version "2.17.0" - resolved "https://registry.yarnpkg.com/easygettext/-/easygettext-2.17.0.tgz#af55ec030b9aabf514aadf0e32383a6f45cc43af" - integrity sha512-QmMWIu6l83SW2QuEFd4GIDrTey0qOn0haTOMt4NdPKPHEBihAqdo9HHYRDHiPg/msZSKaye7qDOLAcqHlmfo+g== - dependencies: - "@babel/core" "^7.11.6" - acorn "^7.4.0" - acorn-stage3 "^4.0.0" - acorn-walk "^8.0.0" - buntis "0.2.1" - cheerio "^1.0.0-rc.3" - estree-walker "^2.0.1" - flow-remove-types "^2.135.0" - minimist "^1.2.5" - pofile "^1.1.0" - optionalDependencies: - "@vue/compiler-sfc" "^3.0.0" - pug "^3.0.2" - -editorconfig@^0.15.3: - version "0.15.3" - resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" - integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== - dependencies: - commander "^2.19.0" - lru-cache "^4.1.5" - semver "^5.6.0" - sigmund "^1.0.1" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -electron-to-chromium@^1.4.251: - version "1.4.258" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.258.tgz#44c5456f487be082f038282fbcfd7b06ae99720d" - integrity sha512-vutF4q0dTUXoAFI7Vbtdwen/BJVwPgj8GRg/SElOodfH7VTX+svUe62A5BG41QRQGk5HsZPB0M++KH1lAlOt0A== - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enhanced-resolve@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e" - integrity sha512-kxpoMgrdtkXZ5h0SeraBS1iRntpTpQ3R8ussdb38+UAFnMGX5DDyJXePm+OCHOcoXvHDw7mc2erbJBpDnl7TPw== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.2.0" - tapable "^0.1.8" - -enhanced-resolve@^5.10.0: - version "5.10.0" - resolved "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" - integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.npmmirror.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - -entities@^4.2.0, entities@^4.3.0, entities@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" - integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== - -errno@^0.1.3: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" +env-paths@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== error-ex@^1.3.1: version "1.3.2" @@ -3492,323 +714,133 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -error-stack-parser@^2.0.6: - version "2.1.4" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" - integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== - dependencies: - stackframe "^1.3.4" - -es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5: - version "1.20.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.3.tgz#90b143ff7aedc8b3d189bcfac7f1e3e3f81e9da1" - integrity sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.6" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-weakref "^1.0.2" - object-inspect "^1.12.2" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trimend "^1.0.5" - string.prototype.trimstart "^1.0.5" - unbox-primitive "^1.0.2" - -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== - -es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== - dependencies: - has "^1.0.3" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +esbuild@^0.19.3: + version "0.19.12" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.12.tgz#dc82ee5dc79e82f5a5c3b4323a2a641827db3e04" + integrity sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg== + optionalDependencies: + "@esbuild/aix-ppc64" "0.19.12" + "@esbuild/android-arm" "0.19.12" + "@esbuild/android-arm64" "0.19.12" + "@esbuild/android-x64" "0.19.12" + "@esbuild/darwin-arm64" "0.19.12" + "@esbuild/darwin-x64" "0.19.12" + "@esbuild/freebsd-arm64" "0.19.12" + "@esbuild/freebsd-x64" "0.19.12" + "@esbuild/linux-arm" "0.19.12" + "@esbuild/linux-arm64" "0.19.12" + "@esbuild/linux-ia32" "0.19.12" + "@esbuild/linux-loong64" "0.19.12" + "@esbuild/linux-mips64el" "0.19.12" + "@esbuild/linux-ppc64" "0.19.12" + "@esbuild/linux-riscv64" "0.19.12" + "@esbuild/linux-s390x" "0.19.12" + "@esbuild/linux-x64" "0.19.12" + "@esbuild/netbsd-x64" "0.19.12" + "@esbuild/openbsd-x64" "0.19.12" + "@esbuild/sunos-x64" "0.19.12" + "@esbuild/win32-arm64" "0.19.12" + "@esbuild/win32-ia32" "0.19.12" + "@esbuild/win32-x64" "0.19.12" escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== -escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-prettier@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" + integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== + +eslint-plugin-vue@^9.21.1: + version "9.21.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz#da5629efa48527cec98278dca0daa90fada4caf7" + integrity sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw== dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -eslint-config-standard@^16.0.3: - version "16.0.3" - resolved "https://registry.npmmirror.com/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz#6c8761e544e96c531ff92642eeb87842b8488516" - integrity sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg== - -eslint-import-resolver-node@^0.3.4, eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.npmmirror.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== - dependencies: - debug "^3.2.7" - resolve "^1.20.0" - -eslint-import-resolver-webpack@^0.13.1: - version "0.13.2" - resolved "https://registry.npmmirror.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.13.2.tgz#fc813df0d08b9265cc7072d22393bda5198bdc1e" - integrity sha512-XodIPyg1OgE2h5BDErz3WJoK7lawxKTJNhgPNafRST6csC/MZC+L5P6kKqsZGRInpbgc02s/WZMrb4uGJzcuRg== - dependencies: - array-find "^1.0.0" - debug "^3.2.7" - enhanced-resolve "^0.9.1" - find-root "^1.1.0" - has "^1.0.3" - interpret "^1.4.0" - is-core-module "^2.7.0" - is-regex "^1.1.4" - lodash "^4.17.21" - resolve "^1.20.0" - semver "^5.7.1" - -eslint-module-utils@^2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== - dependencies: - debug "^3.2.7" - -eslint-plugin-es@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" - integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== - dependencies: - eslint-utils "^2.0.0" - regexpp "^3.0.0" - -eslint-plugin-import@^2.25.3: - version "2.26.0" - resolved "https://registry.npmmirror.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" - integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== - dependencies: - array-includes "^3.1.4" - array.prototype.flat "^1.2.5" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.3" - has "^1.0.3" - is-core-module "^2.8.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.values "^1.1.5" - resolve "^1.22.0" - tsconfig-paths "^3.14.1" - -eslint-plugin-node@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" - integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== - dependencies: - eslint-plugin-es "^3.0.0" - eslint-utils "^2.0.0" - ignore "^5.1.1" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" - -eslint-plugin-promise@^5.1.0: - version "5.2.0" - resolved "https://registry.npmmirror.com/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz#a596acc32981627eb36d9d75f9666ac1a4564971" - integrity sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw== - -eslint-plugin-standard@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz#0c3bf3a67e853f8bbbc580fb4945fbf16f41b7c5" - integrity sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ== - -eslint-plugin-vue@^8.0.3: - version "8.7.1" - resolved "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz#f13c53547a0c9d64588a675cc5ecc6ccaf63703f" - integrity sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg== - dependencies: - eslint-utils "^3.0.0" + "@eslint-community/eslint-utils" "^4.4.0" natural-compare "^1.4.0" - nth-check "^2.0.1" - postcss-selector-parser "^6.0.9" - semver "^7.3.5" - vue-eslint-parser "^8.0.1" + nth-check "^2.1.1" + postcss-selector-parser "^6.0.13" + semver "^7.5.4" + vue-eslint-parser "^9.4.2" + xml-name-validator "^4.0.0" -eslint-scope@5.1.1, eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.0.0: - version "7.1.1" - resolved "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== +eslint-scope@^7.1.1, eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-utils@^2.0.0, eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.npmmirror.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@^8.56.0: + version "8.56.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.56.0.tgz#4957ce8da409dc0809f99ab07a1b94832ab74b15" + integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: - version "2.1.0" - resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint-visitor-keys@^3.1.0, eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== - -eslint-webpack-plugin@^3.1.0: - version "3.2.0" - resolved "https://registry.npmmirror.com/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz#1978cdb9edc461e4b0195a20da950cf57988347c" - integrity sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w== - dependencies: - "@types/eslint" "^7.29.0 || ^8.4.1" - jest-worker "^28.0.2" - micromatch "^4.0.5" - normalize-path "^3.0.0" - schema-utils "^4.0.0" - -eslint@^7.32.0: - version "7.32.0" - resolved "https://registry.npmmirror.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" - integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== - dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.3" - "@humanwhocodes/config-array" "^0.5.0" - ajv "^6.10.0" + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.56.0" + "@humanwhocodes/config-array" "^0.11.13" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" - debug "^4.0.1" + debug "^4.3.2" doctrine "^3.0.0" - enquirer "^2.3.5" escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" - esquery "^1.4.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" - globals "^13.6.0" - ignore "^4.0.6" - import-fresh "^3.0.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^3.13.1" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" - minimatch "^3.0.4" + minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^6.0.9" + optionator "^0.9.3" + strip-ansi "^6.0.1" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.npmmirror.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== +espree@^9.3.1, espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" - -espree@^9.0.0: - version "9.4.0" - resolved "https://registry.npmmirror.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" - integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== - dependencies: - acorn "^8.8.0" + acorn "^8.9.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.3.0" + eslint-visitor-keys "^3.4.1" -esprima@^4.0.0, esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== +esquery@^1.4.0, esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" @@ -3819,17 +851,12 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -estree-walker@^2.0.1, estree-walker@^2.0.2: +estree-walker@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== @@ -3839,120 +866,15 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -event-pubsub@4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/event-pubsub/-/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e" - integrity sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ== - -eventemitter3@^4.0.0: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -events@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -execa@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" - integrity sha512-zDWS+Rb1E8BlqqhALSt9kUhss8Qq4nN3iof3gsOdyINksElaPyNBtKUMTR62qhvgVWR0CqCX7sdnKe4MnUbFEA== - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -express@^4.17.3: - version "4.18.1" - resolved "https://registry.npmmirror.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" - integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.0" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.5.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.10.3" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.0.3, fast-glob@^3.2.7, fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== +fast-glob@^3.2.12: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -3965,47 +887,25 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== dependencies: reusify "^1.0.4" -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA== - dependencies: - escape-string-regexp "^1.0.5" - file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" -file-loader@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" - integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -4013,248 +913,87 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" + array-back "^3.0.1" -find-cache-dir@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-root@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" - integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== - -find-up@5.0.0: +find-up@^5.0.0: version "5.0.0" - resolved "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" path-exists "^4.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: - flatted "^3.1.0" + flatted "^3.2.9" + keyv "^4.5.3" rimraf "^3.0.2" -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.npmmirror.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== +flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmmirror.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -flow-parser@^0.187.1: - version "0.187.1" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.187.1.tgz#52b2c7ebd7544b75bda0676380138bc5b3de3177" - integrity sha512-ZvlTeakTTMmYGukt4EIQtLEp4ie45W+jK325uukGgiqFg2Rl7TdpOJQbOLUN2xMeGS+WvXaK0uIJ3coPGDXFGQ== - -flow-remove-types@^2.135.0: - version "2.187.1" - resolved "https://registry.yarnpkg.com/flow-remove-types/-/flow-remove-types-2.187.1.tgz#3325563818b021896e2fac76ce3bd048b6c6d9ee" - integrity sha512-kfNwss9K0A76VeeYZgNQ2pTeNPGmVNOh9mBDDJOzueejctZL/Tuiwa8lT10LAWRxTQIzdQcWFrUEzGSDSzZNdg== - dependencies: - flow-parser "^0.187.1" - pirates "^3.0.2" - vlq "^0.2.1" - -follow-redirects@^1.0.0, follow-redirects@^1.15.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== +follow-redirects@^1.15.4: + version "1.15.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" + integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== form-data@^4.0.0: version "4.0.0" - resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" mime-types "^2.1.12" -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fraction.js@^4.2.0: - version "4.2.0" - resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" - integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -fs-extra@^9.1.0: - version "9.1.0" - resolved "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-monkey@^1.0.3: - version "1.0.3" - resolved "https://registry.npmmirror.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.1, fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== +gettext-extractor@^3.6.2: + version "3.8.0" + resolved "https://registry.yarnpkg.com/gettext-extractor/-/gettext-extractor-3.8.0.tgz#b2e8497a5952b039e5f488dca3d2e3aea2cb54b4" + integrity sha512-i/3mDQufQoJd2/EKm/B+VlaYrt3yGjVfLZu8DQpESKH29klNiW6z2S89FVCIEB85bDNgtGCeM/3A/yR1njr/Lw== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" + "@types/glob" "5 - 7" + "@types/parse5" "^5" + css-selector-parser "^1.3" + glob "5 - 7" + parse5 "5 - 6" + pofile "1.0.x" + typescript "4 - 5" -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - -functions-have-names@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.1, get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" - integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -glob-parent@5.1.2, glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1: +glob-parent@^6.0.2: version "6.0.2" - resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.3" -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.npmmirror.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - -glob@7.1.6: - version "7.1.6" - resolved "https://registry.npmmirror.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.1.3: +"glob@5 - 7", glob@^7.1.3, glob@^7.2.0: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -4266,81 +1005,17 @@ glob@^7.0.0, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" - integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.6.0, globals@^13.9.0: - version "13.17.0" - resolved "https://registry.npmmirror.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" - integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== +globals@^13.19.0: + version "13.24.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== dependencies: type-fest "^0.20.2" -globby@^10.0.1: - version "10.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" - integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.0.3" - glob "^7.1.3" - ignore "^5.1.1" - merge2 "^1.2.3" - slash "^3.0.0" - -globby@^11.0.2, globby@^11.0.3: - version "11.1.0" - resolved "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -gzip-size@^6.0.0: - version "6.0.0" - resolved "https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" - integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== - dependencies: - duplexer "^0.1.2" - -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== has-flag@^3.0.0: version "3.0.0" @@ -4352,241 +1027,17 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" +ignore@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +immutable@^4.0.0: + version "4.3.5" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.5.tgz#f8b436e66d59f99760dc577f5c99a4fd2a5cc5a0" + integrity sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw== -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-sum@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" - integrity sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA== - -hash-sum@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" - integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== - -he@1.2.0, he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -highlight.js@^10.7.1: - version "10.7.3" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" - integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-encoding-sniffer@^3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" - integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== - dependencies: - whatwg-encoding "^2.0.0" - -html-entities@^2.3.2: - version "2.3.3" - resolved "https://registry.npmmirror.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" - integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== - -html-minifier-terser@^6.0.2: - version "6.1.0" - resolved "https://registry.npmmirror.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" - integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== - dependencies: - camel-case "^4.1.2" - clean-css "^5.2.2" - commander "^8.3.0" - he "^1.2.0" - param-case "^3.0.4" - relateurl "^0.2.7" - terser "^5.10.0" - -html-tags@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b" - integrity sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g== - -html-tags@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961" - integrity sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg== - -html-webpack-plugin@^5.1.0: - version "5.5.0" - resolved "https://registry.npmmirror.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" - integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== - dependencies: - "@types/html-minifier-terser" "^6.0.0" - html-minifier-terser "^6.0.2" - lodash "^4.17.21" - pretty-error "^4.0.0" - tapable "^2.0.0" - -htmlparser2@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" - integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.0.0" - domutils "^2.5.2" - entities "^2.0.0" - -htmlparser2@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010" - integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.2" - domutils "^3.0.1" - entities "^4.3.0" - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.5.1: - version "0.5.8" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" - integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== - -http-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" - integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== - dependencies: - "@tootallnate/once" "2" - agent-base "6" - debug "4" - -http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.npmmirror.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@0.6.3: - version "0.6.3" - resolved "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.1.1, ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - -import-fresh@^3.0.0, import-fresh@^3.2.1: +import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -4607,57 +1058,16 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== - -ini@^1.3.4: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -interpret@^1.0.0, interpret@^1.2.0, interpret@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -4665,85 +1075,11 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-callable@^1.1.4, is-callable@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.6.tgz#fd6170b0b8c7e2cc73de342ef8284a2202023c44" - integrity sha512-krO72EO2NptOGAX2KYyqbP9vYMlNAXdB53rq6f8LXY6RY7JdSR/3BD6wLUlPHSAesmY9vstNrjvqGaCiRK/91Q== - -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== - dependencies: - ci-info "^1.5.0" - -is-core-module@^2.7.0, is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" - integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-expression@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab" - integrity sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A== - dependencies: - acorn "^7.1.1" - object-assign "^4.1.1" - -is-extendable@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-file-esm@^1.0.0: - version "1.0.0" - resolved "https://registry.npmmirror.com/is-file-esm/-/is-file-esm-1.0.0.tgz#987086b0f5a5318179e9d30f4f2f8d37321e1b5f" - integrity sha512-rZlaNKb4Mr8WlRu2A9XdeoKgnO5aA53XdPHgCKVyCrQ/rWi89RET1+bq37Ru46obaQXeiX4vmFIm1vks41hoSA== - dependencies: - read-pkg-up "^7.0.1" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -4751,266 +1087,44 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.npmmirror.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - -is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.npmmirror.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - -is-promise@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" - integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== - -is-regex@^1.0.3, is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -is-whitespace@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f" - integrity sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg== - -is-wsl@^2.1.1, is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -javascript-stringify@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" - integrity sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg== - -jest-worker@^27.0.2, jest-worker@^27.4.5: - version "27.5.1" - resolved "https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest-worker@^28.0.2: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" - integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -joi@^17.4.0: - version "17.6.1" - resolved "https://registry.npmmirror.com/joi/-/joi-17.6.1.tgz#e77422f277091711599634ac39a409e599d7bdaa" - integrity sha512-Hl7/iBklIX345OCM1TiFSCZRVaAOLDGlWCp0Df2vWYgBgjkezaR7Kvm3joBciBHQjZj5sxXs859r6eqsRSlG8w== - dependencies: - "@hapi/hoek" "^9.0.0" - "@hapi/topo" "^5.0.0" - "@sideway/address" "^4.1.3" - "@sideway/formula" "^3.0.0" - "@sideway/pinpoint" "^2.0.0" - -js-beautify@^1.6.12: - version "1.14.6" - resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.14.6.tgz#b23ca5d74a462c282c7711bb51150bcc97f2b507" - integrity sha512-GfofQY5zDp+cuHc+gsEXKPpNw2KbPddreEo35O6jT6i0RVK6LhsoYBhq5TvK4/n74wnA0QbK8gGd+jUZwTMKJw== - dependencies: - config-chain "^1.1.13" - editorconfig "^0.15.3" - glob "^8.0.3" - nopt "^6.0.0" - -js-cookie@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" - integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== - -js-message@1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/js-message/-/js-message-1.0.7.tgz#fbddd053c7a47021871bb8b2c95397cc17c20e47" - integrity sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA== - -js-stringify@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" - integrity sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g== +js-cookie@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc" + integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw== js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" - integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== -jsdom-global@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/jsdom-global/-/jsdom-global-3.0.2.tgz#6bd299c13b0c4626b2da2c0393cd4385d606acb9" - integrity sha512-t1KMcBkz/pT5JrvcJbpUR2u/w1kO9jXctaaGJ0vZDzwFnIvGWw9IDSRciT83kIs8Bnw4qpOl8bQK08V01YgMPg== - -jsdom@^18.0.1: - version "18.1.1" - resolved "https://registry.npmmirror.com/jsdom/-/jsdom-18.1.1.tgz#15ec896f5ab7df9669a62375606f47c8c09551aa" - integrity sha512-NmJQbjQ/gpS/1at/ce3nCx89HbXL/f5OcenBe8wU1Eik0ROhyUc3LtmG3567dEHAGXkN8rmILW/qtCOPxPHQJw== - dependencies: - abab "^2.0.5" - acorn "^8.5.0" - acorn-globals "^6.0.0" - cssom "^0.5.0" - cssstyle "^2.3.0" - data-urls "^3.0.1" - decimal.js "^10.3.1" - domexception "^4.0.0" - escodegen "^2.0.0" - form-data "^4.0.0" - html-encoding-sniffer "^3.0.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "6.0.1" - saxes "^5.0.1" - symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" - w3c-xmlserializer "^3.0.0" - webidl-conversions "^7.0.0" - whatwg-encoding "^2.0.0" - whatwg-mimetype "^3.0.0" - whatwg-url "^10.0.0" - ws "^8.2.3" - xml-name-validator "^4.0.0" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== - -json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: +json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== @@ -5020,239 +1134,53 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json5@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== dependencies: - minimist "^1.2.0" - -json5@^2.1.2, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jstransformer@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" - integrity sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A== - dependencies: - is-promise "^2.0.0" - promise "^7.0.1" - -kind-of@^3.0.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - -kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -klona@^2.0.5: - version "2.0.5" - resolved "https://registry.npmmirror.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" - integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== - -launch-editor-middleware@^2.2.1: - version "2.6.0" - resolved "https://registry.yarnpkg.com/launch-editor-middleware/-/launch-editor-middleware-2.6.0.tgz#2ba4fe4b695d7fe3d44dee86b6d46d57b8332dfd" - integrity sha512-K2yxgljj5TdCeRN1lBtO3/J26+AIDDDw+04y6VAiZbWcTdBwsYN6RrZBnW5DN/QiSIdKNjKdATLUUluWWFYTIA== - dependencies: - launch-editor "^2.6.0" - -launch-editor@^2.2.1, launch-editor@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.0.tgz#4c0c1a6ac126c572bd9ff9a30da1d2cae66defd7" - integrity sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ== - dependencies: - picocolors "^1.0.0" - shell-quote "^1.7.3" + json-buffer "3.0.1" levn@^0.4.1: version "0.4.1" - resolved "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" type-check "~0.4.0" -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lilconfig@^2.0.3: - version "2.0.6" - resolved "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" - integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== - lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -loader-runner@^4.1.0, loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.npmmirror.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" - integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== - -loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: - version "1.4.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" - integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^1.0.1" - -loader-utils@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" - integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== - -lodash.defaultsdeep@^4.6.1: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" - integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== - -lodash.kebabcase@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" - integrity sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g== - -lodash.mapvalues@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" - integrity sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ== - -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.npmmirror.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== - -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== - -lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: +lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" - integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== - dependencies: - chalk "^4.0.0" - -log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.npmmirror.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -log-update@^2.3.0: - version "2.3.0" - resolved "https://registry.npmmirror.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" - integrity sha512-vlP11XfFGyeNQlmEn9tJ66rEW1coA/79m5z6BCkudjbAGE83uhAcGYrBFwfs3AdLiLzGRusRPAbSPK9xZteCmg== - dependencies: - ansi-escapes "^3.0.0" - cli-cursor "^2.0.0" - wrap-ansi "^3.0.1" - -loupe@^2.3.1: - version "2.3.4" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" - integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== - dependencies: - get-func-name "^2.0.0" - -lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.npmmirror.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== - dependencies: - tslib "^2.0.3" - -lru-cache@^4.0.1, lru-cache@^4.1.2, lru-cache@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -5260,83 +1188,24 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -luxon@^1.28.1: - version "1.28.1" - resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.1.tgz#528cdf3624a54506d710290a2341aa8e6e6c61b0" - integrity sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw== +luxon@^3.4.4: + version "3.4.4" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af" + integrity sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA== -magic-string@^0.25.7: - version "0.25.9" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" - integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== +magic-string@^0.30.6: + version "0.30.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.7.tgz#0cecd0527d473298679da95a2d7aeb8c64048505" + integrity sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA== dependencies: - sourcemap-codec "^1.4.8" + "@jridgewell/sourcemap-codec" "^1.4.15" -make-dir@^3.0.2, make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -mdn-data@2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" - integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -memfs@^3.4.3: - version "3.4.7" - resolved "https://registry.npmmirror.com/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a" - integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== - dependencies: - fs-monkey "^1.0.3" - -memory-fs@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290" - integrity sha512-+y4mDxU4rvXXu5UDSGCGNiesFmwCHuefGMoPCO1WYucNYj7DsLqrFaa2fXVI0H+NNiPTwwzKwspn9yTZqUGqng== - -memory-fs@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== - -merge-source-map@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== - dependencies: - source-map "^0.6.1" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: +merge2@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: +micromatch@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -5344,503 +1213,85 @@ micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" -mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": +mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mini-css-extract-plugin@^2.5.3: - version "2.6.1" - resolved "https://registry.npmmirror.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz#9a1251d15f2035c342d99a468ab9da7a0451b71e" - integrity sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg== - dependencies: - schema-utils "^4.0.0" - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" - integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== - -minipass@^3.1.1: - version "3.3.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.4.tgz#ca99f95dd77c43c7a76bf51e6d200025eee0ffae" - integrity sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw== - dependencies: - yallist "^4.0.0" - -mkdirp@^0.5.6: - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - -mocha@^8.3.0: - version "8.4.0" - resolved "https://registry.npmmirror.com/mocha/-/mocha-8.4.0.tgz#677be88bf15980a3cae03a73e10a0fc3997f0cff" - integrity sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.1" - debug "4.3.1" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.6" - growl "1.10.5" - he "1.2.0" - js-yaml "4.0.0" - log-symbols "4.0.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.20" - serialize-javascript "5.0.1" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - wide-align "1.1.3" - workerpool "6.1.0" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -mochapack@^2.1.0: - version "2.1.4" - resolved "https://registry.npmmirror.com/mochapack/-/mochapack-2.1.4.tgz#308e55a0b79423287d4cdb1eb7ef9736aab90c65" - integrity sha512-qoZYT8ibht6z35e936P6Y/3nynFX843Jm+2l/pNWB3Sue63IHBfqZeAnF6Ypez85kUll7HtapMogfO2hGb2N2Q== - dependencies: - "@babel/runtime-corejs2" "^7.0.0" - chalk "^2.4.2" - chokidar "^3.5.2" - glob-parent "5.1.2" - globby "^10.0.1" - interpret "^1.2.0" - is-glob "^4.0.1" - loader-utils "^1.2.3" - lodash "^4.17.15" - memory-fs "^0.4.1" - minimatch "^3.0.4" - nodent-runtime "^3.2.1" - normalize-path "^3.0.0" - progress "^2.0.3" - source-map-support "^0.5.13" - toposort "^2.0.2" - yargs "14.0.0" - -module-alias@^2.2.2: - version "2.2.2" - resolved "https://registry.npmmirror.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0" - integrity sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q== - -mrmime@^1.0.0: - version "1.0.1" - resolved "https://registry.npmmirror.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27" - integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.npmmirror.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" - integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - -mz@^2.4.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -nanoid@3.1.20: - version "3.1.20" - resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" - integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== - -nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -neo-async@^2.6.1, neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.npmmirror.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - -node-fetch@^2.6.7: - version "2.6.7" - resolved "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-forge@^1: - version "1.3.1" - resolved "https://registry.npmmirror.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha512-JMaRS9L4wSRIR+6PTVEikTrq/lMGEZR43a48ETeilY0Q0iMwVnccMFrUM1k+tNzmYuIU0Vh710bCUqHX+/+ctQ== - -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== - -nodent-runtime@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/nodent-runtime/-/nodent-runtime-3.2.1.tgz#9e2755d85e39f764288f0d4752ebcfe3e541e00e" - integrity sha512-7Ws63oC+215smeKJQCxzrK21VFVlCFBkwl0MOObt0HOpVQXs3u483sAmtkF33nNqZ5rSOQjB76fgyPBmAUrtCA== - -nopt@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" - integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== - dependencies: - abbrev "^1.0.0" - -normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" - integrity sha512-7WyT0w8jhpDStXRq5836AMmihQwq2nrUVQrgjvUo/p/NZf9uy/MeJ246lBJVmWuYXMlJuG9BNZHF0hWjfTbQUA== - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== - -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.npmmirror.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== - dependencies: - path-key "^2.0.0" - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -nth-check@^2.0.1: +nth-check@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== dependencies: boolbase "^1.0.0" -null-loader@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/null-loader/-/null-loader-4.0.1.tgz#8e63bd3a2dd3c64236a4679428632edd0a6dbc6a" - integrity sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -nwsapi@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" - integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== - -object-assign@^4.0.1, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.12.2, object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.0, object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.values@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ== - dependencies: - mimic-fn "^1.0.0" - -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.0.2, open@^8.0.9: - version "8.4.0" - resolved "https://registry.npmmirror.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -opener@^1.5.2: - version "1.5.2" - resolved "https://registry.npmmirror.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" - integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmmirror.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" - -ora@^5.3.0: - version "5.4.1" - resolved "https://registry.npmmirror.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== - -p-limit@^2.0.0, p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" -p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.npmmirror.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== - dependencies: - "@types/retry" "0.12.0" - retry "^0.13.1" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -param-case@^3.0.4: - version "3.0.4" - resolved "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" - integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -5848,7 +1299,7 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-json@^5.0.0: +parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -5858,56 +1309,18 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse5-htmlparser2-tree-adapter@^6.0.0: +parse5-htmlparser2-tree-adapter@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== dependencies: parse5 "^6.0.1" -parse5-htmlparser2-tree-adapter@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" - integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== - dependencies: - domhandler "^5.0.2" - parse5 "^7.0.0" - -parse5@6.0.1, parse5@^6.0.1: +"parse5@5 - 6", parse5@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== -parse5@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== - -parse5@^7.0.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.1.tgz#4649f940ccfb95d8754f37f73078ea20afe0c746" - integrity sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg== - dependencies: - entities "^4.4.0" - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascal-case@^3.1.2: - version "3.1.2" - resolved "https://registry.npmmirror.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" - integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -5918,41 +1331,11 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== - -path-key@^3.0.0, path-key@^3.1.0: +path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -5963,597 +1346,71 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pirates@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-3.0.2.tgz#7e6f85413fd9161ab4e12b539b06010d85954bb9" - integrity sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q== +pinia@^2.1.7: + version "2.1.7" + resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.1.7.tgz#4cf5420d9324ca00b7b4984d3fbf693222115bbc" + integrity sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ== dependencies: - node-modules-regexp "^1.0.0" + "@vue/devtools-api" "^6.5.0" + vue-demi ">=0.14.5" -pkg-dir@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" +pofile@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954" + integrity sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg== -pofile@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.1.3.tgz#e2c0d4052b9829f171b888bfb35c87791dbea297" - integrity sha512-sk96pUvpNwDV6PLrnhr68Uu1S5NohsxqLKz0GuracgrDo40BdF/r1RhHnjakUk6Q4Z0OKIybOQ7GevLKGN1iYw== +pofile@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.1.4.tgz#eab7e29f5017589b2a61b2259dff608c0cad76a2" + integrity sha512-r6Q21sKsY1AjTVVjOuU02VYKVNQGJNQHjTIvs4dEbeuuYfxgYk/DGD2mqqq4RDaVkwdSq0VEtmQUOPe/wH8X3g== -portfinder@^1.0.26: - version "1.0.32" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81" - integrity sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg== - dependencies: - async "^2.6.4" - debug "^3.2.7" - mkdirp "^0.5.6" - -postcss-calc@^8.2.3: - version "8.2.4" - resolved "https://registry.npmmirror.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" - integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== - dependencies: - postcss-selector-parser "^6.0.9" - postcss-value-parser "^4.2.0" - -postcss-colormin@^5.3.0: - version "5.3.0" - resolved "https://registry.npmmirror.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz#3cee9e5ca62b2c27e84fce63affc0cfb5901956a" - integrity sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg== - dependencies: - browserslist "^4.16.6" - caniuse-api "^3.0.0" - colord "^2.9.1" - postcss-value-parser "^4.2.0" - -postcss-convert-values@^5.1.2: - version "5.1.2" - resolved "https://registry.npmmirror.com/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz#31586df4e184c2e8890e8b34a0b9355313f503ab" - integrity sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g== - dependencies: - browserslist "^4.20.3" - postcss-value-parser "^4.2.0" - -postcss-discard-comments@^5.1.2: - version "5.1.2" - resolved "https://registry.npmmirror.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696" - integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ== - -postcss-discard-duplicates@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" - integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== - -postcss-discard-empty@^5.1.1: - version "5.1.1" - resolved "https://registry.npmmirror.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" - integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== - -postcss-discard-overridden@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" - integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== - -postcss-loader@^6.1.1: - version "6.2.1" - resolved "https://registry.npmmirror.com/postcss-loader/-/postcss-loader-6.2.1.tgz#0895f7346b1702103d30fdc66e4d494a93c008ef" - integrity sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q== - dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.5" - semver "^7.3.5" - -postcss-merge-longhand@^5.1.6: - version "5.1.6" - resolved "https://registry.npmmirror.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz#f378a8a7e55766b7b644f48e5d8c789ed7ed51ce" - integrity sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw== - dependencies: - postcss-value-parser "^4.2.0" - stylehacks "^5.1.0" - -postcss-merge-rules@^5.1.2: - version "5.1.2" - resolved "https://registry.npmmirror.com/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz#7049a14d4211045412116d79b751def4484473a5" - integrity sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ== - dependencies: - browserslist "^4.16.6" - caniuse-api "^3.0.0" - cssnano-utils "^3.1.0" - postcss-selector-parser "^6.0.5" - -postcss-minify-font-values@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" - integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-minify-gradients@^5.1.1: - version "5.1.1" - resolved "https://registry.npmmirror.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c" - integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw== - dependencies: - colord "^2.9.1" - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - -postcss-minify-params@^5.1.3: - version "5.1.3" - resolved "https://registry.npmmirror.com/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz#ac41a6465be2db735099bbd1798d85079a6dc1f9" - integrity sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg== - dependencies: - browserslist "^4.16.6" - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - -postcss-minify-selectors@^5.2.1: - version "5.2.1" - resolved "https://registry.npmmirror.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6" - integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg== - dependencies: - postcss-selector-parser "^6.0.5" - -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== - -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== - dependencies: - postcss-selector-parser "^6.0.4" - -postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - -postcss-normalize-charset@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" - integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== - -postcss-normalize-display-values@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" - integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-positions@^5.1.1: - version "5.1.1" - resolved "https://registry.npmmirror.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" - integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-repeat-style@^5.1.1: - version "5.1.1" - resolved "https://registry.npmmirror.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" - integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-string@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" - integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-timing-functions@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" - integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-unicode@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz#3d23aede35e160089a285e27bf715de11dc9db75" - integrity sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ== - dependencies: - browserslist "^4.16.6" - postcss-value-parser "^4.2.0" - -postcss-normalize-url@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" - integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== - dependencies: - normalize-url "^6.0.1" - postcss-value-parser "^4.2.0" - -postcss-normalize-whitespace@^5.1.1: - version "5.1.1" - resolved "https://registry.npmmirror.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" - integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-ordered-values@^5.1.3: - version "5.1.3" - resolved "https://registry.npmmirror.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" - integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== - dependencies: - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - -postcss-reduce-initial@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz#fc31659ea6e85c492fb2a7b545370c215822c5d6" - integrity sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw== - dependencies: - browserslist "^4.16.6" - caniuse-api "^3.0.0" - -postcss-reduce-transforms@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" - integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: - version "6.0.10" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" - integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== +postcss-selector-parser@^6.0.13: + version "6.0.15" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz#11cc2b21eebc0b99ea374ffb9887174855a01535" + integrity sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-svgo@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" - integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== +postcss@^8.4.33, postcss@^8.4.35: + version "8.4.35" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.35.tgz#60997775689ce09011edf083a549cea44aabe2f7" + integrity sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA== dependencies: - postcss-value-parser "^4.2.0" - svgo "^2.7.0" - -postcss-unique-selectors@^5.1.1: - version "5.1.1" - resolved "https://registry.npmmirror.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" - integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== - dependencies: - postcss-selector-parser "^6.0.5" - -postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: - version "4.2.0" - resolved "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -postcss@^7.0.36: - version "7.0.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== - dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" - -postcss@^8.1.10, postcss@^8.2.6, postcss@^8.3.5, postcss@^8.4.14, postcss@^8.4.7: - version "8.4.16" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" - integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== - dependencies: - nanoid "^3.3.4" + nanoid "^3.3.7" picocolors "^1.0.0" source-map-js "^1.0.2" prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== - -"prettier@^1.18.2 || ^2.0.0": - version "2.7.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" - integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== - -pretty-error@^4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" - integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== - dependencies: - lodash "^4.17.20" - renderkid "^3.0.0" - -pretty@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pretty/-/pretty-2.0.0.tgz#adbc7960b7bbfe289a557dc5f737619a220d06a5" - integrity sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w== - dependencies: - condense-newlines "^0.2.1" - extend-shallow "^2.0.1" - js-beautify "^1.6.12" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -progress-webpack-plugin@^1.0.12: - version "1.0.16" - resolved "https://registry.npmmirror.com/progress-webpack-plugin/-/progress-webpack-plugin-1.0.16.tgz#278f5c1afd21af783aad72c5ec95241520230fe5" - integrity sha512-sdiHuuKOzELcBANHfrupYo+r99iPRyOnw15qX+rNlVUqXGfjXdH4IgxriKwG1kNJwVswKQHMdj1hYZMcb9jFaA== - dependencies: - chalk "^2.1.0" - figures "^2.0.0" - log-update "^2.3.0" - -progress@^2.0.0, progress@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise@^7.0.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" +prettier@^3.1.1: + version "3.2.5" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" + integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== - -psl@^1.1.33: - version "1.9.0" - resolved "https://registry.npmmirror.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" - integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== - -pug-attrs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-3.0.0.tgz#b10451e0348165e31fad1cc23ebddd9dc7347c41" - integrity sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA== - dependencies: - constantinople "^4.0.1" - js-stringify "^1.0.2" - pug-runtime "^3.0.0" - -pug-code-gen@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-3.0.2.tgz#ad190f4943133bf186b60b80de483100e132e2ce" - integrity sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg== - dependencies: - constantinople "^4.0.1" - doctypes "^1.1.0" - js-stringify "^1.0.2" - pug-attrs "^3.0.0" - pug-error "^2.0.0" - pug-runtime "^3.0.0" - void-elements "^3.1.0" - with "^7.0.0" - -pug-error@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-2.0.0.tgz#5c62173cb09c34de2a2ce04f17b8adfec74d8ca5" - integrity sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ== - -pug-filters@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-4.0.0.tgz#d3e49af5ba8472e9b7a66d980e707ce9d2cc9b5e" - integrity sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A== - dependencies: - constantinople "^4.0.1" - jstransformer "1.0.0" - pug-error "^2.0.0" - pug-walk "^2.0.0" - resolve "^1.15.1" - -pug-lexer@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-5.0.1.tgz#ae44628c5bef9b190b665683b288ca9024b8b0d5" - integrity sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w== - dependencies: - character-parser "^2.2.0" - is-expression "^4.0.0" - pug-error "^2.0.0" - -pug-linker@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-4.0.0.tgz#12cbc0594fc5a3e06b9fc59e6f93c146962a7708" - integrity sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw== - dependencies: - pug-error "^2.0.0" - pug-walk "^2.0.0" - -pug-load@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-3.0.0.tgz#9fd9cda52202b08adb11d25681fb9f34bd41b662" - integrity sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ== - dependencies: - object-assign "^4.1.1" - pug-walk "^2.0.0" - -pug-parser@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-6.0.0.tgz#a8fdc035863a95b2c1dc5ebf4ecf80b4e76a1260" - integrity sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw== - dependencies: - pug-error "^2.0.0" - token-stream "1.0.0" - -pug-runtime@^3.0.0, pug-runtime@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-3.0.1.tgz#f636976204723f35a8c5f6fad6acda2a191b83d7" - integrity sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg== - -pug-strip-comments@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz#f94b07fd6b495523330f490a7f554b4ff876303e" - integrity sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ== - dependencies: - pug-error "^2.0.0" - -pug-walk@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-2.0.0.tgz#417aabc29232bb4499b5b5069a2b2d2a24d5f5fe" - integrity sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ== - -pug@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/pug/-/pug-3.0.2.tgz#f35c7107343454e43bc27ae0ff76c731b78ea535" - integrity sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw== - dependencies: - pug-code-gen "^3.0.2" - pug-filters "^4.0.0" - pug-lexer "^5.0.1" - pug-linker "^4.0.0" - pug-load "^3.0.0" - pug-parser "^6.0.0" - pug-runtime "^3.0.1" - pug-strip-comments "^2.0.0" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qrcode.vue@~1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/qrcode.vue/-/qrcode.vue-1.7.0.tgz#c54b2934f0650c10d92785d08aaad36c55e0fc56" - integrity sha512-R7t6Y3fDDtcU7L4rtqwGUDP9xD64gJhIwpfjhRCTKmBoYF6SS49PIJHRJ048cse6OI7iwTwgyy2C46N9Ygoc6g== - -qs@6.10.3: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== - dependencies: - side-channel "^1.0.4" - -querystringify@^2.1.1: - version "2.2.0" - resolved "https://registry.npmmirror.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" - integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== +qrcode.vue@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/qrcode.vue/-/qrcode.vue-3.4.1.tgz#dd8141da9c4ea07ee56b111cd13eadf123af822a" + integrity sha512-wq/zHsifH4FJ1GXQi8/wNxD1KfQkckIpjK1KPTc/qwYU5/Bkd4me0w4xZSg6EXk6xLBkVDE0zxVagewv5EMAVA== queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.npmmirror.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - -read-pkg@^5.1.1, read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -readable-stream@^2.0.1: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6, readable-stream@^3.4.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.npmmirror.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== - dependencies: - picomatch "^2.2.1" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -6561,146 +1418,11 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== - dependencies: - resolve "^1.1.6" - -regenerate-unicode-properties@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" - integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== - dependencies: - regenerate "^1.4.2" - -regenerate@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -regenerator-transform@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" - integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== - dependencies: - "@babel/runtime" "^7.8.4" - -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - -regexpp@^3.0.0, regexpp@^3.1.0: - version "3.2.0" - resolved "https://registry.npmmirror.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -regexpu-core@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.2.1.tgz#a69c26f324c1e962e9ffd0b88b055caba8089139" - integrity sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ== - dependencies: - regenerate "^1.4.2" - regenerate-unicode-properties "^10.1.0" - regjsgen "^0.7.1" - regjsparser "^0.9.1" - unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.0.0" - -regjsgen@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.7.1.tgz#ee5ef30e18d3f09b7c369b76e7c2373ed25546f6" - integrity sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA== - -regjsparser@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" - integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== - dependencies: - jsesc "~0.5.0" - -relateurl@^0.2.7: - version "0.2.7" - resolved "https://registry.npmmirror.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== - -renderkid@^3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" - integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== - dependencies: - css-select "^4.1.3" - dom-converter "^0.2.0" - htmlparser2 "^6.1.0" - lodash "^4.17.21" - strip-ansi "^6.0.1" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== - resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.14.2, resolve@^1.15.1, resolve@^1.20.0, resolve@^1.22.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q== - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.npmmirror.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -6708,11 +1430,38 @@ reusify@^1.0.4: rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" +roboto-fontface@*: + version "0.10.0" + resolved "https://registry.yarnpkg.com/roboto-fontface/-/roboto-fontface-0.10.0.tgz#7eee40cfa18b1f7e4e605eaf1a2740afb6fd71b0" + integrity sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g== + +rollup@^4.2.0: + version "4.11.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.11.0.tgz#28f28d8f8660facfed001b512d3cfda8c0dc09b6" + integrity sha512-2xIbaXDXjf3u2tajvA5xROpib7eegJ9Y/uPlSFhXLNpK9ampCczXAhLEb5yLzJyG3LAdI1NWtNjDXiLyniNdjQ== + dependencies: + "@types/estree" "1.0.5" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.11.0" + "@rollup/rollup-android-arm64" "4.11.0" + "@rollup/rollup-darwin-arm64" "4.11.0" + "@rollup/rollup-darwin-x64" "4.11.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.11.0" + "@rollup/rollup-linux-arm64-gnu" "4.11.0" + "@rollup/rollup-linux-arm64-musl" "4.11.0" + "@rollup/rollup-linux-riscv64-gnu" "4.11.0" + "@rollup/rollup-linux-x64-gnu" "4.11.0" + "@rollup/rollup-linux-x64-musl" "4.11.0" + "@rollup/rollup-win32-arm64-msvc" "4.11.0" + "@rollup/rollup-win32-ia32-msvc" "4.11.0" + "@rollup/rollup-win32-x64-msvc" "4.11.0" + fsevents "~2.3.2" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -6720,197 +1469,22 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sass-loader@^8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-8.0.2.tgz#debecd8c3ce243c76454f2e8290482150380090d" - integrity sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ== - dependencies: - clone-deep "^4.0.1" - loader-utils "^1.2.3" - neo-async "^2.6.1" - schema-utils "^2.6.1" - semver "^6.3.0" - -sass@~1.32.12: - version "1.32.13" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.13.tgz#8d29c849e625a415bce71609c7cf95e15f74ed00" - integrity sha512-dEgI9nShraqP7cXQH+lEXVf73WOPCse0QlFzSD8k+1TcOxCMwVXfQlr0jtoluZysQOyJGnfr21dLvYKDJq8HkA== +sass@^1.69.5: + version "1.71.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.71.0.tgz#b3085759b9b2ab503a977aecb7e91153bf941117" + integrity sha512-HKKIKf49Vkxlrav3F/w6qRuPcmImGVbIXJ2I3Kg0VMA+3Bav+8yE9G5XmP5lMj6nl4OlqbPftGAscNaNu28b8w== dependencies: chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" -saxes@^5.0.1: - version "5.0.1" - resolved "https://registry.npmmirror.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" - integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== - dependencies: - xmlchars "^2.2.0" - -schema-utils@^2.6.1, schema-utils@^2.6.5: - version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" - integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== - dependencies: - "@types/json-schema" "^7.0.5" - ajv "^6.12.4" - ajv-keywords "^3.5.2" - -schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.8.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== - -selfsigned@^2.1.1: - version "2.1.1" - resolved "https://registry.npmmirror.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" - integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== - dependencies: - node-forge "^1" - -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.1.2, semver@^7.2.1, semver@^7.3.4, semver@^7.3.5: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== +semver@^7.3.6, semver@^7.5.4: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== dependencies: lru-cache "^6.0.0" -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - -serialize-javascript@5.0.1: - version "5.0.1" - resolved "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" - integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== - dependencies: - randombytes "^2.1.0" - -serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== - dependencies: - shebang-regex "^1.0.0" - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -6918,304 +1492,28 @@ shebang-command@^2.0.0: dependencies: shebang-regex "^3.0.0" -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== - shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" - integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== - -shelljs@^0.8.3: - version "0.8.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" - integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -sigmund@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" - integrity sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g== - -signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -sirv@^1.0.7: - version "1.0.19" - resolved "https://registry.npmmirror.com/sirv/-/sirv-1.0.19.tgz#1d73979b38c7fe91fcba49c85280daa9c2363b49" - integrity sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ== - dependencies: - "@polka/url" "^1.0.0-next.20" - mrmime "^1.0.0" - totalist "^1.0.0" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.npmmirror.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - -source-map-js@^1.0.2: +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-support@^0.5.13, source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -sourcemap-codec@^1.4.8: - version "1.4.8" - resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.12" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz#69077835abe2710b65f03969898b6637b505a779" - integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== - dependencies: - minipass "^3.1.1" - -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== - -stackframe@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" - integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -"statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - -"string-width@^1.0.2 || 2", string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.trimend@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" - integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - -string.prototype.trimstart@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" - integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - integrity sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA== - -strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -stylehacks@^5.1.0: - version "5.1.0" - resolved "https://registry.npmmirror.com/stylehacks/-/stylehacks-5.1.0.tgz#a40066490ca0caca04e96c6b02153ddc39913520" - integrity sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q== - dependencies: - browserslist "^4.16.6" - postcss-selector-parser "^6.0.4" - -supports-color@8.1.1, supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -7230,16 +1528,6 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -svg-tags@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" - integrity sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA== - svg.draggable.js@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz#c514a2f1405efb6f0263e7958f5b68fce50603ba" @@ -7295,111 +1583,11 @@ svg.select.js@^3.0.1: dependencies: svg.js "^2.6.5" -svgo@^2.7.0: - version "2.8.0" - resolved "https://registry.npmmirror.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" - integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== - dependencies: - "@trysound/sax" "0.2.0" - commander "^7.2.0" - css-select "^4.1.3" - css-tree "^1.1.3" - csso "^4.2.0" - picocolors "^1.0.0" - stable "^0.1.8" - -symbol-tree@^3.2.4: - version "3.2.4" - resolved "https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -table@^6.0.9: - version "6.8.0" - resolved "https://registry.npmmirror.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca" - integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA== - dependencies: - ajv "^8.0.1" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - -tapable@^0.1.8: - version "0.1.10" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4" - integrity sha512-jX8Et4hHg57mug1/079yitEKWGB3LCwoxByLsNim89LABq8NqgiX+6iYVOsq0vX8uJHkU+DZ5fnq95f800bEsQ== - -tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -terser-webpack-plugin@^5.1.1, terser-webpack-plugin@^5.1.3: - version "5.3.6" - resolved "https://registry.npmmirror.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c" - integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== - dependencies: - "@jridgewell/trace-mapping" "^0.3.14" - jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - terser "^5.14.1" - -terser@^5.10.0, terser@^5.14.1: - version "5.15.0" - resolved "https://registry.npmmirror.com/terser/-/terser-5.15.0.tgz#e16967894eeba6e1091509ec83f0c60e179f2425" - integrity sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA== - dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" - commander "^2.20.0" - source-map-support "~0.5.20" - text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - -thread-loader@^3.0.0: - version "3.0.4" - resolved "https://registry.npmmirror.com/thread-loader/-/thread-loader-3.0.4.tgz#c392e4c0241fbc80430eb680e4886819b504a31b" - integrity sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA== - dependencies: - json-parse-better-errors "^1.0.2" - loader-runner "^4.1.0" - loader-utils "^2.0.0" - neo-async "^2.6.2" - schema-utils "^3.0.0" - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - -tiny-cookie@^1.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tiny-cookie/-/tiny-cookie-1.0.1.tgz#753786079c642a3c3d0b2accad600f8de119ac2a" - integrity sha512-4KJ21HYTNumxnHvCbLrtrrhSwtWXzpmaRJIUg4biBii5AiSe2izod5bauXiiQxVuf2Fta57U2DTW1Fa4/6Cmgw== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -7407,160 +1595,60 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -token-stream@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-1.0.0.tgz#cc200eab2613f4166d27ff9afc7ca56d49df6eb4" - integrity sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg== - -toposort@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" - integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== - -totalist@^1.0.0: - version "1.1.0" - resolved "https://registry.npmmirror.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" - integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== - -tough-cookie@^4.0.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" - integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== - dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.2.0" - url-parse "^1.5.3" - -tr46@^3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" - integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== - dependencies: - punycode "^2.1.1" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -tsconfig-paths@^3.14.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@^2.0.3: - version "2.4.0" - resolved "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +tslib@^2.4.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== - dependencies: - prelude-ls "~1.1.2" - -type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== +"typescript@4 - 5": + version "5.3.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +unplugin-fonts@^1.0.3: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unplugin-fonts/-/unplugin-fonts-1.1.1.tgz#cd6600d2a048d8237a010b53c9c4dfb1ea73d80f" + integrity sha512-/Aw/rL9D2aslGGM0vi+2R2aG508RSwawLnnBuo+JDSqYc4cHJO1R1phllhN6GysEhBp/6a4B6+vSFPVapWyAAw== dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" + fast-glob "^3.2.12" + unplugin "^1.3.1" -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== +unplugin@^1.3.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.7.1.tgz#009571e3128640f4e327f33680d2db27afaf1e11" + integrity sha512-JqzORDAPxxs8ErLV4x+LL7bk5pk3YlcWqpSNsIkAZj972KzFZLClc/ekppahKkOczGkwIG6ElFgdOgOlK4tXZw== dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" + acorn "^8.11.3" + chokidar "^3.5.3" + webpack-sources "^3.2.3" + webpack-virtual-modules "^0.6.1" -unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" - integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== - -unicode-match-property-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" - integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== - dependencies: - unicode-canonical-property-names-ecmascript "^2.0.0" - unicode-property-aliases-ecmascript "^2.0.0" - -unicode-match-property-value-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" - integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== - -unicode-property-aliases-ecmascript@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" - integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== - -universalify@^0.2.0: - version "0.2.0" - resolved "https://registry.npmmirror.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" - integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -update-browserslist-db@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18" - integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" +upath@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" + integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== uri-js@^4.2.2: version "4.4.1" @@ -7569,605 +1657,125 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -url-parse@^1.5.3: - version "1.5.10" - resolved "https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" - integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: +util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -utila@~0.4: - version "0.4.0" - resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== +vite-plugin-vuetify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/vite-plugin-vuetify/-/vite-plugin-vuetify-2.0.1.tgz#172ffb6c46fec469fa96b3df03fd11b90d48f5d6" + integrity sha512-GlRVAruohE8b0FqmeYYh1cYg3n8THGOv066uMA44qLv9uhUxSLw55CS7fi2yU0wH363TJ2vq36zUsPTjRFrjGQ== dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" + "@vuetify/loader-shared" "^2.0.1" + debug "^4.3.3" + upath "^2.0.1" -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -vee-validate@^3.4.5: - version "3.4.14" - resolved "https://registry.yarnpkg.com/vee-validate/-/vee-validate-3.4.14.tgz#51f91c01d6660c43c6252c417c89fb07cdf8b8dd" - integrity sha512-Hqqic8G9WcRSIzCxiCPqMZv4qB8JE1lIQqIOLDm2K5BXUiL8d4a2+kqkanv8gQSGDzYpnCQZ7BO/T99Aj05T1Q== - -vlq@^0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26" - integrity sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow== - -void-elements@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" - integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== - -vue-apexcharts@^1.6.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/vue-apexcharts/-/vue-apexcharts-1.6.2.tgz#0547826067f97e8ea67ca9423e524eb6669746ad" - integrity sha512-9HS3scJwWgKjmkcWIf+ndNDR0WytUJD8Ju0V2ZYcjYtlTLwJAf2SKUlBZaQTkDmwje/zMgulvZRi+MXmi+WkKw== - -vue-cli-plugin-axios@~0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/vue-cli-plugin-axios/-/vue-cli-plugin-axios-0.0.4.tgz#29d4eb48275c7fe15b92e1fd5d95fbe2a966436f" - integrity sha512-p2b/fvPJuPBnvU8027PAAuU5DiOzUn2lku8XLG/f6c8FU0N+/MXWZAlOuHhqd9e7+KIZitwe/c8qlmv7TglbTg== - -vue-cli-plugin-vuetify@~2.5.8: - version "2.5.8" - resolved "https://registry.npmmirror.com/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.5.8.tgz#a67ef81375fb2cd9f4f912e665e5190de105f2f6" - integrity sha512-uqi0/URJETJBbWlQHD1l0pnY7JN8Ytu+AL1fw50HFlGByPa8/xx+mq19GkFXA9FcwFT01IqEc/TkxMPugchomg== +vite@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.1.3.tgz#dd072653a80225702265550a4700561740dfde55" + integrity sha512-UfmUD36DKkqhi/F75RrxvPpry+9+tTkrXfMNZD+SboZqBCMsxKtO52XeGzzuh7ioz+Eo/SYDBbdb0Z7vgcDJew== dependencies: - null-loader "^4.0.1" - semver "^7.1.2" - shelljs "^0.8.3" + esbuild "^0.19.3" + postcss "^8.4.35" + rollup "^4.2.0" + optionalDependencies: + fsevents "~2.3.3" -vue-cookie@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/vue-cookie/-/vue-cookie-1.1.4.tgz#b8b46d112bda9f93a2f47017c2ed5282d2064fda" - integrity sha512-lxWIzmUTCVra0H7YPbNpYx0wbTQThV+n7ueUOcqtK8dlckmfB8fcyf4OEiRuQUd7iiVub2T3IDlWiisEM5Ku0Q== - dependencies: - tiny-cookie "^1.0" +vue-demi@>=0.14.5: + version "0.14.7" + resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.7.tgz#8317536b3ef74c5b09f268f7782e70194567d8f2" + integrity sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA== -vue-eslint-parser@^8.0.1: - version "8.3.0" - resolved "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz#5d31129a1b3dd89c0069ca0a1c88f970c360bd0d" - integrity sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g== +vue-eslint-parser@^9.4.2: + version "9.4.2" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz#02ffcce82042b082292f2d1672514615f0d95b6d" + integrity sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ== dependencies: - debug "^4.3.2" - eslint-scope "^7.0.0" - eslint-visitor-keys "^3.1.0" - espree "^9.0.0" + debug "^4.3.4" + eslint-scope "^7.1.1" + eslint-visitor-keys "^3.3.0" + espree "^9.3.1" esquery "^1.4.0" lodash "^4.17.21" - semver "^7.3.5" + semver "^7.3.6" -vue-gettext@^2.1.12: - version "2.1.12" - resolved "https://registry.yarnpkg.com/vue-gettext/-/vue-gettext-2.1.12.tgz#444d3220149b17fa4c7caeded3f12d439b698f33" - integrity sha512-7Kw36xtKvARp8ZafQGPK9WR6EM+dhFUikR5f0+etSkiHuvUM3yf1HsRDLYoLLdJ0AMaXxKwgekumzvCk6KX8rA== - -vue-hot-reload-api@^2.3.0: - version "2.3.4" - resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2" - integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog== - -vue-loader@^17.0.0: - version "17.0.0" - resolved "https://registry.npmmirror.com/vue-loader/-/vue-loader-17.0.0.tgz#2eaa80aab125b19f00faa794b5bd867b17f85acb" - integrity sha512-OWSXjrzIvbF2LtOUmxT3HYgwwubbfFelN8PAP9R9dwpIkj48TVioHhWWSx7W7fk+iF5cgg3CBJRxwTdtLU4Ecg== +vue-router@^4.0.0: + version "4.2.5" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.2.5.tgz#b9e3e08f1bd9ea363fdd173032620bc50cf0e98a" + integrity sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw== dependencies: - chalk "^4.1.0" - hash-sum "^2.0.0" - loader-utils "^2.0.0" + "@vue/devtools-api" "^6.5.0" -vue-router@^3.2.0: - version "3.6.5" - resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.6.5.tgz#95847d52b9a7e3f1361cb605c8e6441f202afad8" - integrity sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ== +vue3-apexcharts@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/vue3-apexcharts/-/vue3-apexcharts-1.5.2.tgz#fc179d80e34e6f25982dae809c27173d7374db48" + integrity sha512-rGbgUJDjtsyjfRF0uzwDjzt8+M7ICSRAbm1N9KCDiczW8BSpbEZuaEsJDJYnJuLFIIVXIGilYzIcjNBf6NbeYA== -vue-style-loader@^4.1.0, vue-style-loader@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.3.tgz#6d55863a51fa757ab24e89d9371465072aa7bc35" - integrity sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg== +vue3-gettext@^3.0.0-beta.4: + version "3.0.0-beta.4" + resolved "https://registry.yarnpkg.com/vue3-gettext/-/vue3-gettext-3.0.0-beta.4.tgz#76368e5a8e469cea351e57e00b8f5bbf33062d80" + integrity sha512-EW9F5NexUQW9GNJMjujmMJo8hUQvw6POCVQN9ya0RdapPVEfmkXjuxuhkVEKyBNxq5lRPCepfYkMT8Pu3M6T6w== dependencies: - hash-sum "^1.0.2" - loader-utils "^1.0.2" + chalk "^4.1.2" + command-line-args "^5.2.1" + cosmiconfig "^9.0.0" + gettext-extractor "^3.6.2" + glob "^7.2.0" + parse5 "^6.0.1" + parse5-htmlparser2-tree-adapter "^6.0.1" + pofile "^1.1.3" + tslib "^2.4.0" -vue-template-compiler@^2.6.11: - version "2.7.10" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.7.10.tgz#9e20f35b2fdccacacf732dd7dedb49bf65f4556b" - integrity sha512-QO+8R9YRq1Gudm8ZMdo/lImZLJVUIAM8c07Vp84ojdDAf8HmPJc7XB556PcXV218k2AkKznsRz6xB5uOjAC4EQ== +vue@^3.4.19: + version "3.4.19" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.19.tgz#f9ae0a44db86628548736ff04152830726a97263" + integrity sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw== dependencies: - de-indent "^1.0.2" - he "^1.2.0" + "@vue/compiler-dom" "3.4.19" + "@vue/compiler-sfc" "3.4.19" + "@vue/runtime-dom" "3.4.19" + "@vue/server-renderer" "3.4.19" + "@vue/shared" "3.4.19" -vue-template-es2015-compiler@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" - integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== - -vue@^2.6.14: - version "2.7.10" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.7.10.tgz#ae516cc6c88e1c424754468844218fdd5e280f40" - integrity sha512-HmFC70qarSHPXcKtW8U8fgIkF6JGvjEmDiVInTkKZP0gIlEPhlVlcJJLkdGIDiNkIeA2zJPQTWJUI4iWe+AVfg== - dependencies: - "@vue/compiler-sfc" "2.7.10" - csstype "^3.1.0" - -vuetify-loader@^1.3.0: - version "1.9.2" - resolved "https://registry.yarnpkg.com/vuetify-loader/-/vuetify-loader-1.9.2.tgz#adcadac71c6d9b24bde42a5b81dfda1871f73f81" - integrity sha512-8PP2w7aAs/rjA+Izec6qY7sHVb75MNrGQrDOTZJ5IEnvl+NiFhVpU2iWdRDZ3eMS842cWxSWStvkr+KJJKy+Iw== - dependencies: - acorn "^8.4.1" - acorn-walk "^8.2.0" - decache "^4.6.0" - file-loader "^6.2.0" - loader-utils "^2.0.0" - -vuetify@^2.6.10: - version "2.6.10" - resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-2.6.10.tgz#b86cd7a97bf8cd3828a72c349795b5b3c539ebc2" - integrity sha512-fgUeRDDCwYkwu6WGEEKGe7IdfzOsXJCZGrqkn1pcS2ycuoDL8mR2/dejH5iFNnBY6MnsT365PAGn0J+9otjfQg== - -vuex@^3.4.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.6.2.tgz#236bc086a870c3ae79946f107f16de59d5895e71" - integrity sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw== - -w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.npmmirror.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -w3c-xmlserializer@^3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923" - integrity sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg== - dependencies: - xml-name-validator "^4.0.0" - -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== - dependencies: - defaults "^1.0.3" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -webidl-conversions@^7.0.0: - version "7.0.0" - resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" - integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== - -webpack-bundle-analyzer@^4.4.0: - version "4.6.1" - resolved "https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.6.1.tgz#bee2ee05f4ba4ed430e4831a319126bb4ed9f5a6" - integrity sha512-oKz9Oz9j3rUciLNfpGFjOb49/jEpXNmWdVH8Ls//zNcnLlQdTGXQQMsBbb/gR7Zl8WNLxVCq+0Hqbx3zv6twBw== - dependencies: - acorn "^8.0.4" - acorn-walk "^8.0.0" - chalk "^4.1.0" - commander "^7.2.0" - gzip-size "^6.0.0" - lodash "^4.17.20" - opener "^1.5.2" - sirv "^1.0.7" - ws "^7.3.1" - -webpack-chain@^6.5.1: - version "6.5.1" - resolved "https://registry.npmmirror.com/webpack-chain/-/webpack-chain-6.5.1.tgz#4f27284cbbb637e3c8fbdef43eef588d4d861206" - integrity sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA== - dependencies: - deepmerge "^1.5.2" - javascript-stringify "^2.0.1" - -webpack-dev-middleware@^5.3.1: - version "5.3.3" - resolved "https://registry.npmmirror.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" - integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== - dependencies: - colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@^4.7.3: - version "4.11.1" - resolved "https://registry.npmmirror.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5" - integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.1" - ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^5.3.1" - ws "^8.4.2" - -webpack-merge@^5.7.3: - version "5.8.0" - resolved "https://registry.npmmirror.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" - integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== - dependencies: - clone-deep "^4.0.1" - wildcard "^2.0.0" +vuetify@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-3.5.4.tgz#f919c5194995a123815c277a95812bc230e33464" + integrity sha512-fHgfWMI7+z/UtbVPOezX+O1MNBOOMBW9HnKejcBIyQQ7jFRnTHbDQmbINf25FK0wrg/zkjfzyOmWWREKW39eXg== webpack-sources@^3.2.3: version "3.2.3" - resolved "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack-virtual-modules@^0.4.2: - version "0.4.5" - resolved "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.4.5.tgz#e476842dab5eafb7beb844aa2f747fc12ebbf6ec" - integrity sha512-8bWq0Iluiv9lVf9YaqWQ9+liNgXSHICm+rg544yRgGYaR8yXZTVBaHZkINZSB2yZSWo4b0F6MIxqJezVfOEAlg== +webpack-virtual-modules@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.1.tgz#ac6fdb9c5adb8caecd82ec241c9631b7a3681b6f" + integrity sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg== -webpack@^5.54.0: - version "5.76.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.1.tgz#7773de017e988bccb0f13c7d75ec245f377d295c" - integrity sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.7.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.4.0" - webpack-sources "^3.2.3" - -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - -whatwg-encoding@^2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" - integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== - dependencies: - iconv-lite "0.6.3" - -whatwg-fetch@^3.6.2: - version "3.6.2" - resolved "https://registry.npmmirror.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" - integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== - -whatwg-mimetype@^3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" - integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== - -whatwg-url@^10.0.0: - version "10.0.0" - resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-10.0.0.tgz#37264f720b575b4a311bd4094ed8c760caaa05da" - integrity sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w== - dependencies: - tr46 "^3.0.0" - webidl-conversions "^7.0.0" - -whatwg-url@^11.0.0: - version "11.0.0" - resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" - integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== - dependencies: - tr46 "^3.0.0" - webidl-conversions "^7.0.0" - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== - -which@2.0.2, which@^2.0.1: +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wide-align@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" - integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== - -with@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac" - integrity sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w== - dependencies: - "@babel/parser" "^7.9.6" - "@babel/types" "^7.9.6" - assert-never "^1.2.1" - babel-walk "3.0.0-canary-5" - -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" - integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== - -workerpool@6.1.0: - version "6.1.0" - resolved "https://registry.npmmirror.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" - integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== - -wrap-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" - integrity sha512-iXR3tDXpbnTpzjKSylUJRkLuOrEC7hwEB221cgn6wtF8wpmz28puFXAEfPT5zrjM3wahygB//VuWEr1vTkDcNQ== - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@^7.3.1: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - -ws@^8.2.3, ws@^8.4.2: - version "8.9.0" - resolved "https://registry.npmmirror.com/ws/-/ws-8.9.0.tgz#2a994bb67144be1b53fe2d23c53c028adeb7f45e" - integrity sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg== - xml-name-validator@^4.0.0: version "4.0.0" - resolved "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== -xmlchars@^2.2.0: - version "2.2.0" - resolved "https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0, yaml@^1.10.2: - version "1.10.2" - resolved "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^13.1.1: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@14.0.0: - version "14.0.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.0.0.tgz#ba4cacc802b3c0b3e36a9e791723763d57a85066" - integrity sha512-ssa5JuRjMeZEUjg7bEL99AwpitxU/zWGAGpdj0di41pOEmJti8NR6kyUIJBkR78DTYNPZOU08luUo0GTHuB+ow== - dependencies: - cliui "^5.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.1" - -yargs@16.2.0, yargs@^16.0.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -yorkie@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yorkie/-/yorkie-2.0.0.tgz#92411912d435214e12c51c2ae1093e54b6bb83d9" - integrity sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw== - dependencies: - execa "^0.8.0" - is-ci "^1.0.10" - normalize-path "^1.0.0" - strip-indent "^2.0.0" diff --git a/modoboa/__init__.py b/modoboa/__init__.py index bd516d64a..0ec95caec 100644 --- a/modoboa/__init__.py +++ b/modoboa/__init__.py @@ -8,6 +8,8 @@ except DistributionNotFound: # package is not installed pass + def modoboa_admin(): from modoboa.core.commands import handle_command_line + handle_command_line() diff --git a/modoboa/admin/api/v1/serializers.py b/modoboa/admin/api/v1/serializers.py index 0ba2c6b3c..8582cd576 100644 --- a/modoboa/admin/api/v1/serializers.py +++ b/modoboa/admin/api/v1/serializers.py @@ -15,12 +15,18 @@ from rest_framework import serializers from modoboa.admin import models as admin_models from modoboa.core import ( - constants as core_constants, models as core_models, signals as core_signals + constants as core_constants, + models as core_models, + signals as core_signals, ) from modoboa.lib.exceptions import AliasExists from modoboa.lib import ( - email_utils, exceptions as lib_exceptions, fields as lib_fields, - permissions, validators, web_utils + email_utils, + exceptions as lib_exceptions, + fields as lib_fields, + permissions, + validators, + web_utils, ) from modoboa.parameters import tools as param_tools @@ -35,43 +41,61 @@ class DomainSerializer(serializers.ModelSerializer): help_text=gettext_lazy( "Quota shared between mailboxes. Can be expressed in KB, " "MB (default) or GB. A value of 0 means no quota." - ) + ), ) default_mailbox_quota = serializers.CharField( required=False, help_text=gettext_lazy( - "Default quota in MB applied to mailboxes. A value of 0 means " - "no quota." - ) + "Default quota in MB applied to mailboxes. A value of 0 means " "no quota." + ), ) class Meta: model = models.Domain fields = ( - "pk", "name", "quota", "default_mailbox_quota", "enabled", "type", - "enable_dkim", "dkim_key_selector", "dkim_key_length", - "dkim_public_key", "dkim_private_key_path", - "mailbox_count", "mbalias_count", "domainalias_count", - "dns_global_status", "message_limit", "creation", - "last_modification" + "pk", + "name", + "quota", + "default_mailbox_quota", + "enabled", + "type", + "enable_dkim", + "dkim_key_selector", + "dkim_key_length", + "dkim_public_key", + "dkim_private_key_path", + "mailbox_count", + "mbalias_count", + "domainalias_count", + "dns_global_status", + "message_limit", + "creation", + "last_modification", ) read_only_fields = ( - "pk", "dkim_public_key", "dns_global_status", "allocated_quota_in_percent" - "mailbox_count", "mbalias_count", "domainalias_count", - "enable_dns_checks", "creation", "last_modification" + "pk", + "dkim_public_key", + "dns_global_status", + "allocated_quota_in_percent" "mailbox_count", + "mbalias_count", + "domainalias_count", + "enable_dns_checks", + "creation", + "last_modification", ) def validate_name(self, value): """Check name constraints.""" - domains_must_have_authorized_mx = ( - param_tools.get_global_parameter("domains_must_have_authorized_mx") + domains_must_have_authorized_mx = param_tools.get_global_parameter( + "domains_must_have_authorized_mx" ) user = self.context["request"].user value = value.lower() if domains_must_have_authorized_mx and not user.is_superuser: if not lib.domain_has_authorized_mx(value): raise serializers.ValidationError( - _("No authorized MX record found for this domain")) + _("No authorized MX record found for this domain") + ) return value def validate_quota(self, value): @@ -87,10 +111,9 @@ class DomainSerializer(serializers.ModelSerializer): quota = data.get("quota", 0) default_mailbox_quota = data.get("default_mailbox_quota", 0) if quota != 0 and default_mailbox_quota > quota: - raise serializers.ValidationError({ - "default_mailbox_quota": - _("Cannot be greater than domain quota") - }) + raise serializers.ValidationError( + {"default_mailbox_quota": _("Cannot be greater than domain quota")} + ) return data def create(self, validated_data): @@ -98,15 +121,15 @@ class DomainSerializer(serializers.ModelSerializer): params = dict(param_tools.get_global_parameters("admin")) domain = models.Domain(**validated_data) condition = ( - params["default_domain_message_limit"] is not None and - "message_limit" not in validated_data + params["default_domain_message_limit"] is not None + and "message_limit" not in validated_data ) if condition: domain.message_limit = params["default_domain_message_limit"] creator = self.context["request"].user core_signals.can_create_object.send( - sender=self.__class__, context=creator, - klass=models.Domain, instance=domain) + sender=self.__class__, context=creator, klass=models.Domain, instance=domain + ) domain.save(creator=creator) return domain @@ -125,7 +148,12 @@ class DomainAliasSerializer(serializers.ModelSerializer): class Meta: model = admin_models.DomainAlias - fields = ("pk", "name", "target", "enabled", ) + fields = ( + "pk", + "name", + "target", + "enabled", + ) def validate_target(self, value): """Check target domain.""" @@ -143,14 +171,15 @@ class DomainAliasSerializer(serializers.ModelSerializer): creator = self.context["request"].user try: core_signals.can_create_object.send( - sender=self.__class__, context=creator, - klass=models.DomainAlias) + sender=self.__class__, context=creator, klass=models.DomainAlias + ) core_signals.can_create_object.send( - sender=self.__class__, context=domain_alias.target, - object_type="domain_aliases") + sender=self.__class__, + context=domain_alias.target, + object_type="domain_aliases", + ) except lib_exceptions.ModoboaException as inst: - raise serializers.ValidationError({ - "domain": force_str(inst)}) + raise serializers.ValidationError({"domain": force_str(inst)}) domain_alias.save(creator=creator) return domain_alias @@ -165,8 +194,13 @@ class MailboxSerializer(serializers.ModelSerializer): class Meta: model = models.Mailbox fields = ( - "pk", "full_address", "use_domain_quota", "quota", "message_limit", - "quota_usage", "is_send_only" + "pk", + "full_address", + "use_domain_quota", + "quota", + "message_limit", + "quota_usage", + "is_send_only", ) def get_quota_usage(self, mb) -> int: @@ -185,9 +219,9 @@ class MailboxSerializer(serializers.ModelSerializer): method = self.context["request"].method if not data.get("use_domain_quota", False): if "quota" not in data and method != "PATCH": - raise serializers.ValidationError({ - "quota": _("This field is required") - }) + raise serializers.ValidationError( + {"quota": _("This field is required")} + ) return data @@ -199,15 +233,28 @@ class AccountSerializer(serializers.ModelSerializer): domains = serializers.SerializerMethodField( help_text=_( "List of administered domains (resellers and domain " - "administrators only).")) + "administrators only)." + ) + ) class Meta: model = core_models.User fields = ( - "pk", "username", "first_name", "last_name", "is_active", - "master_user", "mailbox", "role", "language", "phone_number", - "secondary_email", "domains", "tfa_enabled", "date_joined", - "last_login" + "pk", + "username", + "first_name", + "last_name", + "is_active", + "master_user", + "mailbox", + "role", + "language", + "phone_number", + "secondary_email", + "domains", + "tfa_enabled", + "date_joined", + "last_login", ) def __init__(self, *args, **kwargs): @@ -230,7 +277,8 @@ class AccountSerializer(serializers.ModelSerializer): if account.role not in ["DomainAdmins", "Resellers"]: return [] return admin_models.Domain.objects.get_for_admin(account).values_list( - "name", flat=True) + "name", flat=True + ) class AccountExistsSerializer(serializers.Serializer): @@ -240,7 +288,6 @@ class AccountExistsSerializer(serializers.Serializer): class AccountPasswordSerializer(serializers.ModelSerializer): - """A serializer used to change a user password.""" new_password = serializers.CharField() @@ -248,7 +295,9 @@ class AccountPasswordSerializer(serializers.ModelSerializer): class Meta: model = core_models.User fields = ( - "password", "new_password", ) + "password", + "new_password", + ) def validate_password(self, value): """Check password.""" @@ -279,8 +328,7 @@ class WritableAccountSerializer(AccountSerializer): password = serializers.CharField(required=False) class Meta(AccountSerializer.Meta): - fields = AccountSerializer.Meta.fields + ( - "password", "random_password") + fields = AccountSerializer.Meta.fields + ("password", "random_password") def __init__(self, *args, **kwargs): """Adapt fields to current user.""" @@ -290,9 +338,11 @@ class WritableAccountSerializer(AccountSerializer): return user = self.context["request"].user self.fields["role"] = serializers.ChoiceField( - choices=permissions.get_account_roles(user)) + choices=permissions.get_account_roles(user) + ) self.fields["domains"] = serializers.ListField( - child=serializers.CharField(), allow_empty=False, required=False) + child=serializers.CharField(), allow_empty=False, required=False + ) def validate_username(self, value): """Lower case username.""" @@ -303,9 +353,9 @@ class WritableAccountSerializer(AccountSerializer): master_user = data.get("master_user", False) role = data.get("role") if master_user and role != "SuperAdmins": - raise serializers.ValidationError({ - "master_user": _("Not allowed for this role.") - }) + raise serializers.ValidationError( + {"master_user": _("Not allowed for this role.")} + ) if role == "SimpleUsers": username = data.get("username") if username: @@ -318,49 +368,50 @@ class WritableAccountSerializer(AccountSerializer): if not self.instance: data["mailbox"] = { "full_address": username, - "use_domain_quota": True + "use_domain_quota": True, } elif "full_address" in mailbox and mailbox["full_address"] != username: - raise serializers.ValidationError({ - "username": _("Must be equal to mailbox full_address") - }) + raise serializers.ValidationError( + {"username": _("Must be equal to mailbox full_address")} + ) if "mailbox" in data: - self.address, domain_name = email_utils.split_mailbox(data["mailbox"]["full_address"]) - self.domain = get_object_or_404( - admin_models.Domain, name=domain_name) + self.address, domain_name = email_utils.split_mailbox( + data["mailbox"]["full_address"] + ) + self.domain = get_object_or_404(admin_models.Domain, name=domain_name) creator = self.context["request"].user if not creator.can_access(self.domain): raise serializers.ValidationError({"mailbox": _("Permission denied.")}) if not self.instance: try: core_signals.can_create_object.send( - sender=self.__class__, context=creator, - klass=admin_models.Mailbox) + sender=self.__class__, + context=creator, + klass=admin_models.Mailbox, + ) core_signals.can_create_object.send( - sender=self.__class__, context=self.domain, - object_type="mailboxes") + sender=self.__class__, + context=self.domain, + object_type="mailboxes", + ) except lib_exceptions.ModoboaException as inst: - raise serializers.ValidationError({ - "mailbox": force_str(inst)}) - condition = ( - not data.get("random_password") and ( - data.get("password") or - not self.partial - ) + raise serializers.ValidationError({"mailbox": force_str(inst)}) + condition = not data.get("random_password") and ( + data.get("password") or not self.partial ) if condition: password = data.get("password") if password: try: password_validation.validate_password( - data["password"], self.instance) + data["password"], self.instance + ) except ValidationError as exc: - raise serializers.ValidationError({ - "password": exc.messages[0]}) + raise serializers.ValidationError({"password": exc.messages[0]}) elif not self.instance: - raise serializers.ValidationError({ - "password": _("This field is required.") - }) + raise serializers.ValidationError( + {"password": _("This field is required.")} + ) domain_names = data.get("domains") if not domain_names: return data @@ -370,9 +421,9 @@ class WritableAccountSerializer(AccountSerializer): if domain: domains.append(domain) continue - raise serializers.ValidationError({ - "domains": _("Local domain {} does not exist").format(name) - }) + raise serializers.ValidationError( + {"domains": _("Local domain {} does not exist").format(name)} + ) data["domains"] = domains return data @@ -381,10 +432,12 @@ class WritableAccountSerializer(AccountSerializer): full_address = data.pop("full_address") quota = data.pop("quota", None) mb = admin_models.Mailbox( - user=account, address=self.address, domain=self.domain, **data) + user=account, address=self.address, domain=self.domain, **data + ) mb.set_quota(quota, creator.has_perm("admin.add_domain")) default_msg_limit = param_tools.get_global_parameter( - "default_mailbox_message_limit") + "default_mailbox_message_limit" + ) if default_msg_limit is not None: mb.message_limit = default_msg_limit mb.save(creator=creator) @@ -457,20 +510,19 @@ class AliasSerializer(serializers.ModelSerializer): recipients = serializers.ListField( child=lib_fields.DRFEmailFieldUTF8AndEmptyUser(), allow_empty=False, - help_text=gettext_lazy("A list of recipient") + help_text=gettext_lazy("A list of recipient"), ) class Meta: model = admin_models.Alias - fields = ( - "pk", "address", "enabled", "internal", "recipients" - ) + fields = ("pk", "address", "enabled", "internal", "recipients") def validate_address(self, value): """Check domain.""" try: local_part, self.domain = admin_models.validate_alias_address( - value, self.context["request"].user, instance=self.instance) + value, self.context["request"].user, instance=self.instance + ) except ValidationError as err: raise serializers.ValidationError(err) except AliasExists: @@ -481,7 +533,8 @@ class AliasSerializer(serializers.ModelSerializer): """Create appropriate objects.""" creator = self.context["request"].user return admin_models.Alias.objects.create( - creator=creator, domain=self.domain, **validated_data) + creator=creator, domain=self.domain, **validated_data + ) def update(self, instance, validated_data): """Update objects.""" @@ -509,7 +562,8 @@ class SenderAddressSerializer(serializers.ModelSerializer): user = self.context["request"].user if domain and not user.can_access(domain): raise serializers.ValidationError( - _("You don't have access to this domain.")) + _("You don't have access to this domain.") + ) return value.lower() def validate_mailbox(self, value): @@ -517,7 +571,8 @@ class SenderAddressSerializer(serializers.ModelSerializer): user = self.context["request"].user if not user.can_access(value): raise serializers.ValidationError( - _("You don't have access to this mailbox.")) + _("You don't have access to this mailbox.") + ) return value diff --git a/modoboa/admin/api/v1/tests.py b/modoboa/admin/api/v1/tests.py index 7922e8c29..3cc1fd953 100644 --- a/modoboa/admin/api/v1/tests.py +++ b/modoboa/admin/api/v1/tests.py @@ -28,7 +28,8 @@ class DomainAPITestCase(ModoAPITestCase): super(DomainAPITestCase, cls).setUpTestData() factories.populate_database() cls.da_token = Token.objects.create( - user=core_models.User.objects.get(username="admin@test.com")) + user=core_models.User.objects.get(username="admin@test.com") + ) def test_get_domains(self): """Retrieve a list of domains.""" @@ -37,8 +38,7 @@ class DomainAPITestCase(ModoAPITestCase): self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 2) domain = response.data[0] - url = reverse( - "v1:domain-detail", args=[domain["pk"]]) + url = reverse("v1:domain-detail", args=[domain["pk"]]) response = self.client.get(url) data = response.json() self.assertEqual(response.status_code, 200) @@ -65,10 +65,10 @@ class DomainAPITestCase(ModoAPITestCase): self.assertEqual(response.status_code, 400) self.assertIn("default_mailbox_quota", response.data) - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.da_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.da_token.key) response = self.client.post( - url, {"name": "test4.com", "default_mailbox_quota": 10}) + url, {"name": "test4.com", "default_mailbox_quota": 10} + ) self.assertEqual(response.status_code, 403) @mock.patch.object(dns.resolver.Resolver, "resolve") @@ -81,19 +81,19 @@ class DomainAPITestCase(ModoAPITestCase): self.set_global_parameter("valid_mxs", "192.0.2.1 2001:db8::1") self.set_global_parameter("domains_must_have_authorized_mx", True) reseller = core_factories.UserFactory( - username="reseller", groups=("Resellers", )) + username="reseller", groups=("Resellers",) + ) token = Token.objects.create(user=reseller) self.client.credentials(HTTP_AUTHORIZATION="Token " + token.key) url = reverse("v1:domain-list") response = self.client.post( - url, {"name": "no-mx.example.com", "quota": 0, - "default_mailbox_quota": 10} + url, {"name": "no-mx.example.com", "quota": 0, "default_mailbox_quota": 10} ) self.assertEqual(response.status_code, 400) self.assertEqual( - response.json()["name"][0], - "No authorized MX record found for this domain") + response.json()["name"][0], "No authorized MX record found for this domain" + ) mock_getaddrinfo.side_effect = utils.mock_ip_query_result response = self.client.post( @@ -104,25 +104,28 @@ class DomainAPITestCase(ModoAPITestCase): def test_update_domain(self): """Check domain update.""" domain = models.Domain.objects.get(name="test.com") - models.Mailbox.objects.filter( - domain__name="test.com", address="user").update( - use_domain_quota=True) + models.Mailbox.objects.filter(domain__name="test.com", address="user").update( + use_domain_quota=True + ) url = reverse("v1:domain-detail", args=[domain.pk]) response = self.client.put( - url, {"name": "test.com", "default_mailbox_quota": 1000}) + url, {"name": "test.com", "default_mailbox_quota": 1000} + ) self.assertEqual(response.status_code, 200) domain.refresh_from_db() self.assertEqual(domain.default_mailbox_quota, 1000) - mb = models.Mailbox.objects.get( - domain__name="test.com", address="user") + mb = models.Mailbox.objects.get(domain__name="test.com", address="user") self.assertEqual(mb.quota, 1000) response = self.client.put( - url, {"name": "test42.com", "default_mailbox_quota": 1000}) + url, {"name": "test42.com", "default_mailbox_quota": 1000} + ) self.assertEqual(response.status_code, 200) self.assertTrue( models.Mailbox.objects.filter( - address="user", domain__name="test42.com").exists()) + address="user", domain__name="test42.com" + ).exists() + ) def test_patch_domain(self): """Check domain partial update.""" @@ -137,8 +140,7 @@ class DomainAPITestCase(ModoAPITestCase): """Try to remove DKIM from a domain.""" domain = models.Domain.objects.get(name="test.com") url = reverse("v1:domain-detail", args=[domain.pk]) - response = self.client.put( - url, {"name": "test.com", "enable_dkim": False}) + response = self.client.put(url, {"name": "test.com", "enable_dkim": False}) self.assertEqual(response.status_code, 200) domain.refresh_from_db() self.assertEqual(domain.dkim_private_key_path, "") @@ -161,11 +163,14 @@ class DomainAliasAPITestCase(ModoAPITestCase): super(DomainAliasAPITestCase, cls).setUpTestData() factories.populate_database() cls.dom_alias1 = factories.DomainAliasFactory( - name="dalias1.com", target__name="test.com") + name="dalias1.com", target__name="test.com" + ) cls.dom_alias2 = factories.DomainAliasFactory( - name="dalias2.com", target__name="test2.com") + name="dalias2.com", target__name="test2.com" + ) cls.da_token = Token.objects.create( - user=core_models.User.objects.get(username="admin@test.com")) + user=core_models.User.objects.get(username="admin@test.com") + ) def test_get(self): """Retrieve a list of domain aliases.""" @@ -173,8 +178,7 @@ class DomainAliasAPITestCase(ModoAPITestCase): response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 2) - url = reverse( - "v1:domain_alias-detail", args=[response.data[0]["pk"]]) + url = reverse("v1:domain_alias-detail", args=[response.data[0]["pk"]]) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.data["name"], "dalias1.com") @@ -184,8 +188,7 @@ class DomainAliasAPITestCase(ModoAPITestCase): self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.da_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.da_token.key) response = self.client.get(reverse("v1:domain_alias-list")) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 0) @@ -194,31 +197,25 @@ class DomainAliasAPITestCase(ModoAPITestCase): """Try to create a new domain alias.""" url = reverse("v1:domain_alias-list") target = models.Domain.objects.get(name="test.com") - data = { - "name": "dalias3.com", - "target": target.pk - } + data = {"name": "dalias3.com", "target": target.pk} response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 201) dalias = response.json() - dalias = models.DomainAlias.objects.filter( - pk=dalias["pk"]).first() + dalias = models.DomainAlias.objects.filter(pk=dalias["pk"]).first() self.assertEqual(dalias.target, target) - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.da_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.da_token.key) response = self.client.post( - url, {"name": "dalias4.com", "target": target.pk}, format="json") + url, {"name": "dalias4.com", "target": target.pk}, format="json" + ) self.assertEqual(response.status_code, 403) def test_put(self): """Try to update a domain alias.""" dalias = models.DomainAlias.objects.get(name="dalias1.com") url = reverse("v1:domain_alias-detail", args=[dalias.pk]) - data = { - "name": "dalias3.com", "target": dalias.target.pk - } + data = {"name": "dalias3.com", "target": dalias.target.pk} response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) @@ -232,8 +229,7 @@ class DomainAliasAPITestCase(ModoAPITestCase): url = reverse("v1:domain_alias-detail", args=[dalias.pk]) response = self.client.delete(url) self.assertEqual(response.status_code, 204) - self.assertFalse( - models.DomainAlias.objects.filter(pk=dalias.pk).exists()) + self.assertFalse(models.DomainAlias.objects.filter(pk=dalias.pk).exists()) class AccountAPITestCase(ModoAPITestCase): @@ -243,10 +239,7 @@ class AccountAPITestCase(ModoAPITestCase): "username": "fromapi@test.com", "role": "SimpleUsers", "password": "Toto1234", - "mailbox": { - "full_address": "fromapi@test.com", - "quota": 10 - } + "mailbox": {"full_address": "fromapi@test.com", "quota": 10}, } @classmethod @@ -255,15 +248,15 @@ class AccountAPITestCase(ModoAPITestCase): super(AccountAPITestCase, cls).setUpTestData() factories.populate_database() cls.da_token = Token.objects.create( - user=core_models.User.objects.get(username="admin@test.com")) + user=core_models.User.objects.get(username="admin@test.com") + ) def setUp(self): """Test setup.""" super().setUp() - self.set_global_parameters({ - "enable_admin_limits": False, - "enable_domain_limits": False - }, app="limits") + self.set_global_parameters( + {"enable_admin_limits": False, "enable_domain_limits": False}, app="limits" + ) def test_get_accounts(self): """Retrieve a list of accounts.""" @@ -351,12 +344,10 @@ class AccountAPITestCase(ModoAPITestCase): response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 201) domain = models.Domain.objects.get(name="test.com") - admin = core_models.User.objects.get( - pk=response.json()["pk"]) + admin = core_models.User.objects.get(pk=response.json()["pk"]) self.assertIn(admin, domain.admins) - response = self.client.get( - reverse("v1:account-detail", args=[admin.pk])) + response = self.client.get(reverse("v1:account-detail", args=[admin.pk])) self.assertEqual(response.status_code, 200) self.assertIn("domains", response.json()) @@ -376,8 +367,7 @@ class AccountAPITestCase(ModoAPITestCase): user = core_models.User.objects.filter(pk=account["pk"]).first() self.assertIsNot(user, None) self.assertIsNot(user.mailbox, None) - self.assertEqual( - user.mailbox.quota, user.mailbox.domain.default_mailbox_quota) + self.assertEqual(user.mailbox.quota, user.mailbox.domain.default_mailbox_quota) def test_create_existing_account(self): """Check if unicity is respected.""" @@ -404,8 +394,7 @@ class AccountAPITestCase(ModoAPITestCase): def test_create_account_as_domadmin(self): """As DomainAdmin, try to create a new account.""" - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.da_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.da_token.key) data = copy.deepcopy(self.ACCOUNT_DATA) data["mailbox"]["quota"] = 1000 url = reverse("v1:account-list") @@ -414,8 +403,7 @@ class AccountAPITestCase(ModoAPITestCase): self.assertEqual(response.status_code, 400) data["username"] = "fromapi@test2.com" - data["mailbox"].update({"full_address": "fromapi@test2.com", - "quota": 10}) + data["mailbox"].update({"full_address": "fromapi@test2.com", "quota": 10}) response = self.client.post(url, data, format="json") # Should fail because admin has no access to @test2.com domain self.assertEqual(response.status_code, 400) @@ -442,8 +430,8 @@ class AccountAPITestCase(ModoAPITestCase): "password": "Toto1234", "mailbox": { "full_address": "fromapi@test.com", - "quota": account.mailbox.quota - } + "quota": account.mailbox.quota, + }, } response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) @@ -460,14 +448,9 @@ class AccountAPITestCase(ModoAPITestCase): def test_update_account_with_no_mailbox(self): """Try to disable an account.""" - account = core_factories.UserFactory( - username="reseller", groups=("Resellers", )) + account = core_factories.UserFactory(username="reseller", groups=("Resellers",)) url = reverse("v1:account-detail", args=[account.pk]) - data = { - "username": "reseller", - "role": account.role, - "is_active": False - } + data = {"username": "reseller", "role": account.role, "is_active": False} response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) @@ -480,7 +463,7 @@ class AccountAPITestCase(ModoAPITestCase): "username": "fromapi@test.com", "mailbox": { "full_address": "fromapi@test.com", - } + }, } response = self.client.patch(url, data, format="json") self.assertEqual(response.status_code, 200) @@ -498,9 +481,9 @@ class AccountAPITestCase(ModoAPITestCase): "password": "Toto1234", "mailbox": { "full_address": account.mailbox.full_address, - "quota": account.mailbox.quota + "quota": account.mailbox.quota, }, - "domains": ["test.com", "test2.com"] + "domains": ["test.com", "test2.com"], } response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) @@ -525,8 +508,8 @@ class AccountAPITestCase(ModoAPITestCase): "password": "Toto1234", "mailbox": { "full_address": "fromapi@test3.com", - "quota": account.mailbox.quota - } + "quota": account.mailbox.quota, + }, } response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 404) @@ -539,20 +522,17 @@ class AccountAPITestCase(ModoAPITestCase): url = reverse("v1:account-detail", args=[account.pk]) response = self.client.delete(url) self.assertEqual(response.status_code, 204) - self.assertFalse( - core_models.User.objects.filter(pk=account.pk).exists()) + self.assertFalse(core_models.User.objects.filter(pk=account.pk).exists()) self.assertFalse(domadmin.can_access(account)) def test_account_exists(self): """Validate /exists/ service.""" url = reverse("v1:account-exists") - response = self.client.get( - "{}?email={}".format(url, "user@test.com")) + response = self.client.get("{}?email={}".format(url, "user@test.com")) self.assertEqual(response.status_code, 200) content = response.json() self.assertTrue(content["exists"]) - response = self.client.get( - "{}?email={}".format(url, "pipo@test.com")) + response = self.client.get("{}?email={}".format(url, "pipo@test.com")) self.assertEqual(response.status_code, 200) content = response.json() self.assertFalse(content["exists"]) @@ -562,17 +542,16 @@ class AccountAPITestCase(ModoAPITestCase): def test_change_password(self): """Check the change password service.""" account = core_models.User.objects.get(username="user@test.com") - url = reverse( - "v1:account-password", args=[account.pk]) + url = reverse("v1:account-password", args=[account.pk]) response = self.client.put( - url, {"password": "toto", "new_password": "pass"}, - format="json") + url, {"password": "toto", "new_password": "pass"}, format="json" + ) # must fail because password is too weak self.assertEqual(response.status_code, 400) response = self.client.put( - url, {"password": "toto", "new_password": "Toto1234"}, - format="json") + url, {"password": "toto", "new_password": "Toto1234"}, format="json" + ) self.assertEqual(response.status_code, 200) account.refresh_from_db() self.assertTrue(account.check_password("Toto1234")) @@ -585,13 +564,16 @@ class AccountAPITestCase(ModoAPITestCase): response = self.client.post(url) self.assertEqual(response.status_code, 404) - self.set_global_parameters({ - "sms_password_recovery": True, - "sms_provider": "ovh", - "sms_ovh_application_key": "key", - "sms_ovh_application_secret": "secret", - "sms_ovh_consumer_key": "consumer" - }, app="core") + self.set_global_parameters( + { + "sms_password_recovery": True, + "sms_provider": "ovh", + "sms_ovh_application_key": "key", + "sms_ovh_application_secret": "secret", + "sms_ovh_consumer_key": "consumer", + }, + app="core", + ) # No email provided response = self.client.post(url) self.assertEqual(response.status_code, 400) @@ -615,21 +597,19 @@ class AliasAPITestCase(ModoAPITestCase): ALIAS_DATA = { "address": "alias_fromapi@test.com", - "recipients": [ - "user@test.com", "postmaster@test.com", "user_éé@nonlocal.com" - ] + "recipients": ["user@test.com", "postmaster@test.com", "user_éé@nonlocal.com"], } @classmethod def setUpTestData(cls): # NOQA:N802 """Create test data.""" super(AliasAPITestCase, cls).setUpTestData() - cls.localconfig.parameters.set_value( - "enable_admin_limits", False, app="limits") + cls.localconfig.parameters.set_value("enable_admin_limits", False, app="limits") cls.localconfig.save() factories.populate_database() cls.da_token = Token.objects.create( - user=core_models.User.objects.get(username="admin@test.com")) + user=core_models.User.objects.get(username="admin@test.com") + ) def test_get_aliases(self): """Retrieve a list of aliases.""" @@ -664,13 +644,23 @@ class AliasAPITestCase(ModoAPITestCase): domadmin = core_models.User.objects.get(username="admin@test.com") self.assertTrue(domadmin.can_access(alias)) self.assertEqual(alias.aliasrecipient_set.count(), 3) - self.assertTrue(alias.aliasrecipient_set.filter( - address="user@test.com", r_mailbox__isnull=False).exists()) - self.assertTrue(alias.aliasrecipient_set.filter( - address="postmaster@test.com", r_alias__isnull=False).exists()) - self.assertTrue(alias.aliasrecipient_set.filter( - address="user_éé@nonlocal.com", - r_mailbox__isnull=True, r_alias__isnull=True).exists()) + self.assertTrue( + alias.aliasrecipient_set.filter( + address="user@test.com", r_mailbox__isnull=False + ).exists() + ) + self.assertTrue( + alias.aliasrecipient_set.filter( + address="postmaster@test.com", r_alias__isnull=False + ).exists() + ) + self.assertTrue( + alias.aliasrecipient_set.filter( + address="user_éé@nonlocal.com", + r_mailbox__isnull=True, + r_alias__isnull=True, + ).exists() + ) # Create catchall alias data = copy.deepcopy(self.ALIAS_DATA) @@ -691,8 +681,7 @@ class AliasAPITestCase(ModoAPITestCase): def test_create_alias_as_domadmin(self): """As DomainAdmin, try to create a new alias.""" - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.da_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.da_token.key) url = reverse("v1:alias-list") response = self.client.post(url, self.ALIAS_DATA, format="json") self.assertEqual(response.status_code, 201) @@ -710,26 +699,20 @@ class AliasAPITestCase(ModoAPITestCase): url = reverse("v1:alias-detail", args=[alias.pk]) data = { "address": "alias@test.com", - "recipients": ["user@test.com", "user@nonlocal.com"] + "recipients": ["user@test.com", "user@nonlocal.com"], } response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) alias.refresh_from_db() self.assertEqual(alias.aliasrecipient_set.count(), 2) - data = { - "address": "alias@test.com", - "recipients": ["user@nonlocal.com"] - } + data = {"address": "alias@test.com", "recipients": ["user@nonlocal.com"]} response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) alias.refresh_from_db() self.assertEqual(alias.aliasrecipient_set.count(), 1) - data = { - "address": "alias@test.com", - "recipients": [] - } + data = {"address": "alias@test.com", "recipients": []} response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 400) @@ -741,13 +724,12 @@ class AliasAPITestCase(ModoAPITestCase): url = reverse("v1:alias-detail", args=[alias.pk]) response = self.client.delete(url) self.assertEqual(response.status_code, 204) - self.assertFalse( - models.Alias.objects.filter(pk=alias.pk).exists()) + self.assertFalse(models.Alias.objects.filter(pk=alias.pk).exists()) self.assertFalse(domadmin.can_access(alias)) self.assertFalse( models.AliasRecipient.objects.filter( - address="user@test.com", alias__address="alias@test.com") - .exists() + address="user@test.com", alias__address="alias@test.com" + ).exists() ) @@ -758,18 +740,18 @@ class SenderAddressAPITestCase(ModoAPITestCase): def setUpTestData(cls): # NOQA:N802 """Create test data.""" super(SenderAddressAPITestCase, cls).setUpTestData() - cls.localconfig.parameters.set_value( - "enable_admin_limits", False, app="limits") + cls.localconfig.parameters.set_value("enable_admin_limits", False, app="limits") cls.localconfig.save() factories.populate_database() cls.sa1 = factories.SenderAddressFactory( address="test@domain.ext", mailbox__user__username="user@test.com", mailbox__address="user", - mailbox__domain__name="test.com" + mailbox__domain__name="test.com", ) cls.da_token = Token.objects.create( - user=core_models.User.objects.get(username="admin@test.com")) + user=core_models.User.objects.get(username="admin@test.com") + ) def test_list(self): """Retrieve a list of sender addresses.""" @@ -782,35 +764,31 @@ class SenderAddressAPITestCase(ModoAPITestCase): def test_create(self): """Create a new sender addresses.""" url = reverse("v1:sender_address-list") - mbox = models.Mailbox.objects.get( - address="admin", domain__name="test.com") + mbox = models.Mailbox.objects.get(address="admin", domain__name="test.com") data = {"address": "@extdomain.test", "mailbox": mbox.pk} response = self.client.post(url, data) self.assertEqual(response.status_code, 201) - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.da_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.da_token.key) data = {"address": "user@test2.com", "mailbox": mbox.pk} response = self.client.post(url, data) self.assertEqual(response.status_code, 400) self.assertEqual( - response.json()["address"][0], - "You don't have access to this domain.") + response.json()["address"][0], "You don't have access to this domain." + ) - mbox = models.Mailbox.objects.get( - address="admin", domain__name="test2.com") + mbox = models.Mailbox.objects.get(address="admin", domain__name="test2.com") data = {"address": "toto@titi.com", "mailbox": mbox.pk} response = self.client.post(url, data) self.assertEqual(response.status_code, 400) self.assertEqual( - response.json()["mailbox"][0], - "You don't have access to this mailbox.") + response.json()["mailbox"][0], "You don't have access to this mailbox." + ) def test_patch(self): """Patch an existing sender address.""" url = reverse("v1:sender_address-detail", args=[self.sa1.pk]) - mbox = models.Mailbox.objects.get( - address="user", domain__name="test.com") + mbox = models.Mailbox.objects.get(address="user", domain__name="test.com") data = {"address": "@extdomain.test"} response = self.client.patch(url, data) self.assertEqual(response.status_code, 200) @@ -821,8 +799,7 @@ class SenderAddressAPITestCase(ModoAPITestCase): def test_update(self): """Update an existing sender address.""" url = reverse("v1:sender_address-detail", args=[self.sa1.pk]) - mbox = models.Mailbox.objects.get( - address="user", domain__name="test.com") + mbox = models.Mailbox.objects.get(address="user", domain__name="test.com") data = {"address": "@extdomain.test", "mailbox": mbox.pk} response = self.client.put(url, data) self.assertEqual(response.status_code, 200) diff --git a/modoboa/admin/api/v1/urls.py b/modoboa/admin/api/v1/urls.py index e2e514aaa..80838574d 100644 --- a/modoboa/admin/api/v1/urls.py +++ b/modoboa/admin/api/v1/urls.py @@ -6,11 +6,11 @@ from . import viewsets router = routers.SimpleRouter() router.register(r"domains", viewsets.DomainViewSet, basename="domain") -router.register( - r"domainaliases", viewsets.DomainAliasViewSet, basename="domain_alias") +router.register(r"domainaliases", viewsets.DomainAliasViewSet, basename="domain_alias") router.register(r"accounts", viewsets.AccountViewSet, basename="account") router.register(r"aliases", viewsets.AliasViewSet, basename="alias") router.register( - r"senderaddresses", viewsets.SenderAddressViewSet, basename="sender_address") + r"senderaddresses", viewsets.SenderAddressViewSet, basename="sender_address" +) urlpatterns = router.urls diff --git a/modoboa/admin/api/v1/viewsets.py b/modoboa/admin/api/v1/viewsets.py index 892be34d0..f6ed5804f 100644 --- a/modoboa/admin/api/v1/viewsets.py +++ b/modoboa/admin/api/v1/viewsets.py @@ -25,23 +25,24 @@ from . import serializers @extend_schema_view( retrieve=extend_schema( description="Retrieve a particular domain", - summary="Retrieve a particular domain" + summary="Retrieve a particular domain", ), list=extend_schema( - description="Retrieve a list of domains", - summary="Retrieve a list of domains" + description="Retrieve a list of domains", summary="Retrieve a list of domains" ), create=extend_schema( - description="Create a new domain", - summary="Create a new domain" - ) + description="Create a new domain", summary="Create a new domain" + ), ) -class DomainViewSet(GetThrottleViewsetMixin, - lib_viewsets.RevisionModelMixin, - viewsets.ModelViewSet): +class DomainViewSet( + GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, viewsets.ModelViewSet +): """Domain viewset.""" - permission_classes = [IsAuthenticated, DjangoModelPermissions, ] + permission_classes = [ + IsAuthenticated, + DjangoModelPermissions, + ] serializer_class = serializers.DomainSerializer def get_queryset(self): @@ -63,13 +64,17 @@ class DomainAliasFilterSet(dj_filters.FilterSet): fields = ["domain"] -class DomainAliasViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, - viewsets.ModelViewSet): +class DomainAliasViewSet( + GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, viewsets.ModelViewSet +): """ViewSet for DomainAlias.""" - filter_backends = (dj_filters.DjangoFilterBackend, ) + filter_backends = (dj_filters.DjangoFilterBackend,) filterset_class = DomainAliasFilterSet - permission_classes = [IsAuthenticated, DjangoModelPermissions, ] + permission_classes = [ + IsAuthenticated, + DjangoModelPermissions, + ] renderer_classes = (renderers.JSONRenderer, lib_renderers.CSVRenderer) serializer_class = serializers.DomainAliasSerializer @@ -83,11 +88,16 @@ class DomainAliasViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixi return context -class AccountViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, viewsets.ModelViewSet): +class AccountViewSet( + GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, viewsets.ModelViewSet +): """ViewSet for User/Mailbox.""" - filter_backends = (filters.SearchFilter, ) - permission_classes = [IsAuthenticated, DjangoModelPermissions, ] + filter_backends = (filters.SearchFilter,) + permission_classes = [ + IsAuthenticated, + DjangoModelPermissions, + ] search_fields = ("^first_name", "^last_name", "^email") def get_throttles(self): @@ -105,15 +115,14 @@ class AccountViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, v "password": serializers.AccountPasswordSerializer, "reset_password": serializers.ResetPasswordSerializer, } - return action_dict.get( - self.action, serializers.WritableAccountSerializer) + return action_dict.get(self.action, serializers.WritableAccountSerializer) def get_queryset(self): """Filter queryset based on current user.""" user = self.request.user - ids = user.objectaccess_set \ - .filter(content_type=ContentType.objects.get_for_model(user)) \ - .values_list("object_id", flat=True) + ids = user.objectaccess_set.filter( + content_type=ContentType.objects.get_for_model(user) + ).values_list("object_id", flat=True) queryset = core_models.User.objects.filter(pk__in=ids) domain = self.request.query_params.get("domain") if domain: @@ -131,8 +140,7 @@ class AccountViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, v if serializer.is_valid(): serializer.save() return Response() - return Response( - serializer.errors, status=status.HTTP_400_BAD_REQUEST) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @action(detail=False) def exists(self, request): @@ -156,25 +164,23 @@ class AccountViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, v @action(methods=["post"], detail=False) def reset_password(self, request): """Reset account password and send a new one by SMS.""" - sms_password_recovery = ( - request.localconfig.parameters - .get_value("sms_password_recovery", app="core") + sms_password_recovery = request.localconfig.parameters.get_value( + "sms_password_recovery", app="core" ) if not sms_password_recovery: return Response(status=404) serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = core_models.User.objects.filter( - email=serializer.validated_data["email"]).first() + email=serializer.validated_data["email"] + ).first() if not user or not user.phone_number: return Response(status=404) - backend = sms_backends.get_active_backend( - request.localconfig.parameters) + backend = sms_backends.get_active_backend(request.localconfig.parameters) if not backend: return Response(status=404) password = lib.make_password() - content = _("Here is your new Modoboa password: {}").format( - password) + content = _("Here is your new Modoboa password: {}").format(password) if not backend.send(content, [str(user.phone_number)]): body = {"status": "ko"} else: @@ -185,23 +191,26 @@ class AccountViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, v return Response(body) -class AliasViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, viewsets.ModelViewSet): +class AliasViewSet( + GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, viewsets.ModelViewSet +): """ create: Create a new alias instance. """ - permission_classes = [IsAuthenticated, DjangoModelPermissions, ] + permission_classes = [ + IsAuthenticated, + DjangoModelPermissions, + ] serializer_class = serializers.AliasSerializer def get_queryset(self): """Filter queryset based on current user.""" user = self.request.user - ids = ( - user.objectaccess_set.filter( - content_type=ContentType.objects.get_for_model(models.Alias)) - .values_list("object_id", flat=True) - ) + ids = user.objectaccess_set.filter( + content_type=ContentType.objects.get_for_model(models.Alias) + ).values_list("object_id", flat=True) queryset = models.Alias.objects.filter(pk__in=ids) domain = self.request.query_params.get("domain") if domain: @@ -217,21 +226,23 @@ class SenderAddressFilterSet(dj_filters.FilterSet): fields = ["mailbox"] -class SenderAddressViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, - viewsets.ModelViewSet): +class SenderAddressViewSet( + GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, viewsets.ModelViewSet +): """View set for SenderAddress model.""" - filter_backends = (dj_filters.DjangoFilterBackend, ) + filter_backends = (dj_filters.DjangoFilterBackend,) filterset_class = SenderAddressFilterSet - permission_classes = [IsAuthenticated, DjangoModelPermissions, ] + permission_classes = [ + IsAuthenticated, + DjangoModelPermissions, + ] serializer_class = serializers.SenderAddressSerializer def get_queryset(self): """Filter queryset based on current user.""" user = self.request.user - mb_ids = ( - user.objectaccess_set.filter( - content_type=ContentType.objects.get_for_model(models.Mailbox)) - .values_list("object_id", flat=True) - ) + mb_ids = user.objectaccess_set.filter( + content_type=ContentType.objects.get_for_model(models.Mailbox) + ).values_list("object_id", flat=True) return models.SenderAddress.objects.filter(mailbox__pk__in=mb_ids) diff --git a/modoboa/admin/api/v2/serializers.py b/modoboa/admin/api/v2/serializers.py index e3e44227a..26fc74906 100644 --- a/modoboa/admin/api/v2/serializers.py +++ b/modoboa/admin/api/v2/serializers.py @@ -56,7 +56,9 @@ class DomainSerializer(v1_serializers.DomainSerializer): class Meta(v1_serializers.DomainSerializer.Meta): fields = v1_serializers.DomainSerializer.Meta.fields + ( - "domain_admin", "transport", "opened_alarms_count" + "domain_admin", + "transport", + "opened_alarms_count", ) def __init__(self, *args, **kwargs): @@ -71,7 +73,9 @@ class DomainSerializer(v1_serializers.DomainSerializer): result = super().validate(data) dtype = data.get("type", "domain") if dtype == "relaydomain" and not data.get("transport"): - raise serializers.ValidationError({"transport": _("This field is required")}) + raise serializers.ValidationError( + {"transport": _("This field is required")} + ) return result def create(self, validated_data): @@ -96,16 +100,15 @@ class DomainSerializer(v1_serializers.DomainSerializer): except core_models.User.DoesNotExist: pass else: - raise lib_exceptions.Conflict( - _("User '%s' already exists") % username) + raise lib_exceptions.Conflict(_("User '%s' already exists") % username) user = self.context["request"].user core_signals.can_create_object.send( - self.__class__, context=user, klass=models.Mailbox) + self.__class__, context=user, klass=models.Mailbox + ) da = core_models.User(username=username, email=username, is_active=True) password = domain_admin.get("password") if password is None: - password = param_tools.get_global_parameter( - "default_password", app="core") + password = param_tools.get_global_parameter("default_password", app="core") da.set_password(password) da.save() da.role = "DomainAdmins" @@ -115,25 +118,28 @@ class DomainSerializer(v1_serializers.DomainSerializer): if domain_admin["with_mailbox"]: dom_admin_username = domain_admin["username"] mb = models.Mailbox( - address=dom_admin_username, domain=domain, - user=da, use_domain_quota=True + address=dom_admin_username, + domain=domain, + user=da, + use_domain_quota=True, ) - mb.set_quota( - override_rules=user.has_perm("admin.change_domain")) + mb.set_quota(override_rules=user.has_perm("admin.change_domain")) mb.save(creator=user) # 3. Create aliases if needed condition = ( - domain.type == "domain" and - domain_admin["with_aliases"] and - dom_admin_username != "postmaster" + domain.type == "domain" + and domain_admin["with_aliases"] + and dom_admin_username != "postmaster" ) if condition: core_signals.can_create_object.send( - self.__class__, context=user, klass=models.Alias) - address = u"postmaster@{}".format(domain.name) + self.__class__, context=user, klass=models.Alias + ) + address = "postmaster@{}".format(domain.name) alias = models.Alias.objects.create( - address=address, domain=domain, enabled=True) + address=address, domain=domain, enabled=True + ) alias.set_recipients([mb.full_address]) alias.post_create(user) @@ -162,9 +168,9 @@ class DomainSerializer(v1_serializers.DomainSerializer): instance.save() if resources: for resource in resources: - instance.domainobjectlimit_set.filter( - name=resource["name"] - ).update(max_value=resource["max_value"]) + instance.domainobjectlimit_set.filter(name=resource["name"]).update( + max_value=resource["max_value"] + ) return instance @@ -190,16 +196,19 @@ class AdminGlobalParametersSerializer(serializers.Serializer): enable_dnsbl_checks = serializers.BooleanField(default=True) dkim_keys_storage_dir = serializers.CharField(allow_blank=True) dkim_default_key_length = serializers.ChoiceField( - default=2048, choices=constants.DKIM_KEY_LENGTHS) + default=2048, choices=constants.DKIM_KEY_LENGTHS + ) default_domain_quota = serializers.IntegerField(default=0) default_domain_message_limit = serializers.IntegerField( - required=False, allow_null=True) + required=False, allow_null=True + ) # Mailboxes settings handle_mailboxes = serializers.BooleanField(default=False) default_mailbox_quota = serializers.IntegerField(default=0) default_mailbox_message_limit = serializers.IntegerField( - required=False, allow_null=True) + required=False, allow_null=True + ) auto_account_removal = serializers.BooleanField(default=False) auto_create_domain_and_mailbox = serializers.BooleanField(default=True) create_alias_on_mbox_rename = serializers.BooleanField(default=False) @@ -207,30 +216,22 @@ class AdminGlobalParametersSerializer(serializers.Serializer): def validate_default_domain_quota(self, value): """Ensure quota is a positive integer.""" if value < 0: - raise serializers.ValidationError( - _("Must be a positive integer") - ) + raise serializers.ValidationError(_("Must be a positive integer")) return value def validate_default_mailbox_quota(self, value): """Ensure quota is a positive integer.""" if value < 0: - raise serializers.ValidationError( - _("Must be a positive integer") - ) + raise serializers.ValidationError(_("Must be a positive integer")) return value def validate_dkim_keys_storage_dir(self, value): """Check that directory exists.""" if value: if not os.path.isdir(value): - raise serializers.ValidationError( - _("Directory not found.") - ) + raise serializers.ValidationError(_("Directory not found.")) if not os.access(value, os.W_OK): - raise serializers.ValidationError( - _("Directory non-writable") - ) + raise serializers.ValidationError(_("Directory non-writable")) code, output = exec_cmd("which openssl") if code: raise serializers.ValidationError( @@ -244,8 +245,7 @@ class AdminGlobalParametersSerializer(serializers.Serializer): return value try: ip_addresses = [ - ipaddress.ip_network(v.strip()) - for v in value.split() if v.strip() + ipaddress.ip_network(v.strip()) for v in value.split() if v.strip() ] except ValueError: raise serializers.ValidationError( @@ -255,11 +255,12 @@ class AdminGlobalParametersSerializer(serializers.Serializer): def validate_auto_create_domain_and_mailbox(self, value): """ - Make sure the option does not get deactivated - while imap migration is enabled. + Make sure the option does not get deactivated + while imap migration is enabled. """ - if not value and param_tools.get_global_parameter("enabled_imapmigration", - "imap_migration"): + if not value and param_tools.get_global_parameter( + "enabled_imapmigration", "imap_migration" + ): raise serializers.ValidationError( _("Please disable imap migration before disabling this option.") ) @@ -268,13 +269,14 @@ class AdminGlobalParametersSerializer(serializers.Serializer): def validate(self, data): """Check MX options.""" condition = ( - data.get("enable_mx_checks") and - data.get("domains_must_have_authorized_mx") and - not data.get("valid_mxs")) + data.get("enable_mx_checks") + and data.get("domains_must_have_authorized_mx") + and not data.get("valid_mxs") + ) if condition: - raise serializers.ValidationError({ - "valid_mxs": _("Define at least one authorized network / address") - }) + raise serializers.ValidationError( + {"valid_mxs": _("Define at least one authorized network / address")} + ) if not data.get("enable_mx_checks"): data["enable_ipv6_mx_checks"] = False return data @@ -335,7 +337,8 @@ class IdentitySerializer(serializers.Serializer): # (not used for now) return [] actions = admin_signals.extra_account_identities_actions.send( - self.__class__, account=identity) + self.__class__, account=identity + ) cleaned_actions = [] for action in actions: try: @@ -358,15 +361,11 @@ class AccountSerializer(v1_serializers.AccountSerializer): """Add support for user resources.""" aliases = serializers.ListField( - child=lib_fields.DRFEmailFieldUTF8(), - source="mailbox.alias_addresses" + child=lib_fields.DRFEmailFieldUTF8(), source="mailbox.alias_addresses" ) class Meta(v1_serializers.AccountSerializer.Meta): - fields = ( - v1_serializers.AccountSerializer.Meta.fields - + ("aliases", ) - ) + fields = v1_serializers.AccountSerializer.Meta.fields + ("aliases",) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -375,7 +374,7 @@ class AccountSerializer(v1_serializers.AccountSerializer): self.fields["resources"] = serializers.SerializerMethodField() def get_resources(self, account) -> List[AccountResourceSerializer]: - if account.role == 'SimpleUsers': + if account.role == "SimpleUsers": return [] resources = [] for limit in account.userobjectlimit_set.all(): @@ -395,7 +394,10 @@ class MailboxSerializer(serializers.ModelSerializer): class Meta: model = models.Mailbox fields = ( - "pk", "use_domain_quota", "quota", "message_limit", + "pk", + "use_domain_quota", + "quota", + "message_limit", "is_send_only", ) @@ -408,9 +410,9 @@ class MailboxSerializer(serializers.ModelSerializer): method = self.context["request"].method if not data.get("use_domain_quota", False): if "quota" not in data and method != "PATCH": - raise serializers.ValidationError({ - "quota": _("This field is required") - }) + raise serializers.ValidationError( + {"quota": _("This field is required")} + ) return data @@ -426,8 +428,7 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer): """Add support for aliases and sender addresses.""" aliases = serializers.ListField( - child=lib_fields.DRFEmailFieldUTF8(), - required=False + child=lib_fields.DRFEmailFieldUTF8(), required=False ) mailbox = MailboxSerializer(required=False) @@ -449,7 +450,8 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer): aliases = [] for alias in value: localpart, domain = models.validate_alias_address( - alias, self.context["request"].user, ignore_existing=True) + alias, self.context["request"].user, ignore_existing=True + ) aliases.append({"localpart": localpart, "domain": domain}) return aliases @@ -458,9 +460,9 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer): master_user = data.get("master_user", False) role = data.get("role") if master_user and role != "SuperAdmins": - raise serializers.ValidationError({ - "master_user": _("Not allowed for this role.") - }) + raise serializers.ValidationError( + {"master_user": _("Not allowed for this role.")} + ) if role == "SimpleUsers": username = data.get("username") if username: @@ -471,46 +473,43 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer): mailbox = data.get("mailbox") if mailbox is None: if not self.instance: - data["mailbox"] = { - "use_domain_quota": True - } + data["mailbox"] = {"use_domain_quota": True} if "mailbox" in data and "username" in data: self.address, domain_name = email_utils.split_mailbox(data["username"]) - self.domain = get_object_or_404( - models.Domain, name=domain_name) + self.domain = get_object_or_404(models.Domain, name=domain_name) creator = self.context["request"].user if not creator.can_access(self.domain): raise serializers.ValidationError({"mailbox": _("Permission denied.")}) if not self.instance: try: core_signals.can_create_object.send( - sender=self.__class__, context=creator, - klass=models.Mailbox) + sender=self.__class__, context=creator, klass=models.Mailbox + ) core_signals.can_create_object.send( - sender=self.__class__, context=self.domain, - object_type="mailboxes") + sender=self.__class__, + context=self.domain, + object_type="mailboxes", + ) except lib_exceptions.ModoboaException as inst: - raise serializers.ValidationError({ - "mailbox": str(inst) - }) + raise serializers.ValidationError({"mailbox": str(inst)}) if data.get("password") or not self.partial: password = data.get("password") if password: try: password_validation.validate_password( - data["password"], self.instance) + data["password"], self.instance + ) except ValidationError as exc: - raise serializers.ValidationError({ - "password": exc.messages[0]}) + raise serializers.ValidationError({"password": exc.messages[0]}) elif not self.instance: - raise serializers.ValidationError({ - "password": _("This field is required.") - }) + raise serializers.ValidationError( + {"password": _("This field is required.")} + ) aliases = data.get("aliases") if aliases and "mailbox" not in data: - raise serializers.ValidationError({ - "aliases": _("A mailbox is required to create aliases.") - }) + raise serializers.ValidationError( + {"aliases": _("A mailbox is required to create aliases.")} + ) domain_names = data.get("domains") if not domain_names: return data @@ -520,9 +519,9 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer): if domain: domains.append(domain) continue - raise serializers.ValidationError({ - "domains": _("Local domain {} does not exist").format(name) - }) + raise serializers.ValidationError( + {"domains": _("Local domain {} does not exist").format(name)} + ) data["domains"] = domains return data @@ -550,8 +549,8 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer): address="{}@{}".format(alias["localpart"], alias["domain"]), recipients=[user.username], creator=creator, - domain=alias["domain"] - ) + domain=alias["domain"], + ) return user def update(self, instance, validated_data): @@ -584,7 +583,7 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer): address=address, recipients=[validated_data["username"]], creator=creator, - domain=alias["domain"] + domain=alias["domain"], ) try: alias_recipients.remove(address) @@ -592,18 +591,17 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer): continue for alias_address in alias_recipients: alias = models.Alias.objects.filter( - address=alias_address, internal=False) + address=alias_address, internal=False + ) if alias.exists(): - alias.first().remove_recipient_or_delete( - validated_data["username"] - ) + alias.first().remove_recipient_or_delete(validated_data["username"]) instance.save() resources = validated_data.get("resources") if resources: for resource in resources: - instance.userobjectlimit_set.filter( - name=resource["name"] - ).update(max_value=resource["max_value"]) + instance.userobjectlimit_set.filter(name=resource["name"]).update( + max_value=resource["max_value"] + ) self.set_permissions(instance, domains) return instance diff --git a/modoboa/admin/api/v2/tests.py b/modoboa/admin/api/v2/tests.py index 472c87e33..fa95f5f0d 100644 --- a/modoboa/admin/api/v2/tests.py +++ b/modoboa/admin/api/v2/tests.py @@ -19,7 +19,8 @@ class DomainViewSetTestCase(ModoAPITestCase): super().setUpTestData() factories.populate_database() cls.da_token = Token.objects.create( - user=core_models.User.objects.get(username="admin@test.com")) + user=core_models.User.objects.get(username="admin@test.com") + ) def test_create(self): url = reverse("v2:domain-list") @@ -28,8 +29,8 @@ class DomainViewSetTestCase(ModoAPITestCase): "domain_admin": { "username": "admin", "with_mailbox": True, - "with_aliases": True - } + "with_aliases": True, + }, } resp = self.client.post(url, data, format="json") self.assertEqual(resp.status_code, 201) @@ -39,8 +40,7 @@ class DomainViewSetTestCase(ModoAPITestCase): admin = dom.admins.first() self.assertTrue(hasattr(admin, "mailbox")) self.assertTrue( - models.Alias.objects.filter( - address="postmaster@domain.tld").exists() + models.Alias.objects.filter(address="postmaster@domain.tld").exists() ) def test_update(self): @@ -50,11 +50,8 @@ class DomainViewSetTestCase(ModoAPITestCase): "type": "relaydomain", "transport": { "service": "relay", - "settings": { - "relay_target_port": 25, - "relay_target_host": "localhost" - } - } + "settings": {"relay_target_port": 25, "relay_target_host": "localhost"}, + }, } url = reverse("v2:domain-detail", args=[domain.pk]) resp = self.client.put(url, data, format="json") @@ -63,7 +60,7 @@ class DomainViewSetTestCase(ModoAPITestCase): self.assertEqual(domain.transport.service, data["transport"]["service"]) self.assertEqual( domain.transport._settings["relay_target_host"], - data["transport"]["settings"]["relay_target_host"] + data["transport"]["settings"]["relay_target_host"], ) data["transport"]["relay_verify_recipients"] = True @@ -75,9 +72,7 @@ class DomainViewSetTestCase(ModoAPITestCase): domain = models.Domain.objects.get(name="test2.com") data = { "name": "test2.com", - "resources": [ - {"name": "domain_aliases", "max_value": 20} - ] + "resources": [{"name": "domain_aliases", "max_value": 20}], } url = reverse("v2:domain-detail", args=[domain.pk]) resp = self.client.put(url, data, format="json") @@ -87,8 +82,7 @@ class DomainViewSetTestCase(ModoAPITestCase): ) def test_delete(self): - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.da_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.da_token.key) domain = models.Domain.objects.get(name="test2.com") url = reverse("v2:domain-delete", args=[domain.pk]) @@ -129,15 +123,14 @@ class DomainViewSetTestCase(ModoAPITestCase): self.assertEqual(resp.status_code, 200) def test_domains_import(self): - f = ContentFile(b"""domain; domain1.com; 1000; 100; True + f = ContentFile( + b"""domain; domain1.com; 1000; 100; True domain; domain2.com; 1000; 200; False domainalias; domalias1.com; domain1.com; True -""", name="domains.csv") - self.client.post( - reverse("v2:domain-import-from-csv"), { - "sourcefile": f - } +""", + name="domains.csv", ) + self.client.post(reverse("v2:domain-import-from-csv"), {"sourcefile": f}) admin = core_models.User.objects.get(username="admin") dom = models.Domain.objects.get(name="domain1.com") self.assertEqual(dom.quota, 1000) @@ -164,8 +157,7 @@ domainalias; domalias1.com; domain1.com; True "domain,test2.com,0,0,True", ] self.assertCountEqual( - expected_response, - force_str(response.content.strip()).split("\r\n") + expected_response, force_str(response.content.strip()).split("\r\n") ) @@ -182,19 +174,14 @@ class AccountViewSetTestCase(ModoAPITestCase): data = { "username": "toto@test.com", "role": "SimpleUsers", - "mailbox": { - "use_domain_quota": True - }, + "mailbox": {"use_domain_quota": True}, "password": "Toto12345", "language": "fr", - "aliases": ["alias3@test.com"] + "aliases": ["alias3@test.com"], } resp = self.client.post(url, data, format="json") self.assertEqual(resp.status_code, 201) - self.assertTrue( - models.Alias.objects.filter( - address="alias3@test.com").exists() - ) + self.assertTrue(models.Alias.objects.filter(address="alias3@test.com").exists()) def test_create_admin(self): url = reverse("v2:account-list") @@ -203,7 +190,7 @@ class AccountViewSetTestCase(ModoAPITestCase): "role": "SuperAdmins", "password": "Toto12345", "language": "fr", - "aliases": ["alias3@test.com"] + "aliases": ["alias3@test.com"], } resp = self.client.post(url, data, format="json") self.assertEqual(resp.status_code, 400) @@ -251,12 +238,8 @@ class AccountViewSetTestCase(ModoAPITestCase): "username": "user@test.com", "role": "SimpleUsers", "password": "Toto12345", - "mailbox": { - "quota": 10 - }, - "aliases": [ - "aliasupdate1@test.com" - ] + "mailbox": {"quota": 10}, + "aliases": ["aliasupdate1@test.com"], } resp = self.client.patch(url, data, format="json") self.assertEqual(resp.status_code, 200) @@ -271,7 +254,7 @@ class AccountViewSetTestCase(ModoAPITestCase): "mailbox": { "message_limit": 10, "is_send_only": True, - } + }, } resp = self.client.patch(url, data, format="json") self.assertEqual(resp.status_code, 200) @@ -283,9 +266,7 @@ class AccountViewSetTestCase(ModoAPITestCase): "username": "user@test.com", "role": "SimpleUsers", "password": "Toto12345", - "mailbox": { - "quota": 10 - } + "mailbox": {"quota": 10}, } resp = self.client.patch(url, data, format="json") self.assertEqual(resp.status_code, 200) @@ -299,7 +280,7 @@ class AccountViewSetTestCase(ModoAPITestCase): "mailbox": { "message_limit": None, "is_send_only": False, - } + }, } resp = self.client.patch(url, data, format="json") self.assertEqual(resp.status_code, 200) @@ -314,29 +295,24 @@ class AccountViewSetTestCase(ModoAPITestCase): "username": "user@test.com", "role": "SimpleUsers", "password": "Toto12345", - "mailbox": { - "quota": 10 - }, - "aliases": [ - "aliasupdate1@test.com" - ] + "mailbox": {"quota": 10}, + "aliases": ["aliasupdate1@test.com"], } resp = self.client.patch(url, data, format="json") self.assertEqual(resp.status_code, 200) self.assertTrue( - models.Alias.objects.filter(address="aliasupdate1@test.com").exists()) + models.Alias.objects.filter(address="aliasupdate1@test.com").exists() + ) # Create an alias for another user url = reverse("v2:account-list") data = { "username": "toto@test.com", "role": "SimpleUsers", - "mailbox": { - "use_domain_quota": True - }, + "mailbox": {"use_domain_quota": True}, "password": "Toto12345", "language": "fr", - "aliases": ["totoalias@test.com"] + "aliases": ["totoalias@test.com"], } resp = self.client.post(url, data, format="json") self.assertEqual(resp.status_code, 201) @@ -347,13 +323,11 @@ class AccountViewSetTestCase(ModoAPITestCase): "username": "user@test.com", "role": "SimpleUsers", "password": "Toto12345", - "mailbox": { - "quota": 10 - }, + "mailbox": {"quota": 10}, "aliases": [ "totoalias@test.com", "aliasupdate1@test.com", - ] + ], } resp = self.client.patch(url, data, format="json") self.assertEqual(resp.status_code, 200) @@ -367,17 +341,16 @@ class AccountViewSetTestCase(ModoAPITestCase): data = { "username": "user@test.com", "role": "SimpleUsers", - "mailbox": { - "quota": 10 - }, - "aliases": [] + "mailbox": {"quota": 10}, + "aliases": [], } resp = self.client.patch(url, data, format="json") self.assertEqual(resp.status_code, 200) self.assertFalse( - models.Alias.objects.filter(address="aliasupdate1@test.com").exists()) - alias_recipients = list(models.Alias.objects.filter( - address="totoalias@test.com").first().recipients + models.Alias.objects.filter(address="aliasupdate1@test.com").exists() + ) + alias_recipients = list( + models.Alias.objects.filter(address="totoalias@test.com").first().recipients ) self.assertEqual(alias_recipients, ["toto@test.com"]) @@ -388,9 +361,7 @@ class AccountViewSetTestCase(ModoAPITestCase): "username": "superadmin@test.com", "role": "SuperAdmins", "password": "Toto12345", - "mailbox": { - "quota": 10 - } + "mailbox": {"quota": 10}, } resp = self.client.patch(url, data, format="json") self.assertEqual(resp.status_code, 200) @@ -405,7 +376,7 @@ class AccountViewSetTestCase(ModoAPITestCase): data = { "resources": [ {"name": "mailboxes", "max_value": 10}, - {"name": "mailbox_aliases", "max_value": 10} + {"name": "mailbox_aliases", "max_value": 10}, ] } resp = self.client.patch(url, data, format="json") @@ -436,17 +407,20 @@ class IdentityViewSetTestCase(ModoAPITestCase): self.assertEqual(len(resp.json()), 8) def test_import(self): - f = ContentFile(""" + f = ContentFile( + """ account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; 0 account; Truc@test.com; toto; René; Truc; True; DomainAdmins; truc@test.com; 5; test.com alias; alias1@test.com; True; user1@test.com forward; alias2@test.com; True; user1+ext@test.com forward; fwd1@test.com; True; user@extdomain.com dlist; dlist@test.com; True; user1@test.com; user@extdomain.com -""", name="identities.csv") # NOQA:E501 +""", + name="identities.csv", + ) # NOQA:E501 self.client.post( reverse("v2:identities-import-from-csv"), - {"sourcefile": f, "crypt_password": True} + {"sourcefile": f, "crypt_password": True}, ) admin = core_models.User.objects.get(username="admin") u1 = core_models.User.objects.get(username="user1@test.com") @@ -461,13 +435,11 @@ dlist; dlist@test.com; True; user1@test.com; user@extdomain.com self.assertEqual(mb1.quota, 0) self.assertTrue(admin.is_owner(mb1)) self.assertEqual(mb1.full_address, "user1@test.com") - self.assertTrue( - self.client.login(username="user1@test.com", password="toto") - ) + self.assertTrue(self.client.login(username="user1@test.com", password="toto")) da = core_models.User.objects.get(username="truc@test.com") damb = da.mailbox - self.assertEqual(da.first_name, u"René") + self.assertEqual(da.first_name, "René") self.assertEqual(da.role, "DomainAdmins") self.assertEqual(damb.quota, 5) self.assertFalse(damb.use_domain_quota) @@ -478,30 +450,23 @@ dlist; dlist@test.com; True; user1@test.com; user@extdomain.com self.assertTrue(da.can_access(u)) al = models.Alias.objects.get(address="alias1@test.com") - self.assertTrue( - al.aliasrecipient_set - .filter(r_mailbox=u1.mailbox).exists() - ) + self.assertTrue(al.aliasrecipient_set.filter(r_mailbox=u1.mailbox).exists()) self.assertTrue(admin.is_owner(al)) fwd = models.Alias.objects.get(address="fwd1@test.com") self.assertTrue( - fwd.aliasrecipient_set - .filter( - address="user@extdomain.com", r_mailbox__isnull=True, - r_alias__isnull=True) - .exists() + fwd.aliasrecipient_set.filter( + address="user@extdomain.com", + r_mailbox__isnull=True, + r_alias__isnull=True, + ).exists() ) self.assertTrue(admin.is_owner(fwd)) dlist = models.Alias.objects.get(address="dlist@test.com") + self.assertTrue(dlist.aliasrecipient_set.filter(r_mailbox=u1.mailbox).exists()) self.assertTrue( - dlist.aliasrecipient_set - .filter(r_mailbox=u1.mailbox).exists() - ) - self.assertTrue( - dlist.aliasrecipient_set.filter(address="user@extdomain.com") - .exists() + dlist.aliasrecipient_set.filter(address="user@extdomain.com").exists() ) self.assertTrue(admin.is_owner(dlist)) @@ -513,10 +478,7 @@ dlist; dlist@test.com; True; user1@test.com; user@extdomain.com admin_row = received_content[0].split(",") admin_row[2] = "" received_content[0] = ",".join(admin_row) - self.assertCountEqual( - expected_response.strip().split("\r\n"), - received_content - ) + self.assertCountEqual(expected_response.strip().split("\r\n"), received_content) class AliasViewSetTestCase(ModoAPITestCase): @@ -536,10 +498,7 @@ class AliasViewSetTestCase(ModoAPITestCase): data = {"address": "alias@test.com"} resp = self.client.post(url, data, format="json") self.assertEqual(resp.status_code, 400) - self.assertEqual( - resp.json()["address"][0], - "This alias already exists" - ) + self.assertEqual(resp.json()["address"][0], "This alias already exists") data = {"address": "alias2@test.com"} resp = self.client.post(url, data, format="json") @@ -563,8 +522,7 @@ class UserAccountViewSetTestCase(ModoAPITestCase): cls.da_token = Token.objects.create(user=cls.da) def test_forward(self): - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.da_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.da_token.key) url = reverse("v2:account-forward") resp = self.client.get(url) self.assertEqual(resp.status_code, 200) @@ -580,8 +538,7 @@ class UserAccountViewSetTestCase(ModoAPITestCase): self.assertEqual(resp.status_code, 200) self.assertEqual( - models.Alias.objects.filter(address=self.da.username).count(), - 2 + models.Alias.objects.filter(address=self.da.username).count(), 2 ) resp = self.client.get(url) @@ -592,8 +549,7 @@ class UserAccountViewSetTestCase(ModoAPITestCase): resp = self.client.post(url, data, format="json") self.assertEqual(resp.status_code, 200) self.assertEqual( - models.Alias.objects.filter(address=self.da.username).count(), - 1 + models.Alias.objects.filter(address=self.da.username).count(), 1 ) @@ -605,9 +561,11 @@ class AlarmViewSetTestCase(ModoAPITestCase): super().setUpTestData() factories.populate_database() factories.AlarmFactory( - domain__name="test.com", mailbox=None, title="Test alarm") + domain__name="test.com", mailbox=None, title="Test alarm" + ) cls.da_token = Token.objects.create( - user=core_models.User.objects.get(username="admin@test.com")) + user=core_models.User.objects.get(username="admin@test.com") + ) def test_list(self): url = reverse("v2:alarm-list") @@ -621,11 +579,11 @@ class AlarmViewSetTestCase(ModoAPITestCase): domain = models.Domain.objects.get(name="test.com") # Try performing action on restricted domains - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.da_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.da_token.key) domain = models.Domain.objects.get(name="test2.com") alarm_restricted = models.Alarm.objects.create( - domain=domain, mailbox=None, title="Test alarm 2") + domain=domain, mailbox=None, title="Test alarm 2" + ) alarm_restricted.save() url = reverse("v2:alarm-switch", args=[alarm_restricted.pk]) resp = self.client.post(url) @@ -638,7 +596,8 @@ class AlarmViewSetTestCase(ModoAPITestCase): self.client.credentials(HTTP_AUTHORIZATION="Token " + self.token.key) alarm = models.Alarm.objects.create( - domain=domain, mailbox=None, title="Test alarm 3") + domain=domain, mailbox=None, title="Test alarm 3" + ) alarm.save() # Switch status of the alarm to close @@ -678,9 +637,11 @@ class AlarmViewSetTestCase(ModoAPITestCase): resp = self.client.delete(f"{url}?ids[]=toto") self.assertEqual(resp.status_code, 400) alarm1 = factories.AlarmFactory( - domain__name="test.com", mailbox=None, title="Test alarm") + domain__name="test.com", mailbox=None, title="Test alarm" + ) alarm2 = factories.AlarmFactory( - domain__name="test.com", mailbox=None, title="Test alarm") + domain__name="test.com", mailbox=None, title="Test alarm" + ) resp = self.client.delete(f"{url}?ids[]={alarm1.pk}&ids[]={alarm2.pk}") self.assertEqual(resp.status_code, 204) with self.assertRaises(models.Alarm.DoesNotExist): diff --git a/modoboa/admin/api/v2/urls.py b/modoboa/admin/api/v2/urls.py index aa0e04b9d..e85b08726 100644 --- a/modoboa/admin/api/v2/urls.py +++ b/modoboa/admin/api/v2/urls.py @@ -9,17 +9,15 @@ from . import viewsets router = routers.SimpleRouter() router.register(r"domains", viewsets.DomainViewSet, basename="domain") router.register( - r"domainaliases", v1_viewsets.DomainAliasViewSet, basename="domain_alias") + r"domainaliases", v1_viewsets.DomainAliasViewSet, basename="domain_alias" +) router.register(r"accounts", viewsets.AccountViewSet, basename="account") router.register(r"aliases", viewsets.AliasViewSet, basename="alias") router.register( - r"senderaddresses", v1_viewsets.SenderAddressViewSet, - basename="sender_address") -router.register( - r"identities", viewsets.IdentityViewSet, basename="identities") -router.register( - r"account", viewsets.UserAccountViewSet, basename="account") -router.register( - r"alarms", viewsets.AlarmViewSet, basename="alarm") + r"senderaddresses", v1_viewsets.SenderAddressViewSet, basename="sender_address" +) +router.register(r"identities", viewsets.IdentityViewSet, basename="identities") +router.register(r"account", viewsets.UserAccountViewSet, basename="account") +router.register(r"alarms", viewsets.AlarmViewSet, basename="alarm") urlpatterns = router.urls diff --git a/modoboa/admin/api/v2/viewsets.py b/modoboa/admin/api/v2/viewsets.py index 44cb89bb9..3555f9f02 100644 --- a/modoboa/admin/api/v2/viewsets.py +++ b/modoboa/admin/api/v2/viewsets.py @@ -7,7 +7,13 @@ from django.contrib.contenttypes.models import ContentType from django_filters import rest_framework as dj_filters from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework import ( - filters, mixins, parsers, permissions, response, status, viewsets + filters, + mixins, + parsers, + permissions, + response, + status, + viewsets, ) from rest_framework.decorators import action from rest_framework.exceptions import PermissionDenied @@ -29,31 +35,32 @@ from . import serializers @extend_schema_view( retrieve=extend_schema( description="Retrieve a particular domain", - summary="Retrieve a particular domain" + summary="Retrieve a particular domain", ), list=extend_schema( - description="Retrieve a list of domains", - summary="Retrieve a list of domains" + description="Retrieve a list of domains", summary="Retrieve a list of domains" ), create=extend_schema( - description="Create a new domain", - summary="Create a new domain" + description="Create a new domain", summary="Create a new domain" ), delete=extend_schema( - description="Delete a particular domain", - summary="Delete a particular domain" + description="Delete a particular domain", summary="Delete a particular domain" ), ) -class DomainViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, - mixins.ListModelMixin, - mixins.RetrieveModelMixin, - mixins.CreateModelMixin, - mixins.UpdateModelMixin, - viewsets.GenericViewSet): +class DomainViewSet( + GetThrottleViewsetMixin, + lib_viewsets.RevisionModelMixin, + mixins.ListModelMixin, + mixins.RetrieveModelMixin, + mixins.CreateModelMixin, + mixins.UpdateModelMixin, + viewsets.GenericViewSet, +): """V2 viewset.""" permission_classes = ( - permissions.IsAuthenticated, permissions.DjangoModelPermissions, + permissions.IsAuthenticated, + permissions.DjangoModelPermissions, ) def get_queryset(self): @@ -112,8 +119,9 @@ class DomainViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, domain.remove_admin(serializer.validated_data["account"]) return response.Response() - @action(methods=["get"], detail=False, - renderer_classes=(lib_renderers.CSVRenderer,)) + @action( + methods=["get"], detail=False, renderer_classes=(lib_renderers.CSVRenderer,) + ) def export(self, request, **kwargs): """Export domains and aliases to CSV.""" result = [] @@ -121,21 +129,19 @@ class DomainViewSet(GetThrottleViewsetMixin, lib_viewsets.RevisionModelMixin, result += domain.to_csv_rows() return response.Response(result) - @extend_schema( - request=serializers.CSVImportSerializer + @extend_schema(request=serializers.CSVImportSerializer) + @action( + methods=["post"], + detail=False, + parser_classes=(parsers.MultiPartParser, parsers.FormParser), + url_path="import", ) - @action(methods=["post"], - detail=False, - parser_classes=(parsers.MultiPartParser, parsers.FormParser), - url_path="import") def import_from_csv(self, request, **kwargs): """Import domains and aliases from CSV file.""" serializer = serializers.CSVImportSerializer(data=request.data) serializer.is_valid(raise_exception=True) status, msg = lib.import_data( - request.user, - request.FILES["sourcefile"], - serializer.validated_data + request.user, request.FILES["sourcefile"], serializer.validated_data ) return response.Response({"status": status, "message": msg}) @@ -144,9 +150,8 @@ class AccountFilterSet(dj_filters.FilterSet): """Custom FilterSet for Account.""" domain = dj_filters.ModelChoiceFilter( - queryset=lambda request: models.Domain.objects.get_for_admin( - request.user), - field_name="mailbox__domain" + queryset=lambda request: models.Domain.objects.get_for_admin(request.user), + field_name="mailbox__domain", ) role = dj_filters.CharFilter(method="filter_role") @@ -176,23 +181,19 @@ class AccountViewSet(v1_viewsets.AccountViewSet): def get_queryset(self): """Filter queryset based on current user.""" user = self.request.user - ids = ( - user.objectaccess_set - .filter(content_type=ContentType.objects.get_for_model(user)) - .values_list("object_id", flat=True) - ) - return ( - core_models.User.objects.filter(pk__in=ids) - .prefetch_related("userobjectlimit_set") + ids = user.objectaccess_set.filter( + content_type=ContentType.objects.get_for_model(user) + ).values_list("object_id", flat=True) + return core_models.User.objects.filter(pk__in=ids).prefetch_related( + "userobjectlimit_set" ) @action(methods=["post"], detail=False) def validate(self, request, **kwargs): """Validate given account without creating it.""" serializer = self.get_serializer( - data=request.data, - context=self.get_serializer_context(), - partial=True) + data=request.data, context=self.get_serializer_context(), partial=True + ) serializer.is_valid(raise_exception=True) return response.Response(status=204) @@ -215,17 +216,19 @@ class AccountViewSet(v1_viewsets.AccountViewSet): class IdentityViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): """Viewset for identities.""" - permission_classes = (permissions.IsAuthenticated, ) + permission_classes = (permissions.IsAuthenticated,) serializer_class = None def list(self, request, **kwargs): """Return all identities.""" serializer = serializers.IdentitySerializer( - lib.get_identities(request.user), many=True) + lib.get_identities(request.user), many=True + ) return response.Response(serializer.data) - @action(methods=["get"], detail=False, - renderer_classes=(lib_renderers.CSVRenderer,)) + @action( + methods=["get"], detail=False, renderer_classes=(lib_renderers.CSVRenderer,) + ) def export(self, request, **kwargs): """Export accounts and aliases to CSV.""" result = [] @@ -233,21 +236,19 @@ class IdentityViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): result.append(idt.to_csv_row()) return response.Response(result) - @extend_schema( - request=serializers.CSVIdentityImportSerializer + @extend_schema(request=serializers.CSVIdentityImportSerializer) + @action( + methods=["post"], + detail=False, + parser_classes=(parsers.MultiPartParser, parsers.FormParser), + url_path="import", ) - @action(methods=["post"], - detail=False, - parser_classes=(parsers.MultiPartParser, parsers.FormParser), - url_path="import") def import_from_csv(self, request, **kwargs): """Import accounts and aliases from CSV file.""" serializer = serializers.CSVIdentityImportSerializer(data=request.data) serializer.is_valid(raise_exception=True) status, msg = lib.import_data( - request.user, - request.FILES["sourcefile"], - serializer.validated_data + request.user, request.FILES["sourcefile"], serializer.validated_data ) return response.Response({"status": status, "message": msg}) @@ -261,23 +262,20 @@ class AliasViewSet(v1_viewsets.AliasViewSet): def validate(self, request, **kwargs): """Validate given alias without creating it.""" serializer = self.get_serializer( - data=request.data, - context=self.get_serializer_context(), - partial=True) + data=request.data, context=self.get_serializer_context(), partial=True + ) try: serializer.is_valid(raise_exception=True) except AliasExists as e: return response.Response( data={"id": e.alias_id, "status": _("This alias already exists")}, - status=409 - ) + status=409, + ) return response.Response(status=204) @action(methods=["get"], detail=False) def random_address(self, request, **kwargs): - return response.Response({ - "address": models.Alias.generate_random_address() - }) + return response.Response({"address": models.Alias.generate_random_address()}) class UserAccountViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): @@ -288,7 +286,8 @@ class UserAccountViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): """Get or define user forward.""" mb = request.user.mailbox alias = models.Alias.objects.filter( - address=mb.full_address, internal=False).first() + address=mb.full_address, internal=False + ).first() data = {} if request.method == "GET": if alias is not None and alias.recipients: @@ -304,17 +303,16 @@ class UserAccountViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): recipients = serializer.validated_data.get("recipients") if not recipients: models.Alias.objects.filter( - address=mb.full_address, internal=False).delete() + address=mb.full_address, internal=False + ).delete() # Make sure internal self-alias is enabled - models.Alias.objects.filter( - address=mb.full_address, internal=True - ).update(enabled=True) + models.Alias.objects.filter(address=mb.full_address, internal=True).update( + enabled=True + ) else: if alias is None: alias = models.Alias.objects.create( - address=mb.full_address, - domain=mb.domain, - enabled=mb.user.is_active + address=mb.full_address, domain=mb.domain, enabled=mb.user.is_active ) alias.post_create(request.user) if serializer.validated_data["keepcopies"]: @@ -346,32 +344,35 @@ class AlarmFilterSet(dj_filters.FilterSet): return queryset.filter(created__gt=value) -class AlarmViewSet(GetThrottleViewsetMixin, - mixins.DestroyModelMixin, - mixins.ListModelMixin, - mixins.RetrieveModelMixin, - viewsets.GenericViewSet): +class AlarmViewSet( + GetThrottleViewsetMixin, + mixins.DestroyModelMixin, + mixins.ListModelMixin, + mixins.RetrieveModelMixin, + viewsets.GenericViewSet, +): """Viewset for Alarm.""" - filter_backends = (filters.OrderingFilter, - filters.SearchFilter, - dj_filters.DjangoFilterBackend) + filter_backends = ( + filters.OrderingFilter, + filters.SearchFilter, + dj_filters.DjangoFilterBackend, + ) filterset_class = AlarmFilterSet ordering_fields = ["created", "status", "title"] pagination_class = pagination.CustomPageNumberPagination - permission_classes = ( - permissions.IsAuthenticated, - ) + permission_classes = (permissions.IsAuthenticated,) search_fields = ["domain__name", "title"] serializer_class = serializers.AlarmSerializer def get_queryset(self): - return models.Alarm.objects.select_related("domain").filter( - domain__in=models.Domain.objects.get_for_admin( - self.request.user) - ).order_by("-created") + return ( + models.Alarm.objects.select_related("domain") + .filter(domain__in=models.Domain.objects.get_for_admin(self.request.user)) + .order_by("-created") + ) - @action(methods=['patch'], detail=True) + @action(methods=["patch"], detail=True) def switch(self, request, **kwargs): """Custom update method that switch status of an alarm.""" alarm = self.get_object() @@ -383,7 +384,7 @@ class AlarmViewSet(GetThrottleViewsetMixin, alarm.reopen() return response.Response(status=status.HTTP_204_NO_CONTENT) - @action(methods=['delete'], detail=False) + @action(methods=["delete"], detail=False) def bulk_delete(self, request, **kwargs): """Delete multiple alarms at the same time.""" ids = request.query_params.getlist("ids[]") @@ -392,7 +393,6 @@ class AlarmViewSet(GetThrottleViewsetMixin, try: ids = [int(alarm_id) for alarm_id in ids] except ValueError: - return response.Response( - _("Received invalid alarm id(s)"), status=400) + return response.Response(_("Received invalid alarm id(s)"), status=400) models.Alarm.objects.filter(pk__in=ids).delete() return response.Response(status=204) diff --git a/modoboa/admin/app_settings.py b/modoboa/admin/app_settings.py index eb97ec8e4..c75292c96 100644 --- a/modoboa/admin/app_settings.py +++ b/modoboa/admin/app_settings.py @@ -25,9 +25,7 @@ class AdminParametersForm(param_forms.AdminParametersForm): enable_mx_checks = YesNoField( label=gettext_lazy("Enable MX checks"), initial=True, - help_text=gettext_lazy( - "Check that every domain has a valid MX record" - ) + help_text=gettext_lazy("Check that every domain has a valid MX record"), ) valid_mxs = forms.CharField( @@ -38,7 +36,7 @@ class AdminParametersForm(param_forms.AdminParametersForm): " A warning will be sent if a record does not respect it." ), widget=forms.Textarea, - required=False + required=False, ) domains_must_have_authorized_mx = YesNoField( @@ -47,40 +45,33 @@ class AdminParametersForm(param_forms.AdminParametersForm): help_text=gettext_lazy( "Prevent the creation of a new domain if its MX record does " "not use one of the defined addresses." - ) + ), ) enable_ipv6_mx_checks = YesNoField( label=gettext_lazy("Enable IPV6 checks"), initial=True, - help_text=gettext_lazy( - "Check if MX setup for ipv6 is valid" - ) + help_text=gettext_lazy("Check if MX setup for ipv6 is valid"), ) enable_spf_checks = YesNoField( label=gettext_lazy("Enable SPF checks"), initial=True, - help_text=gettext_lazy( - "Check if every domain has a valid SPF record" - ) + help_text=gettext_lazy("Check if every domain has a valid SPF record"), ) enable_dkim_checks = YesNoField( label=gettext_lazy("Enable DKIM checks"), initial=True, help_text=gettext_lazy( - "Check if every domain with DKIM signin enabled has a valid DNS " - "record" - ) + "Check if every domain with DKIM signin enabled has a valid DNS " "record" + ), ) enable_dmarc_checks = YesNoField( label=gettext_lazy("Enable DMARC checks"), initial=True, - help_text=gettext_lazy( - "Check if every domain has a valid DMARC record" - ) + help_text=gettext_lazy("Check if every domain has a valid DMARC record"), ) enable_autoconfig_checks = YesNoField( @@ -88,15 +79,13 @@ class AdminParametersForm(param_forms.AdminParametersForm): initial=True, help_text=gettext_lazy( "Check if every domain has a valid records for autoconfiguration" - ) + ), ) enable_dnsbl_checks = YesNoField( label=gettext_lazy("Enable DNSBL checks"), initial=True, - help_text=gettext_lazy( - "Check every domain against major DNSBL providers" - ) + help_text=gettext_lazy("Check every domain against major DNSBL providers"), ) custom_dns_server = GenericIPAddressField( @@ -105,7 +94,7 @@ class AdminParametersForm(param_forms.AdminParametersForm): initial="", help_text=gettext_lazy( "Use a custom DNS server instead of local server configuration" - ) + ), ) dkim_keys_storage_dir = forms.CharField( @@ -116,16 +105,14 @@ class AdminParametersForm(param_forms.AdminParametersForm): "be stored. Make sure this directory belongs to root user " "and is not readable by the outside world." ), - required=False + required=False, ) dkim_default_key_length = forms.ChoiceField( label=gettext_lazy("Default DKIM key length"), initial=2048, choices=constants.DKIM_KEY_LENGTHS, - help_text=gettext_lazy( - "Default length in bits for newly generated DKIM keys." - ) + help_text=gettext_lazy("Default length in bits for newly generated DKIM keys."), ) default_domain_quota = forms.IntegerField( @@ -134,7 +121,7 @@ class AdminParametersForm(param_forms.AdminParametersForm): help_text=gettext_lazy( "Default quota (in MB) applied to freshly created domains with no " "value specified. A value of 0 means no quota." - ) + ), ) default_domain_message_limit = forms.IntegerField( @@ -143,7 +130,7 @@ class AdminParametersForm(param_forms.AdminParametersForm): help_text=gettext_lazy( "Number of messages freshly created domains will be " "allowed to send per day. Leave empty for no limit." - ) + ), ) mbsep = SeparatorField(label=gettext_lazy("Mailboxes")) @@ -154,7 +141,7 @@ class AdminParametersForm(param_forms.AdminParametersForm): help_text=gettext_lazy( "Rename or remove mailboxes on the filesystem when they get" " renamed or removed within Modoboa" - ) + ), ) default_mailbox_quota = forms.IntegerField( @@ -163,7 +150,7 @@ class AdminParametersForm(param_forms.AdminParametersForm): help_text=gettext_lazy( "Default mailbox quota (in MB) applied to freshly created " "mailboxes with no value specified. A value of 0 means no quota." - ) + ), ) default_mailbox_message_limit = forms.IntegerField( @@ -172,23 +159,23 @@ class AdminParametersForm(param_forms.AdminParametersForm): help_text=gettext_lazy( "Number of messages freshly created mailboxes will be " "allowed to send per day. Leave empty for no limit." - ) + ), ) auto_account_removal = YesNoField( label=gettext_lazy("Automatic account removal"), initial=False, help_text=gettext_lazy( - "When a mailbox is removed, also remove the associated account") + "When a mailbox is removed, also remove the associated account" + ), ) auto_create_domain_and_mailbox = YesNoField( label=gettext_lazy("Automatic domain/mailbox creation"), initial=True, help_text=gettext_lazy( - "Create a domain and a mailbox when an account is automatically " - "created." - ) + "Create a domain and a mailbox when an account is automatically " "created." + ), ) create_alias_on_mbox_rename = YesNoField( @@ -196,22 +183,19 @@ class AdminParametersForm(param_forms.AdminParametersForm): initial=False, help_text=gettext_lazy( "Create an alias using the old address when a mailbox is renamed." - ) + ), ) # Visibility rules visibility_rules = { "valid_mxs": "enable_mx_checks=True", "domains_must_have_authorized_mx": "enable_mx_checks=True", - "enable_ipv6_mx_checks": "enable_mx_checks=True" + "enable_ipv6_mx_checks": "enable_mx_checks=True", } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.field_widths = { - "default_domain_quota": 2, - "default_mailbox_quota": 2 - } + self.field_widths = {"default_domain_quota": 2, "default_mailbox_quota": 2} hide_fields = False dpath = None code, output = exec_cmd("which dovecot") @@ -219,8 +203,9 @@ class AdminParametersForm(param_forms.AdminParametersForm): dpath = force_str(output).strip() else: known_paths = getattr( - settings, "DOVECOT_LOOKUP_PATH", - ("/usr/sbin/dovecot", "/usr/local/sbin/dovecot") + settings, + "DOVECOT_LOOKUP_PATH", + ("/usr/sbin/dovecot", "/usr/local/sbin/dovecot"), ) for fpath in known_paths: if os.path.isfile(fpath) and os.access(fpath, os.X_OK): @@ -242,17 +227,13 @@ class AdminParametersForm(param_forms.AdminParametersForm): def clean_default_domain_quota(self): """Ensure quota is a positive integer.""" if self.cleaned_data["default_domain_quota"] < 0: - raise forms.ValidationError( - gettext_lazy("Must be a positive integer") - ) + raise forms.ValidationError(gettext_lazy("Must be a positive integer")) return self.cleaned_data["default_domain_quota"] def clean_default_mailbox_quota(self): """Ensure quota is a positive integer.""" if self.cleaned_data["default_mailbox_quota"] < 0: - raise forms.ValidationError( - gettext_lazy("Must be a positive integer") - ) + raise forms.ValidationError(gettext_lazy("Must be a positive integer")) return self.cleaned_data["default_mailbox_quota"] def clean_dkim_keys_storage_dir(self): @@ -260,14 +241,11 @@ class AdminParametersForm(param_forms.AdminParametersForm): storage_dir = self.cleaned_data.get("dkim_keys_storage_dir", "") if storage_dir: if not os.path.isdir(storage_dir): - raise forms.ValidationError( - gettext_lazy("Directory not found.") - ) + raise forms.ValidationError(gettext_lazy("Directory not found.")) code, output = exec_cmd("which openssl") if code: raise forms.ValidationError( - gettext_lazy( - "openssl not found, please make sure it is installed.") + gettext_lazy("openssl not found, please make sure it is installed.") ) return storage_dir @@ -278,14 +256,11 @@ class AdminParametersForm(param_forms.AdminParametersForm): return value try: ip_addresses = [ - ipaddress.ip_network(v.strip()) - for v in value.split() if v.strip() + ipaddress.ip_network(v.strip()) for v in value.split() if v.strip() ] except ValueError: raise forms.ValidationError( - gettext_lazy( - "This field only allows valid IP addresses (or networks)" - ) + gettext_lazy("This field only allows valid IP addresses (or networks)") ) return value @@ -293,171 +268,249 @@ class AdminParametersForm(param_forms.AdminParametersForm): """Check MX options.""" cleaned_data = super(AdminParametersForm, self).clean() condition = ( - cleaned_data.get("enable_mx_checks") and - cleaned_data.get("domains_must_have_authorized_mx") and - not cleaned_data.get("valid_mxs")) + cleaned_data.get("enable_mx_checks") + and cleaned_data.get("domains_must_have_authorized_mx") + and not cleaned_data.get("valid_mxs") + ) if condition: self.add_error( - "valid_mxs", - _("Define at least one authorized network / address") + "valid_mxs", _("Define at least one authorized network / address") ) if not cleaned_data.get("enable_mx_checks"): cleaned_data["enable_ipv6_mx_checks"] = False return cleaned_data -GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([ - ("domains", { - "label": gettext_lazy("Domains"), - "params": collections.OrderedDict([ - ("enable_mx_checks", { - "label": gettext_lazy("Enable MX checks"), - "help_text": gettext_lazy( - "Check that every domain has a valid MX record" - ) - }), - ("valid_mxs", { - "label": gettext_lazy("Valid MXs"), - "display": "enable_mx_checks=true", - "help_text": gettext_lazy( - "A list of IP or network address every MX record should " - "match. A warning will be sent if a record does not " - "respect it." +GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict( + [ + ( + "domains", + { + "label": gettext_lazy("Domains"), + "params": collections.OrderedDict( + [ + ( + "enable_mx_checks", + { + "label": gettext_lazy("Enable MX checks"), + "help_text": gettext_lazy( + "Check that every domain has a valid MX record" + ), + }, + ), + ( + "valid_mxs", + { + "label": gettext_lazy("Valid MXs"), + "display": "enable_mx_checks=true", + "help_text": gettext_lazy( + "A list of IP or network address every MX record should " + "match. A warning will be sent if a record does not " + "respect it." + ), + }, + ), + ( + "domains_must_have_authorized_mx", + { + "label": gettext_lazy( + "New domains must use authorized MX(s)" + ), + "display": "enable_mx_checks=true", + "help_text": gettext_lazy( + "Prevent the creation of a new domain if its MX record " + "does not use one of the defined addresses." + ), + }, + ), + ( + "enable_ipv6_mx_checks", + { + "label": gettext_lazy("Enable IPV6 checks"), + "display": "enable_mx_checks=true", + "help_text": gettext_lazy( + "Check if MX setup for ipv6 is valid" + ), + }, + ), + ( + "enable_spf_checks", + { + "label": gettext_lazy("Enable SPF checks"), + "help_text": gettext_lazy( + "Check if every domain has a valid SPF record" + ), + }, + ), + ( + "enable_dkim_checks", + { + "label": gettext_lazy("Enable DKIM checks"), + "help_text": gettext_lazy( + "Check if every domain with DKIM signin enabled " + "has a valid DNS record" + ), + }, + ), + ( + "enable_dmarc_checks", + { + "label": gettext_lazy("Enable DMARC checks"), + "help_text": gettext_lazy( + "Check if every domain has a valid DMARC record" + ), + }, + ), + ( + "enable_autoconfig_checks", + { + "label": gettext_lazy("Enable autoconfig checks"), + "help_text": gettext_lazy( + "Check if every domain has a valid records for " + "autoconfiguration" + ), + }, + ), + ( + "enable_dnsbl_checks", + { + "label": gettext_lazy("Enable DNSBL checks"), + "help_text": gettext_lazy( + "Check every domain against major DNSBL providers" + ), + }, + ), + ( + "custom_dns_server", + { + "label": gettext_lazy("Custom DNS server"), + "help_text": gettext_lazy( + "Use a custom DNS server instead of local server " + "configuration" + ), + }, + ), + ( + "dkim_keys_storage_dir", + { + "label": gettext_lazy("DKIM keys storage directory"), + "help_text": gettext_lazy( + "Absolute path of the directory where DKIM private keys " + "will be stored. Make sure this directory belongs to root " + "user and is not readable by the outside world." + ), + }, + ), + ( + "dkim_default_key_length", + { + "label": gettext_lazy("Default DKIM key length"), + "help_text": gettext_lazy( + "Default length in bits for newly generated DKIM keys." + ), + }, + ), + ( + "default_domain_quota", + { + "label": gettext_lazy("Default domain quota"), + "help_text": gettext_lazy( + "Default quota (in MB) applied to freshly created domains " + "with no value specified. A value of 0 means no quota." + ), + }, + ), + ( + "default_domain_message_limit", + { + "label": gettext_lazy("Default domain sending limit"), + "help_text": gettext_lazy( + "Number of messages freshly created domains will be " + "allowed to send per day. Leave empty for no limit." + ), + }, + ), + ] ), - }), - ("domains_must_have_authorized_mx", { - "label": gettext_lazy("New domains must use authorized MX(s)"), - "display": "enable_mx_checks=true", - "help_text": gettext_lazy( - "Prevent the creation of a new domain if its MX record " - "does not use one of the defined addresses." - ) - }), - ("enable_ipv6_mx_checks", { - "label": gettext_lazy("Enable IPV6 checks"), - "display": "enable_mx_checks=true", - "help_text": gettext_lazy( - "Check if MX setup for ipv6 is valid" - ) - }), - ("enable_spf_checks", { - "label": gettext_lazy("Enable SPF checks"), - "help_text": gettext_lazy( - "Check if every domain has a valid SPF record" - ) - }), - ("enable_dkim_checks", { - "label": gettext_lazy("Enable DKIM checks"), - "help_text": gettext_lazy( - "Check if every domain with DKIM signin enabled " - "has a valid DNS record" - ) - }), - ("enable_dmarc_checks", { - "label": gettext_lazy("Enable DMARC checks"), - "help_text": gettext_lazy( - "Check if every domain has a valid DMARC record" - ) - }), - ("enable_autoconfig_checks", { - "label": gettext_lazy("Enable autoconfig checks"), - "help_text": gettext_lazy( - "Check if every domain has a valid records for " - "autoconfiguration" - ) - }), - ("enable_dnsbl_checks", { - "label": gettext_lazy("Enable DNSBL checks"), - "help_text": gettext_lazy( - "Check every domain against major DNSBL providers" - ) - }), - ("custom_dns_server", { - "label": gettext_lazy("Custom DNS server"), - "help_text": gettext_lazy( - "Use a custom DNS server instead of local server " - "configuration" - ) - }), - ("dkim_keys_storage_dir", { - "label": gettext_lazy("DKIM keys storage directory"), - "help_text": gettext_lazy( - "Absolute path of the directory where DKIM private keys " - "will be stored. Make sure this directory belongs to root " - "user and is not readable by the outside world." + }, + ), + ( + "mailboxes", + { + "label": gettext_lazy("Mailboxes"), + "params": collections.OrderedDict( + [ + ( + "handle_mailboxes", + { + "label": gettext_lazy("Handle mailboxes on filesystem"), + "help_text": gettext_lazy( + "Rename or remove mailboxes on the filesystem when they get" + " renamed or removed within Modoboa" + ), + }, + ), + ( + "default_mailbox_quota", + { + "label": gettext_lazy("Default mailbox quota"), + "help_text": gettext_lazy( + "Default mailbox quota (in MB) applied to freshly created " + "domains with no value specified. A value of 0 means no " + "quota." + ), + }, + ), + ( + "default_mailbox_message_limit", + { + "label": gettext_lazy("Default mailbox sending limit"), + "help_text": gettext_lazy( + "Number of messages freshly created mailboxes will be " + "allowed to send per day. Leave empty for no limit." + ), + }, + ), + ( + "auto_account_removal", + { + "label": gettext_lazy("Automatic account removal"), + "help_text": gettext_lazy( + "When a mailbox is removed, also remove the associated " + "account" + ), + }, + ), + ( + "auto_create_domain_and_mailbox", + { + "label": gettext_lazy( + "Automatic domain/mailbox creation" + ), + "help_text": gettext_lazy( + "Create a domain and a mailbox when an account is " + "automatically created." + ), + }, + ), + ( + "create_alias_on_mbox_rename", + { + "label": gettext_lazy( + "Create an alias when a mailbox is renamed" + ), + "help_text": gettext_lazy( + "Create an alias using the old address when a mailbox is " + "renamed." + ), + }, + ), + ] ), - }), - ("dkim_default_key_length", { - "label": gettext_lazy("Default DKIM key length"), - "help_text": gettext_lazy( - "Default length in bits for newly generated DKIM keys." - ) - }), - ("default_domain_quota", { - "label": gettext_lazy("Default domain quota"), - "help_text": gettext_lazy( - "Default quota (in MB) applied to freshly created domains " - "with no value specified. A value of 0 means no quota." - ) - }), - ("default_domain_message_limit", { - "label": gettext_lazy("Default domain sending limit"), - "help_text": gettext_lazy( - "Number of messages freshly created domains will be " - "allowed to send per day. Leave empty for no limit." - ) - }), - ]) - }), - ("mailboxes", { - "label": gettext_lazy("Mailboxes"), - "params": collections.OrderedDict([ - ("handle_mailboxes", { - "label": gettext_lazy("Handle mailboxes on filesystem"), - "help_text": gettext_lazy( - "Rename or remove mailboxes on the filesystem when they get" - " renamed or removed within Modoboa" - ) - }), - ("default_mailbox_quota", { - "label": gettext_lazy("Default mailbox quota"), - "help_text": gettext_lazy( - "Default mailbox quota (in MB) applied to freshly created " - "domains with no value specified. A value of 0 means no " - "quota." - ) - }), - ("default_mailbox_message_limit", { - "label": gettext_lazy("Default mailbox sending limit"), - "help_text": gettext_lazy( - "Number of messages freshly created mailboxes will be " - "allowed to send per day. Leave empty for no limit." - ) - }), - ("auto_account_removal", { - "label": gettext_lazy("Automatic account removal"), - "help_text": gettext_lazy( - "When a mailbox is removed, also remove the associated " - "account") - }), - ("auto_create_domain_and_mailbox", { - "label": gettext_lazy("Automatic domain/mailbox creation"), - "help_text": gettext_lazy( - "Create a domain and a mailbox when an account is " - "automatically created." - ) - }), - ("create_alias_on_mbox_rename", { - "label": gettext_lazy( - "Create an alias when a mailbox is renamed"), - "help_text": gettext_lazy( - "Create an alias using the old address when a mailbox is " - "renamed." - ) - }) - ]) - }), -]) + }, + ), + ] +) def load_admin_settings(): @@ -466,8 +519,12 @@ def load_admin_settings(): from .api.v2 import serializers param_tools.registry.add( - "global", AdminParametersForm, gettext_lazy("Administration")) + "global", AdminParametersForm, gettext_lazy("Administration") + ) param_tools.registry.add2( - "global", "admin", gettext_lazy("Administration"), + "global", + "admin", + gettext_lazy("Administration"), GLOBAL_PARAMETERS_STRUCT, - serializers.AdminGlobalParametersSerializer) + serializers.AdminGlobalParametersSerializer, + ) diff --git a/modoboa/admin/constants.py b/modoboa/admin/constants.py index 7a3595de9..da54ecb7e 100644 --- a/modoboa/admin/constants.py +++ b/modoboa/admin/constants.py @@ -17,12 +17,7 @@ DNSBL_PROVIDERS = [ # Do not run tests for these domains. # https://en.wikipedia.org/wiki/Top-level_domain#Reserved_domains -RESERVED_TLD = [ - "example", - "invalid", - "localhost", - "test" -] +RESERVED_TLD = ["example", "invalid", "localhost", "test"] DOMAIN_TYPES = [ ("domain", _("Domain")), diff --git a/modoboa/admin/factories.py b/modoboa/admin/factories.py index cd5d33221..2d59ff863 100644 --- a/modoboa/admin/factories.py +++ b/modoboa/admin/factories.py @@ -9,12 +9,11 @@ from . import models class DomainFactory(PermissionFactory): - """Factory to create Domains.""" class Meta: model = models.Domain - django_get_or_create = ("name", ) + django_get_or_create = ("name",) name = factory.Sequence(lambda n: "domain{}.test".format(n)) type = "domain" # NOQA:A003 @@ -24,19 +23,17 @@ class DomainFactory(PermissionFactory): class DomainAliasFactory(PermissionFactory): - """Factory to create DomainAlias objects.""" class Meta: model = models.DomainAlias - django_get_or_create = ("name", ) + django_get_or_create = ("name",) target = factory.SubFactory(DomainFactory) enabled = True class MailboxFactory(PermissionFactory): - """A factory to create Mailbox instances.""" class Meta: @@ -98,31 +95,23 @@ def populate_database(): """ dom = DomainFactory(name="test.com", quota=50) admin = UserFactory( - username="admin@test.com", groups=("DomainAdmins", ), - password="{PLAIN}toto" + username="admin@test.com", groups=("DomainAdmins",), password="{PLAIN}toto" ) MailboxFactory(address="admin", domain=dom, user=admin) account = UserFactory.create( - username="user@test.com", groups=("SimpleUsers",), + username="user@test.com", + groups=("SimpleUsers",), ) MailboxFactory.create(address="user", domain=dom, user=account) - al = AliasFactory.create( - address="forward@test.com", domain=dom - ) - AliasRecipientFactory.create( - address="user@external.com", alias=al) + al = AliasFactory.create(address="forward@test.com", domain=dom) + AliasRecipientFactory.create(address="user@external.com", alias=al) - al = AliasFactory.create( - address="alias@test.com", domain=dom - ) + al = AliasFactory.create(address="alias@test.com", domain=dom) mb = account.mailbox - AliasRecipientFactory.create( - address=mb.full_address, alias=al, r_mailbox=mb) + AliasRecipientFactory.create(address=mb.full_address, alias=al, r_mailbox=mb) - al = AliasFactory.create( - address="postmaster@test.com", domain=dom - ) + al = AliasFactory.create(address="postmaster@test.com", domain=dom) for address in ["toto@titi.com", "test@truc.fr"]: AliasRecipientFactory.create(address=address, alias=al) @@ -130,12 +119,9 @@ def populate_database(): dom2 = DomainFactory.create(name="test2.com", default_mailbox_quota=0) admin = UserFactory.create( - username="admin@test2.com", groups=("DomainAdmins",), - password="{PLAIN}toto" + username="admin@test2.com", groups=("DomainAdmins",), password="{PLAIN}toto" ) MailboxFactory.create(address="admin", domain=dom2, user=admin) - u = UserFactory.create( - username="user@test2.com", groups=("SimpleUsers",) - ) + u = UserFactory.create(username="user@test2.com", groups=("SimpleUsers",)) MailboxFactory.create(address="user", domain=dom2, user=u) dom2.add_admin(admin) diff --git a/modoboa/admin/forms/__init__.py b/modoboa/admin/forms/__init__.py index 3637c3637..4239ef97e 100644 --- a/modoboa/admin/forms/__init__.py +++ b/modoboa/admin/forms/__init__.py @@ -1,19 +1,29 @@ from .account import ( - AccountForm, AccountFormGeneral, AccountFormMail, AccountPermissionsForm, - AccountWizard + AccountForm, + AccountFormGeneral, + AccountFormMail, + AccountPermissionsForm, + AccountWizard, ) from .alias import AliasForm -from .domain import ( - DomainForm, DomainFormGeneral, DomainFormOptions, DomainWizard -) +from .domain import DomainForm, DomainFormGeneral, DomainFormOptions, DomainWizard from .export import ExportDataForm from .forward import ForwardForm from .import_ import ImportDataForm, ImportIdentitiesForm __all__ = [ - "DomainFormGeneral", "DomainFormOptions", "DomainForm", - "AccountFormGeneral", "AccountFormMail", "AccountPermissionsForm", - "AccountForm", "AliasForm", "ImportDataForm", "ImportIdentitiesForm", + "DomainFormGeneral", + "DomainFormOptions", + "DomainForm", + "AccountFormGeneral", + "AccountFormMail", + "AccountPermissionsForm", + "AccountForm", + "AliasForm", + "ImportDataForm", + "ImportIdentitiesForm", "ExportDataForm", - "ForwardForm", "DomainWizard", "AccountWizard" + "ForwardForm", + "DomainWizard", + "AccountWizard", ] diff --git a/modoboa/admin/forms/account.py b/modoboa/admin/forms/account.py index 8fd2572b6..cbfcffc52 100644 --- a/modoboa/admin/forms/account.py +++ b/modoboa/admin/forms/account.py @@ -14,9 +14,7 @@ from modoboa.core import signals as core_signals from modoboa.core.models import User from modoboa.lib import exceptions as lib_exceptions, fields as lib_fields from modoboa.lib.email_utils import split_mailbox -from modoboa.lib.form_utils import ( - DynamicForm, TabForms, WizardForm, WizardStep -) +from modoboa.lib.form_utils import DynamicForm, TabForms, WizardForm, WizardStep from modoboa.lib.permissions import get_account_roles from modoboa.lib.validators import validate_utf8_email from modoboa.lib.web_utils import render_to_json_response, size2integer @@ -25,7 +23,6 @@ from .. import lib, models, signals class AccountFormGeneral(forms.ModelForm): - """General account form.""" username = forms.CharField( @@ -33,12 +30,12 @@ class AccountFormGeneral(forms.ModelForm): help_text=gettext_lazy( "The user's name. Must be a valid e-mail address for simple users " "or administrators with a mailbox." - ) + ), ) role = forms.ChoiceField( label=gettext_lazy("Role"), choices=[("", gettext_lazy("Choose"))], - help_text=gettext_lazy("What level of permission this user will have") + help_text=gettext_lazy("What level of permission this user will have"), ) random_password = forms.BooleanField( label=gettext_lazy("Random password"), @@ -46,55 +43,66 @@ class AccountFormGeneral(forms.ModelForm): "Generate a random password. If you're updating this account and " "check this box, a new password will be generated." ), - required=False + required=False, ) password1 = forms.CharField( - label=gettext_lazy("Password"), widget=forms.widgets.PasswordInput, - required=False + label=gettext_lazy("Password"), + widget=forms.widgets.PasswordInput, + required=False, ) password2 = forms.CharField( label=gettext_lazy("Confirmation"), widget=forms.widgets.PasswordInput, - help_text=gettext_lazy( - "Enter the same password as above, for verification." - ), - required=False + help_text=gettext_lazy("Enter the same password as above, for verification."), + required=False, ) class Meta: model = User fields = ( - "username", "first_name", "last_name", "role", "is_active", + "username", + "first_name", + "last_name", + "role", + "is_active", "master_user", ) - labels = { - "is_active": gettext_lazy("Enabled") - } + labels = {"is_active": gettext_lazy("Enabled")} def __init__(self, user, *args, **kwargs): super(AccountFormGeneral, self).__init__(*args, **kwargs) self.fields = OrderedDict( - (key, self.fields[key]) for key in - ["role", "username", "first_name", "last_name", - "random_password", "password1", "password2", - "master_user", "is_active"] + (key, self.fields[key]) + for key in [ + "role", + "username", + "first_name", + "last_name", + "random_password", + "password1", + "password2", + "master_user", + "is_active", + ] ) self.user = user condition = ( - user.role == "DomainAdmins" or - user.role == "Resellers" and self.instance == user + user.role == "DomainAdmins" + or user.role == "Resellers" + and self.instance == user ) if condition: self.fields["role"] = forms.CharField( label="", widget=forms.HiddenInput(attrs={"class": "form-control"}), - required=False + required=False, ) else: self.fields["role"].choices += ( get_account_roles(user, self.instance) - if self.instance.pk else get_account_roles(user) + if self.instance.pk + else get_account_roles(user) ) if not user.is_superuser: @@ -104,8 +112,8 @@ class AccountFormGeneral(forms.ModelForm): return domain_disabled = ( - hasattr(self.instance, "mailbox") and - not self.instance.mailbox.domain.enabled + hasattr(self.instance, "mailbox") + and not self.instance.mailbox.domain.enabled ) if domain_disabled: self.fields["is_active"].widget.attrs["disabled"] = "disabled" @@ -113,9 +121,10 @@ class AccountFormGeneral(forms.ModelForm): del self.fields["is_active"] self.fields["role"].initial = self.instance.role condition = ( - not self.instance.is_local and - param_tools.get_global_parameter( - "ldap_auth_method", app="core") == "directbind") + not self.instance.is_local + and param_tools.get_global_parameter("ldap_auth_method", app="core") + == "directbind" + ) if condition: del self.fields["random_password"] del self.fields["password1"] @@ -158,13 +167,12 @@ class AccountFormGeneral(forms.ModelForm): if self.errors: return self.cleaned_data condition = ( - self.cleaned_data.get("master_user") and - self.cleaned_data["role"] != "SuperAdmins" + self.cleaned_data.get("master_user") + and self.cleaned_data["role"] != "SuperAdmins" ) if condition: self.add_error( - "master_user", - _("Only super administrators are allowed for this mode") + "master_user", _("Only super administrators are allowed for this mode") ) random_password = self.cleaned_data.get("random_password") if random_password: @@ -182,12 +190,11 @@ class AccountFormGeneral(forms.ModelForm): return self.cleaned_data if password1 != password2: self.add_error( - "password2", - _("The two password fields didn't match.")) + "password2", _("The two password fields didn't match.") + ) return self.cleaned_data try: - password_validation.validate_password( - password2, self.instance) + password_validation.validate_password(password2, self.instance) except forms.ValidationError as ve: self.add_error("password2", ve.messages) return self.cleaned_data @@ -196,7 +203,8 @@ class AccountFormGeneral(forms.ModelForm): account = super(AccountFormGeneral, self).save(commit=False) if self.user == account and not self.cleaned_data["is_active"]: raise lib_exceptions.PermDeniedException( - _("You can't disable your own account")) + _("You can't disable your own account") + ) if not account.pk: account.language = settings.LANGUAGE_CODE if commit: @@ -207,7 +215,8 @@ class AccountFormGeneral(forms.ModelForm): if hasattr(account, "mailbox"): # Update forward status according to account status models.Alias.objects.filter(address=account.email).update( - enabled=account.is_active) + enabled=account.is_active + ) return account @@ -222,12 +231,11 @@ class AccountProfileForm(forms.ModelForm): class AccountFormMail(forms.Form, DynamicForm): """Form to handle mail part.""" - email = lib_fields.UTF8EmailField( - label=gettext_lazy("E-mail"), required=False) + email = lib_fields.UTF8EmailField(label=gettext_lazy("E-mail"), required=False) create_alias_with_old_address = forms.BooleanField( label=gettext_lazy("Create an alias using the old address"), required=False, - initial=False + initial=False, ) quota = forms.CharField( label=gettext_lazy("Quota"), @@ -239,20 +247,20 @@ class AccountFormMail(forms.Form, DynamicForm): "unlimited value (not allowed for domain " "administrators)." ), - widget=forms.widgets.TextInput(attrs={"class": "form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "form-control"}), ) quota_act = forms.BooleanField(required=False) message_limit = forms.IntegerField( label=gettext_lazy("Message sending limit"), required=False, min_value=0, - help_text=gettext_lazy( - "Number of messages this mailbox can send per day") + help_text=gettext_lazy("Number of messages this mailbox can send per day"), ) is_send_only = forms.BooleanField( required=False, help_text=gettext_lazy( - "Block IMAP connection and incoming mails for this mailbox") + "Block IMAP connection and incoming mails for this mailbox" + ), ) aliases = lib_fields.UTF8AndEmptyUserEmailField( label=gettext_lazy("Alias(es)"), @@ -261,7 +269,7 @@ class AccountFormMail(forms.Form, DynamicForm): "Alias(es) of this mailbox. Indicate only one address per input, " "press ENTER to add a new input. To create a catchall alias, just " "enter the domain name (@domain.tld)." - ) + ), ) senderaddress = lib_fields.UTF8AndEmptyUserEmailField( label=gettext_lazy("Sender addresses"), @@ -271,16 +279,14 @@ class AccountFormMail(forms.Form, DynamicForm): "allowed to send emails using this address, even if it " "does not exist locally. Indicate one address per input. Press " "ENTER to add a new input." - ) + ), ) def __init__(self, user, *args, **kwargs): self.mb = kwargs.pop("instance", None) self.user = user super().__init__(*args, **kwargs) - self.field_widths = { - "quota": 3 - } + self.field_widths = {"quota": 3} params = dict(param_tools.get_global_parameters("admin")) if self.mb is not None: self.fields["email"].required = True @@ -288,13 +294,13 @@ class AccountFormMail(forms.Form, DynamicForm): for cpt, ralias in enumerate(qset): name = "aliases_{}".format(cpt + 1) self._create_field( - lib_fields.UTF8AndEmptyUserEmailField, name, - ralias.alias.address) + lib_fields.UTF8AndEmptyUserEmailField, name, ralias.alias.address + ) for cpt, saddress in enumerate(self.mb.senderaddress_set.all()): name = "senderaddress_{}".format(cpt + 1) self._create_field( - lib_fields.UTF8AndEmptyUserEmailField, name, - saddress.address) + lib_fields.UTF8AndEmptyUserEmailField, name, saddress.address + ) self.fields["email"].initial = self.mb.full_address self.fields["quota_act"].initial = self.mb.use_domain_quota if not self.mb.use_domain_quota and self.mb.quota: @@ -302,22 +308,24 @@ class AccountFormMail(forms.Form, DynamicForm): if self.mb.message_limit: self.fields["message_limit"].initial = self.mb.message_limit self.fields["is_send_only"].initial = self.mb.is_send_only - self.fields["create_alias_with_old_address"].initial = ( - params["create_alias_on_mbox_rename"] - ) + self.fields["create_alias_with_old_address"].initial = params[ + "create_alias_on_mbox_rename" + ] else: del self.fields["create_alias_with_old_address"] self.fields["quota_act"].initial = True if params["default_mailbox_message_limit"] is not None: - self.fields["message_limit"].initial = ( - params["default_mailbox_message_limit"]) + self.fields["message_limit"].initial = params[ + "default_mailbox_message_limit" + ] if len(args) and isinstance(args[0], QueryDict): self._load_from_qdict( - args[0], "aliases", lib_fields.UTF8AndEmptyUserEmailField) + args[0], "aliases", lib_fields.UTF8AndEmptyUserEmailField + ) self._load_from_qdict( - args[0], "senderaddress", - lib_fields.UTF8AndEmptyUserEmailField) + args[0], "senderaddress", lib_fields.UTF8AndEmptyUserEmailField + ) def clean_email(self): """Ensure lower case emails""" @@ -332,8 +340,8 @@ class AccountFormMail(forms.Form, DynamicForm): if not self.mb: try: core_signals.can_create_object.send( - sender=self.__class__, context=self.domain, - object_type="mailboxes") + sender=self.__class__, context=self.domain, object_type="mailboxes" + ) except lib_exceptions.ModoboaException as inst: raise forms.ValidationError(inst) return email @@ -350,9 +358,10 @@ class AccountFormMail(forms.Form, DynamicForm): cleaned_data = super(AccountFormMail, self).clean() use_default_domain_quota = cleaned_data["quota_act"] condition = ( - not use_default_domain_quota and - cleaned_data["quota"] is not None and - cleaned_data["quota"] < 0) + not use_default_domain_quota + and cleaned_data["quota"] is not None + and cleaned_data["quota"] < 0 + ) if condition: self.add_error("quota", _("Must be a positive integer")) self.aliases = [] @@ -367,16 +376,14 @@ class AccountFormMail(forms.Form, DynamicForm): self.add_error(name, _("Local domain does not exist")) continue if not self.user.can_access(domain): - self.add_error( - name, _("You don't have access to this domain")) + self.add_error(name, _("You don't have access to this domain")) continue self.aliases.append(value.lower()) elif name.startswith("senderaddress"): local_part, domname = split_mailbox(value) domain = models.Domain.objects.filter(name=domname).first() if domain and not self.user.can_access(domain): - self.add_error( - name, _("You don't have access to this domain")) + self.add_error(name, _("You don't have access to this domain")) continue self.sender_addresses.append(value.lower()) return cleaned_data @@ -386,17 +393,20 @@ class AccountFormMail(forms.Form, DynamicForm): if not user.can_access(self.domain): raise lib_exceptions.PermDeniedException core_signals.can_create_object.send( - self.__class__, context=user, klass=models.Mailbox) + self.__class__, context=user, klass=models.Mailbox + ) self.mb = models.Mailbox( - address=self.locpart, domain=self.domain, user=account, + address=self.locpart, + domain=self.domain, + user=account, use_domain_quota=self.cleaned_data["quota_act"], message_limit=self.cleaned_data.get("message_limit"), - is_send_only=self.cleaned_data.get("is_send_only", False) + is_send_only=self.cleaned_data.get("is_send_only", False), ) override_rules = ( - user.is_superuser or - user.has_perm("admin.add_domain") and - not user.userobjectlimit_set.get(name="quota").max_value + user.is_superuser + or user.has_perm("admin.add_domain") + and not user.userobjectlimit_set.get(name="quota").max_value ) self.mb.set_quota(self.cleaned_data["quota"], override_rules) self.mb.save(creator=user) @@ -405,7 +415,8 @@ class AccountFormMail(forms.Form, DynamicForm): """Update mailbox aliases.""" # 1. We check if existing aliases were removed... qset = self.mb.aliasrecipient_set.select_related("alias").filter( - alias__internal=False) + alias__internal=False + ) for ralias in qset: if ralias.alias.address not in self.aliases: alias = ralias.alias @@ -420,22 +431,28 @@ class AccountFormMail(forms.Form, DynamicForm): return # 3. Check limits at all levels core_signals.can_create_object.send( - self.__class__, context=user, klass=models.Alias, - count=len(self.aliases)) + self.__class__, context=user, klass=models.Alias, count=len(self.aliases) + ) core_signals.can_create_object.send( - self.__class__, context=self.mb.domain, - object_type="mailbox_aliases", count=len(self.aliases)) + self.__class__, + context=self.mb.domain, + object_type="mailbox_aliases", + count=len(self.aliases), + ) # 4. Create / update aliases for alias in self.aliases: - if self.mb.aliasrecipient_set.select_related("alias").filter( - alias__address=alias, alias__internal=False).exists(): + if ( + self.mb.aliasrecipient_set.select_related("alias") + .filter(alias__address=alias, alias__internal=False) + .exists() + ): continue local_part, domname = split_mailbox(alias) al, _ = models.Alias.objects.get_or_create( address=alias, domain=models.Domain.objects.get(name=domname), internal=False, - defaults={'enabled': account.is_active}, + defaults={"enabled": account.is_active}, ) al.add_recipients([self.mb.full_address]) al.post_create(user) @@ -451,8 +468,7 @@ class AccountFormMail(forms.Form, DynamicForm): return to_create = [] for saddress in self.sender_addresses: - to_create.append( - models.SenderAddress(address=saddress, mailbox=self.mb)) + to_create.append(models.SenderAddress(address=saddress, mailbox=self.mb)) models.SenderAddress.objects.bulk_create(to_create) def save(self, user, account): @@ -466,8 +482,7 @@ class AccountFormMail(forms.Form, DynamicForm): if not hasattr(self, "mb") or self.mb is None: self.create_mailbox(user, account) else: - self.cleaned_data["use_domain_quota"] = ( - self.cleaned_data["quota_act"]) + self.cleaned_data["use_domain_quota"] = self.cleaned_data["quota_act"] if self.cleaned_data.get("create_alias_with_old_address", False): self.aliases.append(self.mb.full_address) self.mb.update_from_dict(user, self.cleaned_data) @@ -487,7 +502,7 @@ class AccountPermissionsForm(forms.Form, DynamicForm): domains = lib_fields.DomainNameField( label=gettext_lazy("Domain(s)"), required=False, - help_text=gettext_lazy("Domain(s) that user administrates") + help_text=gettext_lazy("Domain(s) that user administrates"), ) def __init__(self, *args, **kwargs): @@ -504,15 +519,13 @@ class AccountPermissionsForm(forms.Form, DynamicForm): name = "domains_%d" % (pos + 1) self._create_field(lib_fields.DomainNameField, name, dom.name) if len(args) and isinstance(args[0], QueryDict): - self._load_from_qdict( - args[0], "domains", lib_fields.DomainNameField) + self._load_from_qdict(args[0], "domains", lib_fields.DomainNameField) def save(self): if self.account.role == "SimpleUsers": return current_domains = [ - dom.name for dom in - models.Domain.objects.get_for_admin(self.account) + dom.name for dom in models.Domain.objects.get_for_admin(self.account) ] for name, value in self.cleaned_data.items(): if not name.startswith("domains"): @@ -534,45 +547,57 @@ class AccountForm(TabForms): def __init__(self, request, *args, **kwargs): self.user = request.user self.forms = [ - {"id": "general", "title": _("General"), - "formtpl": "admin/account_general_form.html", - "cls": AccountFormGeneral, - "new_args": [self.user], "mandatory": True}, - {"id": "profile", "title": _("Profile"), - "formtpl": "admin/account_profile_form.html", - "cls": AccountProfileForm}, - {"id": "mail", - "title": _("Mail"), "formtpl": "admin/mailform.html", - "cls": AccountFormMail, - "new_args": [self.user]}, - {"id": "perms", "title": _("Permissions"), - "formtpl": "admin/permsform.html", - "cls": AccountPermissionsForm} + { + "id": "general", + "title": _("General"), + "formtpl": "admin/account_general_form.html", + "cls": AccountFormGeneral, + "new_args": [self.user], + "mandatory": True, + }, + { + "id": "profile", + "title": _("Profile"), + "formtpl": "admin/account_profile_form.html", + "cls": AccountProfileForm, + }, + { + "id": "mail", + "title": _("Mail"), + "formtpl": "admin/mailform.html", + "cls": AccountFormMail, + "new_args": [self.user], + }, + { + "id": "perms", + "title": _("Permissions"), + "formtpl": "admin/permsform.html", + "cls": AccountPermissionsForm, + }, ] cbargs = {"user": self.user} if "instances" in kwargs: cbargs["account"] = kwargs["instances"]["general"] - results = signals.extra_account_forms.send( - sender=self.__class__, **cbargs) - self.forms += reduce( - lambda a, b: a + b, [result[1] for result in results]) + results = signals.extra_account_forms.send(sender=self.__class__, **cbargs) + self.forms += reduce(lambda a, b: a + b, [result[1] for result in results]) super(AccountForm, self).__init__(request, *args, **kwargs) def extra_context(self, context): account = self.instances["general"] - context.update({ - "title": account.username, - "formid": "accountform", - "action": reverse("admin:account_change", - args=[account.id]), - }) + context.update( + { + "title": account.username, + "formid": "accountform", + "action": reverse("admin:account_change", args=[account.id]), + } + ) def check_perms(self, account): """Check if perms form must displayed or not.""" return ( - self.user.is_superuser and - not account.is_superuser and - account.has_perm("core.add_user") + self.user.is_superuser + and not account.is_superuser + and account.has_perm("core.add_user") ) def _before_is_valid(self, form): @@ -585,7 +610,8 @@ class AccountForm(TabForms): return True results = signals.check_extra_account_form.send( - sender=self.__class__, account=self.account, form=form) + sender=self.__class__, account=self.account, form=form + ) results = [result[1] for result in results] if False in results: return False @@ -617,31 +643,33 @@ class AccountForm(TabForms): class AccountWizard(WizardForm): - """Account creation wizard.""" def __init__(self, request): super(AccountWizard, self).__init__(request) self.add_step( WizardStep( - "general", AccountFormGeneral, _("General"), - new_args=[request.user] + "general", AccountFormGeneral, _("General"), new_args=[request.user] ) ) self.add_step( WizardStep( - "mail", AccountFormMail, _("Mail"), + "mail", + AccountFormMail, + _("Mail"), "admin/mailform.html", - new_args=[request.user] + new_args=[request.user], ) ) def extra_context(self, context): - context.update({ - "title": _("New account"), - "action": reverse("admin:account_add"), - "formid": "newaccount_form" - }) + context.update( + { + "title": _("New account"), + "action": reverse("admin:account_add"), + "formid": "newaccount_form", + } + ) def done(self): account = self.first_step.form.save() diff --git a/modoboa/admin/forms/alias.py b/modoboa/admin/forms/alias.py index 86e95b5da..33794bfdb 100644 --- a/modoboa/admin/forms/alias.py +++ b/modoboa/admin/forms/alias.py @@ -17,43 +17,50 @@ class AliasForm(forms.ModelForm, DynamicForm): """A form to create/modify an alias.""" random_address = forms.BooleanField( - label=gettext_lazy("Random address"), - required=False) + label=gettext_lazy("Random address"), required=False + ) address = lib_fields.UTF8AndEmptyUserEmailField( label=gettext_lazy("Email address"), help_text=gettext_lazy( "The alias address. To create a catchall alias, just enter the " "domain name (@domain.tld)." ), - widget=forms.TextInput(attrs={"class": "form-control"}) + widget=forms.TextInput(attrs={"class": "form-control"}), ) recipients = lib_fields.UTF8AndEmptyUserEmailField( - label=gettext_lazy("Recipients"), required=False, + label=gettext_lazy("Recipients"), + required=False, help_text=gettext_lazy( "Addresses this alias will point to. Indicate only one address " "per input, press ENTER to add a new input." ), - widget=forms.TextInput(attrs={"class": "form-control"}) + widget=forms.TextInput(attrs={"class": "form-control"}), ) class Meta: model = Alias fields = ("address", "domain", "enabled", "expire_at", "description") - labels = { - "domain": gettext_lazy("Domain") - } + labels = {"domain": gettext_lazy("Domain")} widgets = { "domain": forms.widgets.Select( - attrs={"class": "selectpicker", "data-live-search": "true"}) + attrs={"class": "selectpicker", "data-live-search": "true"} + ) } def __init__(self, user, *args, **kwargs): self.user = user super(AliasForm, self).__init__(*args, **kwargs) self.fields = OrderedDict( - (key, self.fields[key]) for key in - ["random_address", "address", "domain", "recipients", "enabled", - "expire_at", "description"] + (key, self.fields[key]) + for key in [ + "random_address", + "address", + "domain", + "recipients", + "enabled", + "expire_at", + "description", + ] ) if self.instance.pk: del self.fields["random_address"] @@ -87,14 +94,12 @@ class AliasForm(forms.ModelForm, DynamicForm): except Domain.DoesNotExist: raise forms.ValidationError(_("Domain does not exist")) if not self.user.can_access(domain): - raise forms.ValidationError( - _("You don't have access to this domain") - ) + raise forms.ValidationError(_("You don't have access to this domain")) if not self.instance.pk: try: core_signals.can_create_object.send( - sender=self.__class__, context=domain, - object_type="mailbox_aliases") + sender=self.__class__, context=domain, object_type="mailbox_aliases" + ) except lib_exceptions.ModoboaException as inst: raise forms.ValidationError(inst) return self.cleaned_data["address"].lower() @@ -119,14 +124,16 @@ class AliasForm(forms.ModelForm, DynamicForm): alias = super(AliasForm, self).save(commit=False) if self.cleaned_data.get("random_address"): alias.address = "{}@{}".format( - Alias.generate_random_address(), alias.domain) + Alias.generate_random_address(), alias.domain + ) else: local_part, domname = split_mailbox(self.cleaned_data["address"]) alias.domain = Domain.objects.get(name=domname) if commit: alias.save() address_list = [ - value for field, value in self.cleaned_data.items() + value + for field, value in self.cleaned_data.items() if field.startswith("recipients") and value ] alias.set_recipients(address_list) diff --git a/modoboa/admin/forms/domain.py b/modoboa/admin/forms/domain.py index c14bf067f..e5e028527 100644 --- a/modoboa/admin/forms/domain.py +++ b/modoboa/admin/forms/domain.py @@ -13,7 +13,11 @@ from modoboa.core.models import User from modoboa.lib.exceptions import Conflict from modoboa.lib.fields import DomainNameField from modoboa.lib.form_utils import ( - DynamicForm, TabForms, WizardForm, WizardStep, YesNoField + DynamicForm, + TabForms, + WizardForm, + WizardStep, + YesNoField, ) from modoboa.lib.web_utils import render_to_json_response, size2integer from modoboa.parameters import tools as param_tools @@ -33,17 +37,18 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): help_text=gettext_lazy( "Alias(es) of this domain. Indicate only one name per input, " "press ENTER to add a new input." - ) + ), ) dkim_key_selector = forms.CharField( - label=gettext_lazy("Key selector"), initial="modoboa", required=False) + label=gettext_lazy("Key selector"), initial="modoboa", required=False + ) quota = forms.CharField( label=gettext_lazy("Quota"), initial=0, help_text=gettext_lazy( "Quota shared between mailboxes. Can be expressed in KB, " "MB (default) or GB. A value of 0 means no quota." - ) + ), ) default_mailbox_quota = forms.CharField( label=gettext_lazy("Default mailbox quota"), @@ -51,15 +56,23 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): help_text=gettext_lazy( "Default quota applied to mailboxes. Can be expressed in KB, MB " "(default) or GB. A value of 0 means no quota." - ) + ), ) class Meta: model = Domain fields = ( - "name", "type", "quota", "default_mailbox_quota", "message_limit", - "aliases", "enabled", "enable_dns_checks", "enable_dkim", - "dkim_key_selector", "dkim_key_length" + "name", + "type", + "quota", + "default_mailbox_quota", + "message_limit", + "aliases", + "enabled", + "enable_dns_checks", + "enable_dkim", + "dkim_key_selector", + "dkim_key_length", ) def __init__(self, user, *args, **kwargs): @@ -71,15 +84,12 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): params = dict(param_tools.get_global_parameters("admin")) self.fields["quota"].initial = params["default_domain_quota"] if params["default_domain_message_limit"] is not None: - self.fields["message_limit"].initial = ( - params["default_domain_message_limit"]) - self.fields["default_mailbox_quota"].initial = ( - params["default_mailbox_quota"]) + self.fields["message_limit"].initial = params[ + "default_domain_message_limit" + ] + self.fields["default_mailbox_quota"].initial = params["default_mailbox_quota"] self.fields["type"].choices = constants.DOMAIN_TYPES - self.field_widths = { - "quota": 3, - "default_mailbox_quota": 3 - } + self.field_widths = {"quota": 3, "default_mailbox_quota": 3} self.user = user if len(args) and isinstance(args[0], QueryDict): @@ -93,19 +103,20 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): def clean_name(self): """Check unicity and more.""" name = self.cleaned_data["name"].lower() - label = lib.check_if_domain_exists( - name, [(DomainAlias, _("domain alias"))]) + label = lib.check_if_domain_exists(name, [(DomainAlias, _("domain alias"))]) if label is not None: raise forms.ValidationError( - _("A %s with this name already exists") % force_str(label)) + _("A %s with this name already exists") % force_str(label) + ) - domains_must_have_authorized_mx = ( - param_tools.get_global_parameter("domains_must_have_authorized_mx") + domains_must_have_authorized_mx = param_tools.get_global_parameter( + "domains_must_have_authorized_mx" ) if domains_must_have_authorized_mx and not self.user.is_superuser: if not lib.domain_has_authorized_mx(name): raise forms.ValidationError( - _("No authorized MX record found for this domain")) + _("No authorized MX record found for this domain") + ) return name @@ -116,8 +127,7 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): return enabled storage_dir = param_tools.get_global_parameter("dkim_keys_storage_dir") if not storage_dir: - raise forms.ValidationError( - _("DKIM keys storage directory not configured")) + raise forms.ValidationError(_("DKIM keys storage directory not configured")) return enabled def clean_quota(self): @@ -127,7 +137,8 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): def clean_default_mailbox_quota(self): """Return proper quota value.""" return size2integer( - self.cleaned_data["default_mailbox_quota"], output_unit="MB") + self.cleaned_data["default_mailbox_quota"], output_unit="MB" + ) def clean(self): """Custom fields validation. @@ -141,13 +152,13 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): if self._errors: return cleaned_data condition = ( - self.cleaned_data["quota"] != 0 and - self.cleaned_data["default_mailbox_quota"] > - self.cleaned_data["quota"]) + self.cleaned_data["quota"] != 0 + and self.cleaned_data["default_mailbox_quota"] > self.cleaned_data["quota"] + ) if condition: self.add_error( - "default_mailbox_quota", - _("Cannot be greater than domain quota")) + "default_mailbox_quota", _("Cannot be greater than domain quota") + ) elif self.user.role == "Resellers": limit = self.user.userobjectlimit_set.get(name="quota") if limit.max_value != 0: @@ -155,14 +166,12 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): msg = _("You can't define an unlimited quota.") if quota == 0: self.add_error("quota", msg) - default_mailbox_quota = self.cleaned_data[ - "default_mailbox_quota"] + default_mailbox_quota = self.cleaned_data["default_mailbox_quota"] if default_mailbox_quota == 0: self.add_error("default_mailbox_quota", msg) if self.cleaned_data["enable_dkim"]: if not self.cleaned_data.get("dkim_key_selector"): - self.add_error( - "dkim_key_selector", _("This field is required.")) + self.add_error("dkim_key_selector", _("This field is required.")) self.aliases = [] copied_data = cleaned_data.copy() for k in copied_data.keys(): @@ -177,12 +186,10 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): ) del cleaned_data[k] continue - label = lib.check_if_domain_exists( - cleaned_data[k], [(Domain, _("domain"))]) + label = lib.check_if_domain_exists(cleaned_data[k], [(Domain, _("domain"))]) if label is not None: self.add_error( - k, _("A %s with this name already exists") - % force_str(label) + k, _("A %s with this name already exists") % force_str(label) ) else: self.aliases.append(cleaned_data[k]) @@ -198,7 +205,8 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): """ d = super(DomainFormGeneral, self).save(commit=False) core_signals.can_create_object.send( - sender=self.__class__, context=user, klass=Domain, instance=d) + sender=self.__class__, context=user, klass=Domain, instance=d + ) if not commit: return d d.save() @@ -209,18 +217,23 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): self.aliases.remove(dalias.name) if self.aliases: core_signals.can_create_object.send( - self.__class__, context=user, klass=DomainAlias, - count=len(self.aliases)) + self.__class__, context=user, klass=DomainAlias, count=len(self.aliases) + ) core_signals.can_create_object.send( - self.__class__, context=d, object_type="domain_aliases", - count=len(self.aliases)) + self.__class__, + context=d, + object_type="domain_aliases", + count=len(self.aliases), + ) for alias in self.aliases: if d.domainalias_set.filter(name=alias).exists(): continue options = {"creator": user} if domalias_post_create else {} - DomainAlias(name=alias, target=d, enabled=d.enabled).save( - **options) - if self.cleaned_data.get("enable_dkim") is False and d.dkim_private_key_path != "": + DomainAlias(name=alias, target=d, enabled=d.enabled).save(**options) + if ( + self.cleaned_data.get("enable_dkim") is False + and d.dkim_private_key_path != "" + ): d.dkim_private_key_path = "" d.save() return d @@ -232,9 +245,7 @@ class DomainFormOptions(forms.Form): create_dom_admin = YesNoField( label=gettext_lazy("Create a domain administrator"), initial=False, - help_text=gettext_lazy( - "Automatically create an administrator for this domain" - ) + help_text=gettext_lazy("Automatically create an administrator for this domain"), ) dom_admin_username = forms.CharField( @@ -244,40 +255,35 @@ class DomainFormOptions(forms.Form): "The administrator's name. Don't include the domain's name here, " "it will be automatically appended." ), - required=False + required=False, ) random_password = YesNoField( label=gettext_lazy("Random password"), initial=False, - help_text=gettext_lazy( - "Generate a random password for the administrator." - ), - required=False + help_text=gettext_lazy("Generate a random password for the administrator."), + required=False, ) with_mailbox = YesNoField( label=gettext_lazy("With a mailbox"), initial=True, - help_text=gettext_lazy( - "Create a mailbox for the administrator." - ), - required=False + help_text=gettext_lazy("Create a mailbox for the administrator."), + required=False, ) create_aliases = YesNoField( label=gettext_lazy("Create aliases"), initial=True, - help_text=gettext_lazy( - "Automatically create standard aliases for this domain" - ), - required=False + help_text=gettext_lazy("Automatically create standard aliases for this domain"), + required=False, ) def __init__(self, user, *args, **kwargs): super(DomainFormOptions, self).__init__(*args, **kwargs) results = core_signals.user_can_set_role.send( - sender=self.__class__, user=user, role="DomainAdmins") + sender=self.__class__, user=user, role="DomainAdmins" + ) if False in [result[1] for result in results]: self.fields = {} return @@ -293,11 +299,9 @@ class DomainFormOptions(forms.Form): cleaned_data = super(DomainFormOptions, self).clean() if cleaned_data.get("create_dom_admin"): if not cleaned_data.get("dom_admin_username"): - self.add_error( - "dom_admin_username", _("This field is required.")) + self.add_error("dom_admin_username", _("This field is required.")) if "create_aliases" not in cleaned_data: - self.add_error( - "create_aliases", _("This field is required.")) + self.add_error("create_aliases", _("This field is required.")) return cleaned_data def save(self, *args, **kwargs): @@ -307,22 +311,19 @@ class DomainFormOptions(forms.Form): return user = kwargs.pop("user") domain = kwargs.pop("domain") - username = "%s@%s" % ( - self.cleaned_data["dom_admin_username"], domain.name) + username = "%s@%s" % (self.cleaned_data["dom_admin_username"], domain.name) try: da = User.objects.get(username=username) except User.DoesNotExist: pass else: raise Conflict(_("User '%s' already exists") % username) - core_signals.can_create_object.send( - self.__class__, context=user, klass=Mailbox) + core_signals.can_create_object.send(self.__class__, context=user, klass=Mailbox) da = User(username=username, email=username, is_active=True) if self.cleaned_data["random_password"]: password = lib.make_password() else: - password = param_tools.get_global_parameter( - "default_password", app="core") + password = param_tools.get_global_parameter("default_password", app="core") da.set_password(password) da.save() da.role = "DomainAdmins" @@ -331,24 +332,27 @@ class DomainFormOptions(forms.Form): if self.cleaned_data["with_mailbox"]: dom_admin_username = self.cleaned_data["dom_admin_username"] mb = Mailbox( - address=dom_admin_username, domain=domain, - user=da, use_domain_quota=True + address=dom_admin_username, + domain=domain, + user=da, + use_domain_quota=True, ) - mb.set_quota( - override_rules=user.has_perm("admin.change_domain")) + mb.set_quota(override_rules=user.has_perm("admin.change_domain")) mb.save(creator=user) condition = ( - domain.type == "domain" and - self.cleaned_data["create_aliases"] and - dom_admin_username != "postmaster" + domain.type == "domain" + and self.cleaned_data["create_aliases"] + and dom_admin_username != "postmaster" ) if condition: core_signals.can_create_object.send( - self.__class__, context=user, klass=Alias) - address = u"postmaster@{}".format(domain.name) + self.__class__, context=user, klass=Alias + ) + address = "postmaster@{}".format(domain.name) alias = Alias.objects.create( - address=address, domain=domain, enabled=True) + address=address, domain=domain, enabled=True + ) alias.set_recipients([mb.full_address]) alias.post_create(user) @@ -363,36 +367,37 @@ class DomainForm(TabForms): self.forms = [] self.domain = None if self.user.has_perm("admin.change_domain"): - self.forms.append({ - "id": "general", - "title": _("General"), - "formtpl": "admin/domain_general_form.html", - "cls": DomainFormGeneral, - "mandatory": True, - "new_args": [request.user] - }) + self.forms.append( + { + "id": "general", + "title": _("General"), + "formtpl": "admin/domain_general_form.html", + "cls": DomainFormGeneral, + "mandatory": True, + "new_args": [request.user], + } + ) cbargs = {"user": self.user} if "instances" in kwargs: self.domain = kwargs["instances"]["general"] cbargs["domain"] = self.domain - results = signals.extra_domain_forms.send( - sender=self.__class__, **cbargs) - self.forms += reduce( - lambda a, b: a + b, [result[1] for result in results]) + results = signals.extra_domain_forms.send(sender=self.__class__, **cbargs) + self.forms += reduce(lambda a, b: a + b, [result[1] for result in results]) if not self.forms: self.active_id = "admins" super(DomainForm, self).__init__(request, *args, **kwargs) def extra_context(self, context): """Add information to template context.""" - context.update({ - "title": self.domain.name, - "action": reverse( - "admin:domain_change", args=[self.domain.pk]), - "formid": "domform", - "domain": self.domain - }) + context.update( + { + "title": self.domain.name, + "action": reverse("admin:domain_change", args=[self.domain.pk]), + "formid": "domform", + "domain": self.domain, + } + ) def is_valid(self): """Custom validation. @@ -417,8 +422,7 @@ class DomainForm(TabForms): first_form = self.forms[0]["instance"] options = {} if isinstance(first_form, DomainFormGeneral): - domain = first_form.save( - self.request.user, domalias_post_create=True) + domain = first_form.save(self.request.user, domalias_post_create=True) options.update({"domain": domain}) else: first_form.save(self.request.user) @@ -436,9 +440,11 @@ class DomainWizard(WizardForm): super(DomainWizard, self).__init__(request) self.add_step( WizardStep( - "general", DomainFormGeneral, _("General"), + "general", + DomainFormGeneral, + _("General"), "admin/domain_general_form.html", - [request.user] + [request.user], ) ) results = signals.extra_domain_wizard_steps.send(sender=self.__class__) @@ -447,18 +453,22 @@ class DomainWizard(WizardForm): self.add_step(step) self.add_step( WizardStep( - "options", DomainFormOptions, _("Options"), + "options", + DomainFormOptions, + _("Options"), "admin/domain_options_form.html", - [self.request.user] + [self.request.user], ) ) def extra_context(self, context): - context.update({ - "title": _("New domain"), - "action": reverse("admin:domain_add"), - "formid": "domform" - }) + context.update( + { + "title": _("New domain"), + "action": reverse("admin:domain_add"), + "formid": "domform", + } + ) def done(self): genform = self.first_step.form diff --git a/modoboa/admin/forms/export.py b/modoboa/admin/forms/export.py index 786a726e4..ba0863664 100644 --- a/modoboa/admin/forms/export.py +++ b/modoboa/admin/forms/export.py @@ -9,7 +9,7 @@ class ExportDataForm(forms.Form): label=gettext_lazy("Separator"), max_length=1, required=False, - widget=forms.TextInput(attrs={"class": "form-control"}) + widget=forms.TextInput(attrs={"class": "form-control"}), ) def __init__(self, *args, **kwargs): diff --git a/modoboa/admin/forms/forward.py b/modoboa/admin/forms/forward.py index 8308d2f2a..3d5af289e 100644 --- a/modoboa/admin/forms/forward.py +++ b/modoboa/admin/forms/forward.py @@ -12,14 +12,14 @@ class ForwardForm(forms.Form): label=gettext_lazy("Recipient(s)"), widget=forms.Textarea(attrs={"class": "form-control"}), required=False, - help_text=gettext_lazy( - "Indicate one or more recipients separated by a ','") + help_text=gettext_lazy("Indicate one or more recipients separated by a ','"), ) keepcopies = forms.BooleanField( label=gettext_lazy("Keep local copies"), required=False, help_text=gettext_lazy( - "Forward messages and store copies into your local mailbox") + "Forward messages and store copies into your local mailbox" + ), ) def clean_dest(self): diff --git a/modoboa/admin/forms/import_.py b/modoboa/admin/forms/import_.py index acdb1f3fb..a038d1e35 100644 --- a/modoboa/admin/forms/import_.py +++ b/modoboa/admin/forms/import_.py @@ -5,7 +5,6 @@ from django.utils.translation import gettext_lazy class ImportDataForm(forms.Form): - """Base form to import objects.""" sourcefile = forms.FileField(label=gettext_lazy("Select a file")) @@ -13,11 +12,12 @@ class ImportDataForm(forms.Form): label=gettext_lazy("Separator"), max_length=1, required=False, - widget=forms.TextInput(attrs={"class": "form-control"}) + widget=forms.TextInput(attrs={"class": "form-control"}), ) continue_if_exists = forms.BooleanField( - label=gettext_lazy("Continue on error"), required=False, - help_text=gettext_lazy("Don't treat duplicated objects as error") + label=gettext_lazy("Continue on error"), + required=False, + help_text=gettext_lazy("Don't treat duplicated objects as error"), ) def __init__(self, *args, **kwargs): @@ -31,13 +31,12 @@ class ImportDataForm(forms.Form): class ImportIdentitiesForm(ImportDataForm): - """A form to import identities.""" crypt_password = forms.BooleanField( - label=gettext_lazy("Crypt passwords"), required=False, + label=gettext_lazy("Crypt passwords"), + required=False, help_text=gettext_lazy( - "Check this option if passwords contained in your file " - "are not crypted" - ) + "Check this option if passwords contained in your file " "are not crypted" + ), ) diff --git a/modoboa/admin/handlers.py b/modoboa/admin/handlers.py index 4a6fcf15b..a3f402e4b 100644 --- a/modoboa/admin/handlers.py +++ b/modoboa/admin/handlers.py @@ -23,18 +23,20 @@ def update_domain_mxs_and_mailboxes(sender, instance, **kwargs): if kwargs.get("created"): return instance.mailbox_set.filter(use_domain_quota=True).update( - quota=instance.default_mailbox_quota) + quota=instance.default_mailbox_quota + ) if instance.old_mail_homes is None: return - qset = ( - models.Quota.objects.filter( - username__contains="@{}".format(instance.oldname)) + qset = models.Quota.objects.filter( + username__contains="@{}".format(instance.oldname) ) for q in qset: username = q.username.replace( - "@{}".format(instance.oldname), "@{}".format(instance.name)) + "@{}".format(instance.oldname), "@{}".format(instance.name) + ) models.Quota.objects.create( - username=username, bytes=q.bytes, messages=q.messages) + username=username, bytes=q.bytes, messages=q.messages + ) q.delete() for mb in instance.mailbox_set.all(): mb.rename_dir(instance.old_mail_homes[mb.pk]) @@ -42,8 +44,7 @@ def update_domain_mxs_and_mailboxes(sender, instance, **kwargs): # .update(address=Concat("local_part", Value(instance.name))) # if the local_part was stored aside the address... for alias in instance.alias_set.all(): - alias.address = "{}@{}".format( - alias.address.split("@", 1)[0], instance.name) + alias.address = "{}@{}".format(alias.address.split("@", 1)[0], instance.name) alias.save(update_fields=["address"]) @@ -51,11 +52,8 @@ def update_domain_mxs_and_mailboxes(sender, instance, **kwargs): def create_dkim_key(sender, instance, **kwargs): if not instance.enable_dkim: return - queue = django_rq.get_queue('dkim') - queue.enqueue(call_command, - "modo", - "manage_dkim_keys", - f"--domain={instance.name}") + queue = django_rq.get_queue("dkim") + queue.enqueue(call_command, "modo", "manage_dkim_keys", f"--domain={instance.name}") @receiver(signals.post_save, sender=models.DomainAlias) @@ -64,16 +62,17 @@ def create_alias_for_domainalias(sender, instance, **kwargs): if not kwargs.get("created"): return alias = models.Alias.objects.create( - address=u"@{}".format(instance.name), enabled=True, internal=True) + address="@{}".format(instance.name), enabled=True, internal=True + ) models.AliasRecipient.objects.create( - address=u"@{}".format(instance.target.name), alias=alias) + address="@{}".format(instance.target.name), alias=alias + ) @receiver(signals.post_delete, sender=models.DomainAlias) def remove_alias_for_domainalias(sender, instance, **kwargs): """Remove the alias associated to domain alias.""" - models.Alias.objects.filter( - address=u"@{}".format(instance.name)).delete() + models.Alias.objects.filter(address="@{}".format(instance.name)).delete() @receiver(signals.post_save, sender=models.Mailbox) @@ -84,20 +83,22 @@ def manage_alias_for_mailbox(sender, instance, **kwargs): address=instance.full_address, domain=instance.domain, internal=True, - defaults={ - "enabled": instance.user.enabled - } + defaults={"enabled": instance.user.enabled}, ) models.AliasRecipient.objects.create( - address=instance.full_address, alias=alias, r_mailbox=instance) + address=instance.full_address, alias=alias, r_mailbox=instance + ) return old_address = getattr(instance, "old_full_address", None) if old_address is None or old_address == instance.full_address: return # Update old self alias alr = models.AliasRecipient.objects.get( - alias__address=old_address, address=old_address, - r_mailbox=instance, alias__internal=True) + alias__address=old_address, + address=old_address, + r_mailbox=instance, + alias__internal=True, + ) alr.address = instance.full_address alr.save() alr.alias.address = instance.full_address @@ -106,7 +107,8 @@ def manage_alias_for_mailbox(sender, instance, **kwargs): # Update AliasRecipient instances instance.aliasrecipient_set.filter(alias__internal=False).update( - address=instance.full_address) + address=instance.full_address + ) @receiver(signals.pre_delete, sender=models.Mailbox) @@ -132,7 +134,8 @@ def mailbox_deleted_handler(sender, **kwargs): request = lib_signals.get_request() if request: if not request.localconfig.parameters.get_value( - "handle_mailboxes", raise_exception=False): + "handle_mailboxes", raise_exception=False + ): return keepdir = request.POST.get("keepdir", "false") == "true" if keepdir: @@ -142,7 +145,8 @@ def mailbox_deleted_handler(sender, **kwargs): # Management command context localconfig = core_models.LocalConfig.objects.first() if not localconfig.parameters.get_value( - "handle_mailboxes", raise_exception=False): + "handle_mailboxes", raise_exception=False + ): return mb.delete_dir() @@ -150,17 +154,18 @@ def mailbox_deleted_handler(sender, **kwargs): @receiver(signals.post_delete, sender=models.Mailbox) def remove_alias_for_mailbox(sender, instance, **kwargs): """Remove "self alias" for this mailbox.""" - models.Alias.objects.filter( - address=instance.full_address).delete() + models.Alias.objects.filter(address=instance.full_address).delete() @receiver(core_signals.register_postfix_maps) def register_postfix_maps(sender, **kwargs): """Register admin map files.""" return [ - postfix_maps.DomainsMap, postfix_maps.DomainsAliasesMap, - postfix_maps.AliasesMap, postfix_maps.MaintainMap, - postfix_maps.SenderLoginMap + postfix_maps.DomainsMap, + postfix_maps.DomainsAliasesMap, + postfix_maps.AliasesMap, + postfix_maps.MaintainMap, + postfix_maps.SenderLoginMap, ] @@ -177,11 +182,11 @@ def account_auto_created(sender, user, **kwargs): domain = models.Domain.objects.get(name=domname) except models.Domain.DoesNotExist: label = lib.check_if_domain_exists( - domname, [(models.DomainAlias, _("domain alias"))]) + domname, [(models.DomainAlias, _("domain alias"))] + ) if label is not None: return - domain = models.Domain( - name=domname, enabled=True, default_mailbox_quota=0) + domain = models.Domain(name=domname, enabled=True, default_mailbox_quota=0) domain.save(creator=sadmins[0]) for su in sadmins[1:]: permissions.grant_access_to_object(su, domain) @@ -201,11 +206,10 @@ def account_auto_created(sender, user, **kwargs): @receiver(core_signals.account_exported) def export_admin_domains(sender, user, **kwargs): """Export administered domains too.""" - result = [user.mailbox.quota] if hasattr(user, "mailbox") else [u""] + result = [user.mailbox.quota] if hasattr(user, "mailbox") else [""] if user.role != "DomainAdmins": return result - return result + [ - dom.name for dom in models.Domain.objects.get_for_admin(user)] + return result + [dom.name for dom in models.Domain.objects.get_for_admin(user)] @receiver(core_signals.account_imported) @@ -232,14 +236,17 @@ def import_account_mailbox(sender, user, account, row, **kwargs): if not user.can_access(domain): raise exceptions.PermDeniedException core_signals.can_create_object.send( - sender="import", context=user, klass=models.Mailbox) + sender="import", context=user, klass=models.Mailbox + ) core_signals.can_create_object.send( - sender="import", context=domain, object_type="mailboxes") + sender="import", context=domain, object_type="mailboxes" + ) account.save() qset = models.Mailbox.objects.filter(address=mailbox, domain=domain) if qset.exists(): raise exceptions.Conflict( - _("Mailbox {} already exists").format(account.email)) + _("Mailbox {} already exists").format(account.email) + ) if len(row) == 1: quota = None else: @@ -252,11 +259,12 @@ def import_account_mailbox(sender, user, account, row, **kwargs): ) use_domain_quota = True if not quota else False mb = models.Mailbox( - address=mailbox, domain=domain, - user=account, use_domain_quota=use_domain_quota) - mb.set_quota( - quota, override_rules=user.has_perm("admin.change_domain") + address=mailbox, + domain=domain, + user=account, + use_domain_quota=use_domain_quota, ) + mb.set_quota(quota, override_rules=user.has_perm("admin.change_domain")) mb.save(creator=user) if account.role == "DomainAdmins": for domname in row[2:]: @@ -275,19 +283,20 @@ def admin_menu(sender, location, user, **kwargs): entries = [] if user.has_perm("admin.view_domain"): entries += [ - {"name": "domains", - "url": reverse("admin:domain_list"), - "label": _("Domains")} + { + "name": "domains", + "url": reverse("admin:domain_list"), + "label": _("Domains"), + } ] - conditions = ( - user.has_perm("core.add_user"), - user.has_perm("admin.add_alias") - ) + conditions = (user.has_perm("core.add_user"), user.has_perm("admin.add_alias")) if any(conditions): entries += [ - {"name": "identities", - "url": reverse("admin:identity_list"), - "label": _("Identities")}, + { + "name": "identities", + "url": reverse("admin:identity_list"), + "label": _("Identities"), + }, ] return entries @@ -300,10 +309,12 @@ def user_menu(sender, location, user, **kwargs): if not hasattr(user, "mailbox"): return [] return [ - {"name": "forward", - "class": "ajaxnav", - "url": "forward/", - "label": _("Forward")} + { + "name": "forward", + "class": "ajaxnav", + "url": "forward/", + "label": _("Forward"), + } ] @@ -321,12 +332,15 @@ def grant_access_to_all_objects(sender, account, role, **kwargs): if role != "SuperAdmins": return perm_models = [ - core_models.User, models.Domain, models.DomainAlias, models.Mailbox, - models.Alias] + core_models.User, + models.Domain, + models.DomainAlias, + models.Mailbox, + models.Alias, + ] for model in perm_models: permissions.grant_access_to_objects( - account, model.objects.all(), - ContentType.objects.get_for_model(model) + account, model.objects.all(), ContentType.objects.get_for_model(model) ) @@ -338,19 +352,15 @@ def add_widgets_to_admin_dashboard(sender, user, **kwargs): "domains_counter": models.Domain.objects.count(), "domain_aliases_counter": models.DomainAlias.objects.count(), "identities_counter": ( - core_models.User.objects.count() + - models.Alias.objects.filter(internal=False).count()), + core_models.User.objects.count() + + models.Alias.objects.filter(internal=False).count() + ), } template = "admin/_global_statistics_widget.html" else: - context = { - "domains": models.Domain.objects.get_for_admin(user)} + context = {"domains": models.Domain.objects.get_for_admin(user)} template = "admin/_per_domain_statistics_widget.html" - return [{ - "column": "left", - "template": template, - "context": context - }] + return [{"column": "left", "template": template, "context": context}] @receiver(admin_signals.import_object) diff --git a/modoboa/admin/lib.py b/modoboa/admin/lib.py index a1100cfc9..b81f9dd6f 100644 --- a/modoboa/admin/lib.py +++ b/modoboa/admin/lib.py @@ -25,9 +25,7 @@ from reversion import revisions as reversion from modoboa.core import signals as core_signals from modoboa.core.models import User -from modoboa.lib.exceptions import ( - Conflict, ModoboaException, PermDeniedException -) +from modoboa.lib.exceptions import Conflict, ModoboaException, PermDeniedException from modoboa.parameters import tools as param_tools from . import signals @@ -40,13 +38,16 @@ def needs_mailbox(): Some applications (the webmail for example) need a mailbox to work. """ + def decorator(f): @wraps(f) def wrapped_f(request, *args, **kwargs): if hasattr(request.user, "mailbox"): return f(request, *args, **kwargs) raise PermDeniedException(_("A mailbox is required")) + return wrapped_f + return decorator @@ -61,13 +62,12 @@ def get_identities(user, searchquery=None, idtfilter=None, grpfilter=None): """ accounts = [] if idtfilter is None or not idtfilter or idtfilter == "account": - ids = user.objectaccess_set \ - .filter(content_type=ContentType.objects.get_for_model(user)) \ - .values_list("object_id", flat=True) + ids = user.objectaccess_set.filter( + content_type=ContentType.objects.get_for_model(user) + ).values_list("object_id", flat=True) q = Q(pk__in=ids) if searchquery is not None: - q &= Q(username__icontains=searchquery) \ - | Q(email__icontains=searchquery) + q &= Q(username__icontains=searchquery) | Q(email__icontains=searchquery) if grpfilter is not None and grpfilter: if grpfilter == "SuperAdmins": q &= Q(is_superuser=True) @@ -76,16 +76,19 @@ def get_identities(user, searchquery=None, idtfilter=None, grpfilter=None): accounts = User.objects.filter(q).prefetch_related("groups") aliases = [] - if idtfilter is None or not idtfilter \ - or (idtfilter in ["alias", "forward", "dlist"]): + if ( + idtfilter is None + or not idtfilter + or (idtfilter in ["alias", "forward", "dlist"]) + ): alct = ContentType.objects.get_for_model(Alias) - ids = user.objectaccess_set.filter(content_type=alct) \ - .values_list("object_id", flat=True) + ids = user.objectaccess_set.filter(content_type=alct).values_list( + "object_id", flat=True + ) q = Q(pk__in=ids, internal=False) if searchquery is not None: - q &= ( - Q(address__icontains=searchquery) | - Q(domain__name__icontains=searchquery) + q &= Q(address__icontains=searchquery) | Q( + domain__name__icontains=searchquery ) aliases = Alias.objects.select_related("domain").filter(q) if idtfilter is not None and idtfilter: @@ -101,8 +104,7 @@ def get_domains(user, domfilter=None, searchquery=None, **extrafilters): :rtype: list :return: a list of domains and/or relay domains """ - domains = ( - Domain.objects.get_for_admin(user).prefetch_related("domainalias_set")) + domains = Domain.objects.get_for_admin(user).prefetch_related("domainalias_set") if domfilter: domains = domains.filter(type=domfilter) if searchquery is not None: @@ -110,7 +112,8 @@ def get_domains(user, domfilter=None, searchquery=None, **extrafilters): q |= Q(domainalias__name__contains=searchquery) domains = domains.filter(q).distinct() results = signals.extra_domain_qset_filters.send( - sender="get_domains", domfilter=domfilter, extrafilters=extrafilters) + sender="get_domains", domfilter=domfilter, extrafilters=extrafilters + ) if results: qset_filters = {} for result in results: @@ -136,8 +139,7 @@ def import_domain(user, row, formopts): """Specific code for domains import""" if not user.has_perm("admin.add_domain"): raise PermDeniedException(_("You are not allowed to import domains")) - core_signals.can_create_object.send( - sender="import", context=user, klass=Domain) + core_signals.can_create_object.send(sender="import", context=user, klass=Domain) dom = Domain() dom.from_csv(user, row) @@ -145,10 +147,10 @@ def import_domain(user, row, formopts): def import_domainalias(user, row, formopts): """Specific code for domain aliases import""" if not user.has_perm("admin.add_domainalias"): - raise PermDeniedException( - _("You are not allowed to import domain aliases.")) + raise PermDeniedException(_("You are not allowed to import domain aliases.")) core_signals.can_create_object.send( - sender="import", context=user, klass=DomainAlias) + sender="import", context=user, klass=DomainAlias + ) domalias = DomainAlias() domalias.from_csv(user, row) @@ -200,14 +202,15 @@ def get_dns_records(name, typ, resolver=None): except dns.resolver.NoAnswer as e: logger.error( _("No %(type)s record for %(name)s") % {"type": typ, "name": name}, - exc_info=e + exc_info=e, ) except dns.resolver.NoNameservers as e: logger.error(_("No working name servers found"), exc_info=e) except dns.resolver.Timeout as e: logger.warning( - _("DNS resolution timeout, unable to query %s at the moment") % - name, exc_info=e) + _("DNS resolution timeout, unable to query %s at the moment") % name, + exc_info=e, + ) except dns.name.NameTooLong as e: logger.error(_("DNS name is too long: %s" % name), exc_info=e) else: @@ -225,7 +228,8 @@ def get_domain_mx_list(domain): return result for dns_answer in dns_answers: mx_domain = dns_answer.exchange.to_unicode( - omit_final_dot=True, idna_codec=IDNA_2008_UTS_46) + omit_final_dot=True, idna_codec=IDNA_2008_UTS_46 + ) rtypes = ["A"] if param_tools.get_global_parameter("enable_ipv6_mx_checks", app="admin"): rtypes.append("AAAA") @@ -239,11 +243,11 @@ def get_domain_mx_list(domain): mx_ip = ipaddress.ip_address(address_smart) except ValueError as e: logger.warning( - _("Invalid IP address format for " - "{domain}; {addr}").format( - domain=mx_domain, - addr=smart_str(ip_answer.address) - ), exc_info=e) + _("Invalid IP address format for " "{domain}; {addr}").format( + domain=mx_domain, addr=smart_str(ip_answer.address) + ), + exc_info=e, + ) else: result.append((mx_domain, mx_ip)) return result @@ -252,8 +256,11 @@ def get_domain_mx_list(domain): def domain_has_authorized_mx(name): """Check if domain has authorized mx record at least.""" valid_mxs = param_tools.get_global_parameter("valid_mxs") - valid_mxs = [ipaddress.ip_network(smart_str(v.strip())) - for v in valid_mxs.split() if v.strip()] + valid_mxs = [ + ipaddress.ip_network(smart_str(v.strip())) + for v in valid_mxs.split() + if v.strip() + ] domain_mxs = get_domain_mx_list(name) for _mx_addr, mx_ip_addr in domain_mxs: for subnet in valid_mxs: @@ -264,13 +271,12 @@ def domain_has_authorized_mx(name): def make_password(): """Create a random password.""" - length = int( - param_tools.get_global_parameter("random_password_length", app="core") - ) + length = int(param_tools.get_global_parameter("random_password_length", app="core")) while True: password = "".join( - random.SystemRandom().choice( - string.ascii_letters + string.digits) for _ in range(length)) + random.SystemRandom().choice(string.ascii_letters + string.digits) + for _ in range(length) + ) try: password_validation.validate_password(password) except ValidationError: @@ -297,7 +303,8 @@ def import_data(user, file_object, options: dict): if not row: continue fct = signals.import_object.send( - sender="importdata", objtype=row[0].strip()) + sender="importdata", objtype=row[0].strip() + ) fct = [func for x_, func in fct if func is not None] if not fct: continue @@ -315,6 +322,6 @@ def import_data(user, file_object, options: dict): cpt += 1 msg = _("%d objects imported successfully") % cpt return True, msg - except (ModoboaException) as e: + except ModoboaException as e: error = str(e) return False, error diff --git a/modoboa/admin/management/commands/handle_mailbox_operations.py b/modoboa/admin/management/commands/handle_mailbox_operations.py index b7d9c3b99..bfa527c76 100644 --- a/modoboa/admin/management/commands/handle_mailbox_operations.py +++ b/modoboa/admin/management/commands/handle_mailbox_operations.py @@ -31,8 +31,9 @@ class Command(BaseCommand): def add_arguments(self, parser): """Add extra arguments to command line.""" parser.add_argument( - "--pidfile", default="/tmp/handle_mailbox_operations.pid", - help="Path to the file that will contain the PID of this process" + "--pidfile", + default="/tmp/handle_mailbox_operations.pid", + help="Path to the file that will contain the PID of this process", ) def rename_mailbox(self, operation): @@ -45,9 +46,7 @@ class Command(BaseCommand): os.makedirs(dirname) except os.error as e: raise OperationError(str(e)) - code, output = exec_cmd( - "mv %s %s" % (operation.argument, new_mail_home) - ) + code, output = exec_cmd("mv %s %s" % (operation.argument, new_mail_home)) if code: raise OperationError(output) @@ -58,8 +57,7 @@ class Command(BaseCommand): def onerror(function, path, excinfo): """Handle errors.""" - self.logger.critical( - "delete failed (reason: {})".format(excinfo)) + self.logger.critical("delete failed (reason: {})".format(excinfo)) shutil.rmtree(operation.argument, False, onerror) @@ -97,7 +95,8 @@ class Command(BaseCommand): f(ope) except (OperationError, InternalError) as e: self.logger.critical( - "%s failed (reason: %s)", ope, str(e).decode("utf-8")) + "%s failed (reason: %s)", ope, str(e).decode("utf-8") + ) else: self.logger.info("%s succeed", ope) ope.delete() diff --git a/modoboa/admin/management/commands/modo.py b/modoboa/admin/management/commands/modo.py index 295b09062..a5ce79284 100644 --- a/modoboa/admin/management/commands/modo.py +++ b/modoboa/admin/management/commands/modo.py @@ -26,9 +26,7 @@ class Command(BaseCommand): } def add_arguments(self, parser): - subparsers = parser.add_subparsers( - dest='subcommand', title='subcommands' - ) + subparsers = parser.add_subparsers(dest="subcommand", title="subcommands") # required argument is added in Python 3.7 subparsers.required = True @@ -36,9 +34,7 @@ class Command(BaseCommand): command = command_class(self.stdout, self.stderr) command.style = self.style - subparser = subparsers.add_parser( - command_name, help=command_class.help - ) + subparser = subparsers.add_parser(command_name, help=command_class.help) # This is needed to output console friendly errors subparser.called_from_command_line = self._called_from_command_line @@ -47,4 +43,4 @@ class Command(BaseCommand): subparser.set_defaults(command=command) def execute(self, *args, **options): - return options.pop('command').execute(*args, **options) + return options.pop("command").execute(*args, **options) diff --git a/modoboa/admin/management/commands/subcommands/_export.py b/modoboa/admin/management/commands/subcommands/_export.py index 694035adb..a01df74b2 100644 --- a/modoboa/admin/management/commands/subcommands/_export.py +++ b/modoboa/admin/management/commands/subcommands/_export.py @@ -18,12 +18,18 @@ class ExportCommand(BaseCommand): def add_arguments(self, parser): """Add arguments to command.""" parser.add_argument( - "--sepchar", type=str, dest="sepchar", default=";", - help="Separator used in generated file." + "--sepchar", + type=str, + dest="sepchar", + default=";", + help="Separator used in generated file.", ) parser.add_argument( - "objtype", type=str, choices=["domains", "identities"], - help="The type of object to export (domains or identities)") + "objtype", + type=str, + choices=["domains", "identities"], + help="The type of object to export (domains or identities)", + ) def export_domains(self): """Export all domains.""" @@ -39,7 +45,8 @@ class ExportCommand(BaseCommand): qset = ( models.Alias.objects.filter(internal=False) .exclude(alias_recipient_aliases=None) - .distinct().prefetch_related("aliasrecipient_set") + .distinct() + .prefetch_related("aliasrecipient_set") ) for alias in qset: alias.to_csv(self.csvwriter) @@ -56,5 +63,6 @@ class ExportCommand(BaseCommand): def handle(self, *args, **options): exts_pool.load_all() self.csvwriter = csv.writer( - self.stdout, delimiter=smart_str(options["sepchar"])) + self.stdout, delimiter=smart_str(options["sepchar"]) + ) getattr(self, "export_{}".format(options["objtype"]))() diff --git a/modoboa/admin/management/commands/subcommands/_import.py b/modoboa/admin/management/commands/subcommands/_import.py index 1f1e57e8b..0be4e2575 100644 --- a/modoboa/admin/management/commands/subcommands/_import.py +++ b/modoboa/admin/management/commands/subcommands/_import.py @@ -27,33 +27,33 @@ class ImportCommand(BaseCommand): def add_arguments(self, parser): """Add extra arguments to command.""" parser.add_argument( - "--sepchar", type=str, default=";", - help="Separator used in file.") + "--sepchar", type=str, default=";", help="Separator used in file." + ) parser.add_argument( - "--continue-if-exists", action="store_true", - dest="continue_if_exists", default=False, - help="Continue even if an entry already exists.") + "--continue-if-exists", + action="store_true", + dest="continue_if_exists", + default=False, + help="Continue even if an entry already exists.", + ) parser.add_argument( - "--crypt-password", action="store_true", - default=False, help="Encrypt provided passwords.") - parser.add_argument( - "files", type=str, nargs="+", help="CSV files to import.") + "--crypt-password", + action="store_true", + default=False, + help="Encrypt provided passwords.", + ) + parser.add_argument("files", type=str, nargs="+", help="CSV files to import.") def _import(self, filename, options, encoding="utf-8"): """Import domains or identities.""" - superadmin = ( - core_models.User.objects.filter(is_superuser=True).first() - ) + superadmin = core_models.User.objects.filter(is_superuser=True).first() if not os.path.isfile(filename): raise CommandError("File not found") - num_lines = sum( - 1 for line in io.open(filename, encoding=encoding) if line - ) + num_lines = sum(1 for line in io.open(filename, encoding=encoding) if line) pbar = progressbar.ProgressBar( - widgets=[ - progressbar.Percentage(), progressbar.Bar(), progressbar.ETA() - ], maxval=num_lines + widgets=[progressbar.Percentage(), progressbar.Bar(), progressbar.ETA()], + maxval=num_lines, ).start() with io.open(filename, encoding=encoding, newline="") as f: reader = csv.reader(f, delimiter=options["sepchar"]) @@ -62,7 +62,8 @@ class ImportCommand(BaseCommand): if not row: continue fct = signals.import_object.send( - sender=self.__class__, objtype=row[0].strip()) + sender=self.__class__, objtype=row[0].strip() + ) fct = [func for x_, func in fct if func is not None] if not fct: continue @@ -74,7 +75,9 @@ class ImportCommand(BaseCommand): continue raise CommandError( "Object already exists at line {}: {}".format( - i+1, options["sepchar"].join(row[:2]))) + i + 1, options["sepchar"].join(row[:2]) + ) + ) i += 1 pbar.update(i) @@ -90,10 +93,14 @@ class ImportCommand(BaseCommand): except CommandError as exc: raise exc except UnicodeDecodeError: - self.stdout.write(self.style.NOTICE( - _("CSV file is not encoded in UTF-8, attempting to guess " - "encoding") - )) + self.stdout.write( + self.style.NOTICE( + _( + "CSV file is not encoded in UTF-8, attempting to guess " + "encoding" + ) + ) + ) detector = UniversalDetector() with io.open(filename, "rb") as fp: for line in fp: @@ -102,18 +109,19 @@ class ImportCommand(BaseCommand): break detector.close() - self.stdout.write(self.style.NOTICE( - _("Reading CSV file using %(encoding)s encoding") % - detector.result - )) + self.stdout.write( + self.style.NOTICE( + _("Reading CSV file using %(encoding)s encoding") + % detector.result + ) + ) try: with transaction.atomic(): self._import( - filename, options, - encoding=detector.result["encoding"] + filename, options, encoding=detector.result["encoding"] ) except UnicodeDecodeError as exc: raise CommandError( - _("Unable to decode CSV file using %(encoding)s " - "encoding") % detector.result + _("Unable to decode CSV file using %(encoding)s " "encoding") + % detector.result ) from exc diff --git a/modoboa/admin/management/commands/subcommands/_manage_dkim_keys.py b/modoboa/admin/management/commands/subcommands/_manage_dkim_keys.py index e528809ed..7f5a61275 100644 --- a/modoboa/admin/management/commands/subcommands/_manage_dkim_keys.py +++ b/modoboa/admin/management/commands/subcommands/_manage_dkim_keys.py @@ -25,8 +25,8 @@ class ManageDKIMKeys(BaseCommand): if not os.access(storage_dir, os.W_OK): if not alarm_qset.exists(): domain.alarms.create( - title=_("DKIM path non-writable"), - internal_name=DKIM_WRITE_ERROR) + title=_("DKIM path non-writable"), internal_name=DKIM_WRITE_ERROR + ) else: alarm = alarm_qset.first() if alarm.status != ALARM_OPENED: @@ -35,19 +35,27 @@ class ManageDKIMKeys(BaseCommand): elif alarm_qset.exists(): alarm_qset.first().close() key_size = ( - domain.dkim_key_length if domain.dkim_key_length - else self.default_key_length) + domain.dkim_key_length + if domain.dkim_key_length + else self.default_key_length + ) code, output = sysutils.exec_cmd( - "openssl genrsa -out {} {}".format(pkey_path, key_size)) + "openssl genrsa -out {} {}".format(pkey_path, key_size) + ) if code: - print("Failed to generate DKIM private key for domain {}: {}" - .format(domain.name, smart_str(output))) + print( + "Failed to generate DKIM private key for domain {}: {}".format( + domain.name, smart_str(output) + ) + ) domain.dkim_private_key_path = pkey_path - code, output = sysutils.exec_cmd( - "openssl rsa -in {} -pubout".format(pkey_path)) + code, output = sysutils.exec_cmd("openssl rsa -in {} -pubout".format(pkey_path)) if code: - print("Failed to generate DKIM public key for domain {}: {}" - .format(domain.name, smart_str(output))) + print( + "Failed to generate DKIM public key for domain {}: {}".format( + domain.name, smart_str(output) + ) + ) public_key = "" for cpt, line in enumerate(smart_str(output).splitlines()): if cpt == 0 or line.startswith("-----"): @@ -59,24 +67,27 @@ class ManageDKIMKeys(BaseCommand): def add_arguments(self, parser): """Add arguments to command.""" parser.add_argument( - "--domain", type=str, dest="domain", default="", - help="Domain target for keys generation." + "--domain", + type=str, + dest="domain", + default="", + help="Domain target for keys generation.", ) def handle(self, *args, **options): """Entry point.""" self.default_key_length = param_tools.get_global_parameter( - "dkim_default_key_length") + "dkim_default_key_length" + ) if options["domain"] != "": - domain = models.Domain.objects.filter(name=options["domain"], - enable_dkim=True, - dkim_private_key_path="") + domain = models.Domain.objects.filter( + name=options["domain"], enable_dkim=True, dkim_private_key_path="" + ) if domain.exists(): self.create_new_dkim_key(domain[0]) return - qset = models.Domain.objects.filter( - enable_dkim=True, dkim_private_key_path="") + qset = models.Domain.objects.filter(enable_dkim=True, dkim_private_key_path="") for domain in qset: self.create_new_dkim_key(domain) diff --git a/modoboa/admin/management/commands/subcommands/_mx.py b/modoboa/admin/management/commands/subcommands/_mx.py index 41fd9a349..a2d365da1 100644 --- a/modoboa/admin/management/commands/subcommands/_mx.py +++ b/modoboa/admin/management/commands/subcommands/_mx.py @@ -40,30 +40,41 @@ class CheckMXRecords(BaseCommand): def valid_mxs(self): """Return valid MXs set in admin.""" valid_mxs = param_tools.get_global_parameter("valid_mxs") - return [ipaddress.ip_network(smart_str(v.strip())) - for v in valid_mxs.split() if v.strip()] + return [ + ipaddress.ip_network(smart_str(v.strip())) + for v in valid_mxs.split() + if v.strip() + ] def add_arguments(self, parser): """Add extra arguments to command.""" parser.add_argument( - "--no-dnsbl", action="store_true", default=False, - help="Skip DNSBL queries.") + "--no-dnsbl", action="store_true", default=False, help="Skip DNSBL queries." + ) parser.add_argument( - "--email", type=str, action="append", default=[], - help="One or more email to notify") + "--email", + type=str, + action="append", + default=[], + help="One or more email to notify", + ) parser.add_argument( - "--skip-admin-emails", action="store_true", + "--skip-admin-emails", + action="store_true", default=False, - help="Skip domain's admins email notification.") + help="Skip domain's admins email notification.", + ) parser.add_argument( - "--domain", type=str, action="append", default=[], - help="Domain name or id to update.") + "--domain", + type=str, + action="append", + default=[], + help="Domain name or id to update.", + ) parser.add_argument( - "--timeout", type=int, default=3, - help="Timeout used for queries.") - parser.add_argument( - "--ttl", type=int, default=7200, - help="TTL for dns query.") + "--timeout", type=int, default=3, help="Timeout used for queries." + ) + parser.add_argument("--ttl", type=int, default=7200, help="TTL for dns query.") def query_dnsbl(self, mx_list, provider): """Check given IP against given DNSBL provider.""" @@ -79,10 +90,10 @@ class CheckMXRecords(BaseCommand): pattern = "{}.{}.".format(reverse, provider) try: result = socket.gethostbyname(pattern) - #result from dnsbl is in ipv4 format + # result from dnsbl is in ipv4 format splited_result = result.split(".") if int(splited_result[-1]) > 15: - #Typical dnsbl result : 127.0.0.[1-15] (depends on services) + # Typical dnsbl result : 127.0.0.[1-15] (depends on services) result = False except socket.gaierror: result = False @@ -101,13 +112,14 @@ class CheckMXRecords(BaseCommand): if not result: result = "" dnsbl_result = models.DNSBLResult.objects.filter( - domain=domain, provider=provider, mx=mx).first() + domain=domain, provider=provider, mx=mx + ).first() trigger = False if dnsbl_result is None: to_create.append( models.DNSBLResult( - domain=domain, provider=provider, mx=mx, - status=result) + domain=domain, provider=provider, mx=mx, status=result + ) ) if result: trigger = True @@ -118,22 +130,15 @@ class CheckMXRecords(BaseCommand): trigger = True alarm_name = "domain_mx_in_dnsbl_{}".format(provider) if trigger: - title = _("MX {} listed by DNSBL provider {}").format( - mx.name, provider) + title = _("MX {} listed by DNSBL provider {}").format(mx.name, provider) domain.alarms.create( - internal_name=alarm_name, - status=constants.ALARM_OPENED, - title=title + internal_name=alarm_name, status=constants.ALARM_OPENED, title=title ) alerts.append((provider, mx.name)) else: domain.alarms.filter( - internal_name=alarm_name, - status=constants.ALARM_OPENED - ).update( - status=constants.ALARM_CLOSED, - closed=timezone.now() - ) + internal_name=alarm_name, status=constants.ALARM_OPENED + ).update(status=constants.ALARM_CLOSED, closed=timezone.now()) models.DNSBLResult.objects.bulk_create(to_create) return alerts @@ -142,8 +147,9 @@ class CheckMXRecords(BaseCommand): emails = list(options["email"]) if not options["skip_admin_emails"]: emails.extend( - domain.admins.exclude(mailbox__isnull=True) - .values_list("email", flat=True) + domain.admins.exclude(mailbox__isnull=True).values_list( + "email", flat=True + ) ) if not len(emails): return @@ -159,24 +165,21 @@ class CheckMXRecords(BaseCommand): """ alerts = [] check = False - mxs = [(mx, ipaddress.ip_address("%s" % mx.address)) - for mx in mx_list] + mxs = [(mx, ipaddress.ip_address("%s" % mx.address)) for mx in mx_list] valid_mxs = self.valid_mxs if not mxs: alarm, created = domain.alarms.get_or_create( internal_name="domain_has_no_mx", status=constants.ALARM_OPENED, - defaults={"title": _("Domain has no MX record")} + defaults={"title": _("Domain has no MX record")}, ) if created: - alerts.append( - _("Domain {} has no MX record").format(domain.name)) + alerts.append(_("Domain {} has no MX record").format(domain.name)) else: # Close opened alarm domain.alarms.filter( - internal_name="domain_has_no_mx", - status=constants.ALARM_OPENED).update( - status=constants.ALARM_CLOSED, closed=timezone.now()) + internal_name="domain_has_no_mx", status=constants.ALARM_OPENED + ).update(status=constants.ALARM_CLOSED, closed=timezone.now()) if valid_mxs: for subnet in valid_mxs: for mx, addr in mxs: @@ -184,67 +187,62 @@ class CheckMXRecords(BaseCommand): mx.managed = check = True mx.save() if check is False: - mx_names = [ - "{0.name} ({0.address})".format(mx) for mx in mx_list] + mx_names = ["{0.name} ({0.address})".format(mx) for mx in mx_list] alarm, created = domain.alarms.get_or_create( internal_name="domain_invalid_mx", status=constants.ALARM_OPENED, defaults={ "title": _("Invalid MX record: {}").format( - ", ".join(mx_names)) - } + ", ".join(mx_names) + ) + }, ) if created: alerts.append( - _("MX record for domain {0} is invalid: {1}") - .format(domain, ", ".join(mx_names)) + _("MX record for domain {0} is invalid: {1}").format( + domain, ", ".join(mx_names) + ) ) else: # Close opened alarm domain.alarms.filter( - internal_name="domain_invalid_mx", - status=constants.ALARM_OPENED - ).update( - status=constants.ALARM_CLOSED, - closed=timezone.now() - ) + internal_name="domain_invalid_mx", status=constants.ALARM_OPENED + ).update(status=constants.ALARM_CLOSED, closed=timezone.now()) if not alerts: return - subject = _("[modoboa] MX issue(s) for domain {}").format( - domain.name) + subject = _("[modoboa] MX issue(s) for domain {}").format(domain.name) tpl = "admin/notifications/domain_invalid_mx.html" self.send_alert_notifications(domain, alerts, subject, tpl, **options) def check_domain(self, domain, timeout=3, ttl=7200, **options): """Check specified domain.""" - mx_list = list( - models.MXRecord.objects.get_or_create_for_domain(domain, ttl)) + mx_list = list(models.MXRecord.objects.get_or_create_for_domain(domain, ttl)) if param_tools.get_global_parameter("enable_mx_checks"): self.check_valid_mx(domain, mx_list, **options) if param_tools.get_global_parameter("enable_spf_checks"): - dns_models.DNSRecord.objects.get_or_create_for_domain( - domain, "spf", ttl) + dns_models.DNSRecord.objects.get_or_create_for_domain(domain, "spf", ttl) condition = ( - param_tools.get_global_parameter("enable_dkim_checks") and - domain.dkim_public_key + param_tools.get_global_parameter("enable_dkim_checks") + and domain.dkim_public_key ) if condition: - dns_models.DNSRecord.objects.get_or_create_for_domain( - domain, "dkim", ttl) + dns_models.DNSRecord.objects.get_or_create_for_domain(domain, "dkim", ttl) if param_tools.get_global_parameter("enable_dmarc_checks"): - dns_models.DNSRecord.objects.get_or_create_for_domain( - domain, "dmarc", ttl) + dns_models.DNSRecord.objects.get_or_create_for_domain(domain, "dmarc", ttl) if param_tools.get_global_parameter("enable_autoconfig_checks"): dns_models.DNSRecord.objects.get_or_create_for_domain( - domain, "autoconfig", ttl) + domain, "autoconfig", ttl + ) dns_models.DNSRecord.objects.get_or_create_for_domain( - domain, "autodiscover", ttl) + domain, "autodiscover", ttl + ) condition = ( - not param_tools.get_global_parameter("enable_dnsbl_checks") or - options["no_dnsbl"] is True) + not param_tools.get_global_parameter("enable_dnsbl_checks") + or options["no_dnsbl"] is True + ) if condition or not mx_list: return @@ -257,27 +255,25 @@ class CheckMXRecords(BaseCommand): jobs = [ gevent.spawn(self.query_dnsbl, mx_by_ip, provider) - for provider in self.providers] + for provider in self.providers + ] gevent.joinall(jobs, timeout) alerts = [] for job in jobs: if not job.successful(): continue provider, results = job.value - alerts += self.store_dnsbl_result( - domain, provider, results, **options) + alerts += self.store_dnsbl_result(domain, provider, results, **options) if not alerts: return - subject = _("[modoboa] DNSBL issue(s) for domain {}").format( - domain.name) + subject = _("[modoboa] DNSBL issue(s) for domain {}").format(domain.name) tpl = "admin/notifications/domain_in_dnsbl.html" self.send_alert_notifications(domain, alerts, subject, tpl, **options) def handle(self, *args, **options): """Command entry point.""" # Remove deprecated records first - models.DNSBLResult.objects.exclude( - provider__in=self.providers).delete() + models.DNSBLResult.objects.exclude(provider__in=self.providers).delete() if options["domain"]: domains = [] @@ -290,8 +286,7 @@ class CheckMXRecords(BaseCommand): except models.Domain.DoesNotExist: pass else: - domains = models.Domain.objects.filter( - enabled=True, enable_dns_checks=True) + domains = models.Domain.objects.filter(enabled=True, enable_dns_checks=True) options.pop("domain") diff --git a/modoboa/admin/management/commands/subcommands/_repair.py b/modoboa/admin/management/commands/subcommands/_repair.py index 7cc8178a6..5a921d6ce 100644 --- a/modoboa/admin/management/commands/subcommands/_repair.py +++ b/modoboa/admin/management/commands/subcommands/_repair.py @@ -33,8 +33,7 @@ def fix_owner(qs, dry_run=False, **options): log(" {cls} {obj} has no owner".format(**kw), **options) continue if isinstance(obj, User): - admin = User.objects.filter( - is_superuser=True, is_active=True).first() + admin = User.objects.filter(is_superuser=True, is_active=True).first() elif isinstance(obj, models.Domain): admin = obj.admins.first() elif isinstance(obj, models.DomainAlias): @@ -43,12 +42,10 @@ def fix_owner(qs, dry_run=False, **options): admin = obj.domain.admins.first() if not admin: # Fallback: use the first superuser found - admin = User.objects.filter( - is_superuser=True, is_active=True).first() + admin = User.objects.filter(is_superuser=True, is_active=True).first() grant_access_to_object(admin, obj, is_owner=True) kw["admin"] = admin - log(" {cls} {obj} is now owned by {admin}".format(**kw), - **options) + log(" {cls} {obj} is now owned by {admin}".format(**kw), **options) @known_problem @@ -72,22 +69,24 @@ def sometimes_mailbox_have_no_alias(**options): recipient_created = 0 for instance in models.Mailbox.objects.select_related("domain").all(): alias, created = models.Alias.objects.get_or_create( - address=instance.full_address, - domain=instance.domain, - internal=True) + address=instance.full_address, domain=instance.domain, internal=True + ) if created: alias_created += 1 log("Alias {0} created".format(alias), **options) recipient, created = models.AliasRecipient.objects.get_or_create( - alias=alias, - address=instance.full_address, - r_mailbox=instance) + alias=alias, address=instance.full_address, r_mailbox=instance + ) if created: recipient_created += 1 log("AliasRecipient {0} created".format(recipient), **options) if alias_created or recipient_created: - log("{0} alias created. {1} alias recipient created".format( - alias_created, recipient_created), **options) + log( + "{0} alias created. {1} alias recipient created".format( + alias_created, recipient_created + ), + **options, + ) class Repair(BaseCommand): @@ -98,21 +97,21 @@ class Repair(BaseCommand): def add_arguments(self, parser): """Add extra arguments to command.""" parser.add_argument( - "--dry-run", action="store_true", default=False, - help="List known problems without fixing them.") + "--dry-run", + action="store_true", + default=False, + help="List known problems without fixing them.", + ) parser.add_argument( - "--quiet", action="store_true", default=False, - help="Quiet mode.") + "--quiet", action="store_true", default=False, help="Quiet mode." + ) def handle(self, *args, **options): """Command entry point.""" # Load known problems from extensions. for ext in settings.MODOBOA_APPS: try: - __import__( - ext, locals(), globals(), - [smart_str("known_problems")] - ) + __import__(ext, locals(), globals(), [smart_str("known_problems")]) except ImportError: pass for func in known_problems: diff --git a/modoboa/admin/migrations/0001_initial.py b/modoboa/admin/migrations/0001_initial.py index 09a6edb57..b6ccc300e 100644 --- a/modoboa/admin/migrations/0001_initial.py +++ b/modoboa/admin/migrations/0001_initial.py @@ -10,158 +10,304 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name='Alias', + name="Alias", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('address', models.CharField(help_text='The alias address.', max_length=254, verbose_name='address')), - ('enabled', models.BooleanField(default=True, help_text='Check to activate this alias', verbose_name='enabled')), - ('internal', models.BooleanField(default=False)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ( + "address", + models.CharField( + help_text="The alias address.", + max_length=254, + verbose_name="address", + ), + ), + ( + "enabled", + models.BooleanField( + default=True, + help_text="Check to activate this alias", + verbose_name="enabled", + ), + ), + ("internal", models.BooleanField(default=False)), ], options={ - 'ordering': ['address'], + "ordering": ["address"], }, bases=(models.Model,), ), migrations.CreateModel( - name='AliasRecipient', + name="AliasRecipient", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('address', models.EmailField(max_length=75)), - ('alias', models.ForeignKey(to='admin.Alias', on_delete=models.CASCADE)), - ('r_alias', models.ForeignKey(related_name='alias_recipient_aliases', blank=True, to='admin.Alias', null=True, on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("address", models.EmailField(max_length=75)), + ( + "alias", + models.ForeignKey(to="admin.Alias", on_delete=models.CASCADE), + ), + ( + "r_alias", + models.ForeignKey( + related_name="alias_recipient_aliases", + blank=True, + to="admin.Alias", + null=True, + on_delete=models.CASCADE, + ), + ), ], options={ - 'db_table': 'modoboa_admin_aliasrecipient', + "db_table": "modoboa_admin_aliasrecipient", }, bases=(models.Model,), ), migrations.CreateModel( - name='Domain', + name="Domain", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(help_text='The domain name', unique=True, max_length=100, verbose_name='name')), - ('quota', models.IntegerField()), - ('enabled', models.BooleanField(default=True, help_text='Check to activate this domain', verbose_name='enabled')), - ('type', models.CharField(default=b'domain', max_length=20)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ( + "name", + models.CharField( + help_text="The domain name", + unique=True, + max_length=100, + verbose_name="name", + ), + ), + ("quota", models.IntegerField()), + ( + "enabled", + models.BooleanField( + default=True, + help_text="Check to activate this domain", + verbose_name="enabled", + ), + ), + ("type", models.CharField(default=b"domain", max_length=20)), ], options={ - 'ordering': ['name'], + "ordering": ["name"], }, bases=(models.Model,), ), migrations.CreateModel( - name='DomainAlias', + name="DomainAlias", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(help_text='The alias name', unique=True, max_length=100, verbose_name='name')), - ('enabled', models.BooleanField(default=True, help_text='Check to activate this alias', verbose_name='enabled')), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ( + "name", + models.CharField( + help_text="The alias name", + unique=True, + max_length=100, + verbose_name="name", + ), + ), + ( + "enabled", + models.BooleanField( + default=True, + help_text="Check to activate this alias", + verbose_name="enabled", + ), + ), ], bases=(models.Model,), ), migrations.CreateModel( - name='Mailbox', + name="Mailbox", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('address', models.CharField(help_text='Mailbox address (without the @domain.tld part)', max_length=252, verbose_name='address')), - ('quota', models.PositiveIntegerField()), - ('use_domain_quota', models.BooleanField(default=False)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ( + "address", + models.CharField( + help_text="Mailbox address (without the @domain.tld part)", + max_length=252, + verbose_name="address", + ), + ), + ("quota", models.PositiveIntegerField()), + ("use_domain_quota", models.BooleanField(default=False)), ], bases=(models.Model,), ), migrations.CreateModel( - name='MailboxOperation', + name="MailboxOperation", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('type', models.CharField(max_length=20, choices=[(b'rename', b'rename'), (b'delete', b'delete')])), - ('argument', models.TextField()), - ('mailbox', models.ForeignKey(blank=True, to='admin.Mailbox', null=True, on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ( + "type", + models.CharField( + max_length=20, + choices=[(b"rename", b"rename"), (b"delete", b"delete")], + ), + ), + ("argument", models.TextField()), + ( + "mailbox", + models.ForeignKey( + blank=True, + to="admin.Mailbox", + null=True, + on_delete=models.CASCADE, + ), + ), ], - options={ - }, + options={}, bases=(models.Model,), ), migrations.CreateModel( - name='ObjectDates', + name="ObjectDates", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('creation', models.DateTimeField(auto_now_add=True)), - ('last_modification', models.DateTimeField(auto_now=True)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("creation", models.DateTimeField(auto_now_add=True)), + ("last_modification", models.DateTimeField(auto_now=True)), ], - options={ - }, + options={}, bases=(models.Model,), ), migrations.CreateModel( - name='Quota', + name="Quota", fields=[ - ('username', models.EmailField(max_length=254, serialize=False, primary_key=True)), - ('bytes', models.BigIntegerField(default=0)), - ('messages', models.IntegerField(default=0)), + ( + "username", + models.EmailField( + max_length=254, serialize=False, primary_key=True + ), + ), + ("bytes", models.BigIntegerField(default=0)), + ("messages", models.IntegerField(default=0)), ], - options={ - }, + options={}, bases=(models.Model,), ), migrations.AddField( - model_name='mailbox', - name='dates', - field=models.ForeignKey(to='admin.ObjectDates', on_delete=models.CASCADE), + model_name="mailbox", + name="dates", + field=models.ForeignKey(to="admin.ObjectDates", on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( - model_name='mailbox', - name='domain', - field=models.ForeignKey(to='admin.Domain', on_delete=models.CASCADE), + model_name="mailbox", + name="domain", + field=models.ForeignKey(to="admin.Domain", on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( - model_name='mailbox', - name='user', - field=models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), + model_name="mailbox", + name="user", + field=models.OneToOneField( + to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE + ), preserve_default=True, ), migrations.AddField( - model_name='domainalias', - name='dates', - field=models.ForeignKey(to='admin.ObjectDates', on_delete=models.CASCADE), + model_name="domainalias", + name="dates", + field=models.ForeignKey(to="admin.ObjectDates", on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( - model_name='domainalias', - name='target', - field=models.ForeignKey(verbose_name='target', to='admin.Domain', help_text='The domain this alias points to', on_delete=models.CASCADE), + model_name="domainalias", + name="target", + field=models.ForeignKey( + verbose_name="target", + to="admin.Domain", + help_text="The domain this alias points to", + on_delete=models.CASCADE, + ), preserve_default=True, ), migrations.AddField( - model_name='domain', - name='dates', - field=models.ForeignKey(to='admin.ObjectDates', on_delete=models.CASCADE), + model_name="domain", + name="dates", + field=models.ForeignKey(to="admin.ObjectDates", on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( - model_name='aliasrecipient', - name='r_mailbox', - field=models.ForeignKey(blank=True, to='admin.Mailbox', null=True, on_delete=models.CASCADE), + model_name="aliasrecipient", + name="r_mailbox", + field=models.ForeignKey( + blank=True, to="admin.Mailbox", null=True, on_delete=models.CASCADE + ), preserve_default=True, ), migrations.AlterUniqueTogether( - name='aliasrecipient', - unique_together=set([('alias', 'r_alias'), ('alias', 'r_mailbox')]), + name="aliasrecipient", + unique_together=set([("alias", "r_alias"), ("alias", "r_mailbox")]), ), migrations.AddField( - model_name='alias', - name='dates', - field=models.ForeignKey(to='admin.ObjectDates', on_delete=models.CASCADE), + model_name="alias", + name="dates", + field=models.ForeignKey(to="admin.ObjectDates", on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( - model_name='alias', - name='domain', - field=models.ForeignKey(to='admin.Domain', null=True, on_delete=models.CASCADE), + model_name="alias", + name="domain", + field=models.ForeignKey( + to="admin.Domain", null=True, on_delete=models.CASCADE + ), preserve_default=True, ), migrations.AlterUniqueTogether( - name='alias', - unique_together=set([('address', 'internal')]), + name="alias", + unique_together=set([("address", "internal")]), ), ] diff --git a/modoboa/admin/migrations/0002_migrate_from_modoboa_admin.py b/modoboa/admin/migrations/0002_migrate_from_modoboa_admin.py index 301a6406b..13d831adb 100644 --- a/modoboa/admin/migrations/0002_migrate_from_modoboa_admin.py +++ b/modoboa/admin/migrations/0002_migrate_from_modoboa_admin.py @@ -6,8 +6,7 @@ def rename_and_clean(apps, schema_editor): ContentType = apps.get_model("contenttypes", "ContentType") for ct in ContentType.objects.filter(app_label="admin"): try: - old_ct = ContentType.objects.get( - app_label="modoboa_admin", model=ct.model) + old_ct = ContentType.objects.get(app_label="modoboa_admin", model=ct.model) except ContentType.DoesNotExist: continue old_ct.app_label = "admin" @@ -29,8 +28,8 @@ def rename_and_clean(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('admin', '0001_initial'), - ('contenttypes', '0002_remove_content_type_name'), + ("admin", "0001_initial"), + ("contenttypes", "0002_remove_content_type_name"), ] operations = [ diff --git a/modoboa/admin/migrations/0003_auto_20151118_1215.py b/modoboa/admin/migrations/0003_auto_20151118_1215.py index df92da9f4..59f34eb40 100644 --- a/modoboa/admin/migrations/0003_auto_20151118_1215.py +++ b/modoboa/admin/migrations/0003_auto_20151118_1215.py @@ -4,13 +4,13 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin', '0002_migrate_from_modoboa_admin'), + ("admin", "0002_migrate_from_modoboa_admin"), ] operations = [ migrations.AlterField( - model_name='aliasrecipient', - name='address', + model_name="aliasrecipient", + name="address", field=models.EmailField(max_length=254), ), ] diff --git a/modoboa/admin/migrations/0004_auto_20160914_0907.py b/modoboa/admin/migrations/0004_auto_20160914_0907.py index 6427b4439..fc2870b5d 100644 --- a/modoboa/admin/migrations/0004_auto_20160914_0907.py +++ b/modoboa/admin/migrations/0004_auto_20160914_0907.py @@ -6,59 +6,100 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('admin', '0003_auto_20151118_1215'), + ("admin", "0003_auto_20151118_1215"), ] operations = [ migrations.CreateModel( - name='DNSBLResult', + name="DNSBLResult", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('provider', models.CharField(db_index=True, max_length=254)), - ('status', models.CharField(blank=True, db_index=True, max_length=45)), - ('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='admin.Domain')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("provider", models.CharField(db_index=True, max_length=254)), + ("status", models.CharField(blank=True, db_index=True, max_length=45)), + ( + "domain", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="admin.Domain" + ), + ), ], ), migrations.CreateModel( - name='MXRecord', + name="MXRecord", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=254)), - ('address', models.GenericIPAddressField()), - ('managed', models.BooleanField(default=False)), - ('updated', models.DateTimeField()), - ('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='admin.Domain')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=254)), + ("address", models.GenericIPAddressField()), + ("managed", models.BooleanField(default=False)), + ("updated", models.DateTimeField()), + ( + "domain", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="admin.Domain" + ), + ), ], ), migrations.CreateModel( - name='SenderAddress', + name="SenderAddress", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('address', models.EmailField(max_length=254)), - ('mailbox', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='admin.Mailbox')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("address", models.EmailField(max_length=254)), + ( + "mailbox", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="admin.Mailbox" + ), + ), ], ), migrations.AddField( - model_name='alias', - name='description', + model_name="alias", + name="description", field=models.TextField(blank=True), ), migrations.AddField( - model_name='alias', - name='expire_at', + model_name="alias", + name="expire_at", field=models.DateTimeField(blank=True, null=True), ), migrations.AddField( - model_name='dnsblresult', - name='mx', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='admin.MXRecord'), + model_name="dnsblresult", + name="mx", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="admin.MXRecord" + ), ), migrations.AlterUniqueTogether( - name='senderaddress', - unique_together=set([('address', 'mailbox')]), + name="senderaddress", + unique_together=set([("address", "mailbox")]), ), migrations.AlterUniqueTogether( - name='dnsblresult', - unique_together=set([('domain', 'provider', 'mx')]), + name="dnsblresult", + unique_together=set([("domain", "provider", "mx")]), ), ] diff --git a/modoboa/admin/migrations/0005_auto_20161026_1003.py b/modoboa/admin/migrations/0005_auto_20161026_1003.py index a6c94f83c..feb2a70f7 100644 --- a/modoboa/admin/migrations/0005_auto_20161026_1003.py +++ b/modoboa/admin/migrations/0005_auto_20161026_1003.py @@ -5,18 +5,18 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin', '0004_auto_20160914_0907'), + ("admin", "0004_auto_20160914_0907"), ] operations = [ migrations.AlterField( - model_name='alias', - name='description', - field=models.TextField(blank=True, verbose_name='Description'), + model_name="alias", + name="description", + field=models.TextField(blank=True, verbose_name="Description"), ), migrations.AlterField( - model_name='alias', - name='expire_at', - field=models.DateTimeField(blank=True, null=True, verbose_name='Expire at'), + model_name="alias", + name="expire_at", + field=models.DateTimeField(blank=True, null=True, verbose_name="Expire at"), ), ] diff --git a/modoboa/admin/migrations/0006_auto_20161104_1900.py b/modoboa/admin/migrations/0006_auto_20161104_1900.py index 9b48d6b1a..a8e42a624 100644 --- a/modoboa/admin/migrations/0006_auto_20161104_1900.py +++ b/modoboa/admin/migrations/0006_auto_20161104_1900.py @@ -19,49 +19,49 @@ def move_dates(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('admin', '0005_auto_20161026_1003'), + ("admin", "0005_auto_20161026_1003"), ] operations = [ migrations.AddField( - model_name='alias', - name='creation', + model_name="alias", + name="creation", field=models.DateTimeField(default=django.utils.timezone.now), ), migrations.AddField( - model_name='alias', - name='last_modification', + model_name="alias", + name="last_modification", field=models.DateTimeField(null=True), ), migrations.AddField( - model_name='domain', - name='creation', + model_name="domain", + name="creation", field=models.DateTimeField(default=django.utils.timezone.now), ), migrations.AddField( - model_name='domain', - name='last_modification', + model_name="domain", + name="last_modification", field=models.DateTimeField(null=True), ), migrations.AddField( - model_name='domainalias', - name='creation', + model_name="domainalias", + name="creation", field=models.DateTimeField(default=django.utils.timezone.now), ), migrations.AddField( - model_name='domainalias', - name='last_modification', + model_name="domainalias", + name="last_modification", field=models.DateTimeField(null=True), ), migrations.AddField( - model_name='mailbox', - name='creation', + model_name="mailbox", + name="creation", field=models.DateTimeField(default=django.utils.timezone.now), ), migrations.AddField( - model_name='mailbox', - name='last_modification', + model_name="mailbox", + name="last_modification", field=models.DateTimeField(null=True), ), - migrations.RunPython(move_dates) + migrations.RunPython(move_dates), ] diff --git a/modoboa/admin/migrations/0007_auto_20161104_1915.py b/modoboa/admin/migrations/0007_auto_20161104_1915.py index 318e265a4..fd8dae670 100644 --- a/modoboa/admin/migrations/0007_auto_20161104_1915.py +++ b/modoboa/admin/migrations/0007_auto_20161104_1915.py @@ -5,48 +5,48 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin', '0006_auto_20161104_1900'), - ('relaydomains', '0005_auto_20161105_1426'), + ("admin", "0006_auto_20161104_1900"), + ("relaydomains", "0005_auto_20161105_1426"), ] operations = [ migrations.RemoveField( - model_name='alias', - name='dates', + model_name="alias", + name="dates", ), migrations.RemoveField( - model_name='domain', - name='dates', + model_name="domain", + name="dates", ), migrations.RemoveField( - model_name='domainalias', - name='dates', + model_name="domainalias", + name="dates", ), migrations.RemoveField( - model_name='mailbox', - name='dates', + model_name="mailbox", + name="dates", ), migrations.AlterField( - model_name='alias', - name='last_modification', + model_name="alias", + name="last_modification", field=models.DateTimeField(auto_now=True), ), migrations.AlterField( - model_name='domain', - name='last_modification', + model_name="domain", + name="last_modification", field=models.DateTimeField(auto_now=True), ), migrations.AlterField( - model_name='domainalias', - name='last_modification', + model_name="domainalias", + name="last_modification", field=models.DateTimeField(auto_now=True), ), migrations.AlterField( - model_name='mailbox', - name='last_modification', + model_name="mailbox", + name="last_modification", field=models.DateTimeField(auto_now=True), ), migrations.DeleteModel( - name='ObjectDates', + name="ObjectDates", ), ] diff --git a/modoboa/admin/migrations/0008_domain_enable_dns_checks.py b/modoboa/admin/migrations/0008_domain_enable_dns_checks.py index 974d05025..2c2342a33 100644 --- a/modoboa/admin/migrations/0008_domain_enable_dns_checks.py +++ b/modoboa/admin/migrations/0008_domain_enable_dns_checks.py @@ -5,13 +5,17 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin', '0007_auto_20161104_1915'), + ("admin", "0007_auto_20161104_1915"), ] operations = [ migrations.AddField( - model_name='domain', - name='enable_dns_checks', - field=models.BooleanField(default=True, help_text='Check to enable DNS checks for this domain', verbose_name='Enable DNS checks'), + model_name="domain", + name="enable_dns_checks", + field=models.BooleanField( + default=True, + help_text="Check to enable DNS checks for this domain", + verbose_name="Enable DNS checks", + ), ), ] diff --git a/modoboa/admin/migrations/0009_auto_20170215_0948.py b/modoboa/admin/migrations/0009_auto_20170215_0948.py index 262549b50..3cd3702ed 100644 --- a/modoboa/admin/migrations/0009_auto_20170215_0948.py +++ b/modoboa/admin/migrations/0009_auto_20170215_0948.py @@ -5,13 +5,13 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('admin', '0008_domain_enable_dns_checks'), + ("admin", "0008_domain_enable_dns_checks"), ] operations = [ migrations.RenameField( - model_name='domain', - old_name='quota', - new_name='default_mailbox_quota', + model_name="domain", + old_name="quota", + new_name="default_mailbox_quota", ), ] diff --git a/modoboa/admin/migrations/0010_auto_20170215_1328.py b/modoboa/admin/migrations/0010_auto_20170215_1328.py index bc4535930..ad6ca3d8b 100644 --- a/modoboa/admin/migrations/0010_auto_20170215_1328.py +++ b/modoboa/admin/migrations/0010_auto_20170215_1328.py @@ -5,23 +5,30 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin', '0009_auto_20170215_0948'), + ("admin", "0009_auto_20170215_0948"), ] operations = [ migrations.AddField( - model_name='domain', - name='quota', - field=models.PositiveIntegerField(default=0, help_text='Quota in MB shared between mailboxes. A value of 0 means no quota.'), + model_name="domain", + name="quota", + field=models.PositiveIntegerField( + default=0, + help_text="Quota in MB shared between mailboxes. A value of 0 means no quota.", + ), ), migrations.AlterField( - model_name='domain', - name='default_mailbox_quota', - field=models.PositiveIntegerField(default=0, help_text='Default quota in MB applied to mailboxes. A value of 0 means no quota.', verbose_name='Default mailbox quota'), + model_name="domain", + name="default_mailbox_quota", + field=models.PositiveIntegerField( + default=0, + help_text="Default quota in MB applied to mailboxes. A value of 0 means no quota.", + verbose_name="Default mailbox quota", + ), ), migrations.AlterField( - model_name='mailbox', - name='quota', + model_name="mailbox", + name="quota", field=models.PositiveIntegerField(default=0), ), ] diff --git a/modoboa/admin/migrations/0011_domain_transport.py b/modoboa/admin/migrations/0011_domain_transport.py index 001b23761..9516d06c7 100644 --- a/modoboa/admin/migrations/0011_domain_transport.py +++ b/modoboa/admin/migrations/0011_domain_transport.py @@ -6,14 +6,18 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('transport', '0001_initial'), - ('admin', '0010_auto_20170215_1328'), + ("transport", "0001_initial"), + ("admin", "0010_auto_20170215_1328"), ] operations = [ migrations.AddField( - model_name='domain', - name='transport', - field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='transport.Transport'), + model_name="domain", + name="transport", + field=models.OneToOneField( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="transport.Transport", + ), ), ] diff --git a/modoboa/admin/migrations/0012_auto_20180112_1658.py b/modoboa/admin/migrations/0012_auto_20180112_1658.py index 24bc6f938..71b93b2c9 100644 --- a/modoboa/admin/migrations/0012_auto_20180112_1658.py +++ b/modoboa/admin/migrations/0012_auto_20180112_1658.py @@ -5,33 +5,44 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin', '0011_domain_transport'), + ("admin", "0011_domain_transport"), ] operations = [ migrations.AddField( - model_name='domain', - name='dkim_key_length', - field=models.PositiveIntegerField(blank=True, choices=[(1024, '1024'), (2048, '2048'), (4096, '4096')], null=True, verbose_name='Key length'), + model_name="domain", + name="dkim_key_length", + field=models.PositiveIntegerField( + blank=True, + choices=[(1024, "1024"), (2048, "2048"), (4096, "4096")], + null=True, + verbose_name="Key length", + ), ), migrations.AddField( - model_name='domain', - name='dkim_key_selector', - field=models.CharField(default='modoboa', max_length=30, verbose_name='Key selector'), + model_name="domain", + name="dkim_key_selector", + field=models.CharField( + default="modoboa", max_length=30, verbose_name="Key selector" + ), ), migrations.AddField( - model_name='domain', - name='dkim_private_key_path', + model_name="domain", + name="dkim_private_key_path", field=models.CharField(blank=True, max_length=254), ), migrations.AddField( - model_name='domain', - name='dkim_public_key', + model_name="domain", + name="dkim_public_key", field=models.TextField(blank=True), ), migrations.AddField( - model_name='domain', - name='enable_dkim', - field=models.BooleanField(default=False, help_text='If you activate this feature, a DKIM key will be generated for this domain.', verbose_name='Enable DKIM signing'), + model_name="domain", + name="enable_dkim", + field=models.BooleanField( + default=False, + help_text="If you activate this feature, a DKIM key will be generated for this domain.", + verbose_name="Enable DKIM signing", + ), ), ] diff --git a/modoboa/admin/migrations/0013_auto_20180124_2311.py b/modoboa/admin/migrations/0013_auto_20180124_2311.py index c5bd1d3b5..9985d9b2e 100644 --- a/modoboa/admin/migrations/0013_auto_20180124_2311.py +++ b/modoboa/admin/migrations/0013_auto_20180124_2311.py @@ -5,23 +5,25 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin', '0012_auto_20180112_1658'), + ("admin", "0012_auto_20180112_1658"), ] operations = [ migrations.AlterField( - model_name='domain', - name='dkim_key_selector', - field=models.CharField(default='modoboa', max_length=30), + model_name="domain", + name="dkim_key_selector", + field=models.CharField(default="modoboa", max_length=30), ), migrations.AlterField( - model_name='domain', - name='type', - field=models.CharField(default='domain', max_length=20), + model_name="domain", + name="type", + field=models.CharField(default="domain", max_length=20), ), migrations.AlterField( - model_name='mailboxoperation', - name='type', - field=models.CharField(choices=[('rename', 'rename'), ('delete', 'delete')], max_length=20), + model_name="mailboxoperation", + name="type", + field=models.CharField( + choices=[("rename", "rename"), ("delete", "delete")], max_length=20 + ), ), ] diff --git a/modoboa/admin/migrations/0014_auto_20181017_1628.py b/modoboa/admin/migrations/0014_auto_20181017_1628.py index 73b47d5b8..13d91fbe2 100644 --- a/modoboa/admin/migrations/0014_auto_20181017_1628.py +++ b/modoboa/admin/migrations/0014_auto_20181017_1628.py @@ -5,18 +5,20 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin', '0013_auto_20180124_2311'), + ("admin", "0013_auto_20180124_2311"), ] operations = [ migrations.AlterField( - model_name='domain', - name='default_mailbox_quota', - field=models.PositiveIntegerField(default=0, verbose_name='Default mailbox quota'), + model_name="domain", + name="default_mailbox_quota", + field=models.PositiveIntegerField( + default=0, verbose_name="Default mailbox quota" + ), ), migrations.AlterField( - model_name='domain', - name='quota', + model_name="domain", + name="quota", field=models.PositiveIntegerField(default=0), ), ] diff --git a/modoboa/admin/migrations/0015_rename_view_permissions.py b/modoboa/admin/migrations/0015_rename_view_permissions.py index 744469a87..456db7c75 100644 --- a/modoboa/admin/migrations/0015_rename_view_permissions.py +++ b/modoboa/admin/migrations/0015_rename_view_permissions.py @@ -5,14 +5,14 @@ import sys from django.db import IntegrityError, migrations, transaction VIEW_PERMISSION_CODENAMES = { - 'view_aliases': 'view_alias', - 'view_domaliases': 'view_domainalias', - 'view_mailboxes': 'view_mailbox', + "view_aliases": "view_alias", + "view_domaliases": "view_domainalias", + "view_mailboxes": "view_mailbox", } def rename_view_permissions(apps, schema_editor): - Permission = apps.get_model('auth', 'Permission') + Permission = apps.get_model("auth", "Permission") db_alias = schema_editor.connection.alias # Iterate over permissions and try to rename the codename for perm in Permission.objects.using(db_alias).filter( @@ -36,7 +36,7 @@ def rename_view_permissions(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('admin', '0014_auto_20181017_1628'), + ("admin", "0014_auto_20181017_1628"), ] operations = [ diff --git a/modoboa/admin/migrations/0016_auto_20200602_1201.py b/modoboa/admin/migrations/0016_auto_20200602_1201.py index 4b273fb07..8e2f4351a 100644 --- a/modoboa/admin/migrations/0016_auto_20200602_1201.py +++ b/modoboa/admin/migrations/0016_auto_20200602_1201.py @@ -6,18 +6,28 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin', '0015_rename_view_permissions'), + ("admin", "0015_rename_view_permissions"), ] operations = [ migrations.AddField( - model_name='domain', - name='message_limit', - field=models.PositiveIntegerField(blank=True, help_text='Number of messages this domain can send per day', null=True, verbose_name='Message sending limit'), + model_name="domain", + name="message_limit", + field=models.PositiveIntegerField( + blank=True, + help_text="Number of messages this domain can send per day", + null=True, + verbose_name="Message sending limit", + ), ), migrations.AddField( - model_name='mailbox', - name='message_limit', - field=models.PositiveIntegerField(blank=True, help_text='Number of messages this mailbox can send per day', null=True, verbose_name='Message sending limit'), + model_name="mailbox", + name="message_limit", + field=models.PositiveIntegerField( + blank=True, + help_text="Number of messages this mailbox can send per day", + null=True, + verbose_name="Message sending limit", + ), ), ] diff --git a/modoboa/admin/migrations/0017_alarm.py b/modoboa/admin/migrations/0017_alarm.py index ea955c897..e820ba562 100644 --- a/modoboa/admin/migrations/0017_alarm.py +++ b/modoboa/admin/migrations/0017_alarm.py @@ -8,24 +8,53 @@ import django.utils.timezone class Migration(migrations.Migration): dependencies = [ - ('admin', '0016_auto_20200602_1201'), + ("admin", "0016_auto_20200602_1201"), ] operations = [ migrations.CreateModel( - name='Alarm', + name="Alarm", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(default=django.utils.timezone.now)), - ('closed', models.DateTimeField(blank=True, null=True)), - ('status', models.IntegerField(choices=[(1, 'Opened'), (2, 'Closed')], db_index=True, default=1)), - ('title', models.CharField(max_length=150)), - ('internal_name', models.CharField(max_length=120)), - ('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='alarms', to='admin.Domain')), - ('mailbox', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='alarms', to='admin.Mailbox')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(default=django.utils.timezone.now)), + ("closed", models.DateTimeField(blank=True, null=True)), + ( + "status", + models.IntegerField( + choices=[(1, "Opened"), (2, "Closed")], db_index=True, default=1 + ), + ), + ("title", models.CharField(max_length=150)), + ("internal_name", models.CharField(max_length=120)), + ( + "domain", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="alarms", + to="admin.Domain", + ), + ), + ( + "mailbox", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="alarms", + to="admin.Mailbox", + ), + ), ], options={ - 'ordering': ['created'], + "ordering": ["created"], }, ), ] diff --git a/modoboa/admin/migrations/0018_auto_20201204_0935.py b/modoboa/admin/migrations/0018_auto_20201204_0935.py index 35bdf2f62..4e2503758 100644 --- a/modoboa/admin/migrations/0018_auto_20201204_0935.py +++ b/modoboa/admin/migrations/0018_auto_20201204_0935.py @@ -6,13 +6,13 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin', '0017_alarm'), + ("admin", "0017_alarm"), ] operations = [ migrations.AlterField( - model_name='alarm', - name='title', + model_name="alarm", + name="title", field=models.TextField(), ), ] diff --git a/modoboa/admin/migrations/0019_update_disabled_accounts_aliases.py b/modoboa/admin/migrations/0019_update_disabled_accounts_aliases.py index fe3f727d5..be08bf179 100644 --- a/modoboa/admin/migrations/0019_update_disabled_accounts_aliases.py +++ b/modoboa/admin/migrations/0019_update_disabled_accounts_aliases.py @@ -4,14 +4,13 @@ from django.db import migrations def update_disabled_accounts_aliases(apps, schema_editor): - User = apps.get_model('core', 'User') - Alias = apps.get_model('admin', 'Alias') + User = apps.get_model("core", "User") + Alias = apps.get_model("admin", "Alias") - disabled_accounts = User.objects.filter( - mailbox__isnull=False, is_active=False) + disabled_accounts = User.objects.filter(mailbox__isnull=False, is_active=False) Alias.objects.filter( - address__in=list(disabled_accounts.values_list('email', flat=True)), + address__in=list(disabled_accounts.values_list("email", flat=True)), enabled=True, ).update(enabled=False) @@ -19,8 +18,8 @@ def update_disabled_accounts_aliases(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('admin', '0018_auto_20201204_0935'), - ('core', '0022_user_tfa_enabled'), + ("admin", "0018_auto_20201204_0935"), + ("core", "0022_user_tfa_enabled"), ] operations = [ diff --git a/modoboa/admin/migrations/0020_auto_20210130_2226.py b/modoboa/admin/migrations/0020_auto_20210130_2226.py index ea9e90eb7..a2136047a 100644 --- a/modoboa/admin/migrations/0020_auto_20210130_2226.py +++ b/modoboa/admin/migrations/0020_auto_20210130_2226.py @@ -6,13 +6,18 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('admin', '0019_update_disabled_accounts_aliases'), + ("admin", "0019_update_disabled_accounts_aliases"), ] operations = [ migrations.AlterField( - model_name='domain', - name='name', - field=models.CharField(help_text='The domain name', max_length=253, unique=True, verbose_name='name'), + model_name="domain", + name="name", + field=models.CharField( + help_text="The domain name", + max_length=253, + unique=True, + verbose_name="name", + ), ), ] diff --git a/modoboa/admin/models/__init__.py b/modoboa/admin/models/__init__.py index 0b749b51a..e5a6c1d69 100644 --- a/modoboa/admin/models/__init__.py +++ b/modoboa/admin/models/__init__.py @@ -1,10 +1,7 @@ """Admin models.""" from .alarm import Alarm -from .alias import ( - Alias, - AliasRecipient, - validate_alias_address) +from .alias import Alias, AliasRecipient, validate_alias_address from .base import AdminObject from .domain import Domain from .domain_alias import DomainAlias diff --git a/modoboa/admin/models/alarm.py b/modoboa/admin/models/alarm.py index 1e3575663..15267a609 100644 --- a/modoboa/admin/models/alarm.py +++ b/modoboa/admin/models/alarm.py @@ -20,18 +20,23 @@ class Alarm(models.Model): """A simple alarm to attach to a domain and/or mailbox.""" domain = models.ForeignKey( - "admin.Domain", on_delete=models.CASCADE, related_name="alarms", - blank=True, null=True) - mailbox = models.ForeignKey( - "admin.Mailbox", on_delete=models.SET_NULL, + "admin.Domain", + on_delete=models.CASCADE, related_name="alarms", - null=True, blank=True, + blank=True, + null=True, + ) + mailbox = models.ForeignKey( + "admin.Mailbox", + on_delete=models.SET_NULL, + related_name="alarms", + null=True, + blank=True, ) created = models.DateTimeField(default=timezone.now) closed = models.DateTimeField(null=True, blank=True) status = models.IntegerField( - default=constants.ALARM_OPENED, choices=constants.ALARM_STATUSES, - db_index=True + default=constants.ALARM_OPENED, choices=constants.ALARM_STATUSES, db_index=True ) title = models.TextField() @@ -44,7 +49,8 @@ class Alarm(models.Model): def __str__(self): return "[{}] {} - {}".format( - self.created, self.domain, self.get_status_display()) + self.created, self.domain, self.get_status_display() + ) def close(self): """Close this alarm.""" diff --git a/modoboa/admin/models/alias.py b/modoboa/admin/models/alias.py index 28f48eef8..9d870a9fb 100644 --- a/modoboa/admin/models/alias.py +++ b/modoboa/admin/models/alias.py @@ -6,9 +6,7 @@ import random from django.core.exceptions import ValidationError from django.db import models from django.urls import reverse -from django.utils.encoding import ( - force_bytes, force_str, smart_str -) +from django.utils.encoding import force_bytes, force_str, smart_str from django.utils.translation import gettext as _, gettext_lazy from reversion import revisions as reversion @@ -16,7 +14,11 @@ from reversion import revisions as reversion from modoboa.core import signals as core_signals from modoboa.lib.email_utils import split_mailbox from modoboa.lib.exceptions import ( - BadRequest, Conflict, NotFound, ModoboaException, AliasExists + BadRequest, + Conflict, + NotFound, + ModoboaException, + AliasExists, ) from .. import signals from .base import AdminObject @@ -25,8 +27,8 @@ from .mailbox import Mailbox def validate_alias_address( - address, creator, internal=False, instance=None, ignore_existing=False - ): + address, creator, internal=False, instance=None, ignore_existing=False +): """Check if the given alias address can be created by creator.""" local_part, domain = split_mailbox(address.lower()) domain = Domain.objects.filter(name=domain).first() @@ -36,21 +38,21 @@ def validate_alias_address( raise ValidationError(_("Permission denied.")) if not instance or instance.address != address: alias = Alias.objects.filter(address=address, internal=internal) - condition = ( - alias.exists() - and not ignore_existing - ) + condition = alias.exists() and not ignore_existing if condition: raise AliasExists(alias.first().pk) if instance is None: try: # Check creator limits core_signals.can_create_object.send( - sender="validate_alias_address", context=creator, klass=Alias) + sender="validate_alias_address", context=creator, klass=Alias + ) # Check domain limits core_signals.can_create_object.send( - sender="validate_alias_address", context=domain, - object_type="mailbox_aliases") + sender="validate_alias_address", + context=domain, + object_type="mailbox_aliases", + ) except ModoboaException as inst: raise ValidationError(str(inst)) return local_part, domain @@ -78,10 +80,7 @@ class AliasManager(models.Manager): alias.first().add_recipients(recipients) return self.create( - creator=creator, - domain=domain, - address=address, - recipients=recipients + creator=creator, domain=domain, address=address, recipients=recipients ) @@ -89,29 +88,26 @@ class Alias(AdminObject): """Mailbox alias.""" address = models.CharField( - gettext_lazy("address"), max_length=254, - help_text=gettext_lazy( - "The alias address." - ) + gettext_lazy("address"), + max_length=254, + help_text=gettext_lazy("The alias address."), ) domain = models.ForeignKey(Domain, null=True, on_delete=models.CASCADE) enabled = models.BooleanField( gettext_lazy("enabled"), help_text=gettext_lazy("Check to activate this alias"), - default=True + default=True, ) internal = models.BooleanField(default=False) - description = models.TextField( - gettext_lazy("Description"), blank=True) - expire_at = models.DateTimeField( - gettext_lazy("Expire at"), blank=True, null=True) + description = models.TextField(gettext_lazy("Description"), blank=True) + expire_at = models.DateTimeField(gettext_lazy("Expire at"), blank=True, null=True) _objectname = "MailboxAlias" objects = AliasManager() class Meta: ordering = ["address"] - unique_together = (("address", "internal"), ) + unique_together = (("address", "internal"),) app_label = "admin" def __str__(self): @@ -153,6 +149,7 @@ class Alias(AdminObject): def post_create(self, creator): from modoboa.lib.permissions import grant_access_to_object + super(Alias, self).post_create(creator) if creator.is_superuser: for admin in self.domain.admins: @@ -173,33 +170,32 @@ class Alias(AdminObject): continue if self.aliasrecipient_set.filter(address=address).exists(): continue - local_part, domname, extension = ( - split_mailbox(address, return_extension=True)) + local_part, domname, extension = split_mailbox( + address, return_extension=True + ) if domname is None: - raise BadRequest( - u"%s %s" % (_("Invalid address"), address) - ) + raise BadRequest("%s %s" % (_("Invalid address"), address)) domain = Domain.objects.filter(name=domname).first() kwargs = {"address": address, "alias": self} - if ( - (domain is not None) and - ( - any( - r[1] for r in signals.use_external_recipients.send( - self, recipients=address) - ) is False + if (domain is not None) and ( + any( + r[1] + for r in signals.use_external_recipients.send( + self, recipients=address + ) ) + is False ): - rcpt = Mailbox.objects.filter( - domain=domain, address=local_part).first() + rcpt = Mailbox.objects.filter(domain=domain, address=local_part).first() if rcpt is None: rcpt = Alias.objects.filter( address="%s@%s" % (local_part, domname) ).first() if rcpt is None: raise NotFound( - _("Local recipient {}@{} not found") - .format(local_part, domname) + _("Local recipient {}@{} not found").format( + local_part, domname + ) ) if rcpt.address == self.address: raise Conflict @@ -229,15 +225,13 @@ class Alias(AdminObject): self.add_recipients(address_list) # Remove old recipients - self.aliasrecipient_set.exclude( - address__in=address_list).delete() + self.aliasrecipient_set.exclude(address__in=address_list).delete() @property def recipients(self): """Return the recipient list.""" - return ( - self.aliasrecipient_set.order_by("address") - .values_list("address", flat=True) + return self.aliasrecipient_set.order_by("address").values_list( + "address", flat=True ) @property @@ -245,12 +239,7 @@ class Alias(AdminObject): """Return the number of recipients of this alias.""" return self.aliasrecipient_set.count() - def from_csv(self, - user, - row, - expected_elements=5, - formopts=False, - **kwargs): + def from_csv(self, user, row, expected_elements=5, formopts=False, **kwargs): """Create a new alias from a CSV file entry.""" if len(row) < expected_elements: raise BadRequest(_("Invalid line: {}").format(row)) @@ -264,15 +253,16 @@ class Alias(AdminObject): if formopts: continue_if_exists = formopts.get("continue_if_exists", False) if continue_if_exists: - alias = Alias.objects.filter(address=self.address, - internal=False).first() + alias = Alias.objects.filter( + address=self.address, internal=False + ).first() alias.add_recipients([raddress.strip() for raddress in row[3:]]) alias.save() return else: raise e - self.enabled = (row[2].strip().lower() in ["true", "1", "yes", "y"]) + self.enabled = row[2].strip().lower() in ["true", "1", "yes", "y"] self.save() self.set_recipients([raddress.strip() for raddress in row[3:]]) self.post_create(user) @@ -291,30 +281,29 @@ reversion.register(Alias) class AliasRecipient(models.Model): - """An alias recipient.""" address = models.EmailField() alias = models.ForeignKey(Alias, on_delete=models.CASCADE) # if recipient is a local mailbox - r_mailbox = models.ForeignKey(Mailbox, blank=True, null=True, - on_delete=models.CASCADE) + r_mailbox = models.ForeignKey( + Mailbox, blank=True, null=True, on_delete=models.CASCADE + ) # if recipient is a local alias r_alias = models.ForeignKey( - Alias, related_name="alias_recipient_aliases", blank=True, null=True, - on_delete=models.CASCADE) + Alias, + related_name="alias_recipient_aliases", + blank=True, + null=True, + on_delete=models.CASCADE, + ) class Meta: app_label = "admin" db_table = "modoboa_admin_aliasrecipient" - unique_together = [ - ("alias", "r_mailbox"), - ("alias", "r_alias") - ] + unique_together = [("alias", "r_mailbox"), ("alias", "r_alias")] def __str__(self): """Return alias and recipient.""" - return smart_str( - "{} -> {}".format(self.alias.address, self.address) - ) + return smart_str("{} -> {}".format(self.alias.address, self.address)) diff --git a/modoboa/admin/models/base.py b/modoboa/admin/models/base.py index 8a1d33742..0fc6ef7d3 100644 --- a/modoboa/admin/models/base.py +++ b/modoboa/admin/models/base.py @@ -5,9 +5,7 @@ from django.db import models from django.utils import timezone from modoboa.core import models as core_models -from modoboa.lib.permissions import ( - grant_access_to_object, ungrant_access_to_object -) +from modoboa.lib.permissions import grant_access_to_object, ungrant_access_to_object class AdminObjectManager(models.Manager): diff --git a/modoboa/admin/models/domain.py b/modoboa/admin/models/domain.py index 3cc25bf90..6a84c2f1a 100644 --- a/modoboa/admin/models/domain.py +++ b/modoboa/admin/models/domain.py @@ -23,47 +23,54 @@ from . import mixins class Domain(mixins.MessageLimitMixin, AdminObject): """Mail domain.""" - name = models.CharField(gettext_lazy("name"), max_length=253, unique=True, - help_text=gettext_lazy("The domain name")) + name = models.CharField( + gettext_lazy("name"), + max_length=253, + unique=True, + help_text=gettext_lazy("The domain name"), + ) quota = models.PositiveIntegerField( default=0, ) default_mailbox_quota = models.PositiveIntegerField( - verbose_name=gettext_lazy("Default mailbox quota"), - default=0 + verbose_name=gettext_lazy("Default mailbox quota"), default=0 ) message_limit = models.PositiveIntegerField( gettext_lazy("Message sending limit"), - null=True, blank=True, - help_text=gettext_lazy( - "Number of messages this domain can send per day" - ) + null=True, + blank=True, + help_text=gettext_lazy("Number of messages this domain can send per day"), ) enabled = models.BooleanField( gettext_lazy("enabled"), help_text=gettext_lazy("Check to activate this domain"), - default=True + default=True, ) type = models.CharField(default="domain", max_length=20) # NOQA:A003 enable_dns_checks = models.BooleanField( - gettext_lazy("Enable DNS checks"), default=True, - help_text=gettext_lazy("Check to enable DNS checks for this domain") + gettext_lazy("Enable DNS checks"), + default=True, + help_text=gettext_lazy("Check to enable DNS checks for this domain"), ) transport = models.OneToOneField( - "transport.Transport", null=True, on_delete=models.SET_NULL) + "transport.Transport", null=True, on_delete=models.SET_NULL + ) enable_dkim = models.BooleanField( gettext_lazy("Enable DKIM signing"), help_text=gettext_lazy( "If you activate this feature, a DKIM key will be " - "generated for this domain."), - default=False + "generated for this domain." + ), + default=False, ) dkim_key_selector = models.CharField(max_length=30, default="modoboa") dkim_key_length = models.PositiveIntegerField( - gettext_lazy("Key length"), choices=constants.DKIM_KEY_LENGTHS, - blank=True, null=True + gettext_lazy("Key length"), + choices=constants.DKIM_KEY_LENGTHS, + blank=True, + null=True, ) dkim_public_key = models.TextField(blank=True) dkim_private_key_path = models.CharField(max_length=254, blank=True) @@ -94,9 +101,7 @@ class Domain(mixins.MessageLimitMixin, AdminObject): @property def identities_count(self) -> int: """Total number of identities in this domain.""" - return ( - self.mailbox_set.count() + - self.alias_set.filter(internal=False).count()) + return self.mailbox_set.count() + self.alias_set.filter(internal=False).count() @property def opened_alarms_count(self) -> int: @@ -111,12 +116,14 @@ class Domain(mixins.MessageLimitMixin, AdminObject): label = dt[1] result = [{"name": self.type, "label": label, "type": "dom"}] if self.transport: - result.append({ - "name": self.transport.service, - "label": self.transport.service, - "type": "srv", - "color": "info" - }) + result.append( + { + "name": self.transport.service, + "label": self.transport.service, + "type": "srv", + "color": "info", + } + ) return result @property @@ -128,7 +135,8 @@ class Domain(mixins.MessageLimitMixin, AdminObject): return User.objects.filter( is_superuser=False, objectaccess__content_type__model="domain", - objectaccess__object_id=self.pk) + objectaccess__object_id=self.pk, + ) @property def aliases(self): @@ -165,7 +173,10 @@ class Domain(mixins.MessageLimitMixin, AdminObject): errors = [] if config["enable_mx_checks"] and not self.mxrecord_set.has_valids(): errors.append("mx") - if config["enable_dnsbl_checks"] and self.dnsblresult_set.blacklisted().exists(): + if ( + config["enable_dnsbl_checks"] + and self.dnsblresult_set.blacklisted().exists() + ): errors.append("dnsbl") if config["enable_spf_checks"]: if self.spf_record is None or not self.spf_record.is_valid: @@ -225,8 +236,7 @@ class Domain(mixins.MessageLimitMixin, AdminObject): return 0 if not self.mailbox_set.exists(): return 0 - return self.mailbox_set.aggregate( - total=models.Sum("quota"))["total"] + return self.mailbox_set.aggregate(total=models.Sum("quota"))["total"] @cached_property def allocated_quota_in_percent(self): @@ -268,14 +278,15 @@ class Domain(mixins.MessageLimitMixin, AdminObject): split_record = [] while record: if len(record) > 74: - split_record.append(" \"%s\"" % record[:74]) + split_record.append(' "%s"' % record[:74]) record = record[74:] else: - split_record.append(" \"%s\"" % record) + split_record.append(' "%s"' % record) break record = "\n".join(split_record) return "{}._domainkey.{}. IN TXT (\n{})".format( - self.dkim_key_selector, self.name, record) + self.dkim_key_selector, self.name, record + ) def add_admin(self, account): """Add a new administrator to this domain. @@ -285,7 +296,8 @@ class Domain(mixins.MessageLimitMixin, AdminObject): from modoboa.lib.permissions import grant_access_to_object core_signals.can_create_object.send( - sender=self.__class__, context=self, object_type="domain_admins") + sender=self.__class__, context=self, object_type="domain_admins" + ) grant_access_to_object(account, self) for mb in self.mailbox_set.all(): if mb.user.has_perm("admin.add_domain"): @@ -315,9 +327,7 @@ class Domain(mixins.MessageLimitMixin, AdminObject): """Store current data if domain is renamed.""" # We check that the instance exists to use m2m relationship if self.pk and self.oldname != self.name: - self.old_mail_homes = { - mb.id: mb.mail_home for mb in self.mailbox_set.all() - } + self.old_mail_homes = {mb.id: mb.mail_home for mb in self.mailbox_set.all()} if self.old_dkim_key_length != self.dkim_key_length: self.dkim_public_key = "" self.dkim_private_key_path = "" @@ -359,38 +369,36 @@ class Domain(mixins.MessageLimitMixin, AdminObject): self.name = row[1].strip().lower() if Domain.objects.filter(name=self.name).exists(): raise Conflict - domains_must_have_authorized_mx = ( - param_tools.get_global_parameter("domains_must_have_authorized_mx") + domains_must_have_authorized_mx = param_tools.get_global_parameter( + "domains_must_have_authorized_mx" ) if domains_must_have_authorized_mx and not user.is_superuser: if not lib.domain_has_authorized_mx(self.name): raise BadRequest( - _("{}: no authorized MX record found for domain") - .format(self.name) + _("{}: no authorized MX record found for domain").format(self.name) ) try: self.quota = int(row[2].strip()) except ValueError: - raise BadRequest( - _("{}: invalid quota value for domain") - .format(self.name) - ) + raise BadRequest(_("{}: invalid quota value for domain").format(self.name)) try: self.default_mailbox_quota = int(row[3].strip()) except ValueError: raise BadRequest( - _("{}: invalid default mailbox quota value for domain") - .format(self.name) + _("{}: invalid default mailbox quota value for domain").format( + self.name + ) ) if self.quota != 0 and self.default_mailbox_quota > self.quota: raise BadRequest( - _("{}: default mailbox quota cannot be greater than domain " - "quota").format(self.name) + _( + "{}: default mailbox quota cannot be greater than domain " "quota" + ).format(self.name) ) - self.enabled = (row[4].strip().lower() in ["true", "1", "yes", "y"]) + self.enabled = row[4].strip().lower() in ["true", "1", "yes", "y"] core_signals.can_create_object.send( - sender=self.__class__, context=user, klass=Domain, - instance=self) + sender=self.__class__, context=user, klass=Domain, instance=self + ) self.save(creator=user) def to_csv_rows(self): @@ -401,7 +409,7 @@ class Domain(mixins.MessageLimitMixin, AdminObject): force_str(self.name), self.quota, self.default_mailbox_quota, - self.enabled + self.enabled, ] ] for dalias in self.domainalias_set.all(): diff --git a/modoboa/admin/models/domain_alias.py b/modoboa/admin/models/domain_alias.py index c312f34ec..32a00b7f9 100644 --- a/modoboa/admin/models/domain_alias.py +++ b/modoboa/admin/models/domain_alias.py @@ -27,20 +27,24 @@ class DomainAliasManager(models.Manager): class DomainAlias(AdminObject): - """Domain aliases.""" - name = models.CharField(gettext_lazy("name"), max_length=100, unique=True, - help_text=gettext_lazy("The alias name")) + name = models.CharField( + gettext_lazy("name"), + max_length=100, + unique=True, + help_text=gettext_lazy("The alias name"), + ) target = models.ForeignKey( - Domain, verbose_name=gettext_lazy("target"), + Domain, + verbose_name=gettext_lazy("target"), help_text=gettext_lazy("The domain this alias points to"), - on_delete=models.CASCADE + on_delete=models.CASCADE, ) enabled = models.BooleanField( gettext_lazy("enabled"), help_text=gettext_lazy("Check to activate this alias"), - default=True + default=True, ) owners = GenericRelation(core_models.ObjectAccess) @@ -74,14 +78,14 @@ class DomainAlias(AdminObject): except Domain.DoesNotExist: raise BadRequest(_("Unknown domain %s") % domname) core_signals.can_create_object.send( - sender="import", context=self.target, object_type="domain_aliases") + sender="import", context=self.target, object_type="domain_aliases" + ) self.enabled = row[3].strip().lower() in ["true", "1", "yes", "y"] self.save(creator=user) def to_csv_row(self): """Export to row that can be included in a CSV file.""" - return ["domainalias", self.name, - self.target.name, self.enabled] + return ["domainalias", self.name, self.target.name, self.enabled] def to_csv(self, csvwriter): """Export a domain alias using CSV format diff --git a/modoboa/admin/models/mailbox.py b/modoboa/admin/models/mailbox.py index 0cdf01e69..e87d76502 100644 --- a/modoboa/admin/models/mailbox.py +++ b/modoboa/admin/models/mailbox.py @@ -25,8 +25,7 @@ class QuotaManager(models.Manager): def get_domain_usage(self, domain): """Return current usage for domain.""" - qset = self.get_queryset().filter( - username__endswith="@{}".format(domain.name)) + qset = self.get_queryset().filter(username__endswith="@{}".format(domain.name)) result = qset.aggregate(usage=models.Sum("bytes")).get("usage", 0) if result is None: result = 0 @@ -34,7 +33,6 @@ class QuotaManager(models.Manager): class Quota(models.Model): - """Keeps track of Mailbox current quota.""" username = models.EmailField(primary_key=True, max_length=254) @@ -48,7 +46,6 @@ class Quota(models.Model): class MailboxManager(Manager): - """Custom manager for Mailbox.""" def get_for_admin(self, admin, squery=None): @@ -66,18 +63,14 @@ class MailboxManager(Manager): parts = squery.split("@") addrfilter = "@".join(parts[:-1]) domfilter = parts[-1] - qf = ( - Q(address__contains=addrfilter) & - Q(domain__name__contains=domfilter) + qf = Q(address__contains=addrfilter) & Q( + domain__name__contains=domfilter ) else: - qf = ( - Q(address__contains=squery) | - Q(domain__name__contains=squery) - ) - ids = admin.objectaccess_set \ - .filter(content_type=ContentType.objects.get_for_model(Mailbox)) \ - .values_list("object_id", flat=True) + qf = Q(address__contains=squery) | Q(domain__name__contains=squery) + ids = admin.objectaccess_set.filter( + content_type=ContentType.objects.get_for_model(Mailbox) + ).values_list("object_id", flat=True) if qf is not None: qf = Q(pk__in=ids) & qf else: @@ -89,16 +82,17 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): """User mailbox.""" address = models.CharField( - gettext_lazy("address"), max_length=252, - help_text=gettext_lazy( - "Mailbox address (without the @domain.tld part)") + gettext_lazy("address"), + max_length=252, + help_text=gettext_lazy("Mailbox address (without the @domain.tld part)"), ) quota = models.PositiveIntegerField(default=0) use_domain_quota = models.BooleanField(default=False) message_limit = models.PositiveIntegerField( - gettext_lazy("Message sending limit"), null=True, blank=True, - help_text=gettext_lazy( - "Number of messages this mailbox can send per day") + gettext_lazy("Message sending limit"), + null=True, + blank=True, + help_text=gettext_lazy("Number of messages this mailbox can send per day"), ) domain = models.ForeignKey(Domain, on_delete=models.CASCADE) user = models.OneToOneField(User, on_delete=models.CASCADE) @@ -134,7 +128,8 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): def alias_count(self): return ( self.recipientalias_set.select_related("alias") - .filter(alias__internal=False).count() + .filter(alias__internal=False) + .count() ) @property @@ -155,7 +150,8 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): code, output = doveadm_cmd("user -f home %s" % self.full_address) if code: raise lib_exceptions.InternalError( - _("Failed to retrieve mailbox location (%s)") % output) + _("Failed to retrieve mailbox location (%s)") % output + ) self.__mail_home = force_str(output.strip()) return self.__mail_home @@ -165,9 +161,8 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): :rtype: list of string """ - qset = ( - self.aliasrecipient_set.select_related("alias") - .filter(alias__internal=False) + qset = self.aliasrecipient_set.select_related("alias").filter( + alias__internal=False ) aliases = [alr.alias.address for alr in qset] return aliases @@ -177,8 +172,7 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): """Retrieve the ``Quota`` instance associated to this mailbox.""" if not hasattr(self, "_quota_value"): try: - self._quota_value = Quota.objects.get( - username=self.full_address) + self._quota_value = Quota.objects.get(username=self.full_address) except Quota.DoesNotExist: return None return self._quota_value @@ -195,8 +189,7 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): def rename_dir(self, old_mail_home): """Rename local directory if needed.""" - hm = param_tools.get_global_parameter( - "handle_mailboxes", raise_exception=False) + hm = param_tools.get_global_parameter("handle_mailboxes", raise_exception=False) if not hm: return MailboxOperation.objects.create( @@ -219,15 +212,15 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): self.address = address self.domain = domain self.quota_value = Quota.objects.create( - username=self.full_address, bytes=old_qvalue.bytes, - messages=old_qvalue.messages + username=self.full_address, + bytes=old_qvalue.bytes, + messages=old_qvalue.messages, ) old_qvalue.delete() self.rename_dir(old_mail_home) def delete_dir(self): - hm = param_tools.get_global_parameter( - "handle_mailboxes", raise_exception=False) + hm = param_tools.get_global_parameter("handle_mailboxes", raise_exception=False) if not hm: return MailboxOperation.objects.create(type="delete", argument=self.mail_home) @@ -277,16 +270,15 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): """ if not self.quota: return 0 - return int( - self.quota_value.bytes / float(self.quota * 1048576) * 100 - ) + return int(self.quota_value.bytes / float(self.quota * 1048576) * 100) def post_create(self, creator): from modoboa.lib.permissions import grant_access_to_object + super().post_create(creator) conditions = ( creator.has_perm("admin.add_mailbox"), - not self.user.has_perm("admin.add_domain") + not self.user.has_perm("admin.add_domain"), ) if all(conditions): # An admin is creating a new mailbox. Give @@ -305,8 +297,9 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): newaddress = None if values["email"] != self.full_address: newaddress = values["email"] - elif (self.user.role == "SimpleUsers" and - self.user.username != self.full_address): + elif ( + self.user.role == "SimpleUsers" and self.user.username != self.full_address + ): newaddress = self.user.username if newaddress is not None: local_part, domname = split_mailbox(newaddress) @@ -319,9 +312,10 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): self.use_domain_quota = values["use_domain_quota"] if "use_domain_quota" in values or "quota" in values: override_rules = ( - not self.quota or user.is_superuser or - user.has_perm("admin.add_domain") and - not user.userobjectlimit_set.get(name="quota").max_value + not self.quota + or user.is_superuser + or user.has_perm("admin.add_domain") + and not user.userobjectlimit_set.get(name="quota").max_value ) self.set_quota(values["quota"], override_rules) if "message_limit" in values: @@ -343,11 +337,11 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject): if self.pk: qset = qset.exclude(pk=self.pk) if qset.exists(): - raise lib_exceptions.Conflict( - _("Mailbox {} already exists").format(self)) + raise lib_exceptions.Conflict(_("Mailbox {} already exists").format(self)) if self.quota_value is None: self.quota_value, created = Quota.objects.get_or_create( - username=self.full_address) + username=self.full_address + ) super().save(*args, **kwargs) @@ -377,8 +371,9 @@ reversion.register(SenderAddress) class MailboxOperation(models.Model): """An operation on a mailbox.""" - mailbox = models.ForeignKey(Mailbox, blank=True, null=True, - on_delete=models.CASCADE) + mailbox = models.ForeignKey( + Mailbox, blank=True, null=True, on_delete=models.CASCADE + ) type = models.CharField( # NOQA:A003 max_length=20, choices=(("rename", "rename"), ("delete", "delete")) ) diff --git a/modoboa/admin/models/mixins.py b/modoboa/admin/models/mixins.py index 418c9ad12..848b8b6c0 100644 --- a/modoboa/admin/models/mixins.py +++ b/modoboa/admin/models/mixins.py @@ -15,9 +15,7 @@ class MessageLimitMixin: """Return number of sent messages for the current day.""" if self.message_limit is None: return None - return ( - self.message_limit - get_message_counter(self.message_counter_key) - ) + return self.message_limit - get_message_counter(self.message_counter_key) @property def sent_messages_in_percent(self): diff --git a/modoboa/admin/models/mxrecord.py b/modoboa/admin/models/mxrecord.py index c0653ffbe..e0d630c5c 100644 --- a/modoboa/admin/models/mxrecord.py +++ b/modoboa/admin/models/mxrecord.py @@ -29,8 +29,7 @@ class MXRecordManager(models.Manager): from .. import lib now = timezone.now() - records = self.get_queryset().filter( - domain=domain, updated__gt=now) + records = self.get_queryset().filter(domain=domain, updated__gt=now) if records.exists(): for record in records: yield record @@ -47,7 +46,8 @@ class MXRecordManager(models.Manager): domain=domain, name="{}".format(mx_addr.strip(".")), address="{}".format(mx_ip_addr), - updated=now + delta) + updated=now + delta, + ) yield record diff --git a/modoboa/admin/postfix_maps.py b/modoboa/admin/postfix_maps.py index d7c1eda64..1378997f9 100644 --- a/modoboa/admin/postfix_maps.py +++ b/modoboa/admin/postfix_maps.py @@ -1,7 +1,7 @@ """Map file definitions for postfix.""" -class DomainsMap(object): +class DomainsMap(object): """Map to list all domains.""" filename = "sql-domains.cf" @@ -10,8 +10,7 @@ class DomainsMap(object): "WHERE name='%s' AND type='domain' AND enabled=1" ) postgres = ( - "SELECT name FROM admin_domain " - "WHERE name='%s' AND type='domain' AND enabled" + "SELECT name FROM admin_domain " "WHERE name='%s' AND type='domain' AND enabled" ) sqlite = ( "SELECT name FROM admin_domain " @@ -20,7 +19,6 @@ class DomainsMap(object): class DomainsAliasesMap(object): - """Map to list all domain aliases.""" filename = "sql-domain-aliases.cf" @@ -42,7 +40,6 @@ class DomainsAliasesMap(object): class AliasesMap(object): - """A map to list all mailbox aliases.""" filename = "sql-aliases.cf" @@ -67,7 +64,6 @@ class AliasesMap(object): class MaintainMap(object): - """Map files to list non available mailboxes.""" filename = "sql-maintain.cf" diff --git a/modoboa/admin/signals.py b/modoboa/admin/signals.py index f5fdd32d4..69833fa5f 100644 --- a/modoboa/admin/signals.py +++ b/modoboa/admin/signals.py @@ -2,21 +2,21 @@ import django.dispatch -check_extra_account_form = django.dispatch.Signal() # Provides account, form -extra_account_dashboard_widgets = django.dispatch.Signal() # Provides user, account -extra_account_forms = django.dispatch.Signal() # Provides user, account -extra_admin_content = django.dispatch.Signal() # Provides user, location, currentpage -extra_domain_actions = django.dispatch.Signal() # Provides user, domain -extra_domain_dashboard_widgets = django.dispatch.Signal() # Provides user, domain +check_extra_account_form = django.dispatch.Signal() # Provides account, form +extra_account_dashboard_widgets = django.dispatch.Signal() # Provides user, account +extra_account_forms = django.dispatch.Signal() # Provides user, account +extra_admin_content = django.dispatch.Signal() # Provides user, location, currentpage +extra_domain_actions = django.dispatch.Signal() # Provides user, domain +extra_domain_dashboard_widgets = django.dispatch.Signal() # Provides user, domain extra_domain_filters = django.dispatch.Signal() -extra_domain_forms = django.dispatch.Signal() # Provides user, domain -extra_domain_menu_entries = django.dispatch.Signal() # Provides user -extra_domain_qset_filters = django.dispatch.Signal() # Provides domfilter, extrafilters +extra_domain_forms = django.dispatch.Signal() # Provides user, domain +extra_domain_menu_entries = django.dispatch.Signal() # Provides user +extra_domain_qset_filters = django.dispatch.Signal() # Provides domfilter, extrafilters # extra_domain_types = django.dispatch.Signal() extra_domain_wizard_steps = django.dispatch.Signal() -get_account_form_instances = django.dispatch.Signal() # Provides user, account -get_domain_form_instances = django.dispatch.Signal() # Provides user, domain +get_account_form_instances = django.dispatch.Signal() # Provides user, account +get_domain_form_instances = django.dispatch.Signal() # Provides user, domain # get_domain_tags = django.dispatch.Signal(providing_args=["domain"]) -import_object = django.dispatch.Signal() # Provides objtype -use_external_recipients = django.dispatch.Signal() # Provides recipients -extra_account_identities_actions = django.dispatch.Signal() # Provides account +import_object = django.dispatch.Signal() # Provides objtype +use_external_recipients = django.dispatch.Signal() # Provides recipients +extra_account_identities_actions = django.dispatch.Signal() # Provides account diff --git a/modoboa/admin/templatetags/admin_tags.py b/modoboa/admin/templatetags/admin_tags.py index 1e7e74bb8..0da358765 100644 --- a/modoboa/admin/templatetags/admin_tags.py +++ b/modoboa/admin/templatetags/admin_tags.py @@ -15,9 +15,7 @@ from .. import signals register = template.Library() -genders = { - "Enabled": (gettext_lazy("enabled_m"), gettext_lazy("enabled_f")) -} +genders = {"Enabled": (gettext_lazy("enabled_m"), gettext_lazy("enabled_f"))} @register.simple_tag @@ -43,47 +41,57 @@ def domains_menu(selection, user, ajax_mode=True): quota_list_url = domain_list_url + "#quotas/" logs_url = domain_list_url + "#logs/" entries = [ - {"name": "domains", - "label": _("List domains"), - "img": "fa fa-user", - "class": "ajaxnav navigation", - "url": domain_list_url}, - {"name": "quotas", - "label": _("List quotas"), - "img": "fa fa-hdd-o", - "class": "ajaxnav navigation", - "url": quota_list_url}, - {"name": "logs", - "label": _("Message logs"), - "img": "fa fa-list", - "class": "ajaxnav navigation", - "url": logs_url}, + { + "name": "domains", + "label": _("List domains"), + "img": "fa fa-user", + "class": "ajaxnav navigation", + "url": domain_list_url, + }, + { + "name": "quotas", + "label": _("List quotas"), + "img": "fa fa-hdd-o", + "class": "ajaxnav navigation", + "url": quota_list_url, + }, + { + "name": "logs", + "label": _("Message logs"), + "img": "fa fa-list", + "class": "ajaxnav navigation", + "url": logs_url, + }, ] if user.has_perm("admin.add_domain"): extra_entries = signals.extra_domain_menu_entries.send( - sender="domains_menu", user=user) + sender="domains_menu", user=user + ) for entry in extra_entries: entries += entry[1] entries += [ - {"name": "import", - "label": _("Import"), - "img": "fa fa-folder-open", - "url": reverse("admin:domain_import"), - "modal": True, - "modalcb": "admin.importform_cb"}, - {"name": "export", - "label": _("Export"), - "img": "fa fa-share-alt", - "url": reverse("admin:domain_export"), - "modal": True, - "modalcb": "admin.exportform_cb"} + { + "name": "import", + "label": _("Import"), + "img": "fa fa-folder-open", + "url": reverse("admin:domain_import"), + "modal": True, + "modalcb": "admin.importform_cb", + }, + { + "name": "export", + "label": _("Export"), + "img": "fa fa-share-alt", + "url": reverse("admin:domain_export"), + "modal": True, + "modalcb": "admin.exportform_cb", + }, ] - return render_to_string("common/menulist.html", { - "entries": entries, - "selection": selection, - "user": user - }) + return render_to_string( + "common/menulist.html", + {"entries": entries, "selection": selection, "user": user}, + ) @register.simple_tag @@ -103,71 +111,84 @@ def identities_menu(user, selection=None, ajax_mode=True): identity_list_url = reverse("admin:identity_list") quota_list_url = identity_list_url + "#quotas/" entries = [ - {"name": "identities", - "label": _("List identities"), - "img": "fa fa-user", - "class": nav_classes, - "url": identity_list_url}, - {"name": "quotas", - "label": _("List quotas"), - "img": "fa fa-hdd-o", - "class": nav_classes, - "url": quota_list_url}, - {"name": "import", - "label": _("Import"), - "img": "fa fa-folder-open", - "url": reverse("admin:identity_import"), - "modal": True, - "modalcb": "admin.importform_cb"}, - {"name": "export", - "label": _("Export"), - "img": "fa fa-share-alt", - "url": reverse("admin:identity_export"), - "modal": True, - "modalcb": "admin.exportform_cb"} + { + "name": "identities", + "label": _("List identities"), + "img": "fa fa-user", + "class": nav_classes, + "url": identity_list_url, + }, + { + "name": "quotas", + "label": _("List quotas"), + "img": "fa fa-hdd-o", + "class": nav_classes, + "url": quota_list_url, + }, + { + "name": "import", + "label": _("Import"), + "img": "fa fa-folder-open", + "url": reverse("admin:identity_import"), + "modal": True, + "modalcb": "admin.importform_cb", + }, + { + "name": "export", + "label": _("Export"), + "img": "fa fa-share-alt", + "url": reverse("admin:identity_export"), + "modal": True, + "modalcb": "admin.exportform_cb", + }, ] - return render_to_string("common/menulist.html", { - "entries": entries, - "user": user - }) + return render_to_string("common/menulist.html", {"entries": entries, "user": user}) @register.simple_tag def domain_actions(user, domain): actions = [ - {"name": "listidentities", - "url": u"{0}#list/?searchquery=@{1}".format( - reverse("admin:identity_list"), domain.name), - "title": _("View the domain's identities"), - "img": "fa fa-user"}, + { + "name": "listidentities", + "url": "{0}#list/?searchquery=@{1}".format( + reverse("admin:identity_list"), domain.name + ), + "title": _("View the domain's identities"), + "img": "fa fa-user", + }, ] if domain.alarms.opened().exists(): - actions.append({ - "name": "listalarms", - "url": reverse("admin:domain_alarms", args=[domain.pk]), - "title": _("View domain's alarms"), - "img": "fa fa-bell" - }) + actions.append( + { + "name": "listalarms", + "url": reverse("admin:domain_alarms", args=[domain.pk]), + "title": _("View domain's alarms"), + "img": "fa fa-bell", + } + ) if user.has_perm("admin.change_domain"): - actions.append({ - "name": "editdomain", - "title": _("Edit {}").format(domain), - "url": reverse("admin:domain_change", args=[domain.pk]), - "modal": True, - "modalcb": "admin.domainform_cb", - "img": "fa fa-edit" - }) + actions.append( + { + "name": "editdomain", + "title": _("Edit {}").format(domain), + "url": reverse("admin:domain_change", args=[domain.pk]), + "modal": True, + "modalcb": "admin.domainform_cb", + "img": "fa fa-edit", + } + ) if user.has_perm("admin.delete_domain"): - actions.append({ - "name": "deldomain", - "url": reverse("admin:domain_delete", args=[domain.id]), - "title": _("Delete %s?") % domain.name, - "img": "fa fa-trash" - }) + actions.append( + { + "name": "deldomain", + "url": reverse("admin:domain_delete", args=[domain.id]), + "title": _("Delete %s?") % domain.name, + "img": "fa fa-trash", + } + ) - responses = signals.extra_domain_actions.send( - sender=None, user=user, domain=domain) + responses = signals.extra_domain_actions.send(sender=None, user=user, domain=domain) for _receiver, response in responses: if response: actions += response @@ -182,38 +203,43 @@ def identity_actions(user, ident): if name == "User": actions = [] result = core_signals.extra_account_actions.send( - sender="identity_actions", account=ident) + sender="identity_actions", account=ident + ) for action in result: actions += action[1] - url = ( - reverse("admin:account_change", args=[objid]) + - "?active_tab=default" - ) + url = reverse("admin:account_change", args=[objid]) + "?active_tab=default" actions += [ - {"name": "changeaccount", - "url": url, - "img": "fa fa-edit", - "modal": True, - "modalcb": "admin.editaccount_cb", - "title": _("Edit {}").format(ident.username)}, - {"name": "delaccount", - "url": reverse("admin:account_delete", args=[objid]), - "img": "fa fa-trash", - "title": _("Delete %s?") % ident.username}, + { + "name": "changeaccount", + "url": url, + "img": "fa fa-edit", + "modal": True, + "modalcb": "admin.editaccount_cb", + "title": _("Edit {}").format(ident.username), + }, + { + "name": "delaccount", + "url": reverse("admin:account_delete", args=[objid]), + "img": "fa fa-trash", + "title": _("Delete %s?") % ident.username, + }, ] else: actions = [ - {"name": "changealias", - "url": reverse("admin:alias_change", args=[objid]), - "img": "fa fa-edit", - "modal": True, - "modalcb": "admin.aliasform_cb", - "title": _("Edit {}").format(ident)}, - {"name": "delalias", - "url": "{}?selection={}".format( - reverse("admin:alias_delete"), objid), - "img": "fa fa-trash", - "title": _("Delete %s?") % ident.address}, + { + "name": "changealias", + "url": reverse("admin:alias_change", args=[objid]), + "img": "fa fa-edit", + "modal": True, + "modalcb": "admin.aliasform_cb", + "title": _("Edit {}").format(ident), + }, + { + "name": "delalias", + "url": "{}?selection={}".format(reverse("admin:alias_delete"), objid), + "img": "fa fa-trash", + "title": _("Delete %s?") % ident.address, + }, ] return render_actions(actions) @@ -222,8 +248,7 @@ def identity_actions(user, ident): def check_identity_status(identity): """Check if identity is enabled or not.""" if identity.__class__.__name__ == "User": - if hasattr(identity, "mailbox") \ - and not identity.mailbox.domain.enabled: + if hasattr(identity, "mailbox") and not identity.mailbox.domain.enabled: return False elif not identity.is_active: return False @@ -271,13 +296,16 @@ def identity_modify_link(identity, active_tab="default"): @register.simple_tag def domadmin_actions(daid, domid): - actions = [{ - "name": "removeperm", - "url": "{0}?domid={1}&daid={2}".format( - reverse("admin:permission_remove"), domid, daid), - "img": "fa fa-trash", - "title": _("Remove this permission") - }] + actions = [ + { + "name": "removeperm", + "url": "{0}?domid={1}&daid={2}".format( + reverse("admin:permission_remove"), domid, daid + ), + "img": "fa fa-trash", + "title": _("Remove this permission"), + } + ] return render_actions(actions) @@ -294,7 +322,10 @@ def gender(value, target): def get_extra_admin_content(user, target, currentpage): results = signals.extra_admin_content.send( sender="get_extra_admin_content", - user=user, location=target, currentpage=currentpage) + user=user, + location=target, + currentpage=currentpage, + ) if not results: return "" results = reduce(lambda a, b: a + b, [result[1] for result in results]) diff --git a/modoboa/admin/tests/test_account.py b/modoboa/admin/tests/test_account.py index 6f1c7ab88..0fd77ff20 100644 --- a/modoboa/admin/tests/test_account.py +++ b/modoboa/admin/tests/test_account.py @@ -19,9 +19,10 @@ class AuthenticationTestCase(ModoTestCase): """Create test data.""" super(AuthenticationTestCase, cls).setUpTestData() cls.mb = factories.MailboxFactory( - domain__name="test.com", address="user", + domain__name="test.com", + address="user", user__username="user@test.com", - user__groups=("SimpleUsers",) + user__groups=("SimpleUsers",), ) def test_authentication_unicode(self): @@ -46,10 +47,16 @@ class AccountTestCase(ModoTestCase): def test_crud(self): values = { - "username": "tester@test.com", "first_name": "Tester", - "last_name": "Toto", "password1": "Toto1234", - "password2": "Toto1234", "role": "SimpleUsers", "quota_act": True, - "is_active": True, "email": "tester@test.com", "stepid": "step2" + "username": "tester@test.com", + "first_name": "Tester", + "last_name": "Toto", + "password1": "Toto1234", + "password2": "Toto1234", + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": "tester@test.com", + "stepid": "step2", } self.ajax_post(reverse("admin:account_add"), values) @@ -66,19 +73,24 @@ class AccountTestCase(ModoTestCase): self.assertEqual(mb.domain.mailbox_count, 3) # Check if self alias has been created self.assertTrue( - models.AliasRecipient.objects.select_related("alias").filter( - alias__address=mb.full_address, address=mb.full_address, - alias__internal=True).exists() + models.AliasRecipient.objects.select_related("alias") + .filter( + alias__address=mb.full_address, + address=mb.full_address, + alias__internal=True, + ) + .exists() ) - values.update({ - "username": "pouet@test.com", "language": "en", - "secondary_email": "homer@simpson.com", - "phone_number": "+33612345678" - }) - self.ajax_post( - reverse("admin:account_change", args=[account.id]), values + values.update( + { + "username": "pouet@test.com", + "language": "en", + "secondary_email": "homer@simpson.com", + "phone_number": "+33612345678", + } ) + self.ajax_post(reverse("admin:account_change", args=[account.id]), values) account.refresh_from_db() self.assertEqual(account.secondary_email, values["secondary_email"]) mb = models.Mailbox.objects.get(pk=mb.pk) @@ -86,18 +98,24 @@ class AccountTestCase(ModoTestCase): self.assertEqual(mb.quota_value.username, "pouet@test.com") # Check if self alias has been updated self.assertTrue( - models.AliasRecipient.objects.select_related("alias").filter( - alias__address=mb.full_address, address=mb.full_address, - alias__internal=True).exists() - ) - self.ajax_post( - reverse("admin:account_delete", args=[account.id]), {} + models.AliasRecipient.objects.select_related("alias") + .filter( + alias__address=mb.full_address, + address=mb.full_address, + alias__internal=True, + ) + .exists() ) + self.ajax_post(reverse("admin:account_delete", args=[account.id]), {}) # Check if self alias has been deleted self.assertFalse( - models.AliasRecipient.objects.select_related("alias").filter( - alias__address=mb.full_address, address=mb.full_address, - alias__internal=True).exists() + models.AliasRecipient.objects.select_related("alias") + .filter( + alias__address=mb.full_address, + address=mb.full_address, + alias__internal=True, + ) + .exists() ) @override_settings(LANGUAGE_CODE="fr") @@ -113,7 +131,7 @@ class AccountTestCase(ModoTestCase): "quota_act": True, "is_active": True, "email": "tester@test.com", - "stepid": "step2" + "stepid": "step2", } self.ajax_post(reverse("admin:account_add"), values) account = User.objects.get(username=values["username"]) @@ -148,11 +166,9 @@ class AccountTestCase(ModoTestCase): } self.ajax_post(reverse("admin:account_add"), values) # Check that internal alias has not been updated - alias = models.Alias.objects.get( - address="user@test.com", internal=True) + alias = models.Alias.objects.get(address="user@test.com", internal=True) self.assertTrue(alias.aliasrecipient_set.count() == 1) - alias = models.Alias.objects.get( - address="user@test.com", internal=False) + alias = models.Alias.objects.get(address="user@test.com", internal=False) self.assertTrue(alias.aliasrecipient_set.count() == 1) def test_create_disabled_account(self): @@ -167,7 +183,7 @@ class AccountTestCase(ModoTestCase): "quota_act": True, "is_active": False, "email": "tester@test.com", - "stepid": "step2" + "stepid": "step2", } self.ajax_post(reverse("admin:account_add"), values) account = User.objects.get(username=values["username"]) @@ -186,19 +202,15 @@ class AccountTestCase(ModoTestCase): "quota_act": True, "is_active": False, "email": "user@test.com", - "language": "en" + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[account.id]), values - ) + self.ajax_post(reverse("admin:account_change", args=[account.id]), values) internal.refresh_from_db() self.assertFalse(internal.enabled) forward.refresh_from_db() self.assertFalse(forward.enabled) values["is_active"] = True - self.ajax_post( - reverse("admin:account_change", args=[account.id]), values - ) + self.ajax_post(reverse("admin:account_change", args=[account.id]), values) internal.refresh_from_db() self.assertTrue(internal.enabled) forward.refresh_from_db() @@ -217,7 +229,7 @@ class AccountTestCase(ModoTestCase): "email": "new_user@test.com", "language": "en", "create_alias_with_old_address": False, - "aliases_1": "alias@test.com" + "aliases_1": "alias@test.com", } url = reverse("admin:account_change", args=[account.pk]) self.ajax_post(url, values) @@ -237,42 +249,48 @@ class AccountTestCase(ModoTestCase): "is_active": account.is_active, "email": "new_user@test.com", "language": "en", - "create_alias_with_old_address": False + "create_alias_with_old_address": False, } url = reverse("admin:account_change", args=[account.pk]) # Rename while option is set to False -> no alias created self.ajax_post(url, values) self.assertFalse( models.AliasRecipient.objects.filter( - address="new_user@test.com", alias__address="user@test.com", - alias__internal=False + address="new_user@test.com", + alias__address="user@test.com", + alias__internal=False, ).exists() ) # Now rename while option set to True -> alias created - values.update({ - "username": "user@test.com", - "email": "user@test.com", - "create_alias_with_old_address": True} + values.update( + { + "username": "user@test.com", + "email": "user@test.com", + "create_alias_with_old_address": True, + } ) self.ajax_post(url, values) self.assertTrue( models.AliasRecipient.objects.filter( - address="user@test.com", alias__address="new_user@test.com", - alias__internal=False + address="user@test.com", + alias__address="new_user@test.com", + alias__internal=False, ).exists() ) # Change domain while option set to True -> alias created - values.update({ - "username": "new_user@test2.com", - "email": "new_user@test2.com", - }) + values.update( + { + "username": "new_user@test2.com", + "email": "new_user@test2.com", + } + ) self.ajax_post(url, values) self.assertTrue( models.AliasRecipient.objects.filter( address="new_user@test2.com", alias__address="user@test.com", alias__domain__name="test.com", - alias__internal=False + alias__internal=False, ).exists() ) @@ -280,38 +298,45 @@ class AccountTestCase(ModoTestCase): """Check password constraints.""" values = { "username": "tester@test.com", - "first_name": "Tester", "last_name": "Toto", - "password1": "", "password2": "", + "first_name": "Tester", + "last_name": "Toto", + "password1": "", + "password2": "", "role": "SimpleUsers", - "quota_act": True, "is_active": True, "email": "tester@test.com", - "stepid": "step2" + "quota_act": True, + "is_active": True, + "email": "tester@test.com", + "stepid": "step2", } resp = self.ajax_post(reverse("admin:account_add"), values, 400) - self.assertEqual( - resp["form_errors"]["password1"][0], - "This field is required.") + self.assertEqual(resp["form_errors"]["password1"][0], "This field is required.") values["password1"] = "Toto1234" values["password2"] = "Toto12345" resp = self.ajax_post(reverse("admin:account_add"), values, 400) self.assertEqual( - resp["form_errors"]["password2"][0], - "The two password fields didn't match.") + resp["form_errors"]["password2"][0], "The two password fields didn't match." + ) values["password1"] = "toto1234" values["password2"] = "toto1234" resp = self.ajax_post(reverse("admin:account_add"), values, 400) self.assertEqual( resp["form_errors"]["password2"][0], - "Password must contain at least 1 uppercase letter.") + "Password must contain at least 1 uppercase letter.", + ) def test_random_password(self): """Try to create an account with a random password.""" values = { "username": "tester@test.com", - "first_name": "Tester", "last_name": "Toto", - "random_password": True, "role": "SimpleUsers", - "quota_act": True, "is_active": True, "email": "tester@test.com", - "stepid": "step2" + "first_name": "Tester", + "last_name": "Toto", + "random_password": True, + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": "tester@test.com", + "stepid": "step2", } self.ajax_post(reverse("admin:account_add"), values) @@ -320,62 +345,56 @@ class AccountTestCase(ModoTestCase): values["language"] = "en" # Since 'random_password' is still True, a new password should # be generated - self.ajax_post( - reverse("admin:account_change", args=[account.pk]), values - ) + self.ajax_post(reverse("admin:account_change", args=[account.pk]), values) account.refresh_from_db() self.assertNotEqual(password, account.password) password = account.password values["random_password"] = False - self.ajax_post( - reverse("admin:account_change", args=[account.pk]), values - ) + self.ajax_post(reverse("admin:account_change", args=[account.pk]), values) account.refresh_from_db() self.assertEqual(password, account.password) def test_delete_default_superadmin(self): """Delete default superadmin.""" - sadmin2 = core_factories.UserFactory( - username="admin2", is_superuser=True) + sadmin2 = core_factories.UserFactory(username="admin2", is_superuser=True) sadmin = User.objects.get(username="admin") self.client.force_login(sadmin2) - self.ajax_post( - reverse("admin:account_delete", args=[sadmin.pk]), {} - ) + self.ajax_post(reverse("admin:account_delete", args=[sadmin.pk]), {}) values = { - "username": "user@test.com", "role": "DomainAdmins", - "is_active": True, "email": "user@test.com", - "language": "en" + "username": "user@test.com", + "role": "DomainAdmins", + "is_active": True, + "email": "user@test.com", + "language": "en", } account = User.objects.get(username="user@test.com") - self.ajax_post( - reverse("admin:account_change", args=[account.pk]), values - ) + self.ajax_post(reverse("admin:account_change", args=[account.pk]), values) def test_sender_address(self): """Check if sender addresses are saved.""" account = User.objects.get(username="user@test.com") values = { - "username": "user@test.com", "first_name": "Tester", - "last_name": "Toto", "role": "SimpleUsers", - "quota_act": True, "is_active": True, "email": "user@test.com", - "senderaddress": "test@titi.com", "senderaddress_1": "toto@go.com", - "language": "en" + "username": "user@test.com", + "first_name": "Tester", + "last_name": "Toto", + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": "user@test.com", + "senderaddress": "test@titi.com", + "senderaddress_1": "toto@go.com", + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[account.pk]), values) + self.ajax_post(reverse("admin:account_change", args=[account.pk]), values) self.assertEqual( - models.SenderAddress.objects.filter( - mailbox__address="user").count(), - 2) + models.SenderAddress.objects.filter(mailbox__address="user").count(), 2 + ) del values["senderaddress_1"] - self.ajax_post( - reverse("admin:account_change", args=[account.pk]), values) + self.ajax_post(reverse("admin:account_change", args=[account.pk]), values) self.assertEqual( - models.SenderAddress.objects.filter( - mailbox__address="user").count(), - 1) + models.SenderAddress.objects.filter(mailbox__address="user").count(), 1 + ) def test_sender_address_as_domainadmin(self): """Check that restrictions are applied.""" @@ -383,63 +402,83 @@ class AccountTestCase(ModoTestCase): self.client.force_login(admin) account = User.objects.get(username="user@test.com") values = { - "username": "user@test.com", "first_name": "Tester", - "last_name": "Toto", "role": "SimpleUsers", - "quota_act": True, "is_active": True, "email": "user@test.com", + "username": "user@test.com", + "first_name": "Tester", + "last_name": "Toto", + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": "user@test.com", "senderaddress": "test@titi.com", - "senderaddress_1": "toto@test2.com" + "senderaddress_1": "toto@test2.com", } response = self.ajax_post( - reverse("admin:account_change", args=[account.pk]), values, 400) + reverse("admin:account_change", args=[account.pk]), values, 400 + ) self.assertEqual( response["form_errors"]["senderaddress_1"][0], - "You don't have access to this domain") + "You don't have access to this domain", + ) def test_conflicts(self): """Check if unicity constraints are respected.""" values = { "username": "user@test.com", - "password1": "Toto1234", "password2": "Toto1234", - "role": "SimpleUsers", "quota_act": True, - "is_active": True, "email": "user@test.com", - "stepid": "step2" + "password1": "Toto1234", + "password2": "Toto1234", + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": "user@test.com", + "stepid": "step2", } self.ajax_post(reverse("admin:account_add"), values, status=400) - values.update({"username": "fakeuser@test.com", - "email": "fakeuser@test.com"}) + values.update({"username": "fakeuser@test.com", "email": "fakeuser@test.com"}) self.ajax_post(reverse("admin:account_add"), values) account = User.objects.get(username="fakeuser@test.com") values = { "username": "user@test.com", - "role": "SimpleUsers", "quota_act": True, - "is_active": True, "email": "user@test.com", + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": "user@test.com", } self.ajax_post( - reverse("admin:account_change", args=[account.pk]), values, - status=400 + reverse("admin:account_change", args=[account.pk]), values, status=400 ) def test_utf8_username(self): """Create an account with non-ASCII characters.""" values = { - "username": "téster@test.com", "first_name": "Tester", - "last_name": "Toto", "password1": "Toto1234", - "password2": "Toto1234", "role": "SimpleUsers", "quota_act": True, - "is_active": True, "email": "téster@test.com", "stepid": "step2" + "username": "téster@test.com", + "first_name": "Tester", + "last_name": "Toto", + "password1": "Toto1234", + "password2": "Toto1234", + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": "téster@test.com", + "stepid": "step2", } self.ajax_post(reverse("admin:account_add"), values) def _set_quota(self, email, value, expected_status=200): account = User.objects.get(username=email) values = { - "username": email, "role": "SimpleUsers", "quota_act": False, - "is_active": True, "quota": value, "email": email, - "language": "en" + "username": email, + "role": "SimpleUsers", + "quota_act": False, + "is_active": True, + "quota": value, + "email": email, + "language": "en", } self.ajax_post( reverse("admin:account_change", args=[account.id]), - values, status=expected_status + values, + status=expected_status, ) def test_set_nul_quota_as_superadmin(self): @@ -448,15 +487,11 @@ class AccountTestCase(ModoTestCase): def test_set_nul_quota_as_domainadmin(self): """Check cases where a domain admin set unlimited quota.""" self.client.logout() - self.assertTrue( - self.client.login(username="admin@test.com", password="toto") - ) + self.assertTrue(self.client.login(username="admin@test.com", password="toto")) # Fails because domain has a quota self._set_quota("user@test.com", 0, 400) self.client.logout() - self.assertTrue( - self.client.login(username="admin@test2.com", password="toto") - ) + self.assertTrue(self.client.login(username="admin@test2.com", password="toto")) # Ok because domain has no quota self._set_quota("user@test2.com", 0) @@ -477,25 +512,29 @@ class AccountTestCase(ModoTestCase): def test_master_user(self): """Validate the master user mode.""" values = { - "username": "masteruser", "role": "SuperAdmins", + "username": "masteruser", + "role": "SuperAdmins", "quota_act": False, - "is_active": True, "master_user": True, "stepid": "step2", - "password1": "Toto1234", "password2": "Toto1234" + "is_active": True, + "master_user": True, + "stepid": "step2", + "password1": "Toto1234", + "password2": "Toto1234", } - self.ajax_post( - reverse("admin:account_add"), values - ) + self.ajax_post(reverse("admin:account_add"), values) self.assertTrue(User.objects.get(username="masteruser").master_user) values = { - "username": "testuser", "role": "DomainAdmins", + "username": "testuser", + "role": "DomainAdmins", "quota_act": False, - "is_active": True, "master_user": True, "stepid": "step2", - "password1": "Toto1234", "password2": "Toto1234" + "is_active": True, + "master_user": True, + "stepid": "step2", + "password1": "Toto1234", + "password2": "Toto1234", } - self.ajax_post( - reverse("admin:account_add"), values, status=400 - ) + self.ajax_post(reverse("admin:account_add"), values, status=400) def test_account_detail_view(self): """Test account detail view.""" @@ -513,8 +552,7 @@ class AccountTestCase(ModoTestCase): def test_quota_list_view(self): """Test quota list view.""" - models.Quota.objects.filter(username="user@test.com").update( - bytes=5 * 1048576) + models.Quota.objects.filter(username="user@test.com").update(bytes=5 * 1048576) url = reverse("admin:identity_quota_list") response = self.ajax_get(url) self.assertIn("5M", response["rows"]) @@ -522,24 +560,23 @@ class AccountTestCase(ModoTestCase): self.assertIn("user@test.com", response["rows"]) old_rows = response["rows"] - response = self.ajax_get( - "{}?sort_order=-quota_value__bytes".format(url)) + response = self.ajax_get("{}?sort_order=-quota_value__bytes".format(url)) self.assertNotEqual(old_rows, response["rows"]) old_rows = response["rows"] - response = self.ajax_get( - "{}?sort_order=-quota_usage".format(url)) + response = self.ajax_get("{}?sort_order=-quota_usage".format(url)) self.assertEqual(old_rows, response["rows"]) - response = self.ajax_get( - "{}?sort_order=-unknown".format(url), status=400) + response = self.ajax_get("{}?sort_order=-unknown".format(url), status=400) @skipIf(NO_LDAP, "No ldap module installed") -@override_settings(AUTHENTICATION_BACKENDS=( - "modoboa.lib.authbackends.LDAPBackend", - "django.contrib.auth.backends.ModelBackend", -)) +@override_settings( + AUTHENTICATION_BACKENDS=( + "modoboa.lib.authbackends.LDAPBackend", + "django.contrib.auth.backends.ModelBackend", + ) +) class LDAPAccountTestCase(test_ldap.LDAPTestCaseMixin, ModoTestCase): """Check LDAP related code.""" @@ -550,10 +587,8 @@ class LDAPAccountTestCase(test_ldap.LDAPTestCaseMixin, ModoTestCase): self.set_global_parameter("auto_create_domain_and_mailbox", False) username = "testuser@example.com" self.authenticate(username, "test") - self.assertFalse( - models.Domain.objects.filter(name="example.com").exists()) - self.assertFalse( - models.Mailbox.objects.filter(address="testuser").exists()) + self.assertFalse(models.Domain.objects.filter(name="example.com").exists()) + self.assertFalse(models.Mailbox.objects.filter(address="testuser").exists()) class PermissionsTestCase(ModoTestCase): @@ -576,9 +611,12 @@ class PermissionsTestCase(ModoTestCase): """Initiate test context.""" super(PermissionsTestCase, self).setUp() self.values = { - "username": self.user.username, "role": "DomainAdmins", - "is_active": self.user.is_active, "email": "user@test.com", - "quota_act": True, "language": "en" + "username": self.user.username, + "role": "DomainAdmins", + "is_active": self.user.is_active, + "email": "user@test.com", + "quota_act": True, + "language": "en", } def tearDown(self): @@ -588,8 +626,7 @@ class PermissionsTestCase(ModoTestCase): factories.DomainFactory(name="test2.com") self.ajax_post( - reverse("admin:account_change", args=[self.user.id]), - self.values + reverse("admin:account_change", args=[self.user.id]), self.values ) self.assertEqual(self.user.role, "DomainAdmins") @@ -599,8 +636,7 @@ class PermissionsTestCase(ModoTestCase): self.values["domains_1"] = "test.com" self.values["domains_2"] = "test2.com" self.ajax_post( - reverse("admin:account_change", args=[self.user.id]), - self.values + reverse("admin:account_change", args=[self.user.id]), self.values ) self.assertIn( self.user, models.Domain.objects.get(name="test.com").admins.all() @@ -611,8 +647,7 @@ class PermissionsTestCase(ModoTestCase): del self.values["domains_2"] self.ajax_post( - reverse("admin:account_change", args=[self.user.id]), - self.values + reverse("admin:account_change", args=[self.user.id]), self.values ) self.assertIn( self.user, models.Domain.objects.get(name="test.com").admins.all() @@ -623,12 +658,9 @@ class PermissionsTestCase(ModoTestCase): self.values["role"] = "SimpleUsers" self.ajax_post( - reverse("admin:account_change", args=[self.user.id]), - self.values - ) - self.assertFalse( - self.user.groups.filter(name="DomainAdmins").exists() + reverse("admin:account_change", args=[self.user.id]), self.values ) + self.assertFalse(self.user.groups.filter(name="DomainAdmins").exists()) self.assertNotIn( self.user, models.Domain.objects.get(name="test.com").admins.all() ) @@ -636,46 +668,36 @@ class PermissionsTestCase(ModoTestCase): def test_superusers(self): self.values["role"] = "SuperAdmins" self.ajax_post( - reverse("admin:account_change", args=[self.user.id]), - self.values - ) - self.assertEqual( - User.objects.get(username="user@test.com").is_superuser, True + reverse("admin:account_change", args=[self.user.id]), self.values ) + self.assertEqual(User.objects.get(username="user@test.com").is_superuser, True) self.values["role"] = "SimpleUsers" self.ajax_post( - reverse("admin:account_change", args=[self.user.id]), - self.values + reverse("admin:account_change", args=[self.user.id]), self.values ) - self.assertEqual(User.objects.get( - username="user@test.com").is_superuser, False) + self.assertEqual(User.objects.get(username="user@test.com").is_superuser, False) def test_self_modif(self): self.client.logout() - self.assertTrue( - self.client.login(username="admin@test.com", password="toto") - ) + self.assertTrue(self.client.login(username="admin@test.com", password="toto")) admin = User.objects.get(username="admin@test.com") values = { - "username": "admin@test.com", "first_name": "Admin", - "password1": "", "password2": "", - "quota": 10, "is_active": True, "email": "admin@test.com", - "language": "en" + "username": "admin@test.com", + "first_name": "Admin", + "password1": "", + "password2": "", + "quota": 10, + "is_active": True, + "email": "admin@test.com", + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[admin.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[admin.id]), values) self.assertEqual(admin.role, "DomainAdmins") - self.assertTrue(admin.can_access( - models.Domain.objects.get(name="test.com"))) + self.assertTrue(admin.can_access(models.Domain.objects.get(name="test.com"))) values["role"] = "SuperAdmins" - self.ajax_post( - reverse("admin:account_change", args=[admin.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[admin.id]), values) admin.refresh_from_db() self.assertEqual(admin.role, "DomainAdmins") @@ -683,33 +705,31 @@ class PermissionsTestCase(ModoTestCase): self.client.login(username=self.reseller.username, password="toto") self.assertTrue(self.reseller.can_access(self.reseller)) values = { - "username": self.reseller.username, "first_name": "Reseller", - "password1": "", "password2": "", - "is_active": True, "language": "en" + "username": self.reseller.username, + "first_name": "Reseller", + "password1": "", + "password2": "", + "is_active": True, + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[self.reseller.pk]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[self.reseller.pk]), values) self.assertEqual(self.reseller.role, "Resellers") values["role"] = "SuperAdmins" - self.ajax_post( - reverse("admin:account_change", args=[self.reseller.pk]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[self.reseller.pk]), values) self.assertEqual(self.reseller.role, "Resellers") def test_domadmin_access(self): self.client.logout() self.assertEqual( - self.client.login(username="admin@test.com", password="toto"), - True) + self.client.login(username="admin@test.com", password="toto"), True + ) response = self.client.get(reverse("admin:domain_list")) self.assertEqual(response.status_code, 200) response = self.client.get( reverse("admin:account_change", args=[self.user.id]), - HTTP_X_REQUESTED_WITH="XMLHttpRequest") + HTTP_X_REQUESTED_WITH="XMLHttpRequest", + ) self.assertNotEqual(response["Content-Type"], "application/json") def test_domainadmin_deletes_superadmin(self): @@ -720,21 +740,21 @@ class PermissionsTestCase(ModoTestCase): to access the super admin. """ values = { - "username": "superadmin2@test.com", "first_name": "Super", - "last_name": "Admin", "password1": "Toto1234", - "password2": "Toto1234", "role": "SuperAdmins", "is_active": True, - "email": "superadmin2@test.com", "stepid": "step2" + "username": "superadmin2@test.com", + "first_name": "Super", + "last_name": "Admin", + "password1": "Toto1234", + "password2": "Toto1234", + "role": "SuperAdmins", + "is_active": True, + "email": "superadmin2@test.com", + "stepid": "step2", } - self.ajax_post( - reverse("admin:account_add"), - values - ) + self.ajax_post(reverse("admin:account_add"), values) account = User.objects.get(username="superadmin2@test.com") self.client.logout() self.client.login(username="admin@test.com", password="toto") - self.ajax_post( - reverse("admin:account_delete", args=[account.id]), {}, 403 - ) + self.ajax_post(reverse("admin:account_delete", args=[account.id]), {}, 403) def test_domainadmin_dlist_local_domain_not_owned(self): """Check if a domain admin can use a local mailbox he can't @@ -743,22 +763,25 @@ class PermissionsTestCase(ModoTestCase): "address": "all@test.com", "recipients": "user@test.com", "recipients_1": "user@test2.com", - "enabled": True + "enabled": True, } self.ajax_post(reverse("admin:alias_add"), values) def test_domainadmin_master_user(self): """Check domain administrator is not allowed to access this feature.""" values = { - "username": "user10@test.com", "first_name": "Test", - "last_name": "Test", "password1": "Toto1234", - "password2": "Toto1234", "role": "SimpleUsers", "is_active": True, - "master_user": True, "email": "user10@test.com", "stepid": "step2" + "username": "user10@test.com", + "first_name": "Test", + "last_name": "Test", + "password1": "Toto1234", + "password2": "Toto1234", + "role": "SimpleUsers", + "is_active": True, + "master_user": True, + "email": "user10@test.com", + "stepid": "step2", } - self.ajax_post( - reverse("admin:account_add"), - values, status=400 - ) + self.ajax_post(reverse("admin:account_add"), values, status=400) def test_domadmins_permissions(self): """ @@ -767,17 +790,24 @@ class PermissionsTestCase(ModoTestCase): """ dom = models.Domain.objects.get(name="test.com") mb = factories.MailboxFactory( - domain=dom, address="admin2", - user__username="admin2@test.com", user__groups=("DomainAdmins", ), - user__password="{PLAIN}toto") + domain=dom, + address="admin2", + user__username="admin2@test.com", + user__groups=("DomainAdmins",), + user__password="{PLAIN}toto", + ) dom.add_admin(mb.user) self.client.logout() - self.assertTrue( - self.client.login(username="admin@test.com", password="toto")) + self.assertTrue(self.client.login(username="admin@test.com", password="toto")) values = { - "username": "new@test.com", "password1": "Toto1234", - "password2": "Toto1234", "role": "SimpleUsers", "quota_act": True, - "is_active": True, "email": "new@test.com", "stepid": "step2" + "username": "new@test.com", + "password1": "Toto1234", + "password2": "Toto1234", + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": "new@test.com", + "stepid": "step2", } self.ajax_post(reverse("admin:account_add"), values) diff --git a/modoboa/admin/tests/test_alarms.py b/modoboa/admin/tests/test_alarms.py index 560dde817..07691f3f0 100644 --- a/modoboa/admin/tests/test_alarms.py +++ b/modoboa/admin/tests/test_alarms.py @@ -16,8 +16,7 @@ class AlarmsTestCase(ModoTestCase): def test_set_forward(self): domain = Domain.objects.all().first() - alarm = Alarm.objects.create( - domain=domain, mailbox=None, title="Test alarm 3") + alarm = Alarm.objects.create(domain=domain, mailbox=None, title="Test alarm 3") alarm.save() self.assertEqual(alarm.status, 1) alarm.close() diff --git a/modoboa/admin/tests/test_alias.py b/modoboa/admin/tests/test_alias.py index ffb468e0b..94d3a57b7 100644 --- a/modoboa/admin/tests/test_alias.py +++ b/modoboa/admin/tests/test_alias.py @@ -19,29 +19,28 @@ class AliasTestCase(ModoTestCase): def test_alias(self): user = User.objects.get(username="user@test.com") values = { - "username": "user@test.com", "role": user.role, - "is_active": user.is_active, "email": "user@test.com", - "aliases": "toto@test.com", "aliases_1": "titi@test.com", - "language": "en" + "username": "user@test.com", + "role": user.role, + "is_active": user.is_active, + "email": "user@test.com", + "aliases": "toto@test.com", + "aliases_1": "titi@test.com", + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values - ) - self.assertEqual( - AliasRecipient.objects.filter - (alias__internal=False, r_mailbox=user.mailbox) - .count(), 2 - ) - del values["aliases_1"] - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values) self.assertEqual( AliasRecipient.objects.filter( - alias__internal=False, r_mailbox=user.mailbox) - .count(), 1 + alias__internal=False, r_mailbox=user.mailbox + ).count(), + 2, + ) + del values["aliases_1"] + self.ajax_post(reverse("admin:account_change", args=[user.id]), values) + self.assertEqual( + AliasRecipient.objects.filter( + alias__internal=False, r_mailbox=user.mailbox + ).count(), + 1, ) def test_alias_with_duplicated_recipient(self): @@ -50,11 +49,9 @@ class AliasTestCase(ModoTestCase): "address": "badalias@test.com", "recipients": "user@test.com", "recipients_1": "user@test.com", - "enabled": True + "enabled": True, } - self.ajax_post( - reverse("admin:alias_add"), values - ) + self.ajax_post(reverse("admin:alias_add"), values) alias = Alias.objects.get(address="badalias@test.com") self.assertEqual(alias.recipients_count, 1) @@ -62,55 +59,59 @@ class AliasTestCase(ModoTestCase): """Try to create an upper case alias.""" user = User.objects.get(username="user@test.com") values = { - "username": "user@test.com", "role": user.role, - "is_active": user.is_active, "email": "user@test.com", - "aliases": "Toto@test.com", "language": "en" + "username": "user@test.com", + "role": user.role, + "is_active": user.is_active, + "email": "user@test.com", + "aliases": "Toto@test.com", + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values) mb = user.mailbox self.assertEqual( - AliasRecipient.objects - .filter(alias__internal=False, r_mailbox=mb).count(), 1) + AliasRecipient.objects.filter(alias__internal=False, r_mailbox=mb).count(), + 1, + ) self.assertEqual( AliasRecipient.objects.get( - alias__internal=False, r_mailbox=mb).alias.address, - "toto@test.com" + alias__internal=False, r_mailbox=mb + ).alias.address, + "toto@test.com", ) values = { - "address": "Titi@test.com", "recipients": "user@test.com", - "enabled": True + "address": "Titi@test.com", + "recipients": "user@test.com", + "enabled": True, } self.ajax_post(reverse("admin:alias_add"), values) - self.assertTrue( - Alias.objects.filter(address="titi@test.com").exists()) + self.assertTrue(Alias.objects.filter(address="titi@test.com").exists()) def test_append_alias_with_tag(self): """Try to create a alias with tag in recipient address""" user = User.objects.get(username="user@test.com") values = { - "username": "user@test.com", "role": user.role, - "is_active": user.is_active, "email": "user@test.com", - "language": "en" + "username": "user@test.com", + "role": user.role, + "is_active": user.is_active, + "email": "user@test.com", + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values) values = { - "address": "foobar@test.com", "recipients": "user+spam@test.com", - "enabled": True + "address": "foobar@test.com", + "recipients": "user+spam@test.com", + "enabled": True, } self.ajax_post(reverse("admin:alias_add"), values) alias = Alias.objects.get(address="foobar@test.com") self.assertTrue( alias.aliasrecipient_set.filter( - address="user+spam@test.com", r_mailbox__isnull=False, - r_alias__isnull=True).exists() + address="user+spam@test.com", + r_mailbox__isnull=False, + r_alias__isnull=True, + ).exists() ) def test_utf8_alias(self): @@ -120,11 +121,9 @@ class AliasTestCase(ModoTestCase): "recipients": "user@test.com", "recipients_1": "admin@test.com", "recipients_2": "ext@titi.com", - "enabled": True + "enabled": True, } - self.ajax_post( - reverse("admin:alias_add"), values - ) + self.ajax_post(reverse("admin:alias_add"), values) def test_dlist(self): values = { @@ -132,89 +131,68 @@ class AliasTestCase(ModoTestCase): "recipients": "user@test.com", "recipients_1": "admin@test.com", "recipients_2": "ext@titi.com", - "enabled": True + "enabled": True, } - self.ajax_post( - reverse("admin:alias_add"), values - ) + self.ajax_post(reverse("admin:alias_add"), values) user = User.objects.get(username="user@test.com") mb = user.mailbox self.assertEqual( - AliasRecipient.objects.filter( - alias__internal=False, r_mailbox=mb).count(), 2) + AliasRecipient.objects.filter(alias__internal=False, r_mailbox=mb).count(), + 2, + ) admin = User.objects.get(username="admin@test.com") mb = admin.mailbox self.assertEqual( - AliasRecipient.objects.filter( - alias__internal=False, r_mailbox=mb).count(), 1) + AliasRecipient.objects.filter(alias__internal=False, r_mailbox=mb).count(), + 1, + ) dlist = Alias.objects.get(address="all@test.com") self.assertEqual(dlist.recipients_count, 3) del values["recipients_1"] - self.ajax_post( - reverse("admin:alias_change", args=[dlist.id]), - values - ) + self.ajax_post(reverse("admin:alias_change", args=[dlist.id]), values) self.assertEqual(dlist.recipients_count, 2) self.ajax_delete( - "{}?selection={}".format( - reverse("admin:alias_delete"), dlist.id) + "{}?selection={}".format(reverse("admin:alias_delete"), dlist.id) ) - self.assertRaises( - Alias.DoesNotExist, Alias.objects.get, address="all@test.com") + self.assertRaises(Alias.DoesNotExist, Alias.objects.get, address="all@test.com") def test_forward(self): values = {"address": "forward2@test.com", "recipients": "rcpt@dest.com"} - self.ajax_post( - reverse("admin:alias_add"), values - ) + self.ajax_post(reverse("admin:alias_add"), values) fwd = Alias.objects.get(address="forward2@test.com") self.assertEqual(fwd.recipients_count, 1) values["recipients"] = "rcpt2@dest.com" - self.ajax_post( - reverse("admin:alias_change", - args=[fwd.id]), - values - ) + self.ajax_post(reverse("admin:alias_change", args=[fwd.id]), values) self.assertEqual(fwd.recipients_count, 1) - self.ajax_delete( - reverse("admin:alias_delete") + "?selection=%d" - % fwd.id, {} - ) + self.ajax_delete(reverse("admin:alias_delete") + "?selection=%d" % fwd.id, {}) self.assertRaises( - Alias.DoesNotExist, Alias.objects.get, address="forward2@test.com") + Alias.DoesNotExist, Alias.objects.get, address="forward2@test.com" + ) def test_forward_and_local_copies(self): values = {"address": "user@test.com", "recipients": "rcpt@dest.com"} - self.ajax_post( - reverse("admin:alias_add"), values - ) + self.ajax_post(reverse("admin:alias_add"), values) fwd = Alias.objects.get(address="user@test.com", internal=False) self.assertEqual(fwd.recipients_count, 1) values["recipients"] = "rcpt@dest.com" values["recipients_1"] = "user@test.com" - self.ajax_post( - reverse("admin:alias_change", args=[fwd.id]), - values - ) + self.ajax_post(reverse("admin:alias_change", args=[fwd.id]), values) fwd = Alias.objects.get(pk=fwd.pk) self.assertEqual(fwd.aliasrecipient_set.count(), 2) - self.assertEqual( - fwd.aliasrecipient_set.filter(r_alias__isnull=True).count(), 2) + self.assertEqual(fwd.aliasrecipient_set.filter(r_alias__isnull=True).count(), 2) def test_wildcard_alias(self): """Test creation of a wildcard alias.""" values = { "address": "@test.com", "recipients": "user@test.com", - "enabled": True + "enabled": True, } - self.ajax_post( - reverse("admin:alias_add"), values - ) + self.ajax_post(reverse("admin:alias_add"), values) def test_random_alias(self): """Test creation of a random alias.""" @@ -223,7 +201,7 @@ class AliasTestCase(ModoTestCase): "random_address": True, "domain": Domain.objects.get(name="test.com").pk, "recipients": "user@test.com", - "enabled": True + "enabled": True, } self.ajax_post(reverse("admin:alias_add"), values) self.assertEqual(Alias.objects.count(), alias_count + 1) @@ -234,31 +212,34 @@ class AliasTestCase(ModoTestCase): def test_distribution_list_deletion_on_user_update_bug(self): """This test demonstrates an issue with distribution list being - deleted when one of the users which belong to that list is - changed. + deleted when one of the users which belong to that list is + changed. """ values = { "address": "list@test.com", "recipients": "user@test.com", "recipients_1": "admin@test.com", - "enabled": True + "enabled": True, } - self.ajax_post( - reverse("admin:alias_add"), values - ) + self.ajax_post(reverse("admin:alias_add"), values) user = User.objects.get(username="user@test.com") values = { - "username": user.username, "first_name": "Tester", - "last_name": "Toto", "password1": "Toto1234", - "password2": "Toto1234", "role": "SimpleUsers", "quota_act": True, - "is_active": True, "email": user.email, "language": "en" + "username": user.username, + "first_name": "Tester", + "last_name": "Toto", + "password1": "Toto1234", + "password2": "Toto1234", + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": user.email, + "language": "en", } self.ajax_post(reverse("admin:account_change", args=[user.id]), values) - self.assertEqual( - Alias.objects.filter(address="list@test.com").count(), 1) + self.assertEqual(Alias.objects.filter(address="list@test.com").count(), 1) def test_alias_detail_view(self): """Test alias detail view.""" @@ -276,15 +257,18 @@ class AliasTestCase(ModoTestCase): user = User.objects.get(username="user@test.com") values = { - "username": "user@test.com", "role": user.role, - "is_active": user.is_active, "email": "user@test.com", - "aliases": "toto@test.com", "aliases_1": "titi@test2.com", - "language": "en" + "username": "user@test.com", + "role": user.role, + "is_active": user.is_active, + "email": "user@test.com", + "aliases": "toto@test.com", + "aliases_1": "titi@test2.com", + "language": "en", } response = self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values, 400 + reverse("admin:account_change", args=[user.id]), values, 400 ) self.assertEqual( response["form_errors"]["aliases_1"][0], - "You don't have access to this domain") + "You don't have access to this domain", + ) diff --git a/modoboa/admin/tests/test_domain.py b/modoboa/admin/tests/test_domain.py index 32da141c4..f0b7fcd40 100644 --- a/modoboa/admin/tests/test_domain.py +++ b/modoboa/admin/tests/test_domain.py @@ -20,7 +20,7 @@ from modoboa.core.tests.test_views import SETTINGS_SAMPLE from modoboa.lib.tests import ModoTestCase from modoboa.maillog import factories as ml_factories -from ..import constants +from .. import constants from . import utils from .. import factories from ..models import Alarm, Alias, Domain @@ -38,8 +38,12 @@ class DomainTestCase(ModoTestCase): def test_create(self): """Test the creation of a domain.""" values = { - "name": "pouet.com", "quota": 1000, "default_mailbox_quota": 100, - "create_dom_admin": False, "type": "domain", "stepid": "step3" + "name": "pouet.com", + "quota": 1000, + "default_mailbox_quota": 100, + "create_dom_admin": False, + "type": "domain", + "stepid": "step3", } self.ajax_post(reverse("admin:domain_add"), values) dom = Domain.objects.get(name="pouet.com") @@ -52,12 +56,16 @@ class DomainTestCase(ModoTestCase): def test_create_utf8(self): """Test the creation of a domain with non-ASCII characters.""" values = { - "name": "pouét.com", "quota": 1000, "default_mailbox_quota": 100, - "create_dom_admin": False, "type": "domain", "stepid": "step3" + "name": "pouét.com", + "quota": 1000, + "default_mailbox_quota": 100, + "create_dom_admin": False, + "type": "domain", + "stepid": "step3", } self.ajax_post(reverse("admin:domain_add"), values) - dom = Domain.objects.get(name=u"pouét.com") - self.assertEqual(dom.name, u"pouét.com") + dom = Domain.objects.get(name="pouét.com") + self.assertEqual(dom.name, "pouét.com") self.assertEqual(dom.quota, 1000) self.assertEqual(dom.default_mailbox_quota, 100) self.assertEqual(dom.enabled, False) @@ -66,83 +74,101 @@ class DomainTestCase(ModoTestCase): def test_create_with_template(self): """Test the creation of a domain with a template.""" values = { - "name": "pouet.com", "quota": 1000, "default_mailbox_quota": 100, - "create_dom_admin": True, "dom_admin_username": "toto", - "with_mailbox": True, "create_aliases": True, "type": "domain", - "stepid": "step3" + "name": "pouet.com", + "quota": 1000, + "default_mailbox_quota": 100, + "create_dom_admin": True, + "dom_admin_username": "toto", + "with_mailbox": True, + "create_aliases": True, + "type": "domain", + "stepid": "step3", } self.ajax_post(reverse("admin:domain_add"), values) dom = Domain.objects.get(name="pouet.com") da = User.objects.get(username="toto@pouet.com") self.assertIn(da, dom.admins) al = Alias.objects.get(address="postmaster@pouet.com") - self.assertTrue( - al.aliasrecipient_set.filter(r_mailbox=da.mailbox) - .exists() - ) + self.assertTrue(al.aliasrecipient_set.filter(r_mailbox=da.mailbox).exists()) self.assertTrue(da.can_access(al)) values = { - "name": "pouet2.com", "quota": 1000, "default_mailbox_quota": 100, - "create_dom_admin": True, "dom_admin_username": "postmaster", - "create_aliases": True, "type": "domain", "stepid": "step3", - "with_mailbox": True + "name": "pouet2.com", + "quota": 1000, + "default_mailbox_quota": 100, + "create_dom_admin": True, + "dom_admin_username": "postmaster", + "create_aliases": True, + "type": "domain", + "stepid": "step3", + "with_mailbox": True, } self.ajax_post(reverse("admin:domain_add"), values) - self.assertTrue( - User.objects.filter(username="postmaster@pouet2.com").exists()) + self.assertTrue(User.objects.filter(username="postmaster@pouet2.com").exists()) self.assertFalse( Alias.objects.filter( - address="postmaster@pouet2.com", internal=False).exists()) + address="postmaster@pouet2.com", internal=False + ).exists() + ) def test_create_with_template_and_random_password(self): """Test domain creation with administrator and random password.""" values = { - "name": "pouet.com", "quota": 1000, "default_mailbox_quota": 100, - "create_dom_admin": True, "dom_admin_username": "toto", - "with_mailbox": True, "create_aliases": True, "type": "domain", - "stepid": "step3", "random_password": True + "name": "pouet.com", + "quota": 1000, + "default_mailbox_quota": 100, + "create_dom_admin": True, + "dom_admin_username": "toto", + "with_mailbox": True, + "create_aliases": True, + "type": "domain", + "stepid": "step3", + "random_password": True, } self.ajax_post(reverse("admin:domain_add"), values) self.assertFalse( - self.client.login(username="admin@pouet.com", password="password")) + self.client.login(username="admin@pouet.com", password="password") + ) def test_create_with_template_and_no_mailbox(self): """Test domain creation with administrator but no mailbox.""" values = { - "name": "pouet.com", "quota": 1000, "default_mailbox_quota": 100, - "create_dom_admin": True, "dom_admin_username": "toto", - "with_mailbox": False, "create_aliases": True, "type": "domain", - "stepid": "step3" + "name": "pouet.com", + "quota": 1000, + "default_mailbox_quota": 100, + "create_dom_admin": True, + "dom_admin_username": "toto", + "with_mailbox": False, + "create_aliases": True, + "type": "domain", + "stepid": "step3", } self.ajax_post(reverse("admin:domain_add"), values) dom = Domain.objects.get(name="pouet.com") da = User.objects.get(username="toto@pouet.com") self.assertIn(da, dom.admins) self.assertFalse(hasattr(da, "mailbox")) - self.assertFalse( - Alias.objects.filter(address="postmaster@pouet.com").exists()) + self.assertFalse(Alias.objects.filter(address="postmaster@pouet.com").exists()) def test_create_with_template_and_empty_quota(self): """Test the creation of a domain with a template and no quota""" values = { - "name": "pouet.com", "quota": 0, "default_mailbox_quota": 0, - "create_dom_admin": True, "dom_admin_username": "toto", - "create_aliases": True, "type": "domain", "stepid": "step3", - "with_mailbox": True + "name": "pouet.com", + "quota": 0, + "default_mailbox_quota": 0, + "create_dom_admin": True, + "dom_admin_username": "toto", + "create_aliases": True, + "type": "domain", + "stepid": "step3", + "with_mailbox": True, } - self.ajax_post( - reverse("admin:domain_add"), - values - ) + self.ajax_post(reverse("admin:domain_add"), values) dom = Domain.objects.get(name="pouet.com") da = User.objects.get(username="toto@pouet.com") self.assertIn(da, dom.admins) al = Alias.objects.get(address="postmaster@pouet.com") - self.assertTrue( - al.aliasrecipient_set.filter(r_mailbox=da.mailbox) - .exists() - ) + self.assertTrue(al.aliasrecipient_set.filter(r_mailbox=da.mailbox).exists()) self.assertTrue(da.can_access(al)) def test_create_with_template_and_custom_password(self): @@ -150,61 +176,62 @@ class DomainTestCase(ModoTestCase): password = "Toto1000" self.set_global_parameter("default_password", password, app="core") values = { - "name": "pouet.com", "quota": 0, "default_mailbox_quota": 0, - "create_dom_admin": True, "dom_admin_username": "toto", - "create_aliases": True, "type": "domain", "stepid": "step3", - "with_mailbox": True + "name": "pouet.com", + "quota": 0, + "default_mailbox_quota": 0, + "create_dom_admin": True, + "dom_admin_username": "toto", + "create_aliases": True, + "type": "domain", + "stepid": "step3", + "with_mailbox": True, } - self.ajax_post( - reverse("admin:domain_add"), - values - ) + self.ajax_post(reverse("admin:domain_add"), values) dom = Domain.objects.get(name="pouet.com") da = User.objects.get(username="toto@pouet.com") self.assertIn(da, dom.admins) al = Alias.objects.get(address="postmaster@pouet.com") - self.assertTrue( - al.aliasrecipient_set.filter(r_mailbox=da.mailbox) - .exists() - ) + self.assertTrue(al.aliasrecipient_set.filter(r_mailbox=da.mailbox).exists()) self.assertTrue(da.can_access(al)) - self.assertTrue( - self.client.login(username="toto@pouet.com", password=password)) + self.assertTrue(self.client.login(username="toto@pouet.com", password=password)) def test_quota_constraints(self): """Check quota constraints.""" values = { - "name": "pouet.com", "quota": 10, "default_mailbox_quota": 100, - "create_dom_admin": True, "dom_admin_username": "toto", - "create_aliases": True, "type": "domain", "stepid": "step3" + "name": "pouet.com", + "quota": 10, + "default_mailbox_quota": 100, + "create_dom_admin": True, + "dom_admin_username": "toto", + "create_aliases": True, + "type": "domain", + "stepid": "step3", } - response = self.ajax_post( - reverse("admin:domain_add"), - values, status=400 - ) + response = self.ajax_post(reverse("admin:domain_add"), values, status=400) self.assertEqual( response["form_errors"]["default_mailbox_quota"][0], - "Cannot be greater than domain quota") + "Cannot be greater than domain quota", + ) dom = Domain.objects.get(name="test.com") values["name"] = dom.name values["quota"] = 10 values["default_mailbox_quota"] = 100 response = self.ajax_post( - reverse("admin:domain_change", args=[dom.pk]), - values, status=400 + reverse("admin:domain_change", args=[dom.pk]), values, status=400 ) self.assertEqual( response["form_errors"]["default_mailbox_quota"][0], - "Cannot be greater than domain quota") + "Cannot be greater than domain quota", + ) def test_create_using_default_quota(self): """Check that default value is used for creation.""" self.set_global_parameter("default_domain_quota", 500) self.set_global_parameter("default_mailbox_quota", 50) response = self.client.get(reverse("admin:domain_add")) - self.assertContains(response, "value=\"500\"") - self.assertContains(response, "value=\"50\"") + self.assertContains(response, 'value="500"') + self.assertContains(response, 'value="50"') @mock.patch.object(dns.resolver.Resolver, "resolve") @mock.patch("socket.getaddrinfo") @@ -214,7 +241,8 @@ class DomainTestCase(ModoTestCase): mock_getaddrinfo.side_effect = utils.mock_ip_query_result reseller = core_factories.UserFactory( - username="reseller", groups=("Resellers", )) + username="reseller", groups=("Resellers",) + ) self.client.force_login(reseller) self.set_global_parameter("enable_admin_limits", False, app="limits") @@ -222,15 +250,18 @@ class DomainTestCase(ModoTestCase): self.set_global_parameter("domains_must_have_authorized_mx", True) values = { - "name": "no-mx.example.com", "quota": 0, + "name": "no-mx.example.com", + "quota": 0, "default_mailbox_quota": 0, - "create_dom_admin": True, "dom_admin_username": "toto", - "create_aliases": True, "type": "domain", "stepid": "step3", - "with_mailbox": True + "create_dom_admin": True, + "dom_admin_username": "toto", + "create_aliases": True, + "type": "domain", + "stepid": "step3", + "with_mailbox": True, } self.ajax_post(reverse("admin:domain_add"), values, 400) - self.assertFalse( - Domain.objects.filter(name=values["name"]).exists()) + self.assertFalse(Domain.objects.filter(name=values["name"]).exists()) values["name"] = "pouet.com" mock_getaddrinfo.side_effect = utils.mock_ip_query_result @@ -242,21 +273,20 @@ class DomainTestCase(ModoTestCase): Rename 'test.com' domain to 'pouet.com' """ values = { - "name": "pouet.com", "quota": 1000, "default_mailbox_quota": 100, - "type": "domain", "enabled": True + "name": "pouet.com", + "quota": 1000, + "default_mailbox_quota": 100, + "type": "domain", + "enabled": True, } dom = Domain.objects.get(name="test.com") - self.ajax_post( - reverse("admin:domain_change", args=[dom.id]), - values - ) + self.ajax_post(reverse("admin:domain_change", args=[dom.id]), values) dom = Domain.objects.get(name="pouet.com") self.assertEqual(dom.name, "pouet.com") self.assertTrue(dom.enabled) # Check if aliases were renamed too - self.assertTrue( - dom.alias_set.filter(address="postmaster@pouet.com").exists()) + self.assertTrue(dom.alias_set.filter(address="postmaster@pouet.com").exists()) def test_delete(self): """Test the removal of a domain.""" @@ -264,15 +294,13 @@ class DomainTestCase(ModoTestCase): self.ajax_post(reverse("admin:domain_delete", args=[dom.id])) with self.assertRaises(Domain.DoesNotExist): Domain.objects.get(pk=1) - self.assertTrue( - User.objects.filter(username="user@test.com").exists()) + self.assertTrue(User.objects.filter(username="user@test.com").exists()) self.set_global_parameter("auto_account_removal", True) dom = Domain.objects.get(name="test2.com") self.ajax_post(reverse("admin:domain_delete", args=[dom.id])) with self.assertRaises(Domain.DoesNotExist): Domain.objects.get(pk=1) - self.assertFalse( - User.objects.filter(username="admin@test2.com").exists()) + self.assertFalse(User.objects.filter(username="admin@test2.com").exists()) def test_domain_counters(self): """Check counters at domain level.""" @@ -347,8 +375,10 @@ class DomainTestCase(ModoTestCase): domain = Domain.objects.get(name="test.com") ml_factories.MaillogFactory(from_domain=domain) ml_factories.MaillogFactory( - to_domain=domain, status="received", - date=timezone.now() + relativedelta(days=1)) + to_domain=domain, + status="received", + date=timezone.now() + relativedelta(days=1), + ) ml_factories.MaillogFactory(date=timezone.now() + relativedelta(days=2)) ml_factories.MaillogFactory(date=timezone.now() + relativedelta(days=3)) url = reverse("admin:domain_logs_list") @@ -375,8 +405,7 @@ class DomainTestCase(ModoTestCase): self.assertEqual(response.status_code, 200) self.assertIn("Global statistics", response.content.decode("utf-8")) - self.client.force_login( - User.objects.get(username="admin@test.com")) + self.client.force_login(User.objects.get(username="admin@test.com")) response = self.client.get(url) self.assertEqual(response.status_code, 200) content = response.content.decode("utf-8") @@ -386,7 +415,8 @@ class DomainTestCase(ModoTestCase): def test_page_loader(self): """Test page loader view.""" factories.AlarmFactory( - domain__name="test.com", mailbox=None, title="Test alarm") + domain__name="test.com", mailbox=None, title="Test alarm" + ) url = reverse("admin:domain_page") response = self.ajax_get(url) self.assertIn("handle_mailboxes", response) @@ -418,10 +448,13 @@ class DKIMTestCase(ModoTestCase): settings["admin-dkim_keys_storage_dir"] = "/wrong" response = self.client.post(url, settings, format="json") self.assertEqual(response.status_code, 400) - compare(response.json(), { - "form_errors": {"dkim_keys_storage_dir": ["Directory not found."]}, - "prefix": "admin" - }) + compare( + response.json(), + { + "form_errors": {"dkim_keys_storage_dir": ["Directory not found."]}, + "prefix": "admin", + }, + ) settings["admin-dkim_keys_storage_dir"] = self.workdir response = self.client.post(url, settings, format="json") self.assertEqual(response.status_code, 200) @@ -429,20 +462,26 @@ class DKIMTestCase(ModoTestCase): def test_dkim_key_creation(self): """Test DKIM key creation.""" values = { - "name": "pouet.com", "quota": 1000, "default_mailbox_quota": 100, - "create_dom_admin": False, "type": "domain", "stepid": "step3", - "enable_dkim": True, "dkim_key_selector": "" + "name": "pouet.com", + "quota": 1000, + "default_mailbox_quota": 100, + "create_dom_admin": False, + "type": "domain", + "stepid": "step3", + "enable_dkim": True, + "dkim_key_selector": "", } response = self.ajax_post(reverse("admin:domain_add"), values, 400) self.assertEqual( response["form_errors"]["enable_dkim"][0], - "DKIM keys storage directory not configured") + "DKIM keys storage directory not configured", + ) self.set_global_parameter("dkim_keys_storage_dir", self.workdir) response = self.ajax_post(reverse("admin:domain_add"), values, 400) self.assertEqual( - response["form_errors"]["dkim_key_selector"][0], - "This field is required.") + response["form_errors"]["dkim_key_selector"][0], "This field is required." + ) values["dkim_key_selector"] = "default" self.ajax_post(reverse("admin:domain_add"), values) @@ -453,30 +492,33 @@ class DKIMTestCase(ModoTestCase): domain = Domain.objects.get(name=values["name"]) # Closing the alarm and retry generating dkim keys - Alarm.objects.get(domain=domain, - internal_name=constants.DKIM_WRITE_ERROR - ).close() + Alarm.objects.get( + domain=domain, internal_name=constants.DKIM_WRITE_ERROR + ).close() call_command("modo", "manage_dkim_keys") self.assertEqual( - Alarm.objects.get(domain=domain, - internal_name=constants.DKIM_WRITE_ERROR).status, - constants.ALARM_OPENED) + Alarm.objects.get( + domain=domain, internal_name=constants.DKIM_WRITE_ERROR + ).status, + constants.ALARM_OPENED, + ) # Generate normally self.set_global_parameter("dkim_keys_storage_dir", self.workdir) call_command("modo", "manage_dkim_keys") self.assertEqual( - Alarm.objects.get(domain=domain, - internal_name=constants.DKIM_WRITE_ERROR).status, - constants.ALARM_CLOSED) + Alarm.objects.get( + domain=domain, internal_name=constants.DKIM_WRITE_ERROR + ).status, + constants.ALARM_CLOSED, + ) key_path = os.path.join(self.workdir, "{}.pem".format(values["name"])) self.assertTrue(os.path.exists(key_path)) domain.refresh_from_db() url = reverse("admin:domain_detail", args=[domain.pk]) response = self.client.get(url) - self.assertContains( - response, escape(domain.bind_format_dkim_public_key)) + self.assertContains(response, escape(domain.bind_format_dkim_public_key)) # Try generating DKIM key for a targetted domain domain.dkim_private_key_path = "" @@ -488,14 +530,13 @@ class DKIMTestCase(ModoTestCase): # Try disabling DKIM and checking that dkim_private_key_path is emptied values = { - "name": "pouet.com", "enable_dkim": False, - "quota": 1000, "default_mailbox_quota": 100, - "type": "domain" + "name": "pouet.com", + "enable_dkim": False, + "quota": 1000, + "default_mailbox_quota": 100, + "type": "domain", } - self.ajax_post( - reverse("admin:domain_change", args=[domain.id]), - values - ) + self.ajax_post(reverse("admin:domain_change", args=[domain.id]), values) domain.refresh_from_db() self.assertEqual(domain.dkim_private_key_path, "") @@ -503,9 +544,14 @@ class DKIMTestCase(ModoTestCase): """ """ self.set_global_parameter("dkim_keys_storage_dir", self.workdir) values = { - "name": "pouet.com", "quota": 1000, "default_mailbox_quota": 100, - "create_dom_admin": False, "type": "domain", "stepid": "step3", - "enable_dkim": True, "dkim_key_selector": "default" + "name": "pouet.com", + "quota": 1000, + "default_mailbox_quota": 100, + "create_dom_admin": False, + "type": "domain", + "stepid": "step3", + "enable_dkim": True, + "dkim_key_selector": "default", } self.ajax_post(reverse("admin:domain_add"), values) call_command("modo", "manage_dkim_keys") diff --git a/modoboa/admin/tests/test_domain_alias.py b/modoboa/admin/tests/test_domain_alias.py index 7559c7d8a..6cf4f07cf 100644 --- a/modoboa/admin/tests/test_domain_alias.py +++ b/modoboa/admin/tests/test_domain_alias.py @@ -21,37 +21,30 @@ class DomainAliasTestCase(ModoTestCase): domal.target = dom domal.save() self.assertEqual(dom.domainalias_count, 1) - self.assertTrue( - Alias.objects.filter( - address="@{}".format(domal.name)).exists()) + self.assertTrue(Alias.objects.filter(address="@{}".format(domal.name)).exists()) domal.name = "domalias.org" domal.save() domal.delete() self.assertFalse( - Alias.objects.filter( - address="@{}".format(domal.name)).exists()) + Alias.objects.filter(address="@{}".format(domal.name)).exists() + ) def test_form(self): dom = Domain.objects.get(name="test.com") values = { - "name": dom.name, "quota": dom.quota, + "name": dom.name, + "quota": dom.quota, "default_mailbox_quota": dom.default_mailbox_quota, - "enabled": dom.enabled, "aliases": "domalias.net", - "aliases_1": "domaliasé.com", "type": "domain" + "enabled": dom.enabled, + "aliases": "domalias.net", + "aliases_1": "domaliasé.com", + "type": "domain", } - self.ajax_post( - reverse("admin:domain_change", - args=[dom.id]), - values - ) + self.ajax_post(reverse("admin:domain_change", args=[dom.id]), values) self.assertEqual(dom.domainalias_set.count(), 2) del values["aliases_1"] - self.ajax_post( - reverse("admin:domain_change", - args=[dom.id]), - values - ) + self.ajax_post(reverse("admin:domain_change", args=[dom.id]), values) self.assertEqual(dom.domainalias_set.count(), 1) diff --git a/modoboa/admin/tests/test_export.py b/modoboa/admin/tests/test_export.py index 9317dd7ad..0de2728e0 100644 --- a/modoboa/admin/tests/test_export.py +++ b/modoboa/admin/tests/test_export.py @@ -22,20 +22,19 @@ class ExportTestCase(ModoTestCase): def __export_domains(self, domfilter=""): self.client.get( - "{}?domfilter={}".format( - reverse("admin:_domain_list"), domfilter)) + "{}?domfilter={}".format(reverse("admin:_domain_list"), domfilter) + ) return self.client.post( reverse("admin:domain_export"), {"filename": "test.csv"} ) def __export_identities(self, idtfilter="", grpfilter=""): self.client.get( - reverse("admin:_identity_list") + - "?grpfilter=%s&idtfilter=%s" % (grpfilter, idtfilter) + reverse("admin:_identity_list") + + "?grpfilter=%s&idtfilter=%s" % (grpfilter, idtfilter) ) return self.client.post( - reverse("admin:identity_export"), - {"filename": "test.csv"} + reverse("admin:identity_export"), {"filename": "test.csv"} ) def test_export_domains(self): @@ -49,8 +48,7 @@ class ExportTestCase(ModoTestCase): "domain;test2.com;0;0;True", ] self.assertCountEqual( - expected_response, - force_str(response.content.strip()).split("\r\n") + expected_response, force_str(response.content.strip()).split("\r\n") ) # Test management command too. @@ -59,7 +57,8 @@ class ExportTestCase(ModoTestCase): response = sys.stdout.getvalue() sys.stdout = stdout_backup self.assertCountEqual( - expected_response, force_str(response.strip()).split("\r\n")) + expected_response, force_str(response.strip()).split("\r\n") + ) def test_export_identities(self): response = self.__export_identities() @@ -69,16 +68,15 @@ class ExportTestCase(ModoTestCase): admin_row = received_content[0].split(";") admin_row[2] = "" received_content[0] = ";".join(admin_row) - self.assertCountEqual( - expected_response.strip().split("\r\n"), - received_content - ) + self.assertCountEqual(expected_response.strip().split("\r\n"), received_content) def test_export_simpleusers(self): factories.MailboxFactory( user__username="toto@test.com", - user__first_name="Léon", user__groups=("SimpleUsers", ), - address="toto", domain__name="test.com", + user__first_name="Léon", + user__groups=("SimpleUsers",), + address="toto", + domain__name="test.com", ) response = self.__export_identities( idtfilter="account", grpfilter="SimpleUsers" @@ -86,7 +84,7 @@ class ExportTestCase(ModoTestCase): expected_response = "account;user@test.com;{PLAIN}toto;;;True;SimpleUsers;user@test.com;10\r\naccount;user@test2.com;{PLAIN}toto;;;True;SimpleUsers;user@test2.com;10\r\naccount;toto@test.com;{PLAIN}toto;Léon;;True;SimpleUsers;toto@test.com;10" # NOQA:E501 self.assertCountEqual( expected_response.split("\r\n"), - force_str(response.content.strip()).split("\r\n") + force_str(response.content.strip()).split("\r\n"), ) def test_export_superadmins(self): @@ -100,9 +98,7 @@ class ExportTestCase(ModoTestCase): elements = response.content.decode().strip().split(";") self.assertEqual(len(elements), 9) elements[2] = "" - self.assertEqual( - ";".join(elements), "account;admin;;;;True;SuperAdmins;;" - ) + self.assertEqual(";".join(elements), "account;admin;;;;True;SuperAdmins;;") def test_export_domainadmins(self): response = self.__export_identities( @@ -111,12 +107,12 @@ class ExportTestCase(ModoTestCase): expected_response = "account;admin@test.com;{PLAIN}toto;;;True;DomainAdmins;admin@test.com;10;test.com\r\naccount;admin@test2.com;{PLAIN}toto;;;True;DomainAdmins;admin@test2.com;10;test2.com" # NOQA:E501 self.assertCountEqual( expected_response.split("\r\n"), - force_str(response.content.strip()).split("\r\n") + force_str(response.content.strip()).split("\r\n"), ) def test_export_aliases(self): response = self.__export_identities(idtfilter="alias") self.assertEqual( response.content.decode().strip(), - "alias;alias@test.com;True;user@test.com\r\nalias;forward@test.com;True;user@external.com\r\nalias;postmaster@test.com;True;test@truc.fr;toto@titi.com" # NOQA:E501 + "alias;alias@test.com;True;user@test.com\r\nalias;forward@test.com;True;user@external.com\r\nalias;postmaster@test.com;True;test@truc.fr;toto@titi.com", # NOQA:E501 ) diff --git a/modoboa/admin/tests/test_import_.py b/modoboa/admin/tests/test_import_.py index e9e89038f..5a72ba6d5 100644 --- a/modoboa/admin/tests/test_import_.py +++ b/modoboa/admin/tests/test_import_.py @@ -22,8 +22,7 @@ class ImportTestCase(ModoTestCase): def setUpTestData(cls): # NOQA:N802 """Create test data.""" super(ImportTestCase, cls).setUpTestData() - cls.localconfig.parameters.set_value( - "enable_admin_limits", False, app="limits") + cls.localconfig.parameters.set_value("enable_admin_limits", False, app="limits") cls.localconfig.save() factories.populate_database() @@ -32,15 +31,14 @@ class ImportTestCase(ModoTestCase): self.assertEqual(response.status_code, 200) self.assertIn("Provide a CSV", response.content.decode()) - f = ContentFile(b"""domain; domain1.com; 1000; 100; True + f = ContentFile( + b"""domain; domain1.com; 1000; 100; True domain; domain2.com; 1000; 200; False domainalias; domalias1.com; domain1.com; True -""", name="domains.csv") - self.client.post( - reverse("admin:domain_import"), { - "sourcefile": f - } +""", + name="domains.csv", ) + self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) admin = User.objects.get(username="admin") dom = Domain.objects.get(name="domain1.com") self.assertEqual(dom.quota, 1000) @@ -59,25 +57,21 @@ domainalias; domalias1.com; domain1.com; True def test_domain_import_bad_syntax(self): """Check errors handling.""" url = reverse("admin:domain_import") - f = ContentFile("domain; domain1.com; 100; True", - name="domains.csv") + f = ContentFile("domain; domain1.com; 100; True", name="domains.csv") response = self.client.post(url, {"sourcefile": f}) self.assertContains(response, "Invalid line") - f = ContentFile("domain; domain1.com; XX; 100; True", - name="domains.csv") + f = ContentFile("domain; domain1.com; XX; 100; True", name="domains.csv") response = self.client.post(url, {"sourcefile": f}) self.assertContains(response, "domain1.com: invalid quota value") - f = ContentFile("domain; domain1.com; 100; XX; True", - name="domains.csv") + f = ContentFile("domain; domain1.com; 100; XX; True", name="domains.csv") response = self.client.post(url, {"sourcefile": f}) - self.assertContains( - response, "domain1.com: invalid default mailbox quota") - f = ContentFile("domain; domain1.com; 10; 100; True", - name="domains.csv") + self.assertContains(response, "domain1.com: invalid default mailbox quota") + f = ContentFile("domain; domain1.com; 10; 100; True", name="domains.csv") response = self.client.post(url, {"sourcefile": f}) self.assertContains( response, - "domain1.com: default mailbox quota cannot be greater than domain quota") + "domain1.com: default mailbox quota cannot be greater than domain quota", + ) @mock.patch.object(dns.resolver.Resolver, "resolve") @mock.patch("socket.getaddrinfo") @@ -86,60 +80,49 @@ domainalias; domalias1.com; domain1.com; True mock_query.side_effect = utils.mock_dns_query_result mock_getaddrinfo.side_effect = utils.mock_ip_query_result reseller = core_factories.UserFactory( - username="reseller", groups=("Resellers", )) + username="reseller", groups=("Resellers",) + ) self.client.force_login(reseller) self.set_global_parameter("valid_mxs", "192.0.2.1 2001:db8::1") self.set_global_parameter("domains_must_have_authorized_mx", True) - f = ContentFile( - b"domain; test3.com; 100; 1; True", name="domains.csv") - resp = self.client.post( - reverse("admin:domain_import"), { - "sourcefile": f - } - ) - self.assertContains( - resp, "test3.com: no authorized MX record found for domain") + f = ContentFile(b"domain; test3.com; 100; 1; True", name="domains.csv") + resp = self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) + self.assertContains(resp, "test3.com: no authorized MX record found for domain") mock_getaddrinfo.side_effect = utils.mock_ip_query_result - f = ContentFile( - b"domain; domain1.com; 100; 1; True", name="domains.csv") - resp = self.client.post( - reverse("admin:domain_import"), { - "sourcefile": f - } - ) - self.assertTrue( - Domain.objects.filter(name="domain1.com").exists()) + f = ContentFile(b"domain; domain1.com; 100; 1; True", name="domains.csv") + resp = self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) + self.assertTrue(Domain.objects.filter(name="domain1.com").exists()) def test_import_domains_with_conflict(self): - f = ContentFile(b"""domain;test.alias;100;10;True + f = ContentFile( + b"""domain;test.alias;100;10;True domainalias;test.alias;test.com;True -""", name="domains.csv") - resp = self.client.post( - reverse("admin:domain_import"), { - "sourcefile": f - } +""", + name="domains.csv", ) - self.assertIn( - "Object already exists: domainalias", resp.content.decode()) + resp = self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) + self.assertIn("Object already exists: domainalias", resp.content.decode()) def test_identities_import(self): response = self.client.get(reverse("admin:identity_import")) self.assertEqual(response.status_code, 200) self.assertIn("Provide a CSV", response.content.decode()) - f = ContentFile(""" + f = ContentFile( + """ account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; 0 account; Truc@test.com; toto; René; Truc; True; DomainAdmins; truc@test.com; 5; test.com alias; alias1@test.com; True; user1@test.com forward; alias2@test.com; True; user1+ext@test.com forward; fwd1@test.com; True; user@extdomain.com dlist; dlist@test.com; True; user1@test.com; user@extdomain.com -""", name="identities.csv") # NOQA:E501 +""", + name="identities.csv", + ) # NOQA:E501 self.client.post( - reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True} + reverse("admin:identity_import"), {"sourcefile": f, "crypt_password": True} ) admin = User.objects.get(username="admin") u1 = User.objects.get(username="user1@test.com") @@ -154,13 +137,11 @@ dlist; dlist@test.com; True; user1@test.com; user@extdomain.com self.assertEqual(mb1.quota, 0) self.assertTrue(admin.is_owner(mb1)) self.assertEqual(mb1.full_address, "user1@test.com") - self.assertTrue( - self.client.login(username="user1@test.com", password="toto") - ) + self.assertTrue(self.client.login(username="user1@test.com", password="toto")) da = User.objects.get(username="truc@test.com") damb = da.mailbox - self.assertEqual(da.first_name, u"René") + self.assertEqual(da.first_name, "René") self.assertEqual(da.role, "DomainAdmins") self.assertEqual(damb.quota, 5) self.assertFalse(damb.use_domain_quota) @@ -171,52 +152,48 @@ dlist; dlist@test.com; True; user1@test.com; user@extdomain.com self.assertTrue(da.can_access(u)) al = Alias.objects.get(address="alias1@test.com") - self.assertTrue( - al.aliasrecipient_set - .filter(r_mailbox=u1.mailbox).exists() - ) + self.assertTrue(al.aliasrecipient_set.filter(r_mailbox=u1.mailbox).exists()) self.assertTrue(admin.is_owner(al)) fwd = Alias.objects.get(address="fwd1@test.com") self.assertTrue( - fwd.aliasrecipient_set - .filter( - address="user@extdomain.com", r_mailbox__isnull=True, - r_alias__isnull=True) - .exists() + fwd.aliasrecipient_set.filter( + address="user@extdomain.com", + r_mailbox__isnull=True, + r_alias__isnull=True, + ).exists() ) self.assertTrue(admin.is_owner(fwd)) dlist = Alias.objects.get(address="dlist@test.com") + self.assertTrue(dlist.aliasrecipient_set.filter(r_mailbox=u1.mailbox).exists()) self.assertTrue( - dlist.aliasrecipient_set - .filter(r_mailbox=u1.mailbox).exists() - ) - self.assertTrue( - dlist.aliasrecipient_set.filter(address="user@extdomain.com") - .exists() + dlist.aliasrecipient_set.filter(address="user@extdomain.com").exists() ) self.assertTrue(admin.is_owner(dlist)) def test_import_for_nonlocal_domain(self): """Try to import an account for nonlocal domain.""" - f = ContentFile(b""" + f = ContentFile( + b""" account; user1@nonlocal.com; toto; User; One; True; SimpleUsers; user1@nonlocal.com; 0 -""", name="identities.csv") # NOQA:E501 +""", + name="identities.csv", + ) # NOQA:E501 self.client.post( - reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True} + reverse("admin:identity_import"), {"sourcefile": f, "crypt_password": True} ) - self.assertFalse( - User.objects.filter(username="user1@nonlocal.com").exists()) + self.assertFalse(User.objects.filter(username="user1@nonlocal.com").exists()) def test_import_invalid_quota(self): - f = ContentFile(b""" + f = ContentFile( + b""" account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; ; test.com -""", name="identities.csv") # NOQA:E501 +""", + name="identities.csv", + ) # NOQA:E501 resp = self.client.post( - reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True} + reverse("admin:identity_import"), {"sourcefile": f, "crypt_password": True} ) self.assertIn("wrong quota value", resp.content.decode()) @@ -224,62 +201,69 @@ account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; ; t """Check if a domain admin is not allowed to import a domain.""" self.client.logout() self.client.login(username="admin@test.com", password="toto") - f = ContentFile(b""" + f = ContentFile( + b""" domain; domain2.com; 1000; 200; False -""", name="identities.csv") - resp = self.client.post( - reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True} +""", + name="identities.csv", ) - self.assertIn( - "You are not allowed to import domains", - resp.content.decode()) - f = ContentFile(b""" + resp = self.client.post( + reverse("admin:identity_import"), {"sourcefile": f, "crypt_password": True} + ) + self.assertIn("You are not allowed to import domains", resp.content.decode()) + f = ContentFile( + b""" domainalias; domalias1.com; test.com; True -""", name="identities.csv") +""", + name="identities.csv", + ) resp = self.client.post( - reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True} + reverse("admin:identity_import"), {"sourcefile": f, "crypt_password": True} ) self.assertIn( - "You are not allowed to import domain aliases", - resp.content.decode()) + "You are not allowed to import domain aliases", resp.content.decode() + ) def test_import_quota_too_big(self): self.client.logout() self.client.login(username="admin@test.com", password="toto") - f = ContentFile(b""" + f = ContentFile( + b""" account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; 40 -""", name="identities.csv") +""", + name="identities.csv", + ) resp = self.client.post( - reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True} + reverse("admin:identity_import"), {"sourcefile": f, "crypt_password": True} ) self.assertIn("test.com: domain quota exceeded", resp.content.decode()) def test_import_missing_quota(self): - f = ContentFile(b""" + f = ContentFile( + b""" account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com -""", name="identities.csv") +""", + name="identities.csv", + ) self.client.post( - reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True} + reverse("admin:identity_import"), {"sourcefile": f, "crypt_password": True} ) account = User.objects.get(username="user1@test.com") self.assertEqual( - account.mailbox.quota, - account.mailbox.domain.default_mailbox_quota + account.mailbox.quota, account.mailbox.domain.default_mailbox_quota ) def test_import_duplicate(self): - f = ContentFile(""" + f = ContentFile( + """ account; admin@test.com; toto; Admin; ; True; DomainAdmins; admin@test.com; 0; test.com account; truc@test.com; toto; René; Truc; True; DomainAdmins; truc@test.com; 0; test.com -""", name="identities.csv") # NOQA:E501 +""", + name="identities.csv", + ) # NOQA:E501 self.client.post( reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True, - "continue_if_exists": True} + {"sourcefile": f, "crypt_password": True, "continue_if_exists": True}, ) admin = User.objects.get(username="admin") u1 = User.objects.get(username="truc@test.com") @@ -291,58 +275,63 @@ account; truc@test.com; toto; René; Truc; True; DomainAdmins; truc@test.com; 0; Expected result: no """ self.client.logout() - self.assertTrue( - self.client.login(username="admin@test.com", password="toto") - ) - f = ContentFile(b""" + self.assertTrue(self.client.login(username="admin@test.com", password="toto")) + f = ContentFile( + b""" account; sa@test.com; toto; Super; Admin; True; SuperAdmins; superadmin@test.com; 50 -""", name="identities.csv") # NOQA:E501 +""", + name="identities.csv", + ) # NOQA:E501 self.client.post( reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True, - "continue_if_exists": True} + {"sourcefile": f, "crypt_password": True, "continue_if_exists": True}, ) with self.assertRaises(User.DoesNotExist): User.objects.get(username="sa@test.com") def test_import_alias_with_empty_values(self): - f = ContentFile(b""" + f = ContentFile( + b""" alias;user.alias@test.com;True;user@test.com;;;;;;;;;;;;;;;; -""", name="identities.csv") +""", + name="identities.csv", + ) self.client.post( reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True, - "continue_if_exists": True} + {"sourcefile": f, "crypt_password": True, "continue_if_exists": True}, ) alias = Alias.objects.get(address="user.alias@test.com") self.assertEqual(alias.type, "alias") def test_import_account_alias_conflict(self): """Specific test for #1144.""" - f = ContentFile(b""" + f = ContentFile( + b""" alias;user@test.com;True;admin@test.com -""", name="identities.csv") +""", + name="identities.csv", + ) self.client.post( - reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True} + reverse("admin:identity_import"), {"sourcefile": f, "crypt_password": True} ) self.assertTrue( - Alias.objects.filter( - address="user@test.com", internal=False).exists()) + Alias.objects.filter(address="user@test.com", internal=False).exists() + ) def test_domains_import_utf8(self): response = self.client.get(reverse("admin:domain_import")) self.assertEqual(response.status_code, 200) self.assertIn("Provide a CSV", response.content.decode()) - f = ContentFile("""domain; dómªin1.com; 1000; 100; True + f = ContentFile( + """domain; dómªin1.com; 1000; 100; True dómain; dómªin2.com; 1000; 100; True -""".encode("utf8"), name="dómains.csv") - self.client.post( - reverse("admin:domain_import"), { - "sourcefile": f - } +""".encode( + "utf8" + ), + name="dómains.csv", ) + self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) admin = User.objects.get(username="admin") dom = Domain.objects.get(name="dómªin1.com") self.assertEqual(dom.quota, 1000) @@ -360,8 +349,7 @@ dómain; dómªin2.com; 1000; 100; True def test_import_command(self): test_file = os.path.join( - os.path.dirname(__file__), - "test_data/import_domains.csv" + os.path.dirname(__file__), "test_data/import_domains.csv" ) call_command("modo", "import", test_file) @@ -381,8 +369,7 @@ dómain; dómªin2.com; 1000; 100; True def test_import_command_non_utf8(self): test_file = os.path.join( - os.path.dirname(__file__), - "test_data/import_domains_iso8859.csv" + os.path.dirname(__file__), "test_data/import_domains_iso8859.csv" ) call_command("modo", "import", test_file) dom = Domain.objects.get(name="dómain2.com") @@ -390,8 +377,7 @@ dómain; dómªin2.com; 1000; 100; True def test_import_command_duplicates(self): test_file = os.path.join( - os.path.dirname(__file__), - "test_data/import_domains_duplicates.csv" + os.path.dirname(__file__), "test_data/import_domains_duplicates.csv" ) with self.assertRaises(CommandError) as cm: call_command("modo", "import", test_file) @@ -400,8 +386,7 @@ dómain; dómªin2.com; 1000; 100; True def test_import_command_duplicates_continue(self): test_file = os.path.join( - os.path.dirname(__file__), - "test_data/import_domains_duplicates.csv" + os.path.dirname(__file__), "test_data/import_domains_duplicates.csv" ) call_command("modo", "import", "--continue-if-exists", test_file) @@ -420,20 +405,21 @@ dómain; dómªin2.com; 1000; 100; True self.assertTrue(admin.is_owner(dom)) def test_import_aliases(self): - f = ContentFile(""" + f = ContentFile( + """ account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; 0 account; Truc@test.com; toto; René; Truc; True; DomainAdmins; truc@test.com; 5; test.com alias; alias1@test.com; True; user1@test.com -""", name="identities.csv") # NOQA:E501 +""", + name="identities.csv", + ) # NOQA:E501 resp = self.client.post( - reverse("admin:identity_import"), - {"sourcefile": f, "crypt_password": True} + reverse("admin:identity_import"), {"sourcefile": f, "crypt_password": True} ) self.assertEqual(resp.status_code, 200) test_file = os.path.join( - os.path.dirname(__file__), - "test_data/import_aliases.csv" + os.path.dirname(__file__), "test_data/import_aliases.csv" ) with self.assertRaises(CommandError) as cm: call_command("modo", "import", test_file) diff --git a/modoboa/admin/tests/test_mailbox_operations.py b/modoboa/admin/tests/test_mailbox_operations.py index fb2462987..40003cc62 100644 --- a/modoboa/admin/tests/test_mailbox_operations.py +++ b/modoboa/admin/tests/test_mailbox_operations.py @@ -13,8 +13,7 @@ from modoboa.lib.tests import ModoTestCase from .. import factories, models -@override_settings( - DOVECOT_LOOKUP_PATH=["{}/dovecot".format(os.path.dirname(__file__))]) +@override_settings(DOVECOT_LOOKUP_PATH=["{}/dovecot".format(os.path.dirname(__file__))]) class MailboxOperationTestCase(ModoTestCase): """Test management command.""" @@ -43,10 +42,9 @@ class MailboxOperationTestCase(ModoTestCase): path = "{}/test.com/admin".format(self.workdir) mail_home_mock.__get__ = mock.Mock(return_value=path) mb = models.Mailbox.objects.select_related("user").get( - address="admin", domain__name="test.com") - self.ajax_post( - reverse("admin:account_delete", args=[mb.user.pk]), {} + address="admin", domain__name="test.com" ) + self.ajax_post(reverse("admin:account_delete", args=[mb.user.pk]), {}) call_command("handle_mailbox_operations") self.assertFalse(models.MailboxOperation.objects.exists()) self.assertFalse(os.path.exists(mb.mail_home)) @@ -57,15 +55,16 @@ class MailboxOperationTestCase(ModoTestCase): path = "{}/test.com/admin".format(self.workdir) mail_home_mock.__get__ = mock.Mock(return_value=path) mb = models.Mailbox.objects.select_related("user").get( - address="admin", domain__name="test.com") - values = { - "username": "admin2@test.com", "role": "DomainAdmins", - "is_active": True, "email": "admin2@test.com", - "language": "en" - } - self.ajax_post( - reverse("admin:account_change", args=[mb.user.pk]), values + address="admin", domain__name="test.com" ) + values = { + "username": "admin2@test.com", + "role": "DomainAdmins", + "is_active": True, + "email": "admin2@test.com", + "language": "en", + } + self.ajax_post(reverse("admin:account_change", args=[mb.user.pk]), values) path = "{}/test.com/admin2".format(self.workdir) mail_home_mock.__get__ = mock.Mock(return_value=path) call_command("handle_mailbox_operations") diff --git a/modoboa/admin/tests/test_mapfiles.py b/modoboa/admin/tests/test_mapfiles.py index ecc51951d..6af7eb568 100644 --- a/modoboa/admin/tests/test_mapfiles.py +++ b/modoboa/admin/tests/test_mapfiles.py @@ -11,20 +11,22 @@ from modoboa.lib.test_utils import MapFilesTestCaseMixin class MapFilesTestCase(MapFilesTestCaseMixin, TestCase): - """Test case for admin.""" MAP_FILES = [ - "sql-domains.cf", "sql-domain-aliases.cf", "sql-aliases.cf", - "sql-maintain.cf", "sql-sender-login-map.cf" + "sql-domains.cf", + "sql-domain-aliases.cf", + "sql-aliases.cf", + "sql-maintain.cf", + "sql-sender-login-map.cf", ] def test_map_upgrade(self): """Check that map content is used.""" dburl = "postgres://user:password@localhost/testdb" call_command( - "generate_postfix_maps", - "--dburl", dburl, "--destdir", self.workdir) + "generate_postfix_maps", "--dburl", dburl, "--destdir", self.workdir + ) # Now upgrade files. Map credentials should be preserved. call_command("generate_postfix_maps", "--destdir", self.workdir) @@ -36,8 +38,8 @@ class MapFilesTestCase(MapFilesTestCaseMixin, TestCase): # Now force overwrite, credentials should be different call_command( - "generate_postfix_maps", "--destdir", self.workdir, - "--force-overwrite") + "generate_postfix_maps", "--destdir", self.workdir, "--force-overwrite" + ) dbsettings = settings.DATABASES["default"] for f in self.MAP_FILES: mapcontent = parse_map_file(os.path.join(self.workdir, f)) @@ -45,8 +47,7 @@ class MapFilesTestCase(MapFilesTestCaseMixin, TestCase): self.assertEqual(mapcontent["dbpath"], dbsettings["NAME"]) else: self.assertEqual(mapcontent["user"], dbsettings["USER"]) - self.assertEqual( - mapcontent["password"], dbsettings["PASSWORD"]) + self.assertEqual(mapcontent["password"], dbsettings["PASSWORD"]) self.assertEqual(mapcontent["dbname"], dbsettings["NAME"]) # Now modify a file manually diff --git a/modoboa/admin/tests/test_mx.py b/modoboa/admin/tests/test_mx.py index a8718483d..12bbfd3ce 100644 --- a/modoboa/admin/tests/test_mx.py +++ b/modoboa/admin/tests/test_mx.py @@ -10,8 +10,7 @@ from django.test import override_settings from django.urls import reverse from django.utils.translation import gettext as _ -from modoboa.core import ( - models as core_models, factories as core_factories) +from modoboa.core import models as core_models, factories as core_factories from modoboa.lib.tests import ModoTestCase from . import utils from .. import factories, models @@ -27,23 +26,22 @@ class MXTestCase(ModoTestCase): super(MXTestCase, cls).setUpTestData() cls.domain = factories.DomainFactory(name="modoboa.org") # should not exist - cls.bad_domain = factories.DomainFactory( - name="does-not-exist.example.com") + cls.bad_domain = factories.DomainFactory(name="does-not-exist.example.com") # Add domain admin with mailbox mb = factories.MailboxFactory( - address="admin", domain=cls.bad_domain, + address="admin", + domain=cls.bad_domain, user__username="admin@does-not-exist.example.com", - user__groups=("DomainAdmins", ) + user__groups=("DomainAdmins",), ) cls.bad_domain.add_admin(mb.user) # Add domain admin with no mailbox admin = core_factories.UserFactory( - username="admin2@does-not-exist.example.com", - groups=("DomainAdmins", )) + username="admin2@does-not-exist.example.com", groups=("DomainAdmins",) + ) cls.bad_domain.add_admin(admin) - cls.localconfig.parameters.set_value( - "valid_mxs", "192.0.2.1 2001:db8::1") + cls.localconfig.parameters.set_value("valid_mxs", "192.0.2.1 2001:db8::1") cls.localconfig.save() models.MXRecord.objects.all().delete() @@ -51,15 +49,15 @@ class MXTestCase(ModoTestCase): @mock.patch("socket.getaddrinfo") @mock.patch.object(dns.resolver.Resolver, "resolve") def test_management_command( - self, mock_query, mock_getaddrinfo, mock_g_gethostbyname): + self, mock_query, mock_getaddrinfo, mock_g_gethostbyname + ): """Check that command works fine.""" mock_query.side_effect = utils.mock_dns_query_result mock_getaddrinfo.side_effect = utils.mock_ip_query_result mock_g_gethostbyname.return_value = "1.2.3.4" self.assertEqual(models.MXRecord.objects.count(), 0) management.call_command("modo", "check_mx", "--no-dnsbl", "--ttl=0") - self.assertTrue( - models.MXRecord.objects.filter(domain=self.domain).exists()) + self.assertTrue(models.MXRecord.objects.filter(domain=self.domain).exists()) # we passed a ttl to 0. this will reset the cache this time qs = models.MXRecord.objects.filter(domain=self.domain) @@ -79,32 +77,30 @@ class MXTestCase(ModoTestCase): @mock.patch("socket.getaddrinfo") @mock.patch.object(dns.resolver.Resolver, "resolve") def test_single_domain_update( - self, mock_query, mock_getaddrinfo, mock_g_gethostbyname): + self, mock_query, mock_getaddrinfo, mock_g_gethostbyname + ): """Update only one domain.""" mock_query.side_effect = utils.mock_dns_query_result mock_getaddrinfo.side_effect = utils.mock_ip_query_result mock_g_gethostbyname.return_value = "1.2.3.4" - management.call_command( - "modo", "check_mx", "--domain", self.domain.name) - self.assertTrue( - models.MXRecord.objects.filter(domain=self.domain).exists()) + management.call_command("modo", "check_mx", "--domain", self.domain.name) + self.assertTrue(models.MXRecord.objects.filter(domain=self.domain).exists()) self.assertFalse( - models.MXRecord.objects.filter(domain=self.bad_domain).exists()) + models.MXRecord.objects.filter(domain=self.bad_domain).exists() + ) - management.call_command( - "modo", "check_mx", "--domain", str(self.bad_domain.pk)) + management.call_command("modo", "check_mx", "--domain", str(self.bad_domain.pk)) self.assertFalse( - models.MXRecord.objects.filter(domain=self.bad_domain).exists()) + models.MXRecord.objects.filter(domain=self.bad_domain).exists() + ) self.assertEqual(len(mail.outbox), 1) - management.call_command( - "modo", "check_mx", "--domain", "toto.com") + management.call_command("modo", "check_mx", "--domain", "toto.com") @mock.patch("gevent.socket.gethostbyname") @mock.patch("socket.getaddrinfo") @mock.patch.object(dns.resolver.Resolver, "resolve") - def test_invalid_mx( - self, mock_query, mock_getaddrinfo, mock_g_gethostbyname): + def test_invalid_mx(self, mock_query, mock_getaddrinfo, mock_g_gethostbyname): """Test to check if invalid MX records are detected.""" mock_query.side_effect = utils.mock_dns_query_result mock_getaddrinfo.side_effect = utils.mock_ip_query_result @@ -112,16 +108,19 @@ class MXTestCase(ModoTestCase): domain = factories.DomainFactory(name="invalid-mx.com") # Add domain admin with mailbox mb = factories.MailboxFactory( - address="admin", domain=domain, + address="admin", + domain=domain, user__username="admin@{}".format(domain.name), - user__groups=("DomainAdmins", ) + user__groups=("DomainAdmins",), ) domain.add_admin(mb.user) management.call_command( - "modo", "check_mx", "--domain", domain.name, "--no-dnsbl") + "modo", "check_mx", "--domain", domain.name, "--no-dnsbl" + ) self.assertEqual(domain.alarms.count(), 1) management.call_command( - "modo", "check_mx", "--domain", domain.name, "--no-dnsbl") + "modo", "check_mx", "--domain", domain.name, "--no-dnsbl" + ) self.assertEqual(domain.alarms.count(), 1) self.assertEqual(len(mail.outbox), 1) @@ -149,27 +148,41 @@ class MXTestCase(ModoTestCase): get_domain_mx_list("no-answer.example.Com") get_domain_mx_list("bad-response.example.com") log.check( - ("modoboa.admin", "ERROR", - _("No DNS record found for %s") - % "does-not-exist.example.com"), - ("modoboa.admin", "ERROR", - _("No MX record for %s") % "no-mx.example.com"), + ( + "modoboa.admin", + "ERROR", + _("No DNS record found for %s") % "does-not-exist.example.com", + ), + ("modoboa.admin", "ERROR", _("No MX record for %s") % "no-mx.example.com"), ("modoboa.admin", "ERROR", _("No working name servers found")), - ("modoboa.admin", "WARNING", + ( + "modoboa.admin", + "WARNING", _("DNS resolution timeout, unable to query %s at the moment") - % "timeout.example.com"), - ("modoboa.admin", "ERROR", - _("No DNS record found for %s") - % "does-not-exist.example.com"), - ("modoboa.admin", "ERROR", - _("No DNS record found for %s") - % "does-not-exist.example.com"), - ("modoboa.admin", "WARNING", - _("Invalid IP address format for %(domain)s; %(addr)s") - % {"domain": "bad-response.example.com", "addr": "000.0.0.0"}), - ("modoboa.admin", "WARNING", - _("Invalid IP address format for %(domain)s; %(addr)s") - % {"domain": "bad-response.example.com", "addr": "000.0.0.0"}), + % "timeout.example.com", + ), + ( + "modoboa.admin", + "ERROR", + _("No DNS record found for %s") % "does-not-exist.example.com", + ), + ( + "modoboa.admin", + "ERROR", + _("No DNS record found for %s") % "does-not-exist.example.com", + ), + ( + "modoboa.admin", + "WARNING", + _("Invalid IP address format for %(domain)s; %(addr)s") + % {"domain": "bad-response.example.com", "addr": "000.0.0.0"}, + ), + ( + "modoboa.admin", + "WARNING", + _("Invalid IP address format for %(domain)s; %(addr)s") + % {"domain": "bad-response.example.com", "addr": "000.0.0.0"}, + ), ) @mock.patch("ipaddress.ip_address") @@ -184,9 +197,7 @@ class MXTestCase(ModoTestCase): with LogCapture("modoboa.admin") as log: get_domain_mx_list("test3.com") log.check( - ("modoboa.admin", "ERROR", - _("No AAAA record for %s") - % "mx3.example.com") + ("modoboa.admin", "ERROR", _("No AAAA record for %s") % "mx3.example.com") ) localconfig = core_models.LocalConfig.objects.first() localconfig.parameters.set_value("enable_ipv6_mx_checks", False, "admin") @@ -207,28 +218,32 @@ class DNSBLTestCase(ModoTestCase): cls.domain = factories.DomainFactory(name="modoboa.org") factories.DomainFactory(name="does-not-exist.example.com") cls.domain2 = factories.DomainFactory( - name="test.localhost") # Should not be checked + name="test.localhost" + ) # Should not be checked cls.domain3 = factories.DomainFactory( - name="modoboa.com", enable_dns_checks=False) + name="modoboa.com", enable_dns_checks=False + ) models.DNSBLResult.objects.all().delete() @mock.patch("gevent.socket.gethostbyname") @mock.patch("socket.getaddrinfo") @mock.patch.object(dns.resolver.Resolver, "resolve") def test_management_command( - self, mock_query, mock_getaddrinfo, mock_g_gethostbyname): + self, mock_query, mock_getaddrinfo, mock_g_gethostbyname + ): """Check that command works fine.""" mock_query.side_effect = utils.mock_dns_query_result mock_getaddrinfo.side_effect = utils.mock_ip_query_result mock_g_gethostbyname.return_value = "1.2.3.4" self.assertEqual(models.DNSBLResult.objects.count(), 0) management.call_command("modo", "check_mx") - self.assertTrue( - models.DNSBLResult.objects.filter(domain=self.domain).exists()) + self.assertTrue(models.DNSBLResult.objects.filter(domain=self.domain).exists()) self.assertFalse( - models.DNSBLResult.objects.filter(domain=self.domain3).exists()) + models.DNSBLResult.objects.filter(domain=self.domain3).exists() + ) response = self.client.get( - reverse("admin:dnsbl_domain_detail", args=[self.domain.pk])) + reverse("admin:dnsbl_domain_detail", args=[self.domain.pk]) + ) self.assertEqual(response.status_code, 200) self.assertFalse(self.domain.uses_a_reserved_tld) self.assertTrue(self.domain2.uses_a_reserved_tld) @@ -236,44 +251,43 @@ class DNSBLTestCase(ModoTestCase): @mock.patch("gevent.socket.gethostbyname") @mock.patch("socket.getaddrinfo") @mock.patch.object(dns.resolver.Resolver, "resolve") - def test_notifications( - self, mock_query, mock_getaddrinfo, mock_g_gethostbyname): + def test_notifications(self, mock_query, mock_getaddrinfo, mock_g_gethostbyname): """Check notifications.""" mock_query.side_effect = utils.mock_dns_query_result mock_getaddrinfo.side_effect = utils.mock_ip_query_result mock_g_gethostbyname.return_value = "127.0.0.4" - management.call_command( - "modo", "check_mx", "--email", "user@example.test") + management.call_command("modo", "check_mx", "--email", "user@example.test") self.assertEqual(len(mail.outbox), 2) @mock.patch("gevent.socket.gethostbyname") @mock.patch("socket.getaddrinfo") @mock.patch.object(dns.resolver.Resolver, "resolve") def test_notifications_wrong_dnsbl_response( - self, mock_query, mock_getaddrinfo, mock_g_gethostbyname): + self, mock_query, mock_getaddrinfo, mock_g_gethostbyname + ): """Check notifications.""" mock_query.side_effect = utils.mock_dns_query_result mock_getaddrinfo.side_effect = utils.mock_ip_query_result - mock_g_gethostbyname.return_value = "127.255.255.254" #<--Spamhaus response when querying from an open resolver - management.call_command( - "modo", "check_mx", "--email", "user@example.test") + mock_g_gethostbyname.return_value = "127.255.255.254" # <--Spamhaus response when querying from an open resolver + management.call_command("modo", "check_mx", "--email", "user@example.test") self.assertEqual(len(mail.outbox), 1) @mock.patch("gevent.socket.gethostbyname") @mock.patch("socket.getaddrinfo") @mock.patch.object(dns.resolver.Resolver, "resolve") def test_management_command_no_dnsbl( - self, mock_query, mock_getaddrinfo, mock_g_gethostbyname): + self, mock_query, mock_getaddrinfo, mock_g_gethostbyname + ): """Check that command works fine without dnsbl.""" mock_query.side_effect = utils.mock_dns_query_result mock_getaddrinfo.side_effect = utils.mock_ip_query_result mock_g_gethostbyname.return_value = "1.2.3.4" self.assertEqual(models.DNSBLResult.objects.count(), 0) management.call_command("modo", "check_mx", "--no-dnsbl") - self.assertFalse( - models.DNSBLResult.objects.filter(domain=self.domain).exists()) + self.assertFalse(models.DNSBLResult.objects.filter(domain=self.domain).exists()) response = self.client.get( - reverse("admin:dnsbl_domain_detail", args=[self.domain.pk])) + reverse("admin:dnsbl_domain_detail", args=[self.domain.pk]) + ) self.assertEqual(response.status_code, 200) @@ -290,7 +304,8 @@ class DNSChecksTestCase(ModoTestCase): @mock.patch("socket.getaddrinfo") @mock.patch.object(dns.resolver.Resolver, "resolve") def test_management_command( - self, mock_query, mock_getaddrinfo, mock_g_gethostbyname): + self, mock_query, mock_getaddrinfo, mock_g_gethostbyname + ): """Check that command works fine.""" mock_query.side_effect = utils.mock_dns_query_result mock_getaddrinfo.side_effect = utils.mock_ip_query_result diff --git a/modoboa/admin/tests/test_need_dovecot_update.py b/modoboa/admin/tests/test_need_dovecot_update.py index d55956a91..287348f37 100644 --- a/modoboa/admin/tests/test_need_dovecot_update.py +++ b/modoboa/admin/tests/test_need_dovecot_update.py @@ -48,21 +48,24 @@ class NeedDovecotUpdateTestCase(ModoTestCase): self.assertTrue(self.localconfig.need_dovecot_update) tmp_file = os.path.join(self.workdir, "test-dovecot-ldap.conf") - self.set_global_parameters({ - "authentication_type": "ldap", - "ldap_dovecot_sync": True, - "ldap_dovecot_conf_file": tmp_file, - "ldap_server_address": "localhost", - "ldap_server_port": "636", - "ldap_enable_secondary_server": True, - "ldap_secondary_server_address": "localhost2", - "ldap_secondary_server_port": "636", - "ldap_secured": "ssl", - "ldap_bind_dn": "DC=test,DC=lan", - "ldap_bind_password": "test", - "ldap_search_base": "CN=Users,DC=test,DC=lan", - "ldap_search_filter": "(& (objectClass=user) (|(mail=%(user)s)(sAMAccountName=%(user)s)) )" - }, app="core") + self.set_global_parameters( + { + "authentication_type": "ldap", + "ldap_dovecot_sync": True, + "ldap_dovecot_conf_file": tmp_file, + "ldap_server_address": "localhost", + "ldap_server_port": "636", + "ldap_enable_secondary_server": True, + "ldap_secondary_server_address": "localhost2", + "ldap_secondary_server_port": "636", + "ldap_secured": "ssl", + "ldap_bind_dn": "DC=test,DC=lan", + "ldap_bind_password": "test", + "ldap_search_base": "CN=Users,DC=test,DC=lan", + "ldap_search_filter": "(& (objectClass=user) (|(mail=%(user)s)(sAMAccountName=%(user)s)) )", + }, + app="core", + ) # Generated file checks call_command("update_dovecot_conf") @@ -71,11 +74,17 @@ class NeedDovecotUpdateTestCase(ModoTestCase): with open(tmp_file) as tmp: content = tmp.read() self.assertIn("uris = ldaps://localhost:636 ldaps://localhost2:636", content) - self.assertIn("dn = \"DC=test,DC=lan\"", content) - self.assertIn("dnpass = \'test\'", content) + self.assertIn('dn = "DC=test,DC=lan"', content) + self.assertIn("dnpass = 'test'", content) self.assertIn("base = CN=Users,DC=test,DC=lan", content) - self.assertIn("user_filter = (& (objectClass=user) (|(mail=%u)(sAMAccountName=%u)) )", content) - self.assertIn("pass_filter = (& (objectClass=user) (|(mail=%u)(sAMAccountName=%u)) )", content) + self.assertIn( + "user_filter = (& (objectClass=user) (|(mail=%u)(sAMAccountName=%u)) )", + content, + ) + self.assertIn( + "pass_filter = (& (objectClass=user) (|(mail=%u)(sAMAccountName=%u)) )", + content, + ) self.localconfig.refresh_from_db() self.assertFalse(self.localconfig.need_dovecot_update) diff --git a/modoboa/admin/tests/test_password_schemes.py b/modoboa/admin/tests/test_password_schemes.py index 26ecbe41c..de48eda3f 100644 --- a/modoboa/admin/tests/test_password_schemes.py +++ b/modoboa/admin/tests/test_password_schemes.py @@ -15,15 +15,18 @@ class PasswordSchemesTestCase(ModoTestCase): def _create_account(self): values = { - "username": "tester@test.com", "first_name": "Tester", - "last_name": "Toto", "password1": "Toto1234", - "password2": "Toto1234", "role": "SimpleUsers", "quota_act": True, - "is_active": True, "email": "tester@test.com", "stepid": "step2" + "username": "tester@test.com", + "first_name": "Tester", + "last_name": "Toto", + "password1": "Toto1234", + "password2": "Toto1234", + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": "tester@test.com", + "stepid": "step2", } - self.ajax_post( - reverse("admin:account_add"), - values - ) + self.ajax_post(reverse("admin:account_add"), values) def _test_scheme(self, name, startpattern): self.set_global_parameter("password_scheme", name, app="core") diff --git a/modoboa/admin/tests/test_repair.py b/modoboa/admin/tests/test_repair.py index 4a12b6876..6a6a1e6bb 100644 --- a/modoboa/admin/tests/test_repair.py +++ b/modoboa/admin/tests/test_repair.py @@ -51,10 +51,11 @@ class RepairTestCase(ModoTestCase): def test_management_command_with_no_alias(self): """Check that problem is fixed.""" count, detail = models.Alias.objects.filter( - address="user@test.com", internal=True).delete() + address="user@test.com", internal=True + ).delete() self.assertEqual(count, 3) ret = management.call_command("modo", "repair", "--quiet") assert ret is None self.assertTrue( - models.Alias.objects.filter( - address="user@test.com", internal=True).exists()) + models.Alias.objects.filter(address="user@test.com", internal=True).exists() + ) diff --git a/modoboa/admin/tests/test_user.py b/modoboa/admin/tests/test_user.py index 346300cce..f4614aab4 100644 --- a/modoboa/admin/tests/test_user.py +++ b/modoboa/admin/tests/test_user.py @@ -19,10 +19,7 @@ class ForwardTestCase(ModoTestCase): self.client.logout() self.client.login(username="user@test.com", password="toto") url = reverse("user_forward") - self.ajax_post( - url, - {"dest": "user@extdomain.com", "keepcopies": True} - ) + self.ajax_post(url, {"dest": "user@extdomain.com", "keepcopies": True}) response = self.client.get(url) self.assertEqual(response.status_code, 200) content = response.json() @@ -38,10 +35,7 @@ class ForwardTestCase(ModoTestCase): self.assertTrue(selfalias.enabled) # Deactivate local copies - self.ajax_post( - url, - {"dest": "user@extdomain.com", "keepcopies": False} - ) + self.ajax_post(url, {"dest": "user@extdomain.com", "keepcopies": False}) selfalias.refresh_from_db() self.assertFalse(selfalias.enabled) diff --git a/modoboa/admin/tests/utils.py b/modoboa/admin/tests/utils.py index b124dc91b..f1b9eeaf5 100644 --- a/modoboa/admin/tests/utils.py +++ b/modoboa/admin/tests/utils.py @@ -31,12 +31,17 @@ _SPF_RECORD = TXT("IN", "TXT", ["v=spf1 mx -all"]) _DMARC_RECORD = TXT("IN", "TXT", ["v=DMARC1 p=reject"]) _DKIM_RECORD = TXT("IN", "TXT", ["v=DKIM1 p=XXXXX"]) _BAD_MX_RECORD = MX("IN", "MX", 10, Name("bad-response.example.com".split("."))) -_DNE_MX_RECORD = MX("IN", "MX", 10, Name( - "does-not-exist.example.com".split("."))) +_DNE_MX_RECORD = MX("IN", "MX", 10, Name("does-not-exist.example.com".split("."))) _MX_RECORDS = [_MX_RECORD_1] _IP_SET_RECORDS = [RRset()] -_IPV4_RECORD_REDIS = (socket.AF_INET, socket.SOCK_STREAM, 6, "", ("127.0.0.1", int(settings.REDIS_PORT))) +_IPV4_RECORD_REDIS = ( + socket.AF_INET, + socket.SOCK_STREAM, + 6, + "", + ("127.0.0.1", int(settings.REDIS_PORT)), +) _IPV4_RECORD_1 = (socket.AF_INET, socket.SOCK_STREAM, 6, "", ("192.0.2.1", 25)) _IPV4_RECORD_2 = (socket.AF_INET, socket.SOCK_STREAM, 6, "", ("192.0.2.2", 25)) _IPV6_RECORD = (socket.AF_INET, socket.SOCK_STREAM, 6, "", ("2001:db8::1", 25)) @@ -53,7 +58,7 @@ _POSSIBLE_DNS_RESULTS = { "no-lookup.example.com": [_DNE_MX_RECORD], "no-answer.example.com": [_DNE_MX_RECORD], "dns-checks.com": [_MX_RECORD_2], - "invalid-mx.com": [_MX_RECORD_3] + "invalid-mx.com": [_MX_RECORD_3], } _POSSIBLE_DNS_RESULTS_NO_MX = { @@ -62,12 +67,16 @@ _POSSIBLE_DNS_RESULTS_NO_MX = { "no-lookup.example.com": NXDOMAIN(), "no-answer.example.com": NoAnswer(), "bad-response.example.com": [RRsetInvalid()], - "dns-checks.com": [_SPF_RECORD, ], + "dns-checks.com": [ + _SPF_RECORD, + ], "modoboa._domainkey.dns-checks.com": [_DKIM_RECORD], - "_dmarc.dns-checks.com": [_DMARC_RECORD, ], + "_dmarc.dns-checks.com": [ + _DMARC_RECORD, + ], "autoconfig.dns-checks.com": [_A_RECORD], "autodiscover.dns-checks.com": [_A_RECORD], - "mx3.example.com": [_A_RECORD] + "mx3.example.com": [_A_RECORD], } _POSSIBLE_IP_RESULTS = { settings.REDIS_HOST: [_IPV4_RECORD_REDIS], @@ -82,8 +91,8 @@ _POSSIBLE_IP_RESULTS = { _POSSIBLE_DNS_IPV6_RESULTS = { settings.REDIS_HOST: socket.getaddrinfo(settings.REDIS_HOST, settings.REDIS_PORT), - "mx3.example.com": NoAnswer() - } + "mx3.example.com": NoAnswer(), +} def mock_dns_query_result(qname, *args, **kwargs): diff --git a/modoboa/admin/urls.py b/modoboa/admin/urls.py index 5b741ea53..ec3bd4b05 100644 --- a/modoboa/admin/urls.py +++ b/modoboa/admin/urls.py @@ -4,81 +4,76 @@ from django.urls import path from . import views from .views import ( - alias as alias_views, domain as domain_views, export as export_views, - identity as identity_views, import_ as import_views + alias as alias_views, + domain as domain_views, + export as export_views, + identity as identity_views, + import_ as import_views, ) app_name = "admin" urlpatterns = [ - path('', domain_views.index, name="index"), - path('domains/', domain_views.domains, name="domain_list"), - path('domains//', views.DomainDetailView.as_view(), - name="domain_detail"), - path('domains//alarms/', views.DomainAlarmsView.as_view(), - name="domain_alarms"), - path('domains//dnsbl/', views.DNSBLDomainDetailView.as_view(), - name="dnsbl_domain_detail"), - path('domains//mx/', views.MXDomainDetailView.as_view(), - name="mx_domain_detail"), - path('domains/list/', domain_views._domains, name="_domain_list"), - path('domains/quotas/', domain_views.list_quotas, - name="domain_quota_list"), - path('domains/logs/', domain_views.list_logs, - name="domain_logs_list"), - path('domains/flatlist/', domain_views.domains_list, - name="domain_flat_list"), - path('domains/new/', domain_views.newdomain, name="domain_add"), - path('domains//edit/', domain_views.editdomain, - name="domain_change"), - path('domains//delete/', domain_views.deldomain, - name="domain_delete"), - path('domains/page/', domain_views.get_next_page, - name="domain_page"), + path("", domain_views.index, name="index"), + path("domains/", domain_views.domains, name="domain_list"), + path("domains//", views.DomainDetailView.as_view(), name="domain_detail"), + path( + "domains//alarms/", + views.DomainAlarmsView.as_view(), + name="domain_alarms", + ), + path( + "domains//dnsbl/", + views.DNSBLDomainDetailView.as_view(), + name="dnsbl_domain_detail", + ), + path( + "domains//mx/", + views.MXDomainDetailView.as_view(), + name="mx_domain_detail", + ), + path("domains/list/", domain_views._domains, name="_domain_list"), + path("domains/quotas/", domain_views.list_quotas, name="domain_quota_list"), + path("domains/logs/", domain_views.list_logs, name="domain_logs_list"), + path("domains/flatlist/", domain_views.domains_list, name="domain_flat_list"), + path("domains/new/", domain_views.newdomain, name="domain_add"), + path("domains//edit/", domain_views.editdomain, name="domain_change"), + path("domains//delete/", domain_views.deldomain, name="domain_delete"), + path("domains/page/", domain_views.get_next_page, name="domain_page"), ] urlpatterns += [ - path('permissions/remove/', identity_views.remove_permission, - name="permission_remove"), - - path('identities/', identity_views.identities, name="identity_list"), - path('identities/list/', identity_views._identities, - name="_identity_list"), - path('identities/quotas/', identity_views.list_quotas, - name="identity_quota_list"), - path('identities/page/', identity_views.get_next_page, - name="identity_page"), - - path('accounts/list/', identity_views.accounts_list, - name="account_list"), - path('accounts/new/', identity_views.newaccount, name="account_add"), - path('accounts//', views.AccountDetailView.as_view(), - name="account_detail"), - path('accounts//edit/', identity_views.editaccount, - name="account_change"), - path('accounts//delete/', identity_views.delaccount, - name="account_delete"), + path( + "permissions/remove/", + identity_views.remove_permission, + name="permission_remove", + ), + path("identities/", identity_views.identities, name="identity_list"), + path("identities/list/", identity_views._identities, name="_identity_list"), + path("identities/quotas/", identity_views.list_quotas, name="identity_quota_list"), + path("identities/page/", identity_views.get_next_page, name="identity_page"), + path("accounts/list/", identity_views.accounts_list, name="account_list"), + path("accounts/new/", identity_views.newaccount, name="account_add"), + path( + "accounts//", views.AccountDetailView.as_view(), name="account_detail" + ), + path("accounts//edit/", identity_views.editaccount, name="account_change"), + path("accounts//delete/", identity_views.delaccount, name="account_delete"), ] urlpatterns += [ - path('aliases/new/', alias_views.newalias, name="alias_add"), - path('aliases//', views.AliasDetailView.as_view(), - name="alias_detail"), - path('aliases//edit/', alias_views.editalias, - name="alias_change"), - path('aliases/delete/', alias_views.delalias, name="alias_delete"), + path("aliases/new/", alias_views.newalias, name="alias_add"), + path("aliases//", views.AliasDetailView.as_view(), name="alias_detail"), + path("aliases//edit/", alias_views.editalias, name="alias_change"), + path("aliases/delete/", alias_views.delalias, name="alias_delete"), ] urlpatterns += [ - path('domains/import/', import_views.import_domains, - name="domain_import"), - path('identities/import/', import_views.import_identities, - name="identity_import"), + path("domains/import/", import_views.import_domains, name="domain_import"), + path("identities/import/", import_views.import_identities, name="identity_import"), ] urlpatterns += [ - path('domains/export/', export_views.export_domains, - name="domain_export"), - path('identities/export/', export_views.export_identities, - name="identity_export"), + path("domains/export/", export_views.export_domains, name="domain_export"), + path("identities/export/", export_views.export_identities, name="identity_export"), ] diff --git a/modoboa/admin/views/alias.py b/modoboa/admin/views/alias.py index b22132dca..ac491811d 100644 --- a/modoboa/admin/views/alias.py +++ b/modoboa/admin/views/alias.py @@ -35,18 +35,15 @@ def _validate_alias(request, form, successmsg, callback=None): return render_to_json_response({"form_errors": form.errors}, status=400) -def _new_alias(request, title, action, successmsg, - tplname="admin/aliasform.html"): - core_signals.can_create_object.send( - "new_alias", context=request.user, klass=Alias) +def _new_alias(request, title, action, successmsg, tplname="admin/aliasform.html"): + core_signals.can_create_object.send("new_alias", context=request.user, klass=Alias) if request.method == "POST": + def callback(user, alias): alias.post_create(user) form = AliasForm(request.user, request.POST) - return _validate_alias( - request, form, successmsg, callback - ) + return _validate_alias(request, form, successmsg, callback) ctx = { "title": title, @@ -54,7 +51,7 @@ def _new_alias(request, title, action, successmsg, "formid": "aliasform", "action_label": _("Create"), "action_classes": "submit", - "form": AliasForm(request.user) + "form": AliasForm(request.user), } return render(request, tplname, ctx) @@ -64,8 +61,7 @@ def _new_alias(request, title, action, successmsg, @reversion.create_revision() def newalias(request): return _new_alias( - request, _("New alias"), reverse("admin:alias_add"), - _("Alias created") + request, _("New alias"), reverse("admin:alias_add"), _("Alias created") ) @@ -87,7 +83,7 @@ def editalias(request, alid, tplname="admin/aliasform.html"): "title": alias.address, "action_label": _("Update"), "action_classes": "submit", - "form": AliasForm(request.user, instance=alias) + "form": AliasForm(request.user, instance=alias), } return render(request, tplname, ctx) @@ -106,8 +102,7 @@ def delalias(request): return render_to_json_response(msg) -class AliasDetailView( - auth_mixins.PermissionRequiredMixin, generic.DetailView): +class AliasDetailView(auth_mixins.PermissionRequiredMixin, generic.DetailView): """DetailView for Alias.""" model = Alias diff --git a/modoboa/admin/views/dns.py b/modoboa/admin/views/dns.py index 3a46b84c5..cfdde03eb 100644 --- a/modoboa/admin/views/dns.py +++ b/modoboa/admin/views/dns.py @@ -7,8 +7,7 @@ from django.views import generic from .. import models -class MXDomainDetailView( - auth_mixins.PermissionRequiredMixin, generic.DetailView): +class MXDomainDetailView(auth_mixins.PermissionRequiredMixin, generic.DetailView): """View to display MX records.""" model = models.Domain @@ -18,20 +17,19 @@ class MXDomainDetailView( def get_queryset(self): """Add some prefetching.""" return ( - super(MXDomainDetailView, self).get_queryset() - .prefetch_related("mxrecord_set")) + super(MXDomainDetailView, self) + .get_queryset() + .prefetch_related("mxrecord_set") + ) def get_context_data(self, **kwargs): """Add extra variables.""" context = super(MXDomainDetailView, self).get_context_data(**kwargs) - context.update({ - "title": _("MX records of {}").format(self.object.name) - }) + context.update({"title": _("MX records of {}").format(self.object.name)}) return context -class DNSBLDomainDetailView( - auth_mixins.PermissionRequiredMixin, generic.DetailView): +class DNSBLDomainDetailView(auth_mixins.PermissionRequiredMixin, generic.DetailView): """View to display DNSBL summary.""" model = models.Domain @@ -41,13 +39,13 @@ class DNSBLDomainDetailView( def get_queryset(self): """Add some prefetching.""" return ( - super(DNSBLDomainDetailView, self).get_queryset() - .prefetch_related("dnsblresult_set")) + super(DNSBLDomainDetailView, self) + .get_queryset() + .prefetch_related("dnsblresult_set") + ) def get_context_data(self, **kwargs): """Add extra variables.""" context = super(DNSBLDomainDetailView, self).get_context_data(**kwargs) - context.update({ - "title": _("DNSBL summary for {}").format(self.object.name) - }) + context.update({"title": _("DNSBL summary for {}").format(self.object.name)}) return context diff --git a/modoboa/admin/views/domain.py b/modoboa/admin/views/domain.py index 83c1218e9..b16980e7a 100644 --- a/modoboa/admin/views/domain.py +++ b/modoboa/admin/views/domain.py @@ -6,7 +6,9 @@ from reversion import revisions as reversion from django.contrib.auth import mixins as auth_mixins from django.contrib.auth.decorators import ( - login_required, permission_required, user_passes_test + login_required, + permission_required, + user_passes_test, ) from django.db.models import Q, Sum from django.http import HttpResponseRedirect @@ -37,15 +39,15 @@ def index(request): @login_required @user_passes_test( - lambda u: u.has_perm("admin.view_domain") or - u.has_perm("admin.view_mailbox") + lambda u: u.has_perm("admin.view_domain") or u.has_perm("admin.view_mailbox") ) def _domains(request): sort_order, sort_dir = get_sort_order(request.GET, "name") extra_filters = signals.extra_domain_filters.send(sender="_domains") if extra_filters: extra_filters = reduce( - lambda a, b: a + b, [result[1] for result in extra_filters]) + lambda a, b: a + b, [result[1] for result in extra_filters] + ) filters = { flt: request.GET.get(flt, None) for flt in ["domfilter", "searchquery"] + extra_filters @@ -54,17 +56,19 @@ def _domains(request): domainlist = get_domains(request.user, **filters) if sort_order == "name": domainlist = sorted( - domainlist, - key=lambda d: getattr(d, sort_order), reverse=sort_dir == "-" + domainlist, key=lambda d: getattr(d, sort_order), reverse=sort_dir == "-" ) else: - domainlist = sorted(domainlist, key=lambda d: d.tags[0]["name"], - reverse=sort_dir == "-") + domainlist = sorted( + domainlist, key=lambda d: d.tags[0]["name"], reverse=sort_dir == "-" + ) context = { "handle_mailboxes": request.localconfig.parameters.get_value( - "handle_mailboxes", raise_exception=False), + "handle_mailboxes", raise_exception=False + ), "auto_account_removal": request.localconfig.parameters.get_value( - "auto_account_removal"), + "auto_account_removal" + ), } page = get_listing_page(domainlist, request.GET.get("page", 1)) parameters = request.localconfig.parameters @@ -73,9 +77,8 @@ def _domains(request): "enable_spf_checks": parameters.get_value("enable_spf_checks"), "enable_dkim_checks": parameters.get_value("enable_dkim_checks"), "enable_dmarc_checks": parameters.get_value("enable_dmarc_checks"), - "enable_autoconfig_checks": ( - parameters.get_value("enable_autoconfig_checks")), - "enable_dnsbl_checks": parameters.get_value("enable_dnsbl_checks") + "enable_autoconfig_checks": (parameters.get_value("enable_autoconfig_checks")), + "enable_dnsbl_checks": parameters.get_value("enable_dnsbl_checks"), } context["headers"] = render_to_string( "admin/domain_headers.html", dns_checks, request @@ -97,28 +100,31 @@ def _domains(request): def domains(request, tplname="admin/domains.html"): if not request.user.has_perm("admin.view_domain"): if request.user.has_perm("admin.view_mailbox"): - return HttpResponseRedirect( - reverse("admin:identity_list") - ) + return HttpResponseRedirect(reverse("admin:identity_list")) return HttpResponseRedirect(reverse("core:user_index")) parameters = request.localconfig.parameters - return render(request, tplname, { - "selection": "domains", - "enable_mx_checks": parameters.get_value("enable_mx_checks"), - "enable_spf_checks": parameters.get_value("enable_spf_checks"), - "enable_dkim_checks": parameters.get_value("enable_dkim_checks"), - "enable_dmarc_checks": parameters.get_value("enable_dmarc_checks"), - "enable_autoconfig_checks": ( - parameters.get_value("enable_autoconfig_checks")), - "enable_dnsbl_checks": parameters.get_value("enable_dnsbl_checks") - }) + return render( + request, + tplname, + { + "selection": "domains", + "enable_mx_checks": parameters.get_value("enable_mx_checks"), + "enable_spf_checks": parameters.get_value("enable_spf_checks"), + "enable_dkim_checks": parameters.get_value("enable_dkim_checks"), + "enable_dmarc_checks": parameters.get_value("enable_dmarc_checks"), + "enable_autoconfig_checks": ( + parameters.get_value("enable_autoconfig_checks") + ), + "enable_dnsbl_checks": parameters.get_value("enable_dnsbl_checks"), + }, + ) @login_required @user_passes_test( - lambda u: u.has_perm("admin.view_domain") or - u.has_perm("admin.view_mailbox") or - u.has_perm("admin.add_domain") + lambda u: u.has_perm("admin.view_domain") + or u.has_perm("admin.view_mailbox") + or u.has_perm("admin.add_domain") ) def get_next_page(request): """Return the next page of the domain or quota list.""" @@ -146,15 +152,12 @@ def list_quotas(request): if sort_order in ["name", "quota"]: domains = domains.order_by("{}{}".format(sort_dir, sort_order)) elif sort_order == "allocated_quota": - domains = ( - domains.annotate(allocated_quota=Sum("mailbox__quota")) - .order_by("{}{}".format(sort_dir, sort_order)) + domains = domains.annotate(allocated_quota=Sum("mailbox__quota")).order_by( + "{}{}".format(sort_dir, sort_order) ) page = get_listing_page(domains, request.GET.get("page", 1)) context = { - "headers": render_to_string( - "admin/domains_quota_headers.html", {}, request - ) + "headers": render_to_string("admin/domains_quota_headers.html", {}, request) } if page is None: context["length"] = 0 @@ -182,16 +185,14 @@ def list_logs(request): logs = logs.order_by("{}{}".format(sort_dir, sort_order)) if search: logs = logs.filter( - Q(sender__icontains=search) | - Q(rcpt__icontains=search) | - Q(queue_id__icontains=search) | - Q(status__icontains=search) + Q(sender__icontains=search) + | Q(rcpt__icontains=search) + | Q(queue_id__icontains=search) + | Q(status__icontains=search) ) page = get_listing_page(logs, request.GET.get("page", 1)) context = { - "headers": render_to_string( - "admin/domains_log_headers.html", {}, request - ) + "headers": render_to_string("admin/domains_log_headers.html", {}, request) } if page is None: context["length"] = 0 @@ -207,8 +208,7 @@ def list_logs(request): @permission_required("admin.add_domain") @reversion.create_revision() def newdomain(request): - core_signals.can_create_object.send( - "newdomain", context=request.user, klass=Domain) + core_signals.can_create_object.send("newdomain", context=request.user, klass=Domain) return DomainWizard(request).process() @@ -224,7 +224,8 @@ def editdomain(request, dom_id): instances = {"general": domain} results = signals.get_domain_form_instances.send( - sender="editdomain", user=request.user, domain=domain) + sender="editdomain", user=request.user, domain=domain + ) for result in results: instances.update(result[1]) return DomainForm(request, instances=instances).process() @@ -251,8 +252,7 @@ def deldomain(request, dom_id): return render_to_json_response(msg) -class DomainDetailView( - auth_mixins.PermissionRequiredMixin, generic.DetailView): +class DomainDetailView(auth_mixins.PermissionRequiredMixin, generic.DetailView): """DetailView for Domain.""" model = Domain @@ -260,39 +260,40 @@ class DomainDetailView( def get_queryset(self): """Add some prefetching.""" - return ( - Domain.objects.get_for_admin(self.request.user) - .prefetch_related("domainalias_set", "mailbox_set", "alias_set") + return Domain.objects.get_for_admin(self.request.user).prefetch_related( + "domainalias_set", "mailbox_set", "alias_set" ) def get_context_data(self, **kwargs): """Include extra widgets.""" context = super(DomainDetailView, self).get_context_data(**kwargs) result = signals.extra_domain_dashboard_widgets.send( - self.__class__, user=self.request.user, domain=self.object) + self.__class__, user=self.request.user, domain=self.object + ) parameters = self.request.localconfig.parameters - context.update({ - "templates": {"left": [], "right": []}, - "enable_mx_checks": parameters.get_value("enable_mx_checks"), - "enable_spf_checks": parameters.get_value("enable_spf_checks"), - "enable_dkim_checks": parameters.get_value("enable_dkim_checks"), - "enable_dmarc_checks": parameters.get_value("enable_dmarc_checks"), - "enable_autoconfig_checks": ( - parameters.get_value("enable_autoconfig_checks")), - "enable_dnsbl_checks": parameters.get_value("enable_dnsbl_checks"), - }) + context.update( + { + "templates": {"left": [], "right": []}, + "enable_mx_checks": parameters.get_value("enable_mx_checks"), + "enable_spf_checks": parameters.get_value("enable_spf_checks"), + "enable_dkim_checks": parameters.get_value("enable_dkim_checks"), + "enable_dmarc_checks": parameters.get_value("enable_dmarc_checks"), + "enable_autoconfig_checks": ( + parameters.get_value("enable_autoconfig_checks") + ), + "enable_dnsbl_checks": parameters.get_value("enable_dnsbl_checks"), + } + ) for _receiver, widgets in result: for widget in widgets: - context["templates"][widget["column"]].append( - widget["template"]) + context["templates"][widget["column"]].append(widget["template"]) # FIXME: can raise conflicts... context.update(widget["context"]) return context -class DomainAlarmsView( - auth_mixins.PermissionRequiredMixin, generic.DetailView): +class DomainAlarmsView(auth_mixins.PermissionRequiredMixin, generic.DetailView): """A view to list domain alarms.""" model = Domain @@ -301,7 +302,6 @@ class DomainAlarmsView( def get_queryset(self): """Add some prefetching.""" - return ( - Domain.objects.get_for_admin(self.request.user) - .prefetch_related("alarms") + return Domain.objects.get_for_admin(self.request.user).prefetch_related( + "alarms" ) diff --git a/modoboa/admin/views/export.py b/modoboa/admin/views/export.py index b395a1865..ccb9ec6cc 100644 --- a/modoboa/admin/views/export.py +++ b/modoboa/admin/views/export.py @@ -4,7 +4,9 @@ import csv from io import StringIO from django.contrib.auth.decorators import ( - login_required, permission_required, user_passes_test + login_required, + permission_required, + user_passes_test, ) from django.http import HttpResponse from django.shortcuts import render @@ -48,7 +50,8 @@ def export_identities(request): fp = StringIO() csvwriter = csv.writer(fp, delimiter=form.cleaned_data["sepchar"]) identities = get_identities( - request.user, **request.session["identities_filters"]) + request.user, **request.session["identities_filters"] + ) for ident in identities: ident.to_csv(csvwriter) content = fp.getvalue() @@ -75,8 +78,7 @@ def export_domains(request): form.is_valid() fp = StringIO() csvwriter = csv.writer(fp, delimiter=form.cleaned_data["sepchar"]) - for dom in get_domains(request.user, - **request.session["domains_filters"]): + for dom in get_domains(request.user, **request.session["domains_filters"]): dom.to_csv(csvwriter) content = fp.getvalue() fp.close() diff --git a/modoboa/admin/views/identity.py b/modoboa/admin/views/identity.py index 2d9ea3786..09aa11a8f 100644 --- a/modoboa/admin/views/identity.py +++ b/modoboa/admin/views/identity.py @@ -4,7 +4,9 @@ from reversion import revisions as reversion from django.contrib.auth import mixins as auth_mixins from django.contrib.auth.decorators import ( - login_required, permission_required, user_passes_test + login_required, + permission_required, + user_passes_test, ) from django.shortcuts import render from django.template.loader import render_to_string @@ -25,8 +27,7 @@ from ..models import Domain, Mailbox @login_required @user_passes_test( - lambda u: u.has_perm("core.add_user") or - u.has_perm("admin.add_alias") + lambda u: u.has_perm("core.add_user") or u.has_perm("admin.add_alias") ) def _identities(request): filters = { @@ -35,28 +36,29 @@ def _identities(request): } request.session["identities_filters"] = filters idents_list = get_identities(request.user, **filters) - sort_order, sort_dir = get_sort_order(request.GET, "identity", - ["identity", "name_or_rcpt", "tags"]) + sort_order, sort_dir = get_sort_order( + request.GET, "identity", ["identity", "name_or_rcpt", "tags"] + ) if sort_order in ["identity", "name_or_rcpt"]: - objects = sorted(idents_list, key=lambda o: getattr(o, sort_order), - reverse=sort_dir == "-") + objects = sorted( + idents_list, key=lambda o: getattr(o, sort_order), reverse=sort_dir == "-" + ) else: - objects = sorted(idents_list, key=lambda o: o.tags[0]["label"], - reverse=sort_dir == "-") + objects = sorted( + idents_list, key=lambda o: o.tags[0]["label"], reverse=sort_dir == "-" + ) context = { "handle_mailboxes": request.localconfig.parameters.get_value( - "handle_mailboxes", raise_exception=False) + "handle_mailboxes", raise_exception=False + ) } page = get_listing_page(objects, request.GET.get("page", 1)) - context["headers"] = render_to_string( - "admin/identity_headers.html", {}, request) + context["headers"] = render_to_string("admin/identity_headers.html", {}, request) if page is None: context["length"] = 0 else: context["rows"] = render_to_string( - "admin/identities_table.html", { - "identities": page.object_list - }, request + "admin/identities_table.html", {"identities": page.object_list}, request ) context["pages"] = [page.number] return render_to_json_response(context) @@ -85,7 +87,7 @@ def list_quotas(request): select={"quota_value__bytes": "admin_quota.bytes"}, where=["admin_quota.username=%s" % where], tables=["admin_quota", "admin_domain"], - order_by=["%s%s" % (sort_dir, sort_order)] + order_by=["%s%s" % (sort_dir, sort_order)], ) else: if db_type == "postgres": @@ -102,15 +104,13 @@ def list_quotas(request): select={"quota_usage": select}, where=["admin_quota.username=%s" % where], tables=["admin_quota", "admin_domain"], - order_by=["%s%s" % (sort_dir, sort_order)] + order_by=["%s%s" % (sort_dir, sort_order)], ) else: raise BadRequest(_("Invalid request")) page = get_listing_page(mboxes, request.GET.get("page", 1)) context = { - "headers": render_to_string( - "admin/identities_quota_headers.html", {}, request - ) + "headers": render_to_string("admin/identities_quota_headers.html", {}, request) } if page is None: context["length"] = 0 @@ -124,9 +124,9 @@ def list_quotas(request): @login_required @user_passes_test( - lambda u: u.has_perm("core.add_user") or - u.has_perm("admin.add_alias") or - u.has_perm("admin.add_mailbox") + lambda u: u.has_perm("core.add_user") + or u.has_perm("admin.add_alias") + or u.has_perm("admin.add_mailbox") ) def get_next_page(request): """Return the next page of the identity list.""" @@ -137,22 +137,17 @@ def get_next_page(request): @login_required @user_passes_test( - lambda u: u.has_perm("core.add_user") or - u.has_perm("admin.add_alias") + lambda u: u.has_perm("core.add_user") or u.has_perm("admin.add_alias") ) @ensure_csrf_cookie def identities(request, tplname="admin/identities.html"): - return render(request, tplname, { - "selection": "identities", - "deflocation": "list/" - }) + return render(request, tplname, {"selection": "identities", "deflocation": "list/"}) @login_required @permission_required("core.add_user") def accounts_list(request): - accs = User.objects.filter(is_superuser=False) \ - .exclude(groups__name="SimpleUsers") + accs = User.objects.filter(is_superuser=False).exclude(groups__name="SimpleUsers") res = [a.username for a in accs.all()] return render_to_json_response(res) @@ -175,11 +170,10 @@ def editaccount(request, pk): raise PermDeniedException mb = account.mailbox if hasattr(account, "mailbox") else None - instances = { - "general": account, "profile": account, "mail": mb, "perms": account - } + instances = {"general": account, "profile": account, "mail": mb, "perms": account} results = signals.get_account_form_instances.send( - sender="editaccount", user=request.user, account=account) + sender="editaccount", user=request.user, account=account + ) for result in results: instances.update(result[1]) return AccountForm(request, instances=instances).process() @@ -190,9 +184,7 @@ def editaccount(request, pk): @require_http_methods(["POST"]) def delaccount(request, pk): User.objects.get(pk=pk).delete() - return render_to_json_response( - ngettext("Account deleted", "Accounts deleted", 1) - ) + return render_to_json_response(ngettext("Account deleted", "Accounts deleted", 1)) @login_required @@ -208,15 +200,13 @@ def remove_permission(request): domain = Domain.objects.get(pk=domid) except (User.DoesNotExist, Domain.DoesNotExist): raise BadRequest(_("Invalid request")) - if not request.user.can_access(account) or \ - not request.user.can_access(domain): + if not request.user.can_access(account) or not request.user.can_access(domain): raise PermDeniedException domain.remove_admin(account) return render_to_json_response({}) -class AccountDetailView( - auth_mixins.PermissionRequiredMixin, generic.DetailView): +class AccountDetailView(auth_mixins.PermissionRequiredMixin, generic.DetailView): """DetailView for Account.""" model = User @@ -235,12 +225,12 @@ class AccountDetailView( context = super(AccountDetailView, self).get_context_data(**kwargs) del context["user"] result = signals.extra_account_dashboard_widgets.send( - self.__class__, user=self.request.user, account=self.object) + self.__class__, user=self.request.user, account=self.object + ) context["templates"] = {"left": [], "right": []} for _receiver, widgets in result: for widget in widgets: - context["templates"][widget["column"]].append( - widget["template"]) + context["templates"][widget["column"]].append(widget["template"]) context.update(widget["context"]) if self.object.role in ["Resellers", "DomainAdmins"]: context["domains"] = Domain.objects.get_for_admin(self.object) diff --git a/modoboa/admin/views/import_.py b/modoboa/admin/views/import_.py index 575eb3be1..80744e10d 100644 --- a/modoboa/admin/views/import_.py +++ b/modoboa/admin/views/import_.py @@ -6,7 +6,9 @@ import io from reversion import revisions as reversion from django.contrib.auth.decorators import ( - login_required, permission_required, user_passes_test + login_required, + permission_required, + user_passes_test, ) from django.db import transaction from django.shortcuts import render @@ -35,14 +37,13 @@ def importdata(request, formclass=ImportDataForm): form = formclass(request.POST, request.FILES) if form.is_valid(): status, msg = lib.import_data( - request.user, request.FILES["sourcefile"], form.cleaned_data) + request.user, request.FILES["sourcefile"], form.cleaned_data + ) if status: - return render(request, "admin/import_done.html", { - "status": "ok", "msg": msg - }) - return render(request, "admin/import_done.html", { - "status": "ko", "msg": msg - }) + return render( + request, "admin/import_done.html", {"status": "ok", "msg": msg} + ) + return render(request, "admin/import_done.html", {"status": "ko", "msg": msg}) @login_required @@ -66,8 +67,7 @@ def import_domains(request): @login_required @user_passes_test( - lambda u: u.has_perm("core.add_user") or - u.has_perm("admin.add_alias") + lambda u: u.has_perm("core.add_user") or u.has_perm("admin.add_alias") ) def import_identities(request): if request.method == "POST": @@ -81,6 +81,6 @@ def import_identities(request): "formid": "importform", "enctype": "multipart/form-data", "target": "import_target", - "form": ImportIdentitiesForm() + "form": ImportIdentitiesForm(), } return render(request, "admin/import_identities_form.html", ctx) diff --git a/modoboa/admin/views/user.py b/modoboa/admin/views/user.py index f21de52c7..22039b368 100644 --- a/modoboa/admin/views/user.py +++ b/modoboa/admin/views/user.py @@ -23,37 +23,34 @@ def forward(request, tplname="admin/forward.html"): if form.is_valid(): recipients = form.cleaned_data["dest"] if not recipients: - Alias.objects.filter( - address=mb.full_address, internal=False).delete() + Alias.objects.filter(address=mb.full_address, internal=False).delete() # Make sure internal self-alias is enabled - Alias.objects.filter( - address=mb.full_address, internal=True - ).update(enabled=True) + Alias.objects.filter(address=mb.full_address, internal=True).update( + enabled=True + ) else: if al is None: al = Alias.objects.create( address=mb.full_address, domain=mb.domain, - enabled=mb.user.is_active + enabled=mb.user.is_active, ) al.post_create(request.user) if form.cleaned_data["keepcopies"]: # Make sure internal self-alias is enabled - Alias.objects.filter( - address=mb.full_address, internal=True - ).update(enabled=True) + Alias.objects.filter(address=mb.full_address, internal=True).update( + enabled=True + ) else: # Deactivate internal self-alias to avoid storing # local copies... - Alias.objects.filter( - address=mb.full_address, internal=True - ).update(enabled=False) + Alias.objects.filter(address=mb.full_address, internal=True).update( + enabled=False + ) al.set_recipients(recipients) return render_to_json_response(_("Forward updated")) - return render_to_json_response( - {"form_errors": form.errors}, status=400 - ) + return render_to_json_response({"form_errors": form.errors}, status=400) form = ForwardForm() if al is not None and al.recipients: @@ -62,6 +59,6 @@ def forward(request, tplname="admin/forward.html"): form.fields["keepcopies"].initial = True recipients.remove(mb.full_address) form.fields["dest"].initial = "\n".join(recipients) - return render_to_json_response({ - "content": render_to_string(tplname, {"form": form}, request) - }) + return render_to_json_response( + {"content": render_to_string(tplname, {"form": form}, request)} + ) diff --git a/modoboa/core/api/v1/serializers.py b/modoboa/core/api/v1/serializers.py index c3f115530..50af8729c 100644 --- a/modoboa/core/api/v1/serializers.py +++ b/modoboa/core/api/v1/serializers.py @@ -39,7 +39,7 @@ class CheckPasswordTFASerializer(serializers.Serializer): logger.warning( _("Failed TFA settings editing attempt from '%s' as user '%s'"), self.context["remote_addr"], - escape(user.username) + escape(user.username), ) raise serializers.ValidationError(_("Invalid password")) return value diff --git a/modoboa/core/api/v1/tests.py b/modoboa/core/api/v1/tests.py index 0719a3ba9..0d82ed941 100644 --- a/modoboa/core/api/v1/tests.py +++ b/modoboa/core/api/v1/tests.py @@ -4,7 +4,7 @@ from modoboa.lib.tests import ModoTestCase class OpenAPITestCase(ModoTestCase): - openapi_schema_url = reverse_lazy('schema-v1-legacy') + openapi_schema_url = reverse_lazy("schema-v1-legacy") def test_unauthorized(self): self.client.logout() @@ -17,7 +17,10 @@ class OpenAPITestCase(ModoTestCase): response = self.client.get(self.openapi_schema_url) self.assertEqual(response.status_code, 200) - self.assertEqual(response.json()['info'], { - 'title': "Modoboa API", - 'version': "v1", - }) + self.assertEqual( + response.json()["info"], + { + "title": "Modoboa API", + "version": "v1", + }, + ) diff --git a/modoboa/core/api/v1/viewsets.py b/modoboa/core/api/v1/viewsets.py index fc99450d0..da8c8b634 100644 --- a/modoboa/core/api/v1/viewsets.py +++ b/modoboa/core/api/v1/viewsets.py @@ -22,31 +22,28 @@ class AccountViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): Contains endpoints used to manipulate current user's account. """ - permission_classes = (permissions.IsAuthenticated, ) + permission_classes = (permissions.IsAuthenticated,) serializer_class = None @action(methods=["post"], detail=False, url_path="tfa/setup") def tfa_setup(self, request): """Initiate TFA setup.""" instance, created = TOTPDevice.objects.get_or_create( - user=request.user, - defaults={"name": "{} TOTP device".format(request.user)} + user=request.user, defaults={"name": "{} TOTP device".format(request.user)} ) return response.Response() - @extend_schema( - request=serializers.CheckTFASetupSerializer - ) + @extend_schema(request=serializers.CheckTFASetupSerializer) @action(methods=["post"], detail=False, url_path="tfa/setup/check") def tfa_setup_check(self, request): """Check TFA setup.""" serializer = serializers.CheckTFASetupSerializer( - data=request.data, context={"user": request.user}) + data=request.data, context={"user": request.user} + ) serializer.is_valid(raise_exception=True) # create static device for recovery purposes device = StaticDevice.objects.create( - user=request.user, - name="{} static device".format(request.user) + user=request.user, name="{} static device".format(request.user) ) for cpt in range(10): token = StaticToken.random_token() @@ -59,42 +56,34 @@ class AccountViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): """Disable TFA.""" serializer = serializers.CheckPasswordTFASerializer( data=request.data, - context={ - "user": request.user, - "remote_addr": request.META["REMOTE_ADDR"] - } + context={"user": request.user, "remote_addr": request.META["REMOTE_ADDR"]}, ) serializer.is_valid(raise_exception=True) if not request.user.tfa_enabled: # We include it as "password" to display the error - return response.Response({"error": _("2FA is not enabled")}, - status=403) + return response.Response({"error": _("2FA is not enabled")}, status=403) request.user.totpdevice_set.all().delete() request.user.staticdevice_set.all().delete() request.user.tfa_enabled = False request.user.save() return response.Response() - @extend_schema(tags=['account']) + @extend_schema(tags=["account"]) @action(methods=["post"], detail=False, url_path="tfa/reset_codes") def tfa_reset_codes(self, request, *args, **kwargs): """Reset recovery codes.""" serializer = serializers.CheckPasswordTFASerializer( data=request.data, - context={ - "user": request.user, - "remote_addr": request.META["REMOTE_ADDR"] - } + context={"user": request.user, "remote_addr": request.META["REMOTE_ADDR"]}, ) serializer.is_valid(raise_exception=True) device = request.user.staticdevice_set.first() if device is None: - return response.Response({"error": _("2FA is not enabled")}, - status=403) + return response.Response({"error": _("2FA is not enabled")}, status=403) device.token_set.all().delete() for cpt in range(10): token = StaticToken.random_token() device.token_set.create(token=token) - return response.Response({ - "tokens": device.token_set.all().values_list("token", flat=True) - }) + return response.Response( + {"tokens": device.token_set.all().values_list("token", flat=True)} + ) diff --git a/modoboa/core/api/v2/serializers.py b/modoboa/core/api/v2/serializers.py index e72387123..d52d86acd 100644 --- a/modoboa/core/api/v2/serializers.py +++ b/modoboa/core/api/v2/serializers.py @@ -1,4 +1,5 @@ """Core API v2 serializers.""" + import django_otp import oath @@ -22,7 +23,11 @@ from rest_framework import serializers, status from rest_framework.exceptions import APIException from modoboa.core import ( - constants, models, sms_backends, app_settings, context_processors + constants, + models, + sms_backends, + app_settings, + context_processors, ) from modoboa.core.models import User from modoboa.lib import fields as lib_fields, cryptutils @@ -30,7 +35,7 @@ from modoboa.lib import fields as lib_fields, cryptutils class CustomValidationError(APIException): status_code = status.HTTP_400_BAD_REQUEST - default_detail = 'A server error occurred.' + default_detail = "A server error occurred." def __init__(self, detail, status_code): if status_code is not None: @@ -38,16 +43,17 @@ class CustomValidationError(APIException): if detail is not None: self.detail = detail else: - self.detail = {'detail': force_str(self.default_detail)} + self.detail = {"detail": force_str(self.default_detail)} class NoSMSAvailable(Exception): - """ Raised when no sms totp is available for password reset (to try email).""" + """Raised when no sms totp is available for password reset (to try email).""" + pass class PasswordRequirementsFailure(Exception): - """ Raised when django is not happy with password provided.""" + """Raised when django is not happy with password provided.""" def __init__(self, message_list, *args: object) -> None: super().__init__(*args) @@ -59,46 +65,41 @@ class CoreGlobalParametersSerializer(serializers.Serializer): # General settings authentication_type = serializers.ChoiceField( - choices=[("local", gettext_lazy("Local")), - ("ldap", "LDAP")], - default="local" + choices=[("local", gettext_lazy("Local")), ("ldap", "LDAP")], default="local" ) password_scheme = serializers.ChoiceField( - choices=[("sha512crypt", "sha512crypt")], - required=False + choices=[("sha512crypt", "sha512crypt")], required=False ) rounds_number = serializers.IntegerField(default=70000) update_scheme = serializers.BooleanField(default=True) default_password = serializers.CharField(default="ChangeMe1!") random_password_length = serializers.IntegerField(min_value=8, default=8) - update_password_url = serializers.URLField( - required=False, allow_blank=True) - password_recovery_msg = serializers.CharField( - required=False, allow_blank=True) + update_password_url = serializers.URLField(required=False, allow_blank=True) + password_recovery_msg = serializers.CharField(required=False, allow_blank=True) sms_password_recovery = serializers.BooleanField(default=False) sms_provider = serializers.ChoiceField( - choices=constants.SMS_BACKENDS, required=False, allow_null=True) + choices=constants.SMS_BACKENDS, required=False, allow_null=True + ) # LDAP settings ldap_server_address = serializers.CharField(default="localhost") ldap_server_port = serializers.IntegerField(default=389) ldap_enable_secondary_server = serializers.BooleanField(default=False) ldap_secondary_server_address = serializers.CharField(required=False) - ldap_secondary_server_port = serializers.IntegerField( - default=389, required=False) + ldap_secondary_server_port = serializers.IntegerField(default=389, required=False) ldap_secured = serializers.ChoiceField( - choices=constants.LDAP_SECURE_MODES, - default="none" + choices=constants.LDAP_SECURE_MODES, default="none" ) ldap_is_active_directory = serializers.BooleanField(default=False) ldap_admin_groups = serializers.CharField( - default="", required=False, allow_blank=True) + default="", required=False, allow_blank=True + ) ldap_group_type = serializers.ChoiceField( - default="posixgroup", - choices=constants.LDAP_GROUP_TYPES + default="posixgroup", choices=constants.LDAP_GROUP_TYPES ) ldap_groups_search_base = serializers.CharField( - default="", required=False, allow_blank=True) + default="", required=False, allow_blank=True + ) ldap_password_attribute = serializers.CharField(default="userPassword") # LDAP auth settings @@ -106,32 +107,31 @@ class CoreGlobalParametersSerializer(serializers.Serializer): choices=constants.LDAP_AUTH_METHODS, default="searchbind", ) - ldap_bind_dn = serializers.CharField( - default="", required=False, allow_blank=True) + ldap_bind_dn = serializers.CharField(default="", required=False, allow_blank=True) ldap_bind_password = serializers.CharField( - default="", required=False, allow_blank=True) + default="", required=False, allow_blank=True + ) ldap_search_base = serializers.CharField( - default="", required=False, allow_blank=True) + default="", required=False, allow_blank=True + ) ldap_search_filter = serializers.CharField( - default="(mail=%(user)s)", required=False, - allow_blank=True) + default="(mail=%(user)s)", required=False, allow_blank=True + ) ldap_user_dn_template = serializers.CharField( - default="", required=False, allow_blank=True) + default="", required=False, allow_blank=True + ) # LDAP sync settings ldap_sync_bind_dn = serializers.CharField(required=False, allow_blank=True) - ldap_sync_bind_password = serializers.CharField( - required=False, allow_blank=True) + ldap_sync_bind_password = serializers.CharField(required=False, allow_blank=True) ldap_enable_sync = serializers.BooleanField(default=False) ldap_sync_delete_remote_account = serializers.BooleanField(default=False) ldap_sync_account_dn_template = serializers.CharField( - required=False, allow_blank=True) - ldap_enable_import = serializers.BooleanField(default=False) - ldap_import_search_base = serializers.CharField( - required=False, allow_blank=True) - ldap_import_search_filter = serializers.CharField( - default="(cn=*)", required=False + required=False, allow_blank=True ) + ldap_enable_import = serializers.BooleanField(default=False) + ldap_import_search_base = serializers.CharField(required=False, allow_blank=True) + ldap_import_search_filter = serializers.CharField(default="(cn=*)", required=False) ldap_import_username_attr = serializers.CharField(default="cn") ldap_dovecot_sync = serializers.BooleanField(default=False) ldap_dovecot_conf_file = serializers.CharField( @@ -140,12 +140,12 @@ class CoreGlobalParametersSerializer(serializers.Serializer): # Dashboard settings rss_feed_url = serializers.URLField( - allow_blank=True, required=False, allow_null=True) + allow_blank=True, required=False, allow_null=True + ) hide_features_widget = serializers.BooleanField(default=False) # Notification settings - sender_address = lib_fields.DRFEmailFieldUTF8( - default="noreply@yourdomain.test") + sender_address = lib_fields.DRFEmailFieldUTF8(default="noreply@yourdomain.test") # API settings enable_api_communication = serializers.BooleanField(default=True) @@ -161,16 +161,18 @@ class CoreGlobalParametersSerializer(serializers.Serializer): log_maximum_age = serializers.IntegerField(default=365) items_per_page = serializers.IntegerField(default=30) default_top_redirection = serializers.ChoiceField( - default="user", choices=[("user", _("User profile"))], required=False) + default="user", choices=[("user", _("User profile"))], required=False + ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) sms_backend_fields = sms_backends.get_all_backend_serializer_settings() for field, definition in sms_backend_fields.items(): - self.fields[field] = definition["type"]( - **definition["attrs"]) + self.fields[field] = definition["type"](**definition["attrs"]) # Choices serializer for default_top_redirection field - self.fields["default_top_redirection"].choices = app_settings.enabled_applications() + self.fields["default_top_redirection"].choices = ( + app_settings.enabled_applications() + ) # Populate choices of password_scheme self.fields["password_scheme"].choices = app_settings.get_password_scheme() @@ -286,12 +288,15 @@ class PasswordRecoveryEmailSerializer(serializers.Serializer): def validate(self, data): clean_email = data["email"] - self.context["user"] = (User.objects.filter( - email__iexact=clean_email, is_active=True) - .exclude(Q(secondary_email__isnull=True) | Q(secondary_email="")) + self.context["user"] = ( + User.objects.filter(email__iexact=clean_email, is_active=True).exclude( + Q(secondary_email__isnull=True) | Q(secondary_email="") + ) ).first() if self.context["user"] is None: - raise CustomValidationError({"type": "email", "reason": "No valid user found."}, 404) + raise CustomValidationError( + {"type": "email", "reason": "No valid user found."}, 404 + ) return data def save(self): @@ -301,30 +306,33 @@ class PasswordRecoveryEmailSerializer(serializers.Serializer): site_name = current_site.name domain = current_site.domain context = { - 'email': to_email, - 'domain': domain, - 'site_name': site_name, - 'uid': urlsafe_base64_encode(force_bytes(user.pk)), - 'user': user, - 'token': default_token_generator.make_token(user), - 'protocol': 'https', + "email": to_email, + "domain": domain, + "site_name": site_name, + "uid": urlsafe_base64_encode(force_bytes(user.pk)), + "user": user, + "token": default_token_generator.make_token(user), + "protocol": "https", } context.update(context_processors.new_admin_url()) subject = loader.render_to_string( - "registration/password_reset_subject.txt", context) + "registration/password_reset_subject.txt", context + ) # Email subject *must not* contain newlines - subject = ''.join(subject.splitlines()) + subject = "".join(subject.splitlines()) body = loader.render_to_string( - "registration/password_reset_email_v2.html", context) + "registration/password_reset_email_v2.html", context + ) send_mail(subject, body, None, [to_email], fail_silently=False) def send_sms_code(secret, backend, user): - """ Send a sms containing a TOTP code for password reset. """ + """Send a sms containing a TOTP code for password reset.""" code = oath.totp(secret) text = _( - "Please use the following code to recover your Modoboa password: {}" - .format(code) + "Please use the following code to recover your Modoboa password: {}".format( + code + ) ) if not backend.send(text, [str(user.phone_number)]): raise NoSMSAvailable() @@ -340,14 +348,14 @@ class PasswordRecoverySmsSerializer(serializers.Serializer): user = User.objects.filter(email__iexact=clean_email, is_active=True).first() if user is None: - raise CustomValidationError({ - "type": "sms", "reason": "No valid user found." - }, 404) + raise CustomValidationError( + {"type": "sms", "reason": "No valid user found."}, 404 + ) self.context["user"] = ( - User.objects.filter( - email__iexact=clean_email, is_active=True) - .exclude(Q(phone_number__isnull=True) | Q(phone_number="")) + User.objects.filter(email__iexact=clean_email, is_active=True).exclude( + Q(phone_number__isnull=True) | Q(phone_number="") + ) ).first() if self.context["user"] is None: raise NoSMSAvailable() @@ -358,8 +366,7 @@ class PasswordRecoverySmsSerializer(serializers.Serializer): user = self.context["user"] if not user: raise NoSMSAvailable() - backend = sms_backends.get_active_backend( - request.localconfig.parameters) + backend = sms_backends.get_active_backend(request.localconfig.parameters) secret = cryptutils.random_hex_key(20) send_sms_code(secret, backend, user) request.session["totp_secret"] = secret @@ -376,13 +383,15 @@ class PasswordRecoverySmsConfirmSerializer(serializers.Serializer): self.context["totp_secret"] = self.context["request"].session["totp_secret"] except KeyError: raise CustomValidationError( - {"reason": "totp secret not set in session"}, 403) + {"reason": "totp secret not set in session"}, 403 + ) if not oath.accept_totp(self.context["totp_secret"], data["sms_totp"])[0]: raise CustomValidationError({"reason": "Wrong totp"}, 400) # Attempt to get user, will raise an error if pk is not valid self.context["user"] = User.objects.filter( - pk=self.context["request"].session["user_pk"]).first() + pk=self.context["request"].session["user_pk"] + ).first() if self.context["user"] is None: raise CustomValidationError({"reason": "Invalid user"}, 400) @@ -404,11 +413,13 @@ class PasswordRecoverySmsResendSerializer(serializers.Serializer): self.context["totp_secret"] = self.context["request"].session["totp_secret"] except KeyError: raise CustomValidationError( - {"reason": "totp secret not set in session"}, status.HTTP_403_FORBIDDEN) + {"reason": "totp secret not set in session"}, status.HTTP_403_FORBIDDEN + ) # Attempt to get user, will raise an error if pk is not valid self.context["user"] = User.objects.filter( - pk=self.context["request"].session["user_pk"]).first() + pk=self.context["request"].session["user_pk"] + ).first() if self.context["user"] is None: raise CustomValidationError({"reason": "Invalid user"}, 400) @@ -416,7 +427,8 @@ class PasswordRecoverySmsResendSerializer(serializers.Serializer): def save(self): backend = sms_backends.get_active_backend( - self.context["request"].localconfig.parameters) + self.context["request"].localconfig.parameters + ) send_sms_code(self.context["totp_secret"], backend, self.context["user"]) return True @@ -442,9 +454,11 @@ class PasswordRecoveryConfirmSerializer(serializers.Serializer): def validate(self, data): # Validate password - if data["new_password1"] == "" or data["new_password1"] != data["new_password2"]: - raise serializers.ValidationError( - "Password is empty or does not match") + if ( + data["new_password1"] == "" + or data["new_password1"] != data["new_password2"] + ): + raise serializers.ValidationError("Password is empty or does not match") user = self.get_user(data["id"]) diff --git a/modoboa/core/api/v2/tests.py b/modoboa/core/api/v2/tests.py index b2fa8b7a7..75ea99c3b 100644 --- a/modoboa/core/api/v2/tests.py +++ b/modoboa/core/api/v2/tests.py @@ -11,8 +11,11 @@ from django.urls import reverse from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode -from modoboa.admin import (factories, models as admin_models, - constants as admin_constants) +from modoboa.admin import ( + factories, + models as admin_models, + constants as admin_constants, +) from modoboa.core import models, constants from modoboa.core.tests import utils from modoboa.lib.tests import ModoAPITestCase @@ -72,7 +75,7 @@ CORE_SETTINGS = { "top_notifications_check_interval": 30, "log_maximum_age": 365, "items_per_page": 30, - "default_top_redirection": "user" + "default_top_redirection": "user", } @@ -82,8 +85,9 @@ class ParametersAPITestCase(ModoAPITestCase): super().setUp() cache.delete("password_scheme_choice") - @override_settings(DOVEADM_LOOKUP_PATH=[DOVEADM_TEST_PATH], - DOVECOT_USER=DOVECOT_USER) + @override_settings( + DOVEADM_LOOKUP_PATH=[DOVEADM_TEST_PATH], DOVECOT_USER=DOVECOT_USER + ) def test_update(self): url = reverse("v2:parameter-detail", args=["core"]) data = copy.copy(CORE_SETTINGS) @@ -91,9 +95,7 @@ class ParametersAPITestCase(ModoAPITestCase): self.assertEqual(resp.status_code, 200) self.assertIsNotNone(cache.get("password_scheme_choice")) - self.assertIn(('plain', 'plain (weak)'), - cache.get("password_scheme_choice") - ) + self.assertIn(("plain", "plain (weak)"), cache.get("password_scheme_choice")) # Modify SMS related settings data["sms_password_recovery"] = True resp = self.client.put(url, data, format="json") @@ -102,20 +104,19 @@ class ParametersAPITestCase(ModoAPITestCase): data["sms_provider"] = "test" resp = self.client.put(url, data, format="json") self.assertEqual(resp.status_code, 400) - data.update({ - "sms_provider": "ovh", - "sms_ovh_application_key": "key", - "sms_ovh_application_secret": "secret", - "sms_ovh_consumer_key": "consumer" - }) + data.update( + { + "sms_provider": "ovh", + "sms_ovh_application_key": "key", + "sms_ovh_application_secret": "secret", + "sms_ovh_consumer_key": "consumer", + } + ) resp = self.client.put(url, data, format="json") self.assertEqual(resp.status_code, 200) # Modify some LDAP settings - data.update({ - "authentication_type": "ldap", - "ldap_auth_method": "searchbind" - }) + data.update({"authentication_type": "ldap", "ldap_auth_method": "searchbind"}) resp = self.client.put(url, data, format="json") self.assertEqual(resp.status_code, 400) self.assertIn("ldap_search_base", resp.json()) @@ -125,16 +126,18 @@ class ParametersAPITestCase(ModoAPITestCase): self.assertEqual(resp.status_code, 400) self.assertIn("ldap_user_dn_template", resp.json()) - data.update({ - "ldap_user_dn_template": "%(user)s", - "ldap_sync_account_dn_template": "%(user)s", - "ldap_search_filter": "mail=%(user)s" - }) + data.update( + { + "ldap_user_dn_template": "%(user)s", + "ldap_sync_account_dn_template": "%(user)s", + "ldap_search_filter": "mail=%(user)s", + } + ) resp = self.client.put(url, data, format="json") self.assertEqual(resp.status_code, 200) def test_doveadm_alarm(self): - """ Test that an alarm is opened, closed or reopened + """Test that an alarm is opened, closed or reopened depending on the result of the doveadm command for the password scheme """ # Test case where doveadm command fails @@ -147,22 +150,24 @@ class ParametersAPITestCase(ModoAPITestCase): self.assertIsNone(cache.get("password_scheme_choice")) doveadm_alarm = admin_models.Alarm.objects.filter( - internal_name=constants.DOVEADM_PASS_SCHEME_ALARM) + internal_name=constants.DOVEADM_PASS_SCHEME_ALARM + ) self.assertEqual(doveadm_alarm.count(), 1) cache.delete("job_cache_available_password_hasher") - with self.settings(DOVEADM_LOOKUP_PATH=[DOVEADM_TEST_PATH], - DOVECOT_USER=DOVECOT_USER): + with self.settings( + DOVEADM_LOOKUP_PATH=[DOVEADM_TEST_PATH], DOVECOT_USER=DOVECOT_USER + ): # The command should work and close the alarm resp = self.client.put(url, data, format="json") self.assertEqual(resp.status_code, 200) self.assertIsNotNone(cache.get("password_scheme_choice")) doveadm_alarm = admin_models.Alarm.objects.filter( - internal_name=constants.DOVEADM_PASS_SCHEME_ALARM) + internal_name=constants.DOVEADM_PASS_SCHEME_ALARM + ) self.assertEqual(doveadm_alarm.count(), 1) - self.assertEqual(doveadm_alarm.first().status, - admin_constants.ALARM_CLOSED) + self.assertEqual(doveadm_alarm.first().status, admin_constants.ALARM_CLOSED) cache.delete("job_cache_available_password_hasher") # And lastly check that the alarm is reopened if the issue starts again @@ -172,10 +177,10 @@ class ParametersAPITestCase(ModoAPITestCase): self.assertEqual(resp.status_code, 200) doveadm_alarm = admin_models.Alarm.objects.filter( - internal_name=constants.DOVEADM_PASS_SCHEME_ALARM) + internal_name=constants.DOVEADM_PASS_SCHEME_ALARM + ) self.assertEqual(doveadm_alarm.count(), 1) - self.assertEqual(doveadm_alarm.first().status, - admin_constants.ALARM_OPENED) + self.assertEqual(doveadm_alarm.first().status, admin_constants.ALARM_OPENED) class AccountViewSetTestCase(ModoAPITestCase): @@ -227,11 +232,9 @@ class AccountViewSetTestCase(ModoAPITestCase): self.assertEqual(resp.status_code, 404) @mock.patch("django_otp.plugins.otp_totp.models.TOTPDevice.verify_token") - def test_tfa_setup_modify(self, - verify_mock, - password_ko="Toto1234", - password_ok="password" - ): + def test_tfa_setup_modify( + self, verify_mock, password_ko="Toto1234", password_ok="password" + ): user = models.User.objects.get(username="admin") user.totpdevice_set.create(name="Device") @@ -277,10 +280,7 @@ class AccountViewSetTestCase(ModoAPITestCase): def test_api_token(self): # 1. Obtain a JWT token so we can safely play with basic token url = reverse("v2:token_obtain_pair") - data = { - "username": "admin", - "password": "password" - } + data = {"username": "admin", "password": "password"} resp = self.client.post(url, data, format="json") self.assertEqual(resp.status_code, 200) self.client.credentials( @@ -300,19 +300,16 @@ class AccountViewSetTestCase(ModoAPITestCase): """Simulate a failed login attempt and check that it is logged.""" url = reverse("v2:token_obtain_pair") - data = { - "username": "clearly_non_existent_user", - "password": "password" - } + data = {"username": "clearly_non_existent_user", "password": "password"} - with self.assertLogs(logger='modoboa.auth', level='WARNING') as log: + with self.assertLogs(logger="modoboa.auth", level="WARNING") as log: resp = self.client.post(url, data, format="json") self.assertEqual(resp.status_code, 401) self.assertIn( "WARNING:modoboa.auth:Failed connection attempt from '127.0.0.1'" " as user 'clearly_non_existent_user'", - log.output + log.output, ) @@ -328,7 +325,8 @@ class PasswordResetTestCase(AccountViewSetTestCase): super().setUpTestData() factories.populate_database() cls.da_token = Token.objects.create( - user=models.User.objects.get(username="admin@test.com")) + user=models.User.objects.get(username="admin@test.com") + ) @mock.patch("ovh.Client.get") @mock.patch("ovh.Client.post") @@ -361,13 +359,16 @@ class PasswordResetTestCase(AccountViewSetTestCase): self.assertEqual(response.json()["type"], "email") # SMS reset test - self.set_global_parameters({ - "sms_password_recovery": True, - "sms_provider": "ovh", - "sms_ovh_application_key": "key", - "sms_ovh_application_secret": "secret", - "sms_ovh_consumer_key": "consumer" - }, app="core") + self.set_global_parameters( + { + "sms_password_recovery": True, + "sms_provider": "ovh", + "sms_ovh_application_key": "key", + "sms_ovh_application_secret": "secret", + "sms_ovh_consumer_key": "consumer", + }, + app="core", + ) # Phone number account.phone_number = "+33612345678" @@ -395,13 +396,15 @@ class PasswordResetTestCase(AccountViewSetTestCase): # Send sms client_get.return_value = ["service"] client_post.return_value = {"totalCreditsRemoved": 1} - self.set_global_parameters({ - "sms_password_recovery": True, - "sms_provider": "ovh", - "sms_ovh_application_key": "key", - "sms_ovh_application_secret": "secret", - "sms_ovh_consumer_key": "consumer" - }) + self.set_global_parameters( + { + "sms_password_recovery": True, + "sms_provider": "ovh", + "sms_ovh_application_key": "key", + "sms_ovh_application_secret": "secret", + "sms_ovh_consumer_key": "consumer", + } + ) self.client.logout() self.create_session() data = {"email": account.email} @@ -447,13 +450,15 @@ class PasswordResetTestCase(AccountViewSetTestCase): client_get.return_value = ["service"] client_post.return_value = {"totalCreditsRemoved": 1} - self.set_global_parameters({ - "sms_password_recovery": True, - "sms_provider": "ovh", - "sms_ovh_application_key": "key", - "sms_ovh_application_secret": "secret", - "sms_ovh_consumer_key": "consumer" - }) + self.set_global_parameters( + { + "sms_password_recovery": True, + "sms_provider": "ovh", + "sms_ovh_application_key": "key", + "sms_ovh_application_secret": "secret", + "sms_ovh_consumer_key": "consumer", + } + ) # Prepare account account = models.User.objects.get(username="user@test.com") @@ -477,30 +482,54 @@ class PasswordResetTestCase(AccountViewSetTestCase): token_ok = response.json()["token"] # Password differs - data = {"new_password1": "123456", "new_password2": "123457", "token": token_ok, "id": id_ok} + data = { + "new_password1": "123456", + "new_password2": "123457", + "token": token_ok, + "id": id_ok, + } response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 400) # Wrong ID id_ko = urlsafe_base64_encode(force_bytes(-1)) - data = {"new_password1": "123456", "new_password2": "123456", "token": token_ok, "id": id_ko} + data = { + "new_password1": "123456", + "new_password2": "123456", + "token": token_ok, + "id": id_ko, + } response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 404) # Wrong Token token_ko = "123456" - data = {"new_password1": "123456", "new_password2": "123456", "token": token_ko, "id": id_ok} + data = { + "new_password1": "123456", + "new_password2": "123456", + "token": token_ko, + "id": id_ok, + } response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 403) # Failed password requirements - data = {"new_password1": "123456", "new_password2": "123456", "token": token_ok, "id": id_ok} + data = { + "new_password1": "123456", + "new_password2": "123456", + "token": token_ok, + "id": id_ok, + } response = self.client.post(url, data, format="json") self.assertEqual(response.json()["type"], "password_requirement") # All good - data = {"new_password1": "MyHardenedPass1!", "new_password2": "MyHardenedPass1!", "token": token_ok, - "id": id_ok} + data = { + "new_password1": "MyHardenedPass1!", + "new_password2": "MyHardenedPass1!", + "token": token_ok, + "id": id_ok, + } response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 200) # TODO: See why user doesn't update it's password --> self.test_me_password(password_ok="MyHardenedPass1!") @@ -512,15 +541,13 @@ class AuthenticationTestCase(ModoAPITestCase): def test_2fa(self, match_mock): url = reverse("v2:token_obtain_pair") me_url = reverse("v2:account-me") - data = { - "username": "admin", - "password": "password" - } + data = {"username": "admin", "password": "password"} resp = self.client.post(url, data, format="json") self.assertEqual(resp.status_code, 200) self.client.credentials( - HTTP_AUTHORIZATION="Bearer {}".format(resp.json()["access"])) + HTTP_AUTHORIZATION="Bearer {}".format(resp.json()["access"]) + ) resp = self.client.get(me_url) self.assertEqual(resp.status_code, 200) @@ -540,7 +567,8 @@ class AuthenticationTestCase(ModoAPITestCase): self.assertEqual(resp.status_code, 200) self.client.credentials( - HTTP_AUTHORIZATION="Bearer {}".format(resp.json()["access"])) + HTTP_AUTHORIZATION="Bearer {}".format(resp.json()["access"]) + ) resp = self.client.get(me_url) self.assertEqual(resp.status_code, 200) diff --git a/modoboa/core/api/v2/urls.py b/modoboa/core/api/v2/urls.py index da5784b20..9fc5ef6b6 100644 --- a/modoboa/core/api/v2/urls.py +++ b/modoboa/core/api/v2/urls.py @@ -18,16 +18,22 @@ router.register(r"logs/audit-trail", viewsets.LogViewSet) urlpatterns = router.urls urlpatterns += [ - path('token/', views.TokenObtainPairView.as_view(), - name="token_obtain_pair"), - path('token/refresh/', TokenRefreshView.as_view(), - name="token_refresh"), - path('password_reset/', views.DefaultPasswordResetView.as_view(), - name="password_reset"), - path('reset_confirm/', views.PasswordResetConfirmView.as_view(), - name="password_reset_confirm_v2"), - path('sms_totp/', views.PasswordResetSmsTOTP.as_view(), - name="sms_totp"), - path('admin/components/', views.ComponentsInformationAPIView.as_view(), - name="components_information"), + path("token/", views.TokenObtainPairView.as_view(), name="token_obtain_pair"), + path("token/refresh/", TokenRefreshView.as_view(), name="token_refresh"), + path( + "password_reset/", + views.DefaultPasswordResetView.as_view(), + name="password_reset", + ), + path( + "reset_confirm/", + views.PasswordResetConfirmView.as_view(), + name="password_reset_confirm_v2", + ), + path("sms_totp/", views.PasswordResetSmsTOTP.as_view(), name="sms_totp"), + path( + "admin/components/", + views.ComponentsInformationAPIView.as_view(), + name="components_information", + ), ] diff --git a/modoboa/core/api/v2/views.py b/modoboa/core/api/v2/views.py index 4f69225dc..3e3f32973 100644 --- a/modoboa/core/api/v2/views.py +++ b/modoboa/core/api/v2/views.py @@ -19,8 +19,11 @@ from modoboa.core.password_hashers import get_password_hasher from modoboa.core.utils import check_for_updates from modoboa.lib.permissions import IsSuperUser from modoboa.lib.throttle import ( - UserLesserDdosUser, LoginThrottle, PasswordResetApplyThrottle, - PasswordResetRequestThrottle, PasswordResetTotpThrottle + UserLesserDdosUser, + LoginThrottle, + PasswordResetApplyThrottle, + PasswordResetRequestThrottle, + PasswordResetTotpThrottle, ) from modoboa.parameters import tools as param_tools @@ -53,7 +56,7 @@ class TokenObtainPairView(jwt_views.TokenObtainPairView): logger.warning( _("Failed connection attempt from '%s' as user '%s'"), request.META["REMOTE_ADDR"], - escape(serializer.initial_data["username"]) + escape(serializer.initial_data["username"]), ) raise InvalidToken(e.args[0]) @@ -63,19 +66,16 @@ class TokenObtainPairView(jwt_views.TokenObtainPairView): # Reset login throttle delete_cache_key(LoginThrottle, self.get_throttles(), request) - logger.info( - _("User '%s' successfully logged in"), user.username - ) + logger.info(_("User '%s' successfully logged in"), user.username) if user and user.is_active: - condition = ( - user.is_local and - param_tools.get_global_parameter( - "update_scheme", raise_exception=False) + condition = user.is_local and param_tools.get_global_parameter( + "update_scheme", raise_exception=False ) if condition: # check if password scheme is correct scheme = param_tools.get_global_parameter( - "password_scheme", raise_exception=False) + "password_scheme", raise_exception=False + ) # use SHA512CRYPT as default fallback if scheme is None: pwhash = get_password_hasher("sha512crypt")() @@ -84,21 +84,19 @@ class TokenObtainPairView(jwt_views.TokenObtainPairView): if not user.password.startswith(pwhash.scheme): logger.info( _("Password scheme mismatch. Updating %s password"), - user.username + user.username, ) user.set_password(request.data["password"]) user.save() if pwhash.needs_rehash(user.password): logger.info( - _("Password hash parameter missmatch. " - "Updating %s password"), - user.username + _("Password hash parameter missmatch. " "Updating %s password"), + user.username, ) user.set_password(serializer.data["password"]) user.save() - return response.Response( - serializer.validated_data, status=status.HTTP_200_OK) + return response.Response(serializer.validated_data, status=status.HTTP_200_OK) class EmailPasswordResetView(APIView): @@ -110,15 +108,19 @@ class EmailPasswordResetView(APIView): def post(self, request, *args, **kwargs): serializer = serializers.PasswordRecoveryEmailSerializer( - data=request.data, context={'request': request}) + data=request.data, context={"request": request} + ) serializer.is_valid(raise_exception=True) try: serializer.save() except SMTPException: - return response.Response({ - "type": "email", - "reason": "Error while sending the email. Please contact an administrator." - }, 503) + return response.Response( + { + "type": "email", + "reason": "Error while sending the email. Please contact an administrator.", + }, + 503, + ) # Email response return response.Response({"type": "email"}, 200) @@ -133,7 +135,8 @@ class DefaultPasswordResetView(EmailPasswordResetView): def post(self, request, *args, **kwargs): """Recover password.""" serializer = serializers.PasswordRecoverySmsSerializer( - data=request.data, context={'request': request}) + data=request.data, context={"request": request} + ) try: serializer.is_valid(raise_exception=True) except serializers.NoSMSAvailable: @@ -144,7 +147,7 @@ class DefaultPasswordResetView(EmailPasswordResetView): class PasswordResetSmsTOTP(APIView): - """ Check SMS Totp code. """ + """Check SMS Totp code.""" throttle_classes = [PasswordResetTotpThrottle] @@ -154,7 +157,7 @@ class PasswordResetSmsTOTP(APIView): klass = serializers.PasswordRecoverySmsConfirmSerializer elif request.data["type"] == "resend": klass = serializers.PasswordRecoverySmsResendSerializer - serializer = klass(data=request.data, context={'request': request}) + serializer = klass(data=request.data, context={"request": request}) except (MultiValueDictKeyError, KeyError): return response.Response({"reason": "No type provided."}, 400) serializer.is_valid(raise_exception=True) @@ -162,23 +165,24 @@ class PasswordResetSmsTOTP(APIView): payload = {"type": "resend"} if request.data["type"] == "confirm": serializer_response = serializer.context["response"] - payload.update({ - "token": serializer_response[0], - "id": serializer_response[1], - "type": "confirm" - }) + payload.update( + { + "token": serializer_response[0], + "id": serializer_response[1], + "type": "confirm", + } + ) delete_cache_key(PasswordResetTotpThrottle, self.get_throttles(), request) return response.Response(payload, 200) class PasswordResetConfirmView(APIView): - """ Get and set new user password. """ + """Get and set new user password.""" throttle_classes = [PasswordResetApplyThrottle] def post(self, request, *args, **kwargs): - serializer = serializers.PasswordRecoveryConfirmSerializer( - data=request.data) + serializer = serializers.PasswordRecoveryConfirmSerializer(data=request.data) try: serializer.is_valid(raise_exception=True) except serializers.PasswordRequirementsFailure as e: @@ -202,7 +206,5 @@ class ComponentsInformationAPIView(APIView): @extend_schema(responses=serializers.ModoboaComponentSerializer(many=True)) def get(self, request, *args, **kwargs): status, extensions = check_for_updates() - serializer = serializers.ModoboaComponentSerializer( - extensions, many=True - ) + serializer = serializers.ModoboaComponentSerializer(extensions, many=True) return response.Response(serializer.data) diff --git a/modoboa/core/api/v2/viewsets.py b/modoboa/core/api/v2/viewsets.py index 7cba4fdf6..2dd4dd17c 100644 --- a/modoboa/core/api/v2/viewsets.py +++ b/modoboa/core/api/v2/viewsets.py @@ -30,32 +30,30 @@ class AccountViewSet(core_v1_viewsets.AccountViewSet): return response.Response(serializer.data) @action( - methods=['post'], + methods=["post"], detail=False, - url_path='me/password', - serializer_class=serializers.CheckPasswordSerializer + url_path="me/password", + serializer_class=serializers.CheckPasswordSerializer, ) def check_me_password(self, request): """Check current user password.""" serializer = serializers.CheckPasswordSerializer( - data=request.data, context={"user": request.user}) + data=request.data, context={"user": request.user} + ) serializer.is_valid(raise_exception=True) return response.Response() @extend_schema( description="Get current API token", responses={200: serializers.UserAPITokenSerializer}, - methods=["GET"] + methods=["GET"], ) @extend_schema( description="Generate new API token", responses={201: serializers.UserAPITokenSerializer}, - methods=["POST"] - ) - @extend_schema( - description="Delete current API token", - methods=["DELETE"] + methods=["POST"], ) + @extend_schema(description="Delete current API token", methods=["DELETE"]) @action( methods=["get", "post", "delete"], detail=False, @@ -64,9 +62,7 @@ class AccountViewSet(core_v1_viewsets.AccountViewSet): def manage_api_token(self, request): """Manage API token.""" if not request.user.is_superuser: - raise PermissionDenied( - "Only super administrators can have API tokens" - ) + raise PermissionDenied("Only super administrators can have API tokens") if request.method == "DELETE": Token.objects.filter(user=request.user).delete() return response.Response(status=204) @@ -87,15 +83,16 @@ class AccountViewSet(core_v1_viewsets.AccountViewSet): def tfa_verify_code(self, request): """Verify given code validity.""" serializer = serializers.VerifyTFACodeSerializer( - data=request.data, context={"user": request.user}) + data=request.data, context={"user": request.user} + ) serializer.is_valid(raise_exception=True) refresh = RefreshToken.for_user(request.user) - refresh[constants.TFA_DEVICE_TOKEN_KEY] = ( - serializer.validated_data["code"].persistent_id) - return response.Response({ - "refresh": str(refresh), - "access": str(refresh.access_token) - }) + refresh[constants.TFA_DEVICE_TOKEN_KEY] = serializer.validated_data[ + "code" + ].persistent_id + return response.Response( + {"refresh": str(refresh), "access": str(refresh.access_token)} + ) @action(methods=["get"], detail=False, url_path="tfa/setup/key") def tfa_setup_get_key(self, request): @@ -105,22 +102,22 @@ class AccountViewSet(core_v1_viewsets.AccountViewSet): device = request.user.totpdevice_set.first() if not device: return response.Response(status=404) - return response.Response({"key": device.key, "url":device.config_url}, - content_type="application/json") + return response.Response( + {"key": device.key, "url": device.config_url}, + content_type="application/json", + ) - @extend_schema( - request=core_v1_serializers.CheckTFASetupSerializer - ) + @extend_schema(request=core_v1_serializers.CheckTFASetupSerializer) @action(methods=["post"], detail=False, url_path="tfa/setup/check") def tfa_setup_check(self, request): """Check TFA setup.""" serializer = core_v1_serializers.CheckTFASetupSerializer( - data=request.data, context={"user": request.user}) + data=request.data, context={"user": request.user} + ) serializer.is_valid(raise_exception=True) # create static device for recovery purposes device = StaticDevice.objects.create( - user=request.user, - name="{} static device".format(request.user) + user=request.user, name="{} static device".format(request.user) ) tokens = [] for cpt in range(10): @@ -134,11 +131,13 @@ class AccountViewSet(core_v1_viewsets.AccountViewSet): device = request.user.totpdevice_set.first() refresh = RefreshToken.for_user(request.user) refresh[constants.TFA_DEVICE_TOKEN_KEY] = device.persistent_id - return response.Response({ - "tokens": tokens, - "refresh": str(refresh), - "access": str(refresh.access_token) - }) + return response.Response( + { + "tokens": tokens, + "refresh": str(refresh), + "access": str(refresh.access_token), + } + ) class LogViewSet(GetThrottleViewsetMixin, viewsets.ReadOnlyModelViewSet): @@ -160,9 +159,7 @@ class LogViewSet(GetThrottleViewsetMixin, viewsets.ReadOnlyModelViewSet): class LanguageViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): """Language viewset.""" - permission_classes = ( - permissions.IsAuthenticated, - ) + permission_classes = (permissions.IsAuthenticated,) def list(self, request, *args, **kwargs): languages = [ diff --git a/modoboa/core/app_settings.py b/modoboa/core/app_settings.py index 17a41bd68..5fdb42c7f 100644 --- a/modoboa/core/app_settings.py +++ b/modoboa/core/app_settings.py @@ -10,9 +10,7 @@ from django.utils.translation import gettext as _, gettext_lazy from modoboa.core.password_hashers.utils import cache_available_password_hasher from modoboa.lib import fields as lib_fields -from modoboa.lib.form_utils import ( - HorizontalRadioSelect, SeparatorField, YesNoField -) +from modoboa.lib.form_utils import HorizontalRadioSelect, SeparatorField, YesNoField from modoboa.parameters import forms as param_forms, tools as param_tools from . import constants @@ -47,11 +45,10 @@ class GeneralParametersForm(param_forms.AdminParametersForm): authentication_type = forms.ChoiceField( label=gettext_lazy("Authentication type"), - choices=[("local", gettext_lazy("Local")), - ("ldap", "LDAP")], + choices=[("local", gettext_lazy("Local")), ("ldap", "LDAP")], initial="local", help_text=gettext_lazy("The backend used for authentication"), - widget=HorizontalRadioSelect() + widget=HorizontalRadioSelect(), ) password_scheme = forms.ChoiceField( @@ -75,22 +72,20 @@ class GeneralParametersForm(param_forms.AdminParametersForm): initial=True, help_text=gettext_lazy( "Update user password at login to use the default password scheme" - ) + ), ) default_password = forms.CharField( label=gettext_lazy("Default password"), initial="ChangeMe1!", - help_text=gettext_lazy( - "Default password for automatically created accounts.") + help_text=gettext_lazy("Default password for automatically created accounts."), ) random_password_length = forms.IntegerField( label=gettext_lazy("Random password length"), min_value=8, initial=8, - help_text=gettext_lazy( - "Length of randomly generated passwords.") + help_text=gettext_lazy("Length of randomly generated passwords."), ) update_password_url = forms.URLField( @@ -102,7 +97,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): " to update their password. It applies only to non local" " users, ie. those automatically created after a successful" " external authentication (LDAP, SMTP)." - ) + ), ) password_recovery_msg = forms.CharField( @@ -111,27 +106,23 @@ class GeneralParametersForm(param_forms.AdminParametersForm): required=False, widget=forms.widgets.Textarea(), help_text=gettext_lazy( - "A temporary message that will be displayed on the " - "reset password page." - ) + "A temporary message that will be displayed on the " "reset password page." + ), ) sms_password_recovery = YesNoField( label=gettext_lazy("Enable password recovery by SMS"), initial=False, help_text=gettext_lazy( - "Enable password recovery by SMS for users who filled " - "a phone number." - ) + "Enable password recovery by SMS for users who filled " "a phone number." + ), ) sms_provider = forms.ChoiceField( label=gettext_lazy("SMS provider"), choices=constants.SMS_BACKENDS, - help_text=gettext_lazy( - "Choose a provider to send password recovery SMS" - ), - required=False + help_text=gettext_lazy("Choose a provider to send password recovery SMS"), + required=False, ) # LDAP specific settings @@ -140,8 +131,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): ldap_server_address = forms.CharField( label=gettext_lazy("Server address"), initial="localhost", - help_text=gettext_lazy( - "The IP address or the DNS name of the LDAP server"), + help_text=gettext_lazy("The IP address or the DNS name of the LDAP server"), ) ldap_server_port = forms.IntegerField( @@ -156,21 +146,21 @@ class GeneralParametersForm(param_forms.AdminParametersForm): help_text=gettext_lazy( "Enable a secondary LDAP server which will be used " "if the primary one fails" - ) + ), ) ldap_secondary_server_address = forms.CharField( label=gettext_lazy("Secondary server address"), initial="localhost", help_text=gettext_lazy( - "The IP address or the DNS name of the seondary LDAP server"), + "The IP address or the DNS name of the seondary LDAP server" + ), ) ldap_secondary_server_port = forms.IntegerField( label=gettext_lazy("Secondary server port"), initial=389, - help_text=gettext_lazy( - "The TCP port number used by the LDAP secondary server"), + help_text=gettext_lazy("The TCP port number used by the LDAP secondary server"), ) ldap_secured = forms.ChoiceField( @@ -178,14 +168,14 @@ class GeneralParametersForm(param_forms.AdminParametersForm): choices=constants.LDAP_SECURE_MODES, initial="none", help_text=gettext_lazy( - "Use an SSL/STARTTLS connection to access the LDAP server") + "Use an SSL/STARTTLS connection to access the LDAP server" + ), ) ldap_is_active_directory = YesNoField( label=gettext_lazy("Active Directory"), initial=False, - help_text=gettext_lazy( - "Tell if the LDAP server is an Active Directory one") + help_text=gettext_lazy("Tell if the LDAP server is an Active Directory one"), ) ldap_admin_groups = forms.CharField( @@ -195,16 +185,14 @@ class GeneralParametersForm(param_forms.AdminParametersForm): "Members of those LDAP Posix groups will be created as domain " "administrators. Use ';' characters to separate groups." ), - required=False + required=False, ) ldap_group_type = forms.ChoiceField( label=gettext_lazy("Group type"), initial="posixgroup", choices=constants.LDAP_GROUP_TYPES, - help_text=gettext_lazy( - "The LDAP group type to use with your directory." - ) + help_text=gettext_lazy("The LDAP group type to use with your directory."), ) ldap_groups_search_base = forms.CharField( @@ -213,7 +201,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): help_text=gettext_lazy( "The distinguished name of the search base used to find groups" ), - required=False + required=False, ) ldap_password_attribute = forms.CharField( @@ -223,13 +211,14 @@ class GeneralParametersForm(param_forms.AdminParametersForm): ) # LDAP authentication settings - ldap_auth_sep = SeparatorField( - label=gettext_lazy("LDAP authentication settings")) + ldap_auth_sep = SeparatorField(label=gettext_lazy("LDAP authentication settings")) ldap_auth_method = forms.ChoiceField( label=gettext_lazy("Authentication method"), - choices=[("searchbind", gettext_lazy("Search and bind")), - ("directbind", gettext_lazy("Direct bind"))], + choices=[ + ("searchbind", gettext_lazy("Search and bind")), + ("directbind", gettext_lazy("Direct bind")), + ], initial="searchbind", help_text=gettext_lazy("Choose the authentication method to use"), ) @@ -248,11 +237,10 @@ class GeneralParametersForm(param_forms.AdminParametersForm): label=gettext_lazy("Bind password"), initial="", help_text=gettext_lazy( - "The password to use when binding to the LDAP server " - "(with 'Bind DN')" + "The password to use when binding to the LDAP server " "(with 'Bind DN')" ), widget=forms.PasswordInput(render_value=True), - required=False + required=False, ) ldap_search_base = forms.CharField( @@ -285,8 +273,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): ) # LDAP sync. settings - ldap_sync_sep = SeparatorField( - label=gettext_lazy("LDAP synchronization settings")) + ldap_sync_sep = SeparatorField(label=gettext_lazy("LDAP synchronization settings")) ldap_sync_bind_dn = forms.CharField( label=gettext_lazy("Bind DN"), @@ -302,11 +289,10 @@ class GeneralParametersForm(param_forms.AdminParametersForm): label=gettext_lazy("Bind password"), initial="", help_text=gettext_lazy( - "The password to use when binding to the LDAP server " - "(with 'Bind DN')" + "The password to use when binding to the LDAP server " "(with 'Bind DN')" ), widget=forms.PasswordInput(render_value=True), - required=False + required=False, ) ldap_enable_sync = YesNoField( @@ -314,18 +300,17 @@ class GeneralParametersForm(param_forms.AdminParametersForm): initial=False, help_text=gettext_lazy( "Enable automatic synchronization between local database and " - "LDAP directory") + "LDAP directory" + ), ) ldap_sync_delete_remote_account = YesNoField( - label=gettext_lazy( - "Delete remote LDAP account when local account is deleted" - ), + label=gettext_lazy("Delete remote LDAP account when local account is deleted"), initial=False, help_text=gettext_lazy( "Delete remote LDAP account when local account is deleted, " "otherwise it will be disabled." - ) + ), ) ldap_sync_account_dn_template = forms.CharField( @@ -335,16 +320,15 @@ class GeneralParametersForm(param_forms.AdminParametersForm): "The template used to construct an account's DN. It should contain " "one placeholder (ie. %(user)s)" ), - required=False + required=False, ) ldap_enable_import = YesNoField( label=gettext_lazy("Enable import from LDAP"), initial=False, help_text=gettext_lazy( - "Enable account synchronization from LDAP directory to local " - "database" - ) + "Enable account synchronization from LDAP directory to local " "database" + ), ) ldap_import_search_base = forms.CharField( @@ -378,9 +362,8 @@ class GeneralParametersForm(param_forms.AdminParametersForm): label=gettext_lazy("Enable Dovecot LDAP sync"), initial=False, help_text=gettext_lazy( - "LDAP authentication settings will be applied to Dovecot " - "configuration." - ) + "LDAP authentication settings will be applied to Dovecot " "configuration." + ), ) ldap_dovecot_conf_file = forms.CharField( @@ -390,7 +373,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): help_text=gettext_lazy( "Location of the configuration file which contains " "Dovecot LDAP settings." - ) + ), ) dash_sep = SeparatorField(label=gettext_lazy("Dashboard")) @@ -400,7 +383,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): required=False, help_text=gettext_lazy( "Display custom RSS feed to resellers and domain administrators" - ) + ), ) hide_features_widget = YesNoField( @@ -408,7 +391,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): initial=False, help_text=gettext_lazy( "Hide features widget for resellers and domain administrators" - ) + ), ) notif_sep = SeparatorField(label=gettext_lazy("Notifications")) @@ -416,9 +399,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): sender_address = lib_fields.UTF8EmailField( label=_("Sender address"), initial="noreply@yourdomain.test", - help_text=_( - "Email address used to send notifications." - ) + help_text=_("Email address used to send notifications."), ) api_sep = SeparatorField(label=gettext_lazy("Public API")) @@ -426,38 +407,32 @@ class GeneralParametersForm(param_forms.AdminParametersForm): enable_api_communication = YesNoField( label=gettext_lazy("Enable communication"), initial=True, - help_text=gettext_lazy( - "Enable communication with Modoboa public API") + help_text=gettext_lazy("Enable communication with Modoboa public API"), ) check_new_versions = YesNoField( label=gettext_lazy("Check new versions"), initial=True, - help_text=gettext_lazy( - "Automatically checks if a newer version is available") + help_text=gettext_lazy("Automatically checks if a newer version is available"), ) send_new_versions_email = YesNoField( label=gettext_lazy("Send an email when new versions are found"), initial=False, - help_text=gettext_lazy( - "Send an email to notify admins about new versions" - ) + help_text=gettext_lazy("Send an email to notify admins about new versions"), ) new_versions_email_rcpt = lib_fields.UTF8EmailField( label=_("Recipient"), initial="postmaster@yourdomain.test", - help_text=_( - "Recipient of new versions notification emails." - ) + help_text=_("Recipient of new versions notification emails."), ) send_statistics = YesNoField( label=gettext_lazy("Send statistics"), initial=True, help_text=gettext_lazy( - "Send statistics to Modoboa public API " - "(counters and used extensions)") + "Send statistics to Modoboa public API " "(counters and used extensions)" + ), ) sep3 = SeparatorField(label=gettext_lazy("Miscellaneous")) @@ -465,10 +440,12 @@ class GeneralParametersForm(param_forms.AdminParametersForm): enable_inactive_accounts = YesNoField( label=_("Enable inactive account tracking"), initial=True, - help_text=_("Allow the administrator to set a threshold (in days) " - "beyond which an account is considered inactive " - "if the user hasn't logged in") - ) + help_text=_( + "Allow the administrator to set a threshold (in days) " + "beyond which an account is considered inactive " + "if the user hasn't logged in" + ), + ) inactive_account_threshold = forms.IntegerField( label=_("Inactive account threshold"), @@ -482,9 +459,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): top_notifications_check_interval = forms.IntegerField( label=_("Top notifications check interval"), initial=30, - help_text=_( - "Interval between two top notification checks (in seconds)" - ), + help_text=_("Interval between two top notification checks (in seconds)"), ) log_maximum_age = forms.IntegerField( @@ -533,15 +508,13 @@ class GeneralParametersForm(param_forms.AdminParametersForm): "send_new_versions_email": "check_new_versions=True", "new_versions_email_rcpt": "check_new_versions=True", "sms_provider": "sms_password_recovery=True", - "inactive_account_threshold": "enable_inactive_accounts=True" + "inactive_account_threshold": "enable_inactive_accounts=True", } def __init__(self, *args, **kwargs): super(GeneralParametersForm, self).__init__(*args, **kwargs) self.fields["default_top_redirection"].choices = enabled_applications() - self._add_visibilty_rules( - sms_backends.get_all_backend_visibility_rules() - ) + self._add_visibilty_rules(sms_backends.get_all_backend_visibility_rules()) self.fields["password_scheme"].choices = get_password_scheme() def _add_dynamic_fields(self): @@ -551,8 +524,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): if field == "sms_provider": sms_backend_fields = sms_backends.get_all_backend_settings() for field, definition in sms_backend_fields.items(): - new_fields[field] = definition["type"]( - **definition["attrs"]) + new_fields[field] = definition["type"](**definition["attrs"]) self.fields = new_fields def clean_ldap_user_dn_template(self): @@ -619,7 +591,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): required_fields = ["ldap_user_dn_template"] for f in required_fields: - if f not in cleaned_data or cleaned_data[f] == u'': + if f not in cleaned_data or cleaned_data[f] == "": self.add_error(f, _("This field is required")) return cleaned_data @@ -628,20 +600,22 @@ class GeneralParametersForm(param_forms.AdminParametersForm): """Apply configuration for given backend.""" import ldap from django_auth_ldap.config import ( - LDAPSearch, PosixGroupType, GroupOfNamesType, - ActiveDirectoryGroupType + LDAPSearch, + PosixGroupType, + GroupOfNamesType, + ActiveDirectoryGroupType, ) if not hasattr(settings, backend.setting_fullname("USER_ATTR_MAP")): - setattr(settings, backend.setting_fullname("USER_ATTR_MAP"), { - "first_name": "givenName", - "email": "mail", - "last_name": "sn" - }) + setattr( + settings, + backend.setting_fullname("USER_ATTR_MAP"), + {"first_name": "givenName", "email": "mail", "last_name": "sn"}, + ) ldap_uri = "ldaps://" if values["ldap_secured"] == "ssl" else "ldap://" ldap_uri += "%s:%s" % ( values[backend.srv_address_setting_name], - values[backend.srv_port_setting_name] + values[backend.srv_port_setting_name], ) setattr(settings, backend.setting_fullname("SERVER_URI"), ldap_uri) if values["ldap_secured"] == "starttls": @@ -649,48 +623,54 @@ class GeneralParametersForm(param_forms.AdminParametersForm): if values["ldap_is_active_directory"]: setattr( - settings, backend.setting_fullname("GROUP_TYPE"), - ActiveDirectoryGroupType() + settings, + backend.setting_fullname("GROUP_TYPE"), + ActiveDirectoryGroupType(), ) searchfilter = "(objectClass=group)" elif values["ldap_group_type"] == "groupofnames": - setattr(settings, backend.setting_fullname("GROUP_TYPE"), - GroupOfNamesType()) + setattr( + settings, backend.setting_fullname("GROUP_TYPE"), GroupOfNamesType() + ) searchfilter = "(objectClass=groupOfNames)" else: - setattr(settings, backend.setting_fullname("GROUP_TYPE"), - PosixGroupType()) + setattr(settings, backend.setting_fullname("GROUP_TYPE"), PosixGroupType()) searchfilter = "(objectClass=posixGroup)" - setattr(settings, backend.setting_fullname("GROUP_SEARCH"), LDAPSearch( - values["ldap_groups_search_base"], ldap.SCOPE_SUBTREE, - searchfilter - )) + setattr( + settings, + backend.setting_fullname("GROUP_SEARCH"), + LDAPSearch( + values["ldap_groups_search_base"], ldap.SCOPE_SUBTREE, searchfilter + ), + ) if values["ldap_auth_method"] == "searchbind": - setattr(settings, backend.setting_fullname("BIND_DN"), - values["ldap_bind_dn"]) setattr( - settings, backend.setting_fullname("BIND_PASSWORD"), - values["ldap_bind_password"] + settings, backend.setting_fullname("BIND_DN"), values["ldap_bind_dn"] + ) + setattr( + settings, + backend.setting_fullname("BIND_PASSWORD"), + values["ldap_bind_password"], ) search = LDAPSearch( - values["ldap_search_base"], ldap.SCOPE_SUBTREE, - values["ldap_search_filter"] + values["ldap_search_base"], + ldap.SCOPE_SUBTREE, + values["ldap_search_filter"], ) setattr(settings, backend.setting_fullname("USER_SEARCH"), search) else: setattr( - settings, backend.setting_fullname("USER_DN_TEMPLATE"), - values["ldap_user_dn_template"] + settings, + backend.setting_fullname("USER_DN_TEMPLATE"), + values["ldap_user_dn_template"], ) setattr( - settings, - backend.setting_fullname("BIND_AS_AUTHENTICATING_USER"), True) + settings, backend.setting_fullname("BIND_AS_AUTHENTICATING_USER"), True + ) if values["ldap_is_active_directory"]: setting = backend.setting_fullname("GLOBAL_OPTIONS") if not hasattr(settings, setting): - setattr(settings, setting, { - ldap.OPT_REFERRALS: False - }) + setattr(settings, setting, {ldap.OPT_REFERRALS: False}) else: getattr(settings, setting)[ldap.OPT_REFERRALS] = False @@ -701,6 +681,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm): """ try: import ldap + ldap_available = True except ImportError: ldap_available = False @@ -710,12 +691,14 @@ class GeneralParametersForm(param_forms.AdminParametersForm): return from modoboa.lib.authbackends import LDAPBackend + self._apply_ldap_settings(values, LDAPBackend) if not values["ldap_enable_secondary_server"]: return from modoboa.lib.authbackends import LDAPSecondaryBackend + self._apply_ldap_settings(values, LDAPSecondaryBackend) def save(self): @@ -725,400 +708,622 @@ class GeneralParametersForm(param_forms.AdminParametersForm): self.localconfig.save(update_fields=["need_dovecot_update"]) -GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([ - ("authentication", { - "label": gettext_lazy("Authentication"), - "params": collections.OrderedDict([ - ("authentication_type", { - "label": gettext_lazy("Authentication type"), - "help_text": gettext_lazy( - "The backend used for authentication"), - }), - ("password_scheme", { - "label": gettext_lazy("Default password scheme"), - "help_text": gettext_lazy( - "Scheme used to crypt mailbox passwords"), - }), - ("rounds_number", { - "label": gettext_lazy("Rounds"), - "help_text": gettext_lazy( - "Number of rounds to use (only used by sha256crypt and " - "sha512crypt). Must be between 1000 and 999999999, " - "inclusive." - ) - }), - ("update_scheme", { - "label": gettext_lazy("Update password scheme at login"), - "help_text": gettext_lazy( - "Update user password at login to use the default " - "password scheme" - ) - }), - ("default_password", { - "label": gettext_lazy("Default password"), - "help_text": gettext_lazy( - "Default password for automatically created accounts.") - }), - ("random_password_length", { - "label": gettext_lazy("Random password length"), - "help_text": gettext_lazy( - "Length of randomly generated passwords.") - }), - ("update_password_url", { - "label": gettext_lazy("Update password service URL"), - "help_text": gettext_lazy( - "The URL of an external page where users will be able" - " to update their password. It applies only to non local" - " users, ie. those automatically created after a successful" - " external authentication (LDAP, SMTP)." - ) - }), - ("password_recovery_msg", { - "label": gettext_lazy("Password recovery announcement"), - "help_text": gettext_lazy( - "A temporary message that will be displayed on the " - "reset password page." - ) - }), - ("sms_password_recovery", { - "label": gettext_lazy("Enable password recovery by SMS"), - "help_text": gettext_lazy( - "Enable password recovery by SMS for users who filled " - "a phone number." - ) - }), - ("sms_provider", { - "label": gettext_lazy("SMS provider"), - "display": "sms_password_recovery=true", - "help_text": gettext_lazy( - "Choose a provider to send password recovery SMS" - ) - }), - *sms_backends.get_all_backend_structures() - ]) - }), - ("ldap", { - "label": _("LDAP"), - "params": collections.OrderedDict([ - ("ldap_server_address", { - "label": gettext_lazy("Server address"), - "help_text": gettext_lazy( - "The IP address or the DNS name of the LDAP server"), - }), - ("ldap_server_port", { - "label": gettext_lazy("Server port"), - "help_text": gettext_lazy( - "The TCP port number used by the LDAP server") - }), - ("ldap_enable_secondary_server", { - "label": gettext_lazy("Enable secondary server (fallback)"), - "help_text": gettext_lazy( - "Enable a secondary LDAP server which will be used " - "if the primary one fails" - ) - }), - ("ldap_secondary_server_address", { - "label": gettext_lazy("Secondary server address"), - "display": "ldap_enable_secondary_server=true", - "help_text": gettext_lazy( - "The IP address or the DNS name of the seondary LDAP server" - ) - }), - ("ldap_secondary_server_port", { - "label": gettext_lazy("Secondary server port"), - "display": "ldap_enable_secondary_server=true", - "help_text": gettext_lazy( - "The TCP port number used by the LDAP secondary server" - ) - }), - ("ldap_secured", { - "label": gettext_lazy("Use a secured connection"), - "help_text": gettext_lazy( - "Use an SSL/STARTTLS connection to access the LDAP server") - }), - ("ldap_is_active_directory", { - "label": gettext_lazy("Active Directory"), - "help_text": gettext_lazy( - "Tell if the LDAP server is an Active Directory one") - }), - ("ldap_admin_groups", { - "label": gettext_lazy("Administrator groups"), - "help_text": gettext_lazy( - "Members of those LDAP Posix groups will be created as " - "domain administrators. Use ';' characters to separate " - "groups." - ) - }), - ("ldap_group_type", { - "label": gettext_lazy("Group type"), - "help_text": gettext_lazy( - "The LDAP group type to use with your directory." - ) - }), - ("ldap_groups_search_base", { - "label": gettext_lazy("Groups search base"), - "help_text": gettext_lazy( - "The distinguished name of the search base used to find " - "groups" - ) - }), - ("ldap_password_attribute", { - "label": gettext_lazy("Password attribute"), - "help_text": gettext_lazy( - "The attribute used to store user passwords"), - }), - ("ldap_auth_sep", { - "label": gettext_lazy("LDAP authentication settings"), - "display": "authentication_type=ldap", - "separator": True - }), - ("ldap_auth_method", { - "label": gettext_lazy("Authentication method"), - "display": "authentication_type=ldap", - "help_text": gettext_lazy( - "Choose the authentication method to use"), - }), - ("ldap_bind_dn", { - "label": gettext_lazy("Bind DN"), - "help_text": gettext_lazy( - "The distinguished name to use when binding to the LDAP " - "server. Leave empty for an anonymous bind" +GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict( + [ + ( + "authentication", + { + "label": gettext_lazy("Authentication"), + "params": collections.OrderedDict( + [ + ( + "authentication_type", + { + "label": gettext_lazy("Authentication type"), + "help_text": gettext_lazy( + "The backend used for authentication" + ), + }, + ), + ( + "password_scheme", + { + "label": gettext_lazy("Default password scheme"), + "help_text": gettext_lazy( + "Scheme used to crypt mailbox passwords" + ), + }, + ), + ( + "rounds_number", + { + "label": gettext_lazy("Rounds"), + "help_text": gettext_lazy( + "Number of rounds to use (only used by sha256crypt and " + "sha512crypt). Must be between 1000 and 999999999, " + "inclusive." + ), + }, + ), + ( + "update_scheme", + { + "label": gettext_lazy( + "Update password scheme at login" + ), + "help_text": gettext_lazy( + "Update user password at login to use the default " + "password scheme" + ), + }, + ), + ( + "default_password", + { + "label": gettext_lazy("Default password"), + "help_text": gettext_lazy( + "Default password for automatically created accounts." + ), + }, + ), + ( + "random_password_length", + { + "label": gettext_lazy("Random password length"), + "help_text": gettext_lazy( + "Length of randomly generated passwords." + ), + }, + ), + ( + "update_password_url", + { + "label": gettext_lazy("Update password service URL"), + "help_text": gettext_lazy( + "The URL of an external page where users will be able" + " to update their password. It applies only to non local" + " users, ie. those automatically created after a successful" + " external authentication (LDAP, SMTP)." + ), + }, + ), + ( + "password_recovery_msg", + { + "label": gettext_lazy("Password recovery announcement"), + "help_text": gettext_lazy( + "A temporary message that will be displayed on the " + "reset password page." + ), + }, + ), + ( + "sms_password_recovery", + { + "label": gettext_lazy( + "Enable password recovery by SMS" + ), + "help_text": gettext_lazy( + "Enable password recovery by SMS for users who filled " + "a phone number." + ), + }, + ), + ( + "sms_provider", + { + "label": gettext_lazy("SMS provider"), + "display": "sms_password_recovery=true", + "help_text": gettext_lazy( + "Choose a provider to send password recovery SMS" + ), + }, + ), + *sms_backends.get_all_backend_structures(), + ] ), - "display": "authentication_type=ldap&ldap_auth_method=searchbind" - }), - ("ldap_bind_password", { - "label": gettext_lazy("Bind password"), - "help_text": gettext_lazy( - "The password to use when binding to the LDAP server " - "(with 'Bind DN')" + }, + ), + ( + "ldap", + { + "label": _("LDAP"), + "params": collections.OrderedDict( + [ + ( + "ldap_server_address", + { + "label": gettext_lazy("Server address"), + "help_text": gettext_lazy( + "The IP address or the DNS name of the LDAP server" + ), + }, + ), + ( + "ldap_server_port", + { + "label": gettext_lazy("Server port"), + "help_text": gettext_lazy( + "The TCP port number used by the LDAP server" + ), + }, + ), + ( + "ldap_enable_secondary_server", + { + "label": gettext_lazy( + "Enable secondary server (fallback)" + ), + "help_text": gettext_lazy( + "Enable a secondary LDAP server which will be used " + "if the primary one fails" + ), + }, + ), + ( + "ldap_secondary_server_address", + { + "label": gettext_lazy("Secondary server address"), + "display": "ldap_enable_secondary_server=true", + "help_text": gettext_lazy( + "The IP address or the DNS name of the seondary LDAP server" + ), + }, + ), + ( + "ldap_secondary_server_port", + { + "label": gettext_lazy("Secondary server port"), + "display": "ldap_enable_secondary_server=true", + "help_text": gettext_lazy( + "The TCP port number used by the LDAP secondary server" + ), + }, + ), + ( + "ldap_secured", + { + "label": gettext_lazy("Use a secured connection"), + "help_text": gettext_lazy( + "Use an SSL/STARTTLS connection to access the LDAP server" + ), + }, + ), + ( + "ldap_is_active_directory", + { + "label": gettext_lazy("Active Directory"), + "help_text": gettext_lazy( + "Tell if the LDAP server is an Active Directory one" + ), + }, + ), + ( + "ldap_admin_groups", + { + "label": gettext_lazy("Administrator groups"), + "help_text": gettext_lazy( + "Members of those LDAP Posix groups will be created as " + "domain administrators. Use ';' characters to separate " + "groups." + ), + }, + ), + ( + "ldap_group_type", + { + "label": gettext_lazy("Group type"), + "help_text": gettext_lazy( + "The LDAP group type to use with your directory." + ), + }, + ), + ( + "ldap_groups_search_base", + { + "label": gettext_lazy("Groups search base"), + "help_text": gettext_lazy( + "The distinguished name of the search base used to find " + "groups" + ), + }, + ), + ( + "ldap_password_attribute", + { + "label": gettext_lazy("Password attribute"), + "help_text": gettext_lazy( + "The attribute used to store user passwords" + ), + }, + ), + ( + "ldap_auth_sep", + { + "label": gettext_lazy("LDAP authentication settings"), + "display": "authentication_type=ldap", + "separator": True, + }, + ), + ( + "ldap_auth_method", + { + "label": gettext_lazy("Authentication method"), + "display": "authentication_type=ldap", + "help_text": gettext_lazy( + "Choose the authentication method to use" + ), + }, + ), + ( + "ldap_bind_dn", + { + "label": gettext_lazy("Bind DN"), + "help_text": gettext_lazy( + "The distinguished name to use when binding to the LDAP " + "server. Leave empty for an anonymous bind" + ), + "display": "authentication_type=ldap&ldap_auth_method=searchbind", + }, + ), + ( + "ldap_bind_password", + { + "label": gettext_lazy("Bind password"), + "help_text": gettext_lazy( + "The password to use when binding to the LDAP server " + "(with 'Bind DN')" + ), + "display": "authentication_type=ldap&ldap_auth_method=searchbind", + "password": True, + }, + ), + ( + "ldap_search_base", + { + "label": gettext_lazy("Users search base"), + "help_text": gettext_lazy( + "The distinguished name of the search base used to find " + "users" + ), + "display": "authentication_type=ldap&ldap_auth_method=searchbind", + }, + ), + ( + "ldap_search_filter", + { + "label": gettext_lazy("Search filter"), + "help_text": gettext_lazy( + "An optional filter string (e.g. '(objectClass=person)'). " + "In order to be valid, it must be enclosed in parentheses." + ), + "display": "authentication_type=ldap&ldap_auth_method=searchbind", + }, + ), + ( + "ldap_user_dn_template", + { + "label": gettext_lazy("User DN template"), + "help_text": gettext_lazy( + "The template used to construct a user's DN. It should " + "contain one placeholder (ie. %(user)s)" + ), + "display": "authentication_type=ldap&ldap_auth_method=directbind", + }, + ), + ( + "ldap_sync_sep", + { + "label": gettext_lazy("LDAP synchronization settings"), + "separator": True, + }, + ), + ( + "ldap_sync_bind_dn", + { + "label": gettext_lazy("Bind DN"), + "help_text": gettext_lazy( + "The distinguished name to use when binding to the LDAP server. " + "Leave empty for an anonymous bind" + ), + }, + ), + ( + "ldap_sync_bind_password", + { + "label": gettext_lazy("Bind password"), + "help_text": gettext_lazy( + "The password to use when binding to the LDAP server " + "(with 'Bind DN')" + ), + "password": True, + }, + ), + ( + "ldap_enable_sync", + { + "label": gettext_lazy("Enable export to LDAP"), + "help_text": gettext_lazy( + "Enable automatic synchronization between local database " + "and LDAP directory" + ), + }, + ), + ( + "ldap_sync_delete_remote_account", + { + "label": gettext_lazy( + "Delete remote LDAP account when local account is deleted" + ), + "help_text": gettext_lazy( + "Delete remote LDAP account when local account is deleted, " + "otherwise it will be disabled." + ), + "display": "ldap_enable_sync=true", + }, + ), + ( + "ldap_sync_account_dn_template", + { + "label": gettext_lazy("Account DN template"), + "help_text": gettext_lazy( + "The template used to construct an account's DN. It should " + "contain one placeholder (ie. %(user)s)" + ), + "display": "ldap_enable_sync=true", + }, + ), + ( + "ldap_enable_import", + { + "label": gettext_lazy("Enable import from LDAP"), + "help_text": gettext_lazy( + "Enable account synchronization from LDAP directory to " + "local database" + ), + }, + ), + ( + "ldap_import_search_base", + { + "label": gettext_lazy("Users search base"), + "help_text": gettext_lazy( + "The distinguished name of the search base used to find " + "users" + ), + "display": "ldap_enable_import=true", + }, + ), + ( + "ldap_import_search_filter", + { + "label": gettext_lazy("Search filter"), + "help_text": gettext_lazy( + "An optional filter string (e.g. '(objectClass=person)'). " + "In order to be valid, it must be enclosed in parentheses." + ), + "display": "ldap_enable_import=true", + }, + ), + ( + "ldap_import_username_attr", + { + "label": gettext_lazy("Username attribute"), + "help_text": gettext_lazy( + "The name of the LDAP attribute where the username can be " + "found." + ), + "display": "ldap_enable_import=true", + }, + ), + ( + "ldap_dovecot_sync", + { + "label": gettext_lazy("Enable Dovecot LDAP sync"), + "help_text": gettext_lazy( + "LDAP authentication settings will be applied to Dovecot " + "configuration." + ), + }, + ), + ( + "ldap_dovecot_conf_file", + { + "label": gettext_lazy("Dovecot LDAP config file"), + "help_text": gettext_lazy( + "Location of the configuration file which contains " + "Dovecot LDAP settings." + ), + "display": "ldap_dovecot_sync=true", + }, + ), + ] ), - "display": "authentication_type=ldap&ldap_auth_method=searchbind", - "password": True - }), - ("ldap_search_base", { - "label": gettext_lazy("Users search base"), - "help_text": gettext_lazy( - "The distinguished name of the search base used to find " - "users" + }, + ), + ( + "dashboard", + { + "label": gettext_lazy("Dashboard"), + "params": collections.OrderedDict( + [ + ( + "rss_feed_url", + { + "label": gettext_lazy("Custom RSS feed"), + "help_text": gettext_lazy( + "Display custom RSS feed to resellers and domain " + "administrators" + ), + }, + ), + ( + "hide_features_widget", + { + "label": gettext_lazy("Hide features widget"), + "help_text": gettext_lazy( + "Hide features widget for resellers and domain " + "administrators" + ), + }, + ), + ] ), - "display": "authentication_type=ldap&ldap_auth_method=searchbind" - }), - ("ldap_search_filter", { - "label": gettext_lazy("Search filter"), - "help_text": gettext_lazy( - "An optional filter string (e.g. '(objectClass=person)'). " - "In order to be valid, it must be enclosed in parentheses." + }, + ), + ( + "notifications", + { + "label": gettext_lazy("Notifications"), + "params": collections.OrderedDict( + [ + ( + "sender_address", + { + "label": gettext_lazy("Sender address"), + "help_text": gettext_lazy( + "Email address used to send notifications." + ), + }, + ) + ] ), - "display": "authentication_type=ldap&ldap_auth_method=searchbind" - }), - ("ldap_user_dn_template", { - "label": gettext_lazy("User DN template"), - "help_text": gettext_lazy( - "The template used to construct a user's DN. It should " - "contain one placeholder (ie. %(user)s)" + }, + ), + ( + "api", + { + "label": gettext_lazy("Public API"), + "params": collections.OrderedDict( + [ + ( + "enable_api_communication", + { + "label": gettext_lazy("Enable communication"), + "help_text": gettext_lazy( + "Automatically checks if a newer version is available" + ), + }, + ), + ( + "check_new_versions", + { + "label": gettext_lazy("Check new versions"), + "display": "enable_api_communication=true", + "help_text": gettext_lazy( + "Automatically checks if a newer version is available" + ), + }, + ), + ( + "send_new_versions_email", + { + "label": gettext_lazy( + "Send an email when new versions are found" + ), + "display": "check_new_versions=true", + "help_text": gettext_lazy( + "Send an email to notify admins about new versions" + ), + }, + ), + ( + "new_versions_email_rcpt", + { + "label": gettext_lazy("Recipient"), + "display": "check_new_versions=true", + "help_text": gettext_lazy( + "Recipient of new versions notification emails." + ), + }, + ), + ( + "send_statistics", + { + "label": gettext_lazy("Send statistics"), + "display": "enable_api_communication=true", + "help_text": gettext_lazy( + "Send statistics to Modoboa public API " + "(counters and used extensions)" + ), + }, + ), + ] ), - "display": "authentication_type=ldap&ldap_auth_method=directbind" - }), - ("ldap_sync_sep", { - "label": gettext_lazy("LDAP synchronization settings"), - "separator": True - }), - ("ldap_sync_bind_dn", { - "label": gettext_lazy("Bind DN"), - "help_text": gettext_lazy( - "The distinguished name to use when binding to the LDAP server. " - "Leave empty for an anonymous bind" - ) - }), - ("ldap_sync_bind_password", { - "label": gettext_lazy("Bind password"), - "help_text": gettext_lazy( - "The password to use when binding to the LDAP server " - "(with 'Bind DN')" + }, + ), + ( + "misc", + { + "label": gettext_lazy("Miscellaneous"), + "params": collections.OrderedDict( + [ + ( + "enable_inactive_accounts", + { + "label": gettext_lazy( + "Enable inactive account tracking" + ), + "help_text": gettext_lazy( + "Allow the administrator to set a threshold (in days) " + "beyond which an account is considered inactive " + "if the user hasn't logged in" + ), + }, + ), + ( + "inactive_account_threshold", + { + "label": gettext_lazy("Inactive account threshold"), + "display": "enable_inactive_accounts=true", + "help_text": gettext_lazy( + "An account with a last login date greater than this " + "threshold (in days) will be considered as inactive" + ), + }, + ), + ( + "top_notifications_check_interval", + { + "label": gettext_lazy( + "Top notifications check interval" + ), + "help_text": gettext_lazy( + "Interval between two top notification checks (in seconds)" + ), + }, + ), + ( + "log_maximum_age", + { + "label": gettext_lazy("Maximum log record age"), + "help_text": gettext_lazy( + "The maximum age in days of a log record" + ), + }, + ), + ( + "items_per_page", + { + "label": gettext_lazy("Items per page"), + "help_text": gettext_lazy( + "Number of displayed items per page" + ), + }, + ), + ( + "default_top_redirection", + { + "label": gettext_lazy("Default top redirection"), + "help_text": gettext_lazy( + "The default redirection used when no application is " + "specified" + ), + }, + ), + ] ), - "password": True - }), - ("ldap_enable_sync", { - "label": gettext_lazy("Enable export to LDAP"), - "help_text": gettext_lazy( - "Enable automatic synchronization between local database " - "and LDAP directory" - ) - }), - ("ldap_sync_delete_remote_account", { - "label": gettext_lazy( - "Delete remote LDAP account when local account is deleted"), - "help_text": gettext_lazy( - "Delete remote LDAP account when local account is deleted, " - "otherwise it will be disabled." - ), - "display": "ldap_enable_sync=true" - }), - ("ldap_sync_account_dn_template", { - "label": gettext_lazy("Account DN template"), - "help_text": gettext_lazy( - "The template used to construct an account's DN. It should " - "contain one placeholder (ie. %(user)s)" - ), - "display": "ldap_enable_sync=true" - }), - ("ldap_enable_import", { - "label": gettext_lazy("Enable import from LDAP"), - "help_text": gettext_lazy( - "Enable account synchronization from LDAP directory to " - "local database" - ) - }), - ("ldap_import_search_base", { - "label": gettext_lazy("Users search base"), - "help_text": gettext_lazy( - "The distinguished name of the search base used to find " - "users" - ), - "display": "ldap_enable_import=true" - }), - ("ldap_import_search_filter", { - "label": gettext_lazy("Search filter"), - "help_text": gettext_lazy( - "An optional filter string (e.g. '(objectClass=person)'). " - "In order to be valid, it must be enclosed in parentheses." - ), - "display": "ldap_enable_import=true" - }), - ("ldap_import_username_attr", { - "label": gettext_lazy("Username attribute"), - "help_text": gettext_lazy( - "The name of the LDAP attribute where the username can be " - "found." - ), - "display": "ldap_enable_import=true" - }), - ("ldap_dovecot_sync", { - "label": gettext_lazy("Enable Dovecot LDAP sync"), - "help_text": gettext_lazy( - "LDAP authentication settings will be applied to Dovecot " - "configuration." - ) - }), - ("ldap_dovecot_conf_file", { - "label": gettext_lazy("Dovecot LDAP config file"), - "help_text": gettext_lazy( - "Location of the configuration file which contains " - "Dovecot LDAP settings." - ), - "display": "ldap_dovecot_sync=true" - }), - - ]) - }), - ("dashboard", { - "label": gettext_lazy("Dashboard"), - "params": collections.OrderedDict([ - ("rss_feed_url", { - "label": gettext_lazy("Custom RSS feed"), - "help_text": gettext_lazy( - "Display custom RSS feed to resellers and domain " - "administrators" - ) - }), - ("hide_features_widget", { - "label": gettext_lazy("Hide features widget"), - "help_text": gettext_lazy( - "Hide features widget for resellers and domain " - "administrators" - ) - }), - ]) - }), - ("notifications", { - "label": gettext_lazy("Notifications"), - "params": collections.OrderedDict([ - ("sender_address", { - "label": gettext_lazy("Sender address"), - "help_text": gettext_lazy( - "Email address used to send notifications.") - }) - ]) - }), - ("api", { - "label": gettext_lazy("Public API"), - "params": collections.OrderedDict([ - ("enable_api_communication", { - "label": gettext_lazy("Enable communication"), - "help_text": gettext_lazy( - "Automatically checks if a newer version is available") - }), - ("check_new_versions", { - "label": gettext_lazy("Check new versions"), - "display": "enable_api_communication=true", - "help_text": gettext_lazy( - "Automatically checks if a newer version is available") - }), - ("send_new_versions_email", { - "label": gettext_lazy( - "Send an email when new versions are found"), - "display": "check_new_versions=true", - "help_text": gettext_lazy( - "Send an email to notify admins about new versions" - ) - }), - ("new_versions_email_rcpt", { - "label": gettext_lazy("Recipient"), - "display": "check_new_versions=true", - "help_text": gettext_lazy( - "Recipient of new versions notification emails." - ) - }), - ("send_statistics", { - "label": gettext_lazy("Send statistics"), - "display": "enable_api_communication=true", - "help_text": gettext_lazy( - "Send statistics to Modoboa public API " - "(counters and used extensions)") - }) - ]) - }), - ("misc", { - "label": gettext_lazy("Miscellaneous"), - "params": collections.OrderedDict([ - ("enable_inactive_accounts", { - "label": gettext_lazy("Enable inactive account tracking"), - "help_text": gettext_lazy( - "Allow the administrator to set a threshold (in days) " - "beyond which an account is considered inactive " - "if the user hasn't logged in" - ), - }), - ("inactive_account_threshold", { - "label": gettext_lazy("Inactive account threshold"), - "display": "enable_inactive_accounts=true", - "help_text": gettext_lazy( - "An account with a last login date greater than this " - "threshold (in days) will be considered as inactive" - ) - }), - ("top_notifications_check_interval", { - "label": gettext_lazy("Top notifications check interval"), - "help_text": gettext_lazy( - "Interval between two top notification checks (in seconds)" - ), - }), - ("log_maximum_age", { - "label": gettext_lazy("Maximum log record age"), - "help_text": gettext_lazy( - "The maximum age in days of a log record"), - }), - ("items_per_page", { - "label": gettext_lazy("Items per page"), - "help_text": gettext_lazy("Number of displayed items per page") - }), - ("default_top_redirection", { - "label": gettext_lazy("Default top redirection"), - "help_text": gettext_lazy( - "The default redirection used when no application is " - "specified" - ), - }) - ]) - }) -]) + }, + ), + ] +) diff --git a/modoboa/core/apps.py b/modoboa/core/apps.py index 311f497de..fb3e30eb6 100644 --- a/modoboa/core/apps.py +++ b/modoboa/core/apps.py @@ -16,11 +16,15 @@ def load_core_settings(): from .api.v2 import serializers param_tools.registry.add( - "global", app_settings.GeneralParametersForm, gettext_lazy("General")) + "global", app_settings.GeneralParametersForm, gettext_lazy("General") + ) param_tools.registry.add2( - "global", "core", gettext_lazy("General"), + "global", + "core", + gettext_lazy("General"), app_settings.GLOBAL_PARAMETERS_STRUCT, - serializers.CoreGlobalParametersSerializer) + serializers.CoreGlobalParametersSerializer, + ) class CoreConfig(AppConfig): diff --git a/modoboa/core/checks/settings_checks.py b/modoboa/core/checks/settings_checks.py index d5858e2e1..f72969226 100644 --- a/modoboa/core/checks/settings_checks.py +++ b/modoboa/core/checks/settings_checks.py @@ -3,9 +3,11 @@ from django.core.checks import Warning, register from django.utils.translation import gettext as _ W001 = Warning( - _("You have USE_TZ set to False, this may result in issues during " - "transitions between summer/winter time (ie the same local time occuring " - "twice due to clock change)."), + _( + "You have USE_TZ set to False, this may result in issues during " + "transitions between summer/winter time (ie the same local time occuring " + "twice due to clock change)." + ), hint=_("Set `USE_TZ = True` in settings.py"), id="modoboa.W001", ) diff --git a/modoboa/core/commands/__init__.py b/modoboa/core/commands/__init__.py index 2f73d5ae6..b935d655f 100644 --- a/modoboa/core/commands/__init__.py +++ b/modoboa/core/commands/__init__.py @@ -21,10 +21,9 @@ class Command(object): self._verbose = verbose if not settings.configured: settings.configure( - TEMPLATES=[{ - "BACKEND": ( - "django.template.backends.django.DjangoTemplates") - }] + TEMPLATES=[ + {"BACKEND": ("django.template.backends.django.DjangoTemplates")} + ] ) self._templates_dir = "%s/templates" % os.path.dirname(__file__) @@ -62,12 +61,12 @@ def scan_for_commands(dirname=""): if os.path.isfile(f): continue cmdname = f.replace(".py", "") - cmdmod = __import__("modoboa.core.commands", globals(), locals(), - [smart_str(cmdname)]) + cmdmod = __import__( + "modoboa.core.commands", globals(), locals(), [smart_str(cmdname)] + ) cmdmod = getattr(cmdmod, cmdname) if "_" in cmdname: - cmdclassname = "".join( - [s.capitalize() for s in cmdname.split("_")]) + cmdclassname = "".join([s.capitalize() for s in cmdname.split("_")]) else: cmdclassname = cmdname.capitalize() try: @@ -85,11 +84,13 @@ def handle_command_line(): description="A set of utilities to ease the installation of Modoboa.", epilog="""Available commands: %s -""" % "\n".join(["\t%s" % c for c in sorted(commands)])) - parser.add_argument("--verbose", action="store_true", - help="Activate verbose output") - parser.add_argument("command", type=str, - help="A valid command name") +""" + % "\n".join(["\t%s" % c for c in sorted(commands)]), + ) + parser.add_argument( + "--verbose", action="store_true", help="Activate verbose output" + ) + parser.add_argument("command", type=str, help="A valid command name") (args, remaining) = parser.parse_known_args() if args.command not in commands: diff --git a/modoboa/core/commands/deploy.py b/modoboa/core/commands/deploy.py index db80ee3c4..014fac790 100644 --- a/modoboa/core/commands/deploy.py +++ b/modoboa/core/commands/deploy.py @@ -37,7 +37,6 @@ DBCONN_TPL = """ class DeployCommand(Command): - """The ``deploy`` command.""" help = ( # NOQA:A003 @@ -47,45 +46,59 @@ class DeployCommand(Command): def __init__(self, *args, **kwargs): super(DeployCommand, self).__init__(*args, **kwargs) - self._parser.add_argument("name", type=str, - help="The name of your Modoboa instance") self._parser.add_argument( - "--collectstatic", action="store_true", default=False, - help="Run django collectstatic command" + "name", type=str, help="The name of your Modoboa instance" ) self._parser.add_argument( - "--dburl", type=str, nargs="+", default=None, - help="A database-url with a name") - self._parser.add_argument( - "--domain", type=str, default=None, - help="The domain under which you want to deploy modoboa") - self._parser.add_argument( - "--lang", type=str, default="en", - help="Set the default language" + "--collectstatic", + action="store_true", + default=False, + help="Run django collectstatic command", ) self._parser.add_argument( - "--timezone", type=str, default="UTC", - help="Set the local timezone" + "--dburl", + type=str, + nargs="+", + default=None, + help="A database-url with a name", ) self._parser.add_argument( - "--devel", action="store_true", default=False, - help="Create a development instance" + "--domain", + type=str, + default=None, + help="The domain under which you want to deploy modoboa", ) self._parser.add_argument( - "--extensions", type=str, nargs="*", - help="The list of extension to deploy" + "--lang", type=str, default="en", help="Set the default language" ) self._parser.add_argument( - "--dont-install-extensions", action="store_true", default=False, - help="Do not install extensions using pip" + "--timezone", type=str, default="UTC", help="Set the local timezone" ) self._parser.add_argument( - "--admin-username", default="admin", - help="Username of the initial super administrator" + "--devel", + action="store_true", + default=False, + help="Create a development instance", ) self._parser.add_argument( - "--secret-key-length", default=60, type=int, - help="Specify the length of the secret key" + "--extensions", type=str, nargs="*", help="The list of extension to deploy" + ) + self._parser.add_argument( + "--dont-install-extensions", + action="store_true", + default=False, + help="Do not install extensions using pip", + ) + self._parser.add_argument( + "--admin-username", + default="admin", + help="Username of the initial super administrator", + ) + self._parser.add_argument( + "--secret-key-length", + default=60, + type=int, + help="Specify the length of the secret key", ) def _exec_django_command(self, name, cwd, *args): @@ -109,7 +122,7 @@ class DeployCommand(Command): if output: print( "\n".join([l.decode() for l in output if l is not None]), - file=sys.stderr + file=sys.stderr, ) print("%s failed, check your configuration" % cmd, file=sys.stderr) @@ -124,8 +137,7 @@ class DeployCommand(Command): print("Configuring database connection: %s" % name) info = { "conn_name": name, - "ENGINE": input( - "Database type (mysql, postgres or sqlite3): ") + "ENGINE": input("Database type (mysql, postgres or sqlite3): "), } if info["ENGINE"] not in ["mysql", "postgres", "sqlite3"]: raise RuntimeError("Unsupported database engine") @@ -141,8 +153,7 @@ class DeployCommand(Command): info["ENGINE"] = "django.db.backends.mysql" default_port = 3306 info["HOST"] = input("Database host (default: 'localhost'): ") - info["PORT"] = input( - "Database port (default: '%s'): " % default_port) + info["PORT"] = input("Database port (default: '%s'): " % default_port) # leave port setting empty, if default value is supplied and # leave it to django if info["PORT"] == default_port: @@ -167,7 +178,7 @@ class DeployCommand(Command): is marked as insecure. """ c = string.ascii_letters + string.digits + string.punctuation - secret_key = ''.join(secrets.choice(c) for i in range(secret_key_length)) + secret_key = "".join(secrets.choice(c) for i in range(secret_key_length)) return secret_key def find_extra_settings(self, extensions): @@ -188,9 +199,7 @@ class DeployCommand(Command): def handle(self, parsed_args): django.setup() - management.call_command( - "startproject", parsed_args.name, verbosity=False - ) + management.call_command("startproject", parsed_args.name, verbosity=False) path = "%(name)s/%(name)s" % {"name": parsed_args.name} sys.path.append(parsed_args.name) @@ -210,14 +219,12 @@ class DeployCommand(Command): info["conn_name"] = conn_name connections[conn_name] = conn_tpl.render(Context(info)) else: - connections["default"] = conn_tpl.render( - Context(self.ask_db_info())) + connections["default"] = conn_tpl.render(Context(self.ask_db_info())) if parsed_args.domain: allowed_host = parsed_args.domain else: - allowed_host = input( - "What will be the hostname used to access Modoboa? ") + allowed_host = input("What will be the hostname used to access Modoboa? ") if not allowed_host: allowed_host = "localhost" extra_settings = [] @@ -225,13 +232,14 @@ class DeployCommand(Command): if extensions: if "all" in extensions: extensions = self._get_extension_list() - extensions = [(extension, extension.replace("-", "_")) - for extension in extensions] + extensions = [ + (extension, extension.replace("-", "_")) for extension in extensions + ] if not parsed_args.dont_install_extensions: cmd = ( - sys.executable + - " -m pip install " + - " ".join([extension[0] for extension in extensions]) + sys.executable + + " -m pip install " + + " ".join([extension[0] for extension in extensions]) ) exec_cmd(cmd, capture_output=False) extra_settings = self.find_extra_settings(extensions) @@ -241,11 +249,10 @@ class DeployCommand(Command): os.path.join(os.path.dirname(__file__), "../../bower_components") ) - mod = __import__( - parsed_args.name, globals(), locals(), [smart_str("settings")] - ) + mod = __import__(parsed_args.name, globals(), locals(), [smart_str("settings")]) tpl = self._render_template( - "%s/settings.py.tpl" % self._templates_dir, { + "%s/settings.py.tpl" % self._templates_dir, + { "db_connections": connections, "secret_key": self._generate_secret_key(parsed_args.secret_key_length), "name": parsed_args.name, @@ -255,42 +262,40 @@ class DeployCommand(Command): "bower_components_dir": bower_components_dir, "devmode": parsed_args.devel, "extensions": extensions, - "extra_settings": extra_settings - } + "extra_settings": extra_settings, + }, ) with open("%s/settings.py" % path, "w") as fp: fp.write(tpl) - shutil.copyfile( - "%s/urls.py.tpl" % self._templates_dir, "%s/urls.py" % path - ) + shutil.copyfile("%s/urls.py.tpl" % self._templates_dir, "%s/urls.py" % path) os.mkdir("%s/media" % parsed_args.name) if isfile("%s/settings.pyc" % path): os.unlink("%s/settings.pyc" % path) + self._exec_django_command("migrate", parsed_args.name, "--noinput") self._exec_django_command( - "migrate", parsed_args.name, "--noinput" - ) - self._exec_django_command( - "load_initial_data", parsed_args.name, - "--admin-username", parsed_args.admin_username + "load_initial_data", + parsed_args.name, + "--admin-username", + parsed_args.admin_username, ) if parsed_args.collectstatic: - self._exec_django_command( - "collectstatic", parsed_args.name, "--noinput" - ) - self._exec_django_command( - "set_default_site", parsed_args.name, allowed_host - ) + self._exec_django_command("collectstatic", parsed_args.name, "--noinput") + self._exec_django_command("set_default_site", parsed_args.name, allowed_host) base_frontend_dir = os.path.join( - os.path.dirname(__file__), "../../frontend_dist/") + os.path.dirname(__file__), "../../frontend_dist/" + ) if not os.path.exists(base_frontend_dir): return frontend_target_dir = "{}/frontend".format(parsed_args.name) shutil.copytree(base_frontend_dir, frontend_target_dir) with open("{}/config.json".format(frontend_target_dir), "w") as fp: - fp.write("""{ + fp.write( + """{ "API_BASE_URL": "https://%s/api/v2" } -""" % allowed_host) +""" + % allowed_host + ) diff --git a/modoboa/core/commands/help.py b/modoboa/core/commands/help.py index bbfea1916..2c7049b8f 100644 --- a/modoboa/core/commands/help.py +++ b/modoboa/core/commands/help.py @@ -9,8 +9,7 @@ class HelpCommand(Command): def __init__(self, *args, **kwargs): super(HelpCommand, self).__init__(*args, **kwargs) - self._parser.add_argument("name", type=str, - help="A command name") + self._parser.add_argument("name", type=str, help="A command name") def handle(self, parsed_args): if parsed_args.name not in self._commands: diff --git a/modoboa/core/constants.py b/modoboa/core/constants.py index 20e7a2150..e407a4ed7 100644 --- a/modoboa/core/constants.py +++ b/modoboa/core/constants.py @@ -22,25 +22,25 @@ ADMIN_GROUPS = [ ] LANGUAGES = ( - ("br", u"breton"), - ("cs", u"čeština"), - ("de", u"deutsch"), - ("en", u"english"), - ("el", u"ελληνικά"), - ("es", u"español"), + ("br", "breton"), + ("cs", "čeština"), + ("de", "deutsch"), + ("en", "english"), + ("el", "ελληνικά"), + ("es", "español"), ("fi", "Suomalainen"), - ("fr", u"français"), - ("it", u"italiano"), - ("ja", u"日本の"), - ("nl", u"nederlands"), - ("pt", u"português"), - ("pt-br", u"português (BR)"), - ("pl", u"polski"), - ("ro", u"Română"), - ("ru", u"русский"), - ("sv", u"svenska"), - ("tr", u"türk"), - ("zh-hant", u"中文(台灣)"), + ("fr", "français"), + ("it", "italiano"), + ("ja", "日本の"), + ("nl", "nederlands"), + ("pt", "português"), + ("pt-br", "português (BR)"), + ("pl", "polski"), + ("ro", "Română"), + ("ru", "русский"), + ("sv", "svenska"), + ("tr", "türk"), + ("zh-hant", "中文(台灣)"), ) @@ -52,12 +52,12 @@ LDAP_GROUP_TYPES = ( LDAP_SECURE_MODES = [ ("none", gettext_lazy("No")), ("starttls", "STARTTLS"), - ("ssl", "SSL/TLS") + ("ssl", "SSL/TLS"), ] LDAP_AUTH_METHODS = [ ("searchbind", gettext_lazy("Search and bind")), - ("directbind", gettext_lazy("Direct bind")) + ("directbind", gettext_lazy("Direct bind")), ] PERMISSIONS = { @@ -101,7 +101,7 @@ PERMISSIONS = { ["admin", "domainalias", "add_domainalias"], ["admin", "domainalias", "change_domainalias"], ["admin", "domainalias", "delete_domainalias"], - ] + ], } SMS_BACKENDS = [ diff --git a/modoboa/core/context_processors.py b/modoboa/core/context_processors.py index 6b967b758..c8ce1a41c 100644 --- a/modoboa/core/context_processors.py +++ b/modoboa/core/context_processors.py @@ -11,19 +11,18 @@ def top_notifications(request): if request.user.is_anonymous: return {} interval = request.localconfig.parameters.get_value( - "top_notifications_check_interval") + "top_notifications_check_interval" + ) notifications = signals.get_top_notifications.send( - sender="top_notifications", include_all=False) - notifications = reduce( - lambda a, b: a + b, [notif[1] for notif in notifications]) + sender="top_notifications", include_all=False + ) + notifications = reduce(lambda a, b: a + b, [notif[1] for notif in notifications]) return { "notifications_check_interval": interval * 1000, - "top_notifications": notifications + "top_notifications": notifications, } def new_admin_url(*args): """A context processor to include new admin url.""" - return { - "new_admin": getattr(settings, "NEW_ADMIN_URL", "new-admin") - } + return {"new_admin": getattr(settings, "NEW_ADMIN_URL", "new-admin")} diff --git a/modoboa/core/dev_settings.py b/modoboa/core/dev_settings.py index 8f8b2df1c..21da259aa 100644 --- a/modoboa/core/dev_settings.py +++ b/modoboa/core/dev_settings.py @@ -2,9 +2,7 @@ import os -BOWER_COMPONENTS_ROOT = os.path.join( - os.path.dirname(__file__), ".." -) +BOWER_COMPONENTS_ROOT = os.path.join(os.path.dirname(__file__), "..") BOWER_INSTALLED_APPS = ( "jquery#1.9", diff --git a/modoboa/core/drf_authentication.py b/modoboa/core/drf_authentication.py index 9427fca5a..561c88fee 100644 --- a/modoboa/core/drf_authentication.py +++ b/modoboa/core/drf_authentication.py @@ -14,8 +14,8 @@ from . import constants class NotVerified(APIException): status_code = status.HTTP_418_IM_A_TEAPOT - default_detail = _('Missing 2FA verification.') - default_code = 'not_verified' + default_detail = _("Missing 2FA verification.") + default_code = "not_verified" class JWTAuthenticationWith2FA(JWTAuthentication): @@ -25,9 +25,7 @@ class JWTAuthenticationWith2FA(JWTAuthentication): header = self.get_header(request) raw_token = self.get_raw_token(header) validated_token = self.get_validated_token(raw_token) - url_exceptions = ( - reverse("v2:account-tfa-verify-code"), - ) + url_exceptions = (reverse("v2:account-tfa-verify-code"),) if request.path in url_exceptions: return if constants.TFA_DEVICE_TOKEN_KEY in validated_token: @@ -48,5 +46,5 @@ class JWTAuthenticationWith2FA(JWTAuthentication): class SimpleJWTWith2FAScheme(SimpleJWTScheme): - target_class = 'modoboa.core.drf_authentication.JWTAuthenticationWith2FA' - name = 'jwt2FAAuth' + target_class = "modoboa.core.drf_authentication.JWTAuthenticationWith2FA" + name = "jwt2FAAuth" diff --git a/modoboa/core/extensions.py b/modoboa/core/extensions.py index 0aab96f56..1b1c86b41 100644 --- a/modoboa/core/extensions.py +++ b/modoboa/core/extensions.py @@ -32,10 +32,13 @@ class ModoExtension(object): def infos(self): """Information about this extension.""" return { - "name": self.name, "label": self.label, "version": self.version, - "description": self.description, "url": self.get_url(), + "name": self.name, + "label": self.label, + "version": self.version, + "description": self.description, + "url": self.get_url(), "topredirection_url": self.topredirection_url, - "always_active": self.always_active + "always_active": self.always_active, } def load_initial_data(self): @@ -111,9 +114,7 @@ class ExtensionsPool(object): root = r"^{}/".format(ext.get_url()) pattern = "{}.urls" try: - result.append( - re_path(root, include(pattern.format(ext_name))) - ) + result.append(re_path(root, include(pattern.format(ext_name)))) except ImportError: # No urls for this extension pass diff --git a/modoboa/core/factories.py b/modoboa/core/factories.py index 838b9ffd3..92a2e697f 100644 --- a/modoboa/core/factories.py +++ b/modoboa/core/factories.py @@ -8,7 +8,6 @@ from . import models class PermissionFactory(factory.django.DjangoModelFactory): - """A base factory to handle permissions.""" class Meta(object): @@ -22,7 +21,6 @@ class PermissionFactory(factory.django.DjangoModelFactory): class GroupFactory(factory.django.DjangoModelFactory): - """A factory to create Group instances.""" class Meta(object): @@ -32,12 +30,11 @@ class GroupFactory(factory.django.DjangoModelFactory): class UserFactory(PermissionFactory): - """A factory to create User instances.""" class Meta(object): model = models.User - django_get_or_create = ("username", ) + django_get_or_create = ("username",) email = factory.LazyAttribute(lambda a: a.username) password = "{PLAIN}toto" diff --git a/modoboa/core/forms.py b/modoboa/core/forms.py index 031a78cdc..e5bda6f0c 100644 --- a/modoboa/core/forms.py +++ b/modoboa/core/forms.py @@ -3,9 +3,7 @@ import oath from django import forms -from django.contrib.auth import ( - forms as auth_forms, get_user_model, password_validation -) +from django.contrib.auth import forms as auth_forms, get_user_model, password_validation from django.db.models import Q from django.utils.translation import gettext as _, gettext_lazy @@ -21,41 +19,46 @@ class LoginForm(forms.Form): username = forms.CharField( label=gettext_lazy("Username"), - widget=forms.TextInput(attrs={"class": "form-control"}) + widget=forms.TextInput(attrs={"class": "form-control"}), ) password = forms.CharField( label=gettext_lazy("Password"), - widget=forms.PasswordInput(attrs={"class": "form-control"}) - ) - rememberme = forms.BooleanField( - initial=False, - required=False + widget=forms.PasswordInput(attrs={"class": "form-control"}), ) + rememberme = forms.BooleanField(initial=False, required=False) class ProfileForm(forms.ModelForm): """Form to update User profile.""" oldpassword = forms.CharField( - label=gettext_lazy("Old password"), required=False, - widget=forms.PasswordInput(attrs={"class": "form-control"}) + label=gettext_lazy("Old password"), + required=False, + widget=forms.PasswordInput(attrs={"class": "form-control"}), ) newpassword = forms.CharField( - label=gettext_lazy("New password"), required=False, - widget=forms.PasswordInput(attrs={"class": "form-control"}) + label=gettext_lazy("New password"), + required=False, + widget=forms.PasswordInput(attrs={"class": "form-control"}), ) confirmation = forms.CharField( - label=gettext_lazy("Confirmation"), required=False, - widget=forms.PasswordInput(attrs={"class": "form-control"}) + label=gettext_lazy("Confirmation"), + required=False, + widget=forms.PasswordInput(attrs={"class": "form-control"}), ) class Meta: model = User - fields = ("first_name", "last_name", "language", - "phone_number", "secondary_email") + fields = ( + "first_name", + "last_name", + "language", + "phone_number", + "secondary_email", + ) widgets = { "first_name": forms.TextInput(attrs={"class": "form-control"}), - "last_name": forms.TextInput(attrs={"class": "form-control"}) + "last_name": forms.TextInput(attrs={"class": "form-control"}), } def __init__(self, update_password, *args, **kwargs): @@ -90,7 +93,8 @@ class ProfileForm(forms.ModelForm): else: try: password_validation.validate_password( - confirmation, self.instance) + confirmation, self.instance + ) except forms.ValidationError as err: self.add_error("confirmation", err) else: @@ -107,8 +111,7 @@ class ProfileForm(forms.ModelForm): if commit: if self.cleaned_data.get("confirmation", "") != "": user.set_password( - self.cleaned_data["confirmation"], - self.cleaned_data["oldpassword"] + self.cleaned_data["confirmation"], self.cleaned_data["oldpassword"] ) user.save() return user @@ -118,7 +121,8 @@ class APIAccessForm(forms.Form): """Form to control API access.""" enable_api_access = forms.BooleanField( - label=gettext_lazy("Enable API access"), required=False) + label=gettext_lazy("Enable API access"), required=False + ) def __init__(self, *args, **kwargs): """Initialize form.""" @@ -133,19 +137,30 @@ class PasswordResetForm(auth_forms.PasswordResetForm): def get_users(self, email): """Return matching user(s) who should receive a reset.""" return ( - get_user_model()._default_manager.filter( - email__iexact=email, is_active=True) + get_user_model() + ._default_manager.filter(email__iexact=email, is_active=True) .exclude(Q(secondary_email__isnull=True) | Q(secondary_email="")) ) - def send_mail(self, subject_template_name, email_template_name, - context, from_email, to_email, - html_email_template_name=None): + def send_mail( + self, + subject_template_name, + email_template_name, + context, + from_email, + to_email, + html_email_template_name=None, + ): """Send message to secondary email instead.""" to_email = context["user"].secondary_email super(PasswordResetForm, self).send_mail( - subject_template_name, email_template_name, - context, from_email, to_email, html_email_template_name) + subject_template_name, + email_template_name, + context, + from_email, + to_email, + html_email_template_name, + ) class VerifySMSCodeForm(forms.Form): @@ -153,7 +168,7 @@ class VerifySMSCodeForm(forms.Form): code = forms.CharField( label=gettext_lazy("Verification code"), - widget=forms.widgets.TextInput(attrs={"class": "form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "form-control"}), ) def __init__(self, *args, **kwargs): diff --git a/modoboa/core/handlers.py b/modoboa/core/handlers.py index 0934cb3d0..7c4fe6584 100644 --- a/modoboa/core/handlers.py +++ b/modoboa/core/handlers.py @@ -40,8 +40,9 @@ def post_revision_commit(sender, **kwargs): level = "warning" message = _("%(object)s '%(name)s' %(action)s by user %(user)s") % { "object": smart_str(version.content_type).capitalize(), - "name": version.object_repr, "action": action, - "user": current_user + "name": version.object_repr, + "action": action, + "user": current_user, } getattr(logger, level)(message) @@ -62,7 +63,8 @@ def log_object_removal(sender, instance, **kwargs): logger = logging.getLogger("modoboa.admin") msg = _("%(object)s '%(name)s' %(action)s by ") % { "object": smart_str(version.content_type).capitalize(), - "name": version.object_repr, "action": _("deleted") + "name": version.object_repr, + "action": _("deleted"), } request = get_request() if request: @@ -79,8 +81,7 @@ def create_local_config(sender, **kwargs): return if models.LocalConfig.objects.using(kwargs["using"]).exists(): return - models.LocalConfig.objects.create( - site=sites_models.Site.objects.get_current()) + models.LocalConfig.objects.create(site=sites_models.Site.objects.get_current()) @receiver(signals.pre_delete, sender=models.User) @@ -91,16 +92,13 @@ def update_permissions(sender, instance, **kwargs): if request: from_user = request.user if from_user == instance: - raise exceptions.PermDeniedException( - _("You can't delete your own account") - ) + raise exceptions.PermDeniedException(_("You can't delete your own account")) if not from_user.can_access(instance): raise exceptions.PermDeniedException # We send an additional signal before permissions are removed - core_signals.account_deleted.send( - sender="update_permissions", user=instance) + core_signals.account_deleted.send(sender="update_permissions", user=instance) owner = permissions.get_object_owner(instance) if owner == instance: # The default admin is being removed... @@ -108,10 +106,8 @@ def update_permissions(sender, instance, **kwargs): # Change ownership of existing objects for ooentry in instance.objectaccess_set.filter(is_owner=True): if ooentry.content_object is not None: - permissions.grant_access_to_object( - owner, ooentry.content_object, True) - permissions.ungrant_access_to_object( - ooentry.content_object, instance) + permissions.grant_access_to_object(owner, ooentry.content_object, True) + permissions.ungrant_access_to_object(ooentry.content_object, instance) # Remove existing permissions on this user permissions.ungrant_access_to_object(instance) @@ -125,9 +121,11 @@ def check_for_new_versions(sender, include_all, **kwargs): status, extensions = utils.check_for_updates() if not status: return [{"id": "newversionavailable"}] if include_all else [] - return [{ - "id": "newversionavailable", - "url": reverse("core:index") + "#info/", - "text": _("One or more updates are available"), - "level": "info", - }] + return [ + { + "id": "newversionavailable", + "url": reverse("core:index") + "#info/", + "text": _("One or more updates are available"), + "level": "info", + } + ] diff --git a/modoboa/core/loggers.py b/modoboa/core/loggers.py index 35efe0397..cf52213e4 100644 --- a/modoboa/core/loggers.py +++ b/modoboa/core/loggers.py @@ -7,6 +7,5 @@ class SQLHandler(logging.Handler): from .models import Log Log.objects.create( - message=record.getMessage(), level=record.levelname, - logger=record.name + message=record.getMessage(), level=record.levelname, logger=record.name ) diff --git a/modoboa/core/management/commands/clean_inactive_accounts.py b/modoboa/core/management/commands/clean_inactive_accounts.py index 2c48e4754..fbfed94b9 100644 --- a/modoboa/core/management/commands/clean_inactive_accounts.py +++ b/modoboa/core/management/commands/clean_inactive_accounts.py @@ -17,44 +17,53 @@ class Command(BaseCommand): def add_arguments(self, parser): """Add extra arguments to command line.""" parser.add_argument( - "--delete", action="store_true", default=False, - help="Delete inactive accounts (default is to disable)") + "--delete", + action="store_true", + default=False, + help="Delete inactive accounts (default is to disable)", + ) parser.add_argument( - "--dry-run", action="store_true", default=False, - help="Only look for inactive accounts, no action") + "--dry-run", + action="store_true", + default=False, + help="Only look for inactive accounts, no action", + ) parser.add_argument( - "--silent", action="store_true", default=False, - help="Enable silent mode (no question)") + "--silent", + action="store_true", + default=False, + help="Enable silent mode (no question)", + ) parser.add_argument( - "--verbose", action="store_true", default=False, - help="Enable verbose mode") + "--verbose", action="store_true", default=False, help="Enable verbose mode" + ) def _log_inactive_accounts(self, qset): """Log inactive accounts found.""" - print( - "The following inactive accounts have been found:", - file=self.stdout) + print("The following inactive accounts have been found:", file=self.stdout) for account in qset.values("username", "last_login"): print( "> {}\n (last login: {})".format( - account["username"], account["last_login"]), - file=self.stdout + account["username"], account["last_login"] + ), + file=self.stdout, ) def handle(self, *args, **options): """Command entry point.""" - if not param_tools.get_global_parameter( - "enable_inactive_accounts"): + if not param_tools.get_global_parameter("enable_inactive_accounts"): if options["verbose"]: - print("Inactive accounts detection is disabled.", - file=self.stdout) + print("Inactive accounts detection is disabled.", file=self.stdout) return inactive_account_threshold = param_tools.get_global_parameter( - "inactive_account_threshold") + "inactive_account_threshold" + ) qset = models.User.objects.filter( - is_active=True, is_superuser=False, - last_login__lt=timezone.now() - - relativedelta(days=inactive_account_threshold)) + is_active=True, + is_superuser=False, + last_login__lt=timezone.now() + - relativedelta(days=inactive_account_threshold), + ) if not qset.exists(): return if options["verbose"]: @@ -63,8 +72,7 @@ class Command(BaseCommand): return action = "delete" if options["delete"] else "disable" if not options["silent"]: - answer = input( - "Do you want to {} those accounts? (y/N) ".format(action)) + answer = input("Do you want to {} those accounts? (y/N) ".format(action)) if not answer.lower().startswith("y"): return if action == "disable": diff --git a/modoboa/core/management/commands/cleanlogs.py b/modoboa/core/management/commands/cleanlogs.py index 179aa0262..b7332a6e5 100644 --- a/modoboa/core/management/commands/cleanlogs.py +++ b/modoboa/core/management/commands/cleanlogs.py @@ -16,11 +16,14 @@ class Command(BaseCommand): def add_arguments(self, parser): """Add extra arguments to command line.""" parser.add_argument( - "--debug", action="store_true", default=False, - help="Activate debug output") + "--debug", action="store_true", default=False, help="Activate debug output" + ) parser.add_argument( - "--verbose", action="store_true", default=False, - help="Display informational messages") + "--verbose", + action="store_true", + default=False, + help="Display informational messages", + ) def __vprint(self, msg): if not self.verbose: diff --git a/modoboa/core/management/commands/communicate_with_public_api.py b/modoboa/core/management/commands/communicate_with_public_api.py index d5d850621..a891f8801 100644 --- a/modoboa/core/management/commands/communicate_with_public_api.py +++ b/modoboa/core/management/commands/communicate_with_public_api.py @@ -31,30 +31,29 @@ class Command(BaseCommand): updates[extension["name"]] = extension["last_version"] to_create.append( models.ExtensionUpdateHistory( - extension=extension["name"], - version=extension["last_version"] + extension=extension["name"], version=extension["last_version"] ) ) if not updates: return content = render_to_string( - "core/notifications/update_available.html", { - "updates": updates - }) + "core/notifications/update_available.html", {"updates": updates} + ) subject = _("[modoboa] Update(s) available") sender = local_config.parameters.get_value("sender_address") - recipient = local_config.parameters.get_value( - "new_versions_email_rcpt") + recipient = local_config.parameters.get_value("new_versions_email_rcpt") msg = EmailMessage( - subject, content.strip(), sender, [recipient], + subject, + content.strip(), + sender, + [recipient], ) msg.send() models.ExtensionUpdateHistory.objects.bulk_create(to_create) def handle(self, *args, **options): """Command entry point.""" - local_config = ( - models.LocalConfig.objects.select_related("site").first()) + local_config = models.LocalConfig.objects.select_related("site").first() if not local_config.parameters.get_value("enable_api_communication"): return self.client = api_client.ModoAPIClient() @@ -87,7 +86,8 @@ class Command(BaseCommand): "domain_alias_counter": admin_models.DomainAlias.objects.count(), "mailbox_counter": admin_models.Mailbox.objects.count(), "alias_counter": ( - admin_models.Alias.objects.filter(internal=False).count()), - "extensions": extensions + admin_models.Alias.objects.filter(internal=False).count() + ), + "extensions": extensions, } self.client.update_instance(local_config.api_pk, data) diff --git a/modoboa/core/management/commands/generate_postfix_maps.py b/modoboa/core/management/commands/generate_postfix_maps.py index 92cb87b18..5677d2700 100644 --- a/modoboa/core/management/commands/generate_postfix_maps.py +++ b/modoboa/core/management/commands/generate_postfix_maps.py @@ -28,19 +28,20 @@ class Command(BaseCommand): def add_arguments(self, parser): """Add extra arguments.""" + parser.add_argument("--dburl", help="Custom database url") parser.add_argument( - "--dburl", help="Custom database url") + "--destdir", default=".", help="Directory where files will be created" + ) parser.add_argument( - "--destdir", default=".", - help="Directory where files will be created") - parser.add_argument( - "--force-overwrite", action="store_true", default=False, - help="Force overwrite of existing map files") + "--force-overwrite", + action="store_true", + default=False, + help="Force overwrite of existing map files", + ) def __load_checksums(self, destdir): """Load existing checksums if possible.""" - self.__checksums_file = os.path.join( - destdir, "modoboa-postfix-maps.chk") + self.__checksums_file = os.path.join(destdir, "modoboa-postfix-maps.chk") self.__checksums = {} if not os.path.exists(self.__checksums_file): return @@ -48,7 +49,8 @@ class Command(BaseCommand): for line in fp: fname, dbtype, checksum = line.split(":") self.__checksums[fname.strip()] = { - "dbtype": dbtype, "checksum": checksum.strip() + "dbtype": dbtype, + "checksum": checksum.strip(), } def __register_map_files(self): @@ -62,9 +64,7 @@ class Command(BaseCommand): def __check_file(self, path): """Check if map file has been modified.""" fname = os.path.basename(path) - condition = ( - not self.__checksums or - fname not in self.__checksums) + condition = not self.__checksums or fname not in self.__checksums if condition: return True with open(path, mode="rb") as fp: @@ -92,7 +92,9 @@ query = {{ query|safe }} dburl = options.get("dburl") db_settings = ( dj_database_url.config(default=dburl) - if dburl else settings.DATABASES["default"]) + if dburl + else settings.DATABASES["default"] + ) if "sqlite" in db_settings["ENGINE"]: dbtype = "sqlite" elif "postgresql" in db_settings["ENGINE"]: @@ -102,10 +104,11 @@ query = {{ query|safe }} dbhost = db_settings.get("HOST", "127.0.0.1") dbport = db_settings.get("PORT", "") if len(dbport): - dbhost += ':' + dbport + dbhost += ":" + dbport commandline = "{} {}".format( - os.path.basename(sys.argv[0]), " ".join(sys.argv[1:])) + os.path.basename(sys.argv[0]), " ".join(sys.argv[1:]) + ) context = { "date": timezone.now(), "commandline": commandline, @@ -113,19 +116,20 @@ query = {{ query|safe }} "dbuser": db_settings["USER"], "dbpass": db_settings["PASSWORD"], "dbname": db_settings["NAME"], - "dbhost": dbhost + "dbhost": dbhost, } return context - def __render_map_file( - self, mapobject, destdir, context, force_overwrite=False): + def __render_map_file(self, mapobject, destdir, context, force_overwrite=False): """Render a map file.""" fullpath = os.path.join(destdir, mapobject.filename) if os.path.exists(fullpath) and not force_overwrite: if not self.__check_file(fullpath): print( - "Cannot upgrade '{}' map because it has been modified." - .format(mapobject.filename)) + "Cannot upgrade '{}' map because it has been modified.".format( + mapobject.filename + ) + ) return self.__checksums[mapobject.filename] mapcontent = utils.parse_map_file(fullpath) context = copy.deepcopy(context) @@ -139,8 +143,7 @@ query = {{ query|safe }} context["dbhost"] = mapcontent["hosts"] content = self.get_template(context["dbtype"]).render( Context( - dict(list(context.items()), - query=getattr(mapobject, context["dbtype"])) + dict(list(context.items()), query=getattr(mapobject, context["dbtype"])) ) ) fullpath = os.path.join(destdir, mapobject.filename) @@ -161,10 +164,9 @@ query = {{ query|safe }} checksums = {} for mapobject in mapfiles: checksum = self.__render_map_file( - mapobject, destdir, context, - force_overwrite=options["force_overwrite"]) + mapobject, destdir, context, force_overwrite=options["force_overwrite"] + ) checksums[mapobject.filename] = checksum with open(self.__checksums_file, "w") as fp: for fname, checksum in list(checksums.items()): - fp.write("{}:{}:{}\n".format( - fname, context["dbtype"], checksum)) + fp.write("{}:{}:{}\n".format(fname, context["dbtype"], checksum)) diff --git a/modoboa/core/management/commands/load_initial_data.py b/modoboa/core/management/commands/load_initial_data.py index 446dcd78f..3a19086f6 100644 --- a/modoboa/core/management/commands/load_initial_data.py +++ b/modoboa/core/management/commands/load_initial_data.py @@ -22,12 +22,15 @@ class Command(BaseCommand): def add_arguments(self, parser): """Add extra arguments to command.""" parser.add_argument( - "--admin-username", default="admin", - help="Username of the initial super administrator." + "--admin-username", + default="admin", + help="Username of the initial super administrator.", ) parser.add_argument( - "--extra-fixtures", action="store_true", default=False, - help="Also load some fixtures from the admin application." + "--extra-fixtures", + action="store_true", + default=False, + help="Also load some fixtures from the admin application.", ) def handle(self, *args, **options): @@ -35,22 +38,24 @@ class Command(BaseCommand): extensions.exts_pool.load_all() if not models.User.objects.filter(is_superuser=True).count(): - admin = models.User( - username=options["admin_username"], is_superuser=True) + admin = models.User(username=options["admin_username"], is_superuser=True) admin.set_password("password") admin.save() models.ObjectAccess.objects.create( - user=admin, content_object=admin, is_owner=True) + user=admin, content_object=admin, is_owner=True + ) groups = list(constants.PERMISSIONS.keys()) for groupname in groups: group, created = Group.objects.get_or_create(name=groupname) results = signals.extra_role_permissions.send( - sender=self.__class__, role=groupname) + sender=self.__class__, role=groupname + ) permissions = constants.PERMISSIONS.get(groupname, []) if results: permissions += reduce( - lambda a, b: a + b, [result[1] for result in results]) + lambda a, b: a + b, [result[1] for result in results] + ) if not permissions: continue add_permissions_to_group(group, permissions) @@ -61,15 +66,12 @@ class Command(BaseCommand): extension.load_initial_data() except Exception as e: self.stderr.write( - "Unable to load initial data for '{}' ({}).".format( - extname, str(e) - ) + "Unable to load initial data for '{}' ({}).".format(extname, str(e)) ) else: - signals.initial_data_loaded.send( - sender=self.__class__, extname=extname - ) + signals.initial_data_loaded.send(sender=self.__class__, extname=extname) if options["extra_fixtures"]: from modoboa.admin import factories + factories.populate_database() diff --git a/modoboa/core/management/commands/set_default_site.py b/modoboa/core/management/commands/set_default_site.py index 3c77cf2f9..799826f83 100644 --- a/modoboa/core/management/commands/set_default_site.py +++ b/modoboa/core/management/commands/set_default_site.py @@ -9,7 +9,6 @@ from django.core.management.base import BaseCommand, CommandError class Command(BaseCommand): - """Management command to set the default site.""" help = "Set default site (see django.contrib.sites)" # NOQA:A003 diff --git a/modoboa/core/middleware.py b/modoboa/core/middleware.py index 159f1acb9..b9aaef4aa 100644 --- a/modoboa/core/middleware.py +++ b/modoboa/core/middleware.py @@ -24,17 +24,14 @@ class TwoFAMiddleware: def __call__(self, request): user = getattr(request, "user", None) redirect_url = reverse("core:2fa_verify") - url_exceptions = ( - redirect_url, - "/jsi18n/" - ) + url_exceptions = (redirect_url, "/jsi18n/") condition = ( - user and - not user.is_anonymous and - user.tfa_enabled and - not request.path.startswith('/api/') and - request.path not in url_exceptions and - not user.is_verified() + user + and not user.is_anonymous + and user.tfa_enabled + and not request.path.startswith("/api/") + and request.path not in url_exceptions + and not user.is_verified() ) if condition: return http.HttpResponseRedirect(reverse("core:2fa_verify")) diff --git a/modoboa/core/migrations/0001_initial.py b/modoboa/core/migrations/0001_initial.py index b8a7ea543..d0ba5d42c 100644 --- a/modoboa/core/migrations/0001_initial.py +++ b/modoboa/core/migrations/0001_initial.py @@ -6,73 +6,154 @@ from django.conf import settings class Migration(migrations.Migration): dependencies = [ - ('auth', '0001_initial'), - ('contenttypes', '0001_initial'), + ("auth", "0001_initial"), + ("contenttypes", "0001_initial"), ] operations = [ migrations.CreateModel( - name='User', + name="User", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('username', models.CharField(unique=True, max_length=254)), - ('first_name', models.CharField(max_length=30, blank=True)), - ('last_name', models.CharField(max_length=30, blank=True)), - ('email', models.EmailField(max_length=254, blank=True)), - ('is_staff', models.BooleanField(default=False)), - ('is_active', models.BooleanField(default=True)), - ('date_joined', models.DateTimeField(default=django.utils.timezone.now)), - ('is_local', models.BooleanField(default=True)), - ('password', models.CharField(max_length=256, verbose_name='password')), - ('last_login', models.DateTimeField(default=django.utils.timezone.now, verbose_name='last login')), - ('groups', models.ManyToManyField(related_query_name='user', related_name='user_set', to='auth.Group', blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of his/her group.', verbose_name='groups')), - ('user_permissions', models.ManyToManyField(related_query_name='user', related_name='user_set', to='auth.Permission', blank=True, help_text='Specific permissions for this user.', verbose_name='user permissions')), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ( + "is_superuser", + models.BooleanField( + default=False, + help_text="Designates that this user has all permissions without explicitly assigning them.", + verbose_name="superuser status", + ), + ), + ("username", models.CharField(unique=True, max_length=254)), + ("first_name", models.CharField(max_length=30, blank=True)), + ("last_name", models.CharField(max_length=30, blank=True)), + ("email", models.EmailField(max_length=254, blank=True)), + ("is_staff", models.BooleanField(default=False)), + ("is_active", models.BooleanField(default=True)), + ( + "date_joined", + models.DateTimeField(default=django.utils.timezone.now), + ), + ("is_local", models.BooleanField(default=True)), + ("password", models.CharField(max_length=256, verbose_name="password")), + ( + "last_login", + models.DateTimeField( + default=django.utils.timezone.now, verbose_name="last login" + ), + ), + ( + "groups", + models.ManyToManyField( + related_query_name="user", + related_name="user_set", + to="auth.Group", + blank=True, + help_text="The groups this user belongs to. A user will get all permissions granted to each of his/her group.", + verbose_name="groups", + ), + ), + ( + "user_permissions", + models.ManyToManyField( + related_query_name="user", + related_name="user_set", + to="auth.Permission", + blank=True, + help_text="Specific permissions for this user.", + verbose_name="user permissions", + ), + ), ], options={ - 'ordering': ['username'], + "ordering": ["username"], }, bases=(models.Model,), ), migrations.CreateModel( - name='Extension', + name="Extension", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=150)), - ('enabled', models.BooleanField(default=False, help_text='Check to enable this extension', verbose_name='enabled')), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("name", models.CharField(max_length=150)), + ( + "enabled", + models.BooleanField( + default=False, + help_text="Check to enable this extension", + verbose_name="enabled", + ), + ), ], - options={ - }, + options={}, bases=(models.Model,), ), migrations.CreateModel( - name='Log', + name="Log", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('date_created', models.DateTimeField(auto_now_add=True)), - ('message', models.CharField(max_length=255)), - ('level', models.CharField(max_length=15)), - ('logger', models.CharField(max_length=30)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("date_created", models.DateTimeField(auto_now_add=True)), + ("message", models.CharField(max_length=255)), + ("level", models.CharField(max_length=15)), + ("logger", models.CharField(max_length=30)), ], - options={ - }, + options={}, bases=(models.Model,), ), migrations.CreateModel( - name='ObjectAccess', + name="ObjectAccess", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('object_id', models.PositiveIntegerField()), - ('is_owner', models.BooleanField(default=False)), - ('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("object_id", models.PositiveIntegerField()), + ("is_owner", models.BooleanField(default=False)), + ( + "content_type", + models.ForeignKey( + to="contenttypes.ContentType", on_delete=models.CASCADE + ), + ), + ( + "user", + models.ForeignKey( + to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE + ), + ), ], - options={ - }, + options={}, bases=(models.Model,), ), migrations.AlterUniqueTogether( - name='objectaccess', - unique_together=set([('user', 'content_type', 'object_id')]), + name="objectaccess", + unique_together=set([("user", "content_type", "object_id")]), ), ] diff --git a/modoboa/core/migrations/0002_delete_extension.py b/modoboa/core/migrations/0002_delete_extension.py index 06ea4b5f1..c43cf011f 100644 --- a/modoboa/core/migrations/0002_delete_extension.py +++ b/modoboa/core/migrations/0002_delete_extension.py @@ -4,11 +4,11 @@ from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ - ('core', '0001_initial'), + ("core", "0001_initial"), ] operations = [ migrations.DeleteModel( - name='Extension', + name="Extension", ), ] diff --git a/modoboa/core/migrations/0003_user_master_user.py b/modoboa/core/migrations/0003_user_master_user.py index b31578867..2cac2befc 100644 --- a/modoboa/core/migrations/0003_user_master_user.py +++ b/modoboa/core/migrations/0003_user_master_user.py @@ -4,14 +4,16 @@ from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ - ('core', '0002_delete_extension'), + ("core", "0002_delete_extension"), ] operations = [ migrations.AddField( - model_name='user', - name='master_user', - field=models.BooleanField(default=False, verbose_name='Allow mailboxes access'), + model_name="user", + name="master_user", + field=models.BooleanField( + default=False, verbose_name="Allow mailboxes access" + ), preserve_default=True, ), ] diff --git a/modoboa/core/migrations/0004_auto_20150728_1228.py b/modoboa/core/migrations/0004_auto_20150728_1228.py index ffa20cf95..a7fa76773 100644 --- a/modoboa/core/migrations/0004_auto_20150728_1228.py +++ b/modoboa/core/migrations/0004_auto_20150728_1228.py @@ -4,42 +4,46 @@ from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ - ('core', '0003_user_master_user'), + ("core", "0003_user_master_user"), ] operations = [ migrations.AlterField( - model_name='user', - name='email', + model_name="user", + name="email", field=models.EmailField(db_index=True, max_length=254, blank=True), preserve_default=True, ), migrations.AlterField( - model_name='user', - name='is_active', + model_name="user", + name="is_active", field=models.BooleanField(default=True, db_index=True), preserve_default=True, ), migrations.AlterField( - model_name='user', - name='is_local', + model_name="user", + name="is_local", field=models.BooleanField(default=True, db_index=True), preserve_default=True, ), migrations.AlterField( - model_name='user', - name='is_staff', + model_name="user", + name="is_staff", field=models.BooleanField(default=False, db_index=True), preserve_default=True, ), migrations.AlterField( - model_name='user', - name='master_user', - field=models.BooleanField(default=False, help_text='Allow this administrator to access user mailboxes', verbose_name='Allow mailboxes access'), + model_name="user", + name="master_user", + field=models.BooleanField( + default=False, + help_text="Allow this administrator to access user mailboxes", + verbose_name="Allow mailboxes access", + ), preserve_default=True, ), migrations.AlterIndexTogether( - name='user', - index_together=set([('email', 'is_active')]), + name="user", + index_together=set([("email", "is_active")]), ), ] diff --git a/modoboa/core/migrations/0005_user_language.py b/modoboa/core/migrations/0005_user_language.py index 849940b58..f4af48272 100644 --- a/modoboa/core/migrations/0005_user_language.py +++ b/modoboa/core/migrations/0005_user_language.py @@ -4,14 +4,31 @@ from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ - ('core', '0004_auto_20150728_1228'), + ("core", "0004_auto_20150728_1228"), ] operations = [ migrations.AddField( - model_name='user', - name='language', - field=models.CharField(default=b'en', help_text='Prefered language to display pages.', max_length=10, choices=[(b'cs', '\u010de\u0161tina'), (b'de', 'deutsch'), (b'en', 'english'), (b'es', 'espa\xf1ol'), (b'fr', 'fran\xe7ais'), (b'it', 'italiano'), (b'nl', 'nederlands'), (b'pt_PT', 'portugu\xeas'), (b'pt_BR', 'portugu\xeas (BR)'), (b'ru', '\u0440\u0443\u0441\u0441\u043a\u0438\u0439'), (b'sv', 'svenska')]), + model_name="user", + name="language", + field=models.CharField( + default=b"en", + help_text="Prefered language to display pages.", + max_length=10, + choices=[ + (b"cs", "\u010de\u0161tina"), + (b"de", "deutsch"), + (b"en", "english"), + (b"es", "espa\xf1ol"), + (b"fr", "fran\xe7ais"), + (b"it", "italiano"), + (b"nl", "nederlands"), + (b"pt_PT", "portugu\xeas"), + (b"pt_BR", "portugu\xeas (BR)"), + (b"ru", "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"), + (b"sv", "svenska"), + ], + ), preserve_default=True, ), ] diff --git a/modoboa/core/migrations/0006_auto_20151114_1518.py b/modoboa/core/migrations/0006_auto_20151114_1518.py index 40c125697..8e242c08e 100644 --- a/modoboa/core/migrations/0006_auto_20151114_1518.py +++ b/modoboa/core/migrations/0006_auto_20151114_1518.py @@ -4,20 +4,28 @@ from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ - ('core', '0005_user_language'), + ("core", "0005_user_language"), ] operations = [ migrations.AddField( - model_name='user', - name='phone_number', - field=models.CharField(max_length=128, null=True, verbose_name='Phone number', blank=True), + model_name="user", + name="phone_number", + field=models.CharField( + max_length=128, null=True, verbose_name="Phone number", blank=True + ), preserve_default=True, ), migrations.AddField( - model_name='user', - name='secondary_email', - field=models.EmailField(help_text='An alternative e-mail address, can be used for recovery needs.', max_length=254, null=True, verbose_name='Secondary email', blank=True), + model_name="user", + name="secondary_email", + field=models.EmailField( + help_text="An alternative e-mail address, can be used for recovery needs.", + max_length=254, + null=True, + verbose_name="Secondary email", + blank=True, + ), preserve_default=True, ), ] diff --git a/modoboa/core/migrations/0007_auto_20151116_1349.py b/modoboa/core/migrations/0007_auto_20151116_1349.py index e36ddaf1e..13186b62c 100644 --- a/modoboa/core/migrations/0007_auto_20151116_1349.py +++ b/modoboa/core/migrations/0007_auto_20151116_1349.py @@ -5,24 +5,33 @@ import django.contrib.auth.models class Migration(migrations.Migration): dependencies = [ - ('core', '0006_auto_20151114_1518'), + ("core", "0006_auto_20151114_1518"), ] operations = [ migrations.AlterModelManagers( - name='user', + name="user", managers=[ - ('objects', django.contrib.auth.models.UserManager()), + ("objects", django.contrib.auth.models.UserManager()), ], ), migrations.AlterField( - model_name='user', - name='groups', - field=models.ManyToManyField(related_query_name='user', related_name='user_set', to='auth.Group', blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', verbose_name='groups'), + model_name="user", + name="groups", + field=models.ManyToManyField( + related_query_name="user", + related_name="user_set", + to="auth.Group", + blank=True, + help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.", + verbose_name="groups", + ), ), migrations.AlterField( - model_name='user', - name='last_login', - field=models.DateTimeField(null=True, verbose_name='last login', blank=True), + model_name="user", + name="last_login", + field=models.DateTimeField( + null=True, verbose_name="last login", blank=True + ), ), ] diff --git a/modoboa/core/migrations/0008_localconfig.py b/modoboa/core/migrations/0008_localconfig.py index a9df6ff8d..5b2b671ab 100644 --- a/modoboa/core/migrations/0008_localconfig.py +++ b/modoboa/core/migrations/0008_localconfig.py @@ -6,18 +6,31 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('sites', '0002_alter_domain_unique'), - ('core', '0007_auto_20151116_1349'), + ("sites", "0002_alter_domain_unique"), + ("core", "0007_auto_20151116_1349"), ] operations = [ migrations.CreateModel( - name='LocalConfig', + name="LocalConfig", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('api_pk', models.PositiveIntegerField(null=True)), - ('api_versions', models.JSONField()), - ('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("api_pk", models.PositiveIntegerField(null=True)), + ("api_versions", models.JSONField()), + ( + "site", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="sites.Site" + ), + ), ], ), ] diff --git a/modoboa/core/migrations/0009_auto_20161026_1003.py b/modoboa/core/migrations/0009_auto_20161026_1003.py index c65124efe..722067d4b 100644 --- a/modoboa/core/migrations/0009_auto_20161026_1003.py +++ b/modoboa/core/migrations/0009_auto_20161026_1003.py @@ -5,23 +5,44 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0008_localconfig'), + ("core", "0008_localconfig"), ] operations = [ migrations.AlterField( - model_name='user', - name='first_name', - field=models.CharField(blank=True, max_length=30, verbose_name='First name'), + model_name="user", + name="first_name", + field=models.CharField( + blank=True, max_length=30, verbose_name="First name" + ), ), migrations.AlterField( - model_name='user', - name='language', - field=models.CharField(choices=[(b'cs', '\u010de\u0161tina'), (b'de', 'deutsch'), (b'en', 'english'), (b'es', 'espa\xf1ol'), (b'fr', 'fran\xe7ais'), (b'it', 'italiano'), (b'ja_JP', '\u65e5\u672c\u306e'), (b'nl', 'nederlands'), (b'pt_PT', 'portugu\xeas'), (b'pt_BR', 'portugu\xeas (BR)'), (b'ru', '\u0440\u0443\u0441\u0441\u043a\u0438\u0439'), (b'sv', 'svenska')], default=b'en', help_text='Prefered language to display pages.', max_length=10, verbose_name='language'), + model_name="user", + name="language", + field=models.CharField( + choices=[ + (b"cs", "\u010de\u0161tina"), + (b"de", "deutsch"), + (b"en", "english"), + (b"es", "espa\xf1ol"), + (b"fr", "fran\xe7ais"), + (b"it", "italiano"), + (b"ja_JP", "\u65e5\u672c\u306e"), + (b"nl", "nederlands"), + (b"pt_PT", "portugu\xeas"), + (b"pt_BR", "portugu\xeas (BR)"), + (b"ru", "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"), + (b"sv", "svenska"), + ], + default=b"en", + help_text="Prefered language to display pages.", + max_length=10, + verbose_name="language", + ), ), migrations.AlterField( - model_name='user', - name='last_name', - field=models.CharField(blank=True, max_length=30, verbose_name='Last name'), + model_name="user", + name="last_name", + field=models.CharField(blank=True, max_length=30, verbose_name="Last name"), ), ] diff --git a/modoboa/core/migrations/0010_auto_20161026_1011.py b/modoboa/core/migrations/0010_auto_20161026_1011.py index 930f252a9..1fb4c3566 100644 --- a/modoboa/core/migrations/0010_auto_20161026_1011.py +++ b/modoboa/core/migrations/0010_auto_20161026_1011.py @@ -42,22 +42,22 @@ def clear_parameters(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('core', '0009_auto_20161026_1003'), - ('lib', '0005_auto_20160416_1449'), + ("core", "0009_auto_20161026_1003"), + ("lib", "0005_auto_20160416_1449"), ] operations = [ migrations.AddField( - model_name='localconfig', - name='_parameters', + model_name="localconfig", + name="_parameters", field=models.JSONField(default=dict), preserve_default=False, ), migrations.AddField( - model_name='user', - name='_parameters', + model_name="user", + name="_parameters", field=models.JSONField(default=dict), preserve_default=False, ), - migrations.RunPython(move_parameters, clear_parameters) + migrations.RunPython(move_parameters, clear_parameters), ] diff --git a/modoboa/core/migrations/0011_auto_20161104_2217.py b/modoboa/core/migrations/0011_auto_20161104_2217.py index f8b165155..fb06b7de7 100644 --- a/modoboa/core/migrations/0011_auto_20161104_2217.py +++ b/modoboa/core/migrations/0011_auto_20161104_2217.py @@ -5,18 +5,18 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0010_auto_20161026_1011'), + ("core", "0010_auto_20161026_1011"), ] operations = [ migrations.AlterField( - model_name='localconfig', - name='_parameters', + model_name="localconfig", + name="_parameters", field=models.JSONField(default=dict), ), migrations.AlterField( - model_name='user', - name='_parameters', + model_name="user", + name="_parameters", field=models.JSONField(default=dict), ), ] diff --git a/modoboa/core/migrations/0012_auto_20170215_1034.py b/modoboa/core/migrations/0012_auto_20170215_1034.py index 0adfd9a97..e21975f51 100644 --- a/modoboa/core/migrations/0012_auto_20170215_1034.py +++ b/modoboa/core/migrations/0012_auto_20170215_1034.py @@ -7,13 +7,14 @@ def rename_settings(apps, schema_editor): LocalConfig = apps.get_model("core", "LocalConfig") lc = LocalConfig.objects.first() condition = ( - lc and - "admin" in lc._parameters and - "default_domain_quota" in lc._parameters["admin"] + lc + and "admin" in lc._parameters + and "default_domain_quota" in lc._parameters["admin"] ) if condition: - lc._parameters["admin"]["default_mailbox_quota"] = ( - lc._parameters["admin"]["default_domain_quota"]) + lc._parameters["admin"]["default_mailbox_quota"] = lc._parameters["admin"][ + "default_domain_quota" + ] del lc._parameters["admin"]["default_domain_quota"] lc.save(update_fields=["_parameters"]) @@ -21,9 +22,7 @@ def rename_settings(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('core', '0011_auto_20161104_2217'), + ("core", "0011_auto_20161104_2217"), ] - operations = [ - migrations.RunPython(rename_settings) - ] + operations = [migrations.RunPython(rename_settings)] diff --git a/modoboa/core/migrations/0013_auto_20170707_1058.py b/modoboa/core/migrations/0013_auto_20170707_1058.py index c6ecee2dc..28335393f 100644 --- a/modoboa/core/migrations/0013_auto_20170707_1058.py +++ b/modoboa/core/migrations/0013_auto_20170707_1058.py @@ -6,23 +6,27 @@ import django.utils.timezone class Migration(migrations.Migration): dependencies = [ - ('core', '0012_auto_20170215_1034'), + ("core", "0012_auto_20170215_1034"), ] operations = [ migrations.AlterField( - model_name='user', - name='date_joined', - field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined'), + model_name="user", + name="date_joined", + field=models.DateTimeField( + default=django.utils.timezone.now, verbose_name="date joined" + ), ), migrations.AlterField( - model_name='user', - name='first_name', - field=models.CharField(blank=True, max_length=30, verbose_name='first name'), + model_name="user", + name="first_name", + field=models.CharField( + blank=True, max_length=30, verbose_name="first name" + ), ), migrations.AlterField( - model_name='user', - name='last_name', - field=models.CharField(blank=True, max_length=30, verbose_name='last name'), + model_name="user", + name="last_name", + field=models.CharField(blank=True, max_length=30, verbose_name="last name"), ), ] diff --git a/modoboa/core/migrations/0014_auto_20171010_1746.py b/modoboa/core/migrations/0014_auto_20171010_1746.py index 5d7fd85af..6f162b0fa 100644 --- a/modoboa/core/migrations/0014_auto_20171010_1746.py +++ b/modoboa/core/migrations/0014_auto_20171010_1746.py @@ -23,7 +23,7 @@ def forward(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('core', '0013_auto_20170707_1058'), + ("core", "0013_auto_20170707_1058"), ] operations = [ diff --git a/modoboa/core/migrations/0015_auto_20180112_1642.py b/modoboa/core/migrations/0015_auto_20180112_1642.py index a3aaea97b..ce9dd3f50 100644 --- a/modoboa/core/migrations/0015_auto_20180112_1642.py +++ b/modoboa/core/migrations/0015_auto_20180112_1642.py @@ -5,13 +5,34 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0014_auto_20171010_1746'), + ("core", "0014_auto_20171010_1746"), ] operations = [ migrations.AlterField( - model_name='user', - name='language', - field=models.CharField(choices=[('cs', '\u010de\u0161tina'), ('de', 'deutsch'), ('en', 'english'), ('el_GR', '\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac'), ('es', 'espa\xf1ol'), ('fr', 'fran\xe7ais'), ('it', 'italiano'), ('ja_JP', '\u65e5\u672c\u306e'), ('nl', 'nederlands'), ('pt_PT', 'portugu\xeas'), ('pt_BR', 'portugu\xeas (BR)'), ('pl_PL', 'polski'), ('ru', '\u0440\u0443\u0441\u0441\u043a\u0438\u0439'), ('sv', 'svenska')], default='en', help_text='Prefered language to display pages.', max_length=10, verbose_name='language'), + model_name="user", + name="language", + field=models.CharField( + choices=[ + ("cs", "\u010de\u0161tina"), + ("de", "deutsch"), + ("en", "english"), + ("el_GR", "\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"), + ("es", "espa\xf1ol"), + ("fr", "fran\xe7ais"), + ("it", "italiano"), + ("ja_JP", "\u65e5\u672c\u306e"), + ("nl", "nederlands"), + ("pt_PT", "portugu\xeas"), + ("pt_BR", "portugu\xeas (BR)"), + ("pl_PL", "polski"), + ("ru", "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"), + ("sv", "svenska"), + ], + default="en", + help_text="Prefered language to display pages.", + max_length=10, + verbose_name="language", + ), ), ] diff --git a/modoboa/core/migrations/0016_auto_20180713_1014.py b/modoboa/core/migrations/0016_auto_20180713_1014.py index 9a98017a0..683632868 100644 --- a/modoboa/core/migrations/0016_auto_20180713_1014.py +++ b/modoboa/core/migrations/0016_auto_20180713_1014.py @@ -5,13 +5,36 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0015_auto_20180112_1642'), + ("core", "0015_auto_20180112_1642"), ] operations = [ migrations.AlterField( - model_name='user', - name='language', - field=models.CharField(choices=[('cs', '\u010de\u0161tina'), ('de', 'deutsch'), ('en', 'english'), ('el_GR', '\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac'), ('es', 'espa\xf1ol'), ('fr', 'fran\xe7ais'), ('it', 'italiano'), ('ja_JP', '\u65e5\u672c\u306e'), ('nl', 'nederlands'), ('pt_PT', 'portugu\xeas'), ('pt_BR', 'portugu\xeas (BR)'), ('pl_PL', 'polski'), ('ro_RO', 'Rom\xe2n\u0103'), ('ru', '\u0440\u0443\u0441\u0441\u043a\u0438\u0439'), ('sv', 'svenska'), ('zh_TW', '\u4e2d\u6587\uff08\u53f0\u7063\uff09')], default='en', help_text='Prefered language to display pages.', max_length=10, verbose_name='language'), + model_name="user", + name="language", + field=models.CharField( + choices=[ + ("cs", "\u010de\u0161tina"), + ("de", "deutsch"), + ("en", "english"), + ("el_GR", "\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"), + ("es", "espa\xf1ol"), + ("fr", "fran\xe7ais"), + ("it", "italiano"), + ("ja_JP", "\u65e5\u672c\u306e"), + ("nl", "nederlands"), + ("pt_PT", "portugu\xeas"), + ("pt_BR", "portugu\xeas (BR)"), + ("pl_PL", "polski"), + ("ro_RO", "Rom\xe2n\u0103"), + ("ru", "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"), + ("sv", "svenska"), + ("zh_TW", "\u4e2d\u6587\uff08\u53f0\u7063\uff09"), + ], + default="en", + help_text="Prefered language to display pages.", + max_length=10, + verbose_name="language", + ), ), ] diff --git a/modoboa/core/migrations/0017_auto_20190705_1045.py b/modoboa/core/migrations/0017_auto_20190705_1045.py index 530abdd41..676789195 100644 --- a/modoboa/core/migrations/0017_auto_20190705_1045.py +++ b/modoboa/core/migrations/0017_auto_20190705_1045.py @@ -5,18 +5,43 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0016_auto_20180713_1014'), + ("core", "0016_auto_20180713_1014"), ] operations = [ migrations.AlterField( - model_name='log', - name='message', + model_name="log", + name="message", field=models.TextField(), ), migrations.AlterField( - model_name='user', - name='language', - field=models.CharField(choices=[('br', 'breton'), ('cs', 'čeština'), ('de', 'deutsch'), ('en', 'english'), ('el_GR', 'ελληνικά'), ('es', 'español'), ('fr', 'français'), ('it', 'italiano'), ('ja_JP', '日本の'), ('nl', 'nederlands'), ('pt_PT', 'português'), ('pt_BR', 'português (BR)'), ('pl_PL', 'polski'), ('ro_RO', 'Română'), ('ru', 'русский'), ('sv', 'svenska'), ('tr_TR', 'türk'), ('zh_TW', '中文(台灣)')], default='en', help_text='Prefered language to display pages.', max_length=10, verbose_name='language'), + model_name="user", + name="language", + field=models.CharField( + choices=[ + ("br", "breton"), + ("cs", "čeština"), + ("de", "deutsch"), + ("en", "english"), + ("el_GR", "ελληνικά"), + ("es", "español"), + ("fr", "français"), + ("it", "italiano"), + ("ja_JP", "日本の"), + ("nl", "nederlands"), + ("pt_PT", "português"), + ("pt_BR", "português (BR)"), + ("pl_PL", "polski"), + ("ro_RO", "Română"), + ("ru", "русский"), + ("sv", "svenska"), + ("tr_TR", "türk"), + ("zh_TW", "中文(台灣)"), + ], + default="en", + help_text="Prefered language to display pages.", + max_length=10, + verbose_name="language", + ), ), ] diff --git a/modoboa/core/migrations/0018_auto_20200104_1714.py b/modoboa/core/migrations/0018_auto_20200104_1714.py index c2789e28f..5ced6ee8e 100644 --- a/modoboa/core/migrations/0018_auto_20200104_1714.py +++ b/modoboa/core/migrations/0018_auto_20200104_1714.py @@ -6,13 +6,15 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0017_auto_20190705_1045'), + ("core", "0017_auto_20190705_1045"), ] operations = [ migrations.AlterField( - model_name='user', - name='last_name', - field=models.CharField(blank=True, max_length=150, verbose_name='last name'), + model_name="user", + name="last_name", + field=models.CharField( + blank=True, max_length=150, verbose_name="last name" + ), ), ] diff --git a/modoboa/core/migrations/0019_auto_20200121_1659.py b/modoboa/core/migrations/0019_auto_20200121_1659.py index 131a4b231..43d364469 100644 --- a/modoboa/core/migrations/0019_auto_20200121_1659.py +++ b/modoboa/core/migrations/0019_auto_20200121_1659.py @@ -8,20 +8,28 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0018_auto_20200104_1714'), + ("core", "0018_auto_20200104_1714"), ] operations = [ migrations.CreateModel( - name='ExtensionUpdateHistory', + name="ExtensionUpdateHistory", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extension', models.CharField(max_length=100)), - ('version', models.CharField(max_length=30)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("extension", models.CharField(max_length=100)), + ("version", models.CharField(max_length=30)), ], ), migrations.AlterUniqueTogether( - name='extensionupdatehistory', - unique_together=set([('extension', 'version')]), + name="extensionupdatehistory", + unique_together=set([("extension", "version")]), ), ] diff --git a/modoboa/core/migrations/0020_auto_20200421_0851.py b/modoboa/core/migrations/0020_auto_20200421_0851.py index 1acbe11be..4def6021c 100644 --- a/modoboa/core/migrations/0020_auto_20200421_0851.py +++ b/modoboa/core/migrations/0020_auto_20200421_0851.py @@ -7,13 +7,19 @@ import phonenumber_field.modelfields class Migration(migrations.Migration): dependencies = [ - ('core', '0019_auto_20200121_1659'), + ("core", "0019_auto_20200121_1659"), ] operations = [ migrations.AlterField( - model_name='user', - name='phone_number', - field=phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, null=True, region=None, verbose_name='Phone number'), + model_name="user", + name="phone_number", + field=phonenumber_field.modelfields.PhoneNumberField( + blank=True, + max_length=128, + null=True, + region=None, + verbose_name="Phone number", + ), ), ] diff --git a/modoboa/core/migrations/0021_localconfig_need_dovecot_update.py b/modoboa/core/migrations/0021_localconfig_need_dovecot_update.py index 152e07e71..e43629aa0 100644 --- a/modoboa/core/migrations/0021_localconfig_need_dovecot_update.py +++ b/modoboa/core/migrations/0021_localconfig_need_dovecot_update.py @@ -6,13 +6,13 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0020_auto_20200421_0851'), + ("core", "0020_auto_20200421_0851"), ] operations = [ migrations.AddField( - model_name='localconfig', - name='need_dovecot_update', + model_name="localconfig", + name="need_dovecot_update", field=models.BooleanField(default=False), ), ] diff --git a/modoboa/core/migrations/0022_user_tfa_enabled.py b/modoboa/core/migrations/0022_user_tfa_enabled.py index c97496498..484f73cc4 100644 --- a/modoboa/core/migrations/0022_user_tfa_enabled.py +++ b/modoboa/core/migrations/0022_user_tfa_enabled.py @@ -6,13 +6,13 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0021_localconfig_need_dovecot_update'), + ("core", "0021_localconfig_need_dovecot_update"), ] operations = [ migrations.AddField( - model_name='user', - name='tfa_enabled', + model_name="user", + name="tfa_enabled", field=models.BooleanField(default=False), ), ] diff --git a/modoboa/core/migrations/0023_auto_20221012_0911.py b/modoboa/core/migrations/0023_auto_20221012_0911.py index 65a4d6699..bd92c1f80 100644 --- a/modoboa/core/migrations/0023_auto_20221012_0911.py +++ b/modoboa/core/migrations/0023_auto_20221012_0911.py @@ -6,18 +6,45 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0022_user_tfa_enabled'), + ("core", "0022_user_tfa_enabled"), ] operations = [ migrations.AlterField( - model_name='user', - name='first_name', - field=models.CharField(blank=True, max_length=150, verbose_name='first name'), + model_name="user", + name="first_name", + field=models.CharField( + blank=True, max_length=150, verbose_name="first name" + ), ), migrations.AlterField( - model_name='user', - name='language', - field=models.CharField(choices=[('br', 'breton'), ('cs', 'čeština'), ('de', 'deutsch'), ('en', 'english'), ('el', 'ελληνικά'), ('es', 'español'), ('fr', 'français'), ('it', 'italiano'), ('ja', '日本の'), ('nl', 'nederlands'), ('pt', 'português'), ('pt-br', 'português (BR)'), ('pl', 'polski'), ('ro', 'Română'), ('ru', 'русский'), ('sv', 'svenska'), ('tr', 'türk'), ('zh-hant', '中文(台灣)')], default='en', help_text='Prefered language to display pages.', max_length=10, verbose_name='language'), + model_name="user", + name="language", + field=models.CharField( + choices=[ + ("br", "breton"), + ("cs", "čeština"), + ("de", "deutsch"), + ("en", "english"), + ("el", "ελληνικά"), + ("es", "español"), + ("fr", "français"), + ("it", "italiano"), + ("ja", "日本の"), + ("nl", "nederlands"), + ("pt", "português"), + ("pt-br", "português (BR)"), + ("pl", "polski"), + ("ro", "Română"), + ("ru", "русский"), + ("sv", "svenska"), + ("tr", "türk"), + ("zh-hant", "中文(台灣)"), + ], + default="en", + help_text="Prefered language to display pages.", + max_length=10, + verbose_name="language", + ), ), ] diff --git a/modoboa/core/migrations/0024_alter_user_language.py b/modoboa/core/migrations/0024_alter_user_language.py index f4034db2d..a46a37daa 100644 --- a/modoboa/core/migrations/0024_alter_user_language.py +++ b/modoboa/core/migrations/0024_alter_user_language.py @@ -6,13 +6,39 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0023_auto_20221012_0911'), + ("core", "0023_auto_20221012_0911"), ] operations = [ migrations.AlterField( - model_name='user', - name='language', - field=models.CharField(choices=[('br', 'breton'), ('cs', 'čeština'), ('de', 'deutsch'), ('en', 'english'), ('el', 'ελληνικά'), ('es', 'español'), ('fi', 'Suomalainen'), ('fr', 'français'), ('it', 'italiano'), ('ja', '日本の'), ('nl', 'nederlands'), ('pt', 'português'), ('pt-br', 'português (BR)'), ('pl', 'polski'), ('ro', 'Română'), ('ru', 'русский'), ('sv', 'svenska'), ('tr', 'türk'), ('zh-hant', '中文(台灣)')], default='en', help_text='Prefered language to display pages.', max_length=10, verbose_name='language'), + model_name="user", + name="language", + field=models.CharField( + choices=[ + ("br", "breton"), + ("cs", "čeština"), + ("de", "deutsch"), + ("en", "english"), + ("el", "ελληνικά"), + ("es", "español"), + ("fi", "Suomalainen"), + ("fr", "français"), + ("it", "italiano"), + ("ja", "日本の"), + ("nl", "nederlands"), + ("pt", "português"), + ("pt-br", "português (BR)"), + ("pl", "polski"), + ("ro", "Română"), + ("ru", "русский"), + ("sv", "svenska"), + ("tr", "türk"), + ("zh-hant", "中文(台灣)"), + ], + default="en", + help_text="Prefered language to display pages.", + max_length=10, + verbose_name="language", + ), ), ] diff --git a/modoboa/core/migrations/0026_alter_localconfig__parameters_and_more.py b/modoboa/core/migrations/0026_alter_localconfig__parameters_and_more.py index f3ad50026..aed150f30 100644 --- a/modoboa/core/migrations/0026_alter_localconfig__parameters_and_more.py +++ b/modoboa/core/migrations/0026_alter_localconfig__parameters_and_more.py @@ -7,43 +7,49 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0025_rename_user_email_is_active_core_user_email_c0c03f_idx'), + ("core", "0025_rename_user_email_is_active_core_user_email_c0c03f_idx"), ] operations = [ migrations.AlterField( - model_name='localconfig', - name='_parameters', + model_name="localconfig", + name="_parameters", field=models.JSONField(default=dict), ), migrations.AlterField( - model_name='localconfig', - name='api_versions', + model_name="localconfig", + name="api_versions", field=models.JSONField(), ), migrations.AlterField( - model_name='user', - name='_parameters', + model_name="user", + name="_parameters", field=models.JSONField(default=dict), ), migrations.AlterField( - model_name='localconfig', - name='api_versions', + model_name="localconfig", + name="api_versions", field=models.JSONField(default=dict), ), migrations.AlterField( - model_name='localconfig', - name='_parameters', - field=models.JSONField(default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder), + model_name="localconfig", + name="_parameters", + field=models.JSONField( + default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder + ), ), migrations.AlterField( - model_name='localconfig', - name='api_versions', - field=models.JSONField(default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder), + model_name="localconfig", + name="api_versions", + field=models.JSONField( + default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder + ), ), migrations.AlterField( - model_name='user', - name='_parameters', - field=models.JSONField(default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder), + model_name="user", + name="_parameters", + field=models.JSONField( + default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder + ), ), ] diff --git a/modoboa/core/mocks.py b/modoboa/core/mocks.py index 6cc508470..eaf276d36 100644 --- a/modoboa/core/mocks.py +++ b/modoboa/core/mocks.py @@ -6,48 +6,42 @@ import httmock @httmock.urlmatch( - netloc=r"api\.modoboa\.org$", path=r"^/1/instances/search/", method="post") + netloc=r"api\.modoboa\.org$", path=r"^/1/instances/search/", method="post" +) def modo_api_instance_search(url, request): """Return empty response.""" return {"status_code": 404} -@httmock.urlmatch( - netloc=r"api\.modoboa\.org$", path=r"^/1/instances/", method="post") +@httmock.urlmatch(netloc=r"api\.modoboa\.org$", path=r"^/1/instances/", method="post") def modo_api_instance_create(url, request): """Simulate successful creation.""" - return { - "status_code": 201, - "content": {"pk": 100} - } + return {"status_code": 201, "content": {"pk": 100}} -@httmock.urlmatch( - netloc=r"api\.modoboa\.org$", path=r"^/1/instances/.+/", method="put") +@httmock.urlmatch(netloc=r"api\.modoboa\.org$", path=r"^/1/instances/.+/", method="put") def modo_api_instance_update(url, request): """Simulate successful update.""" return {"status_code": 200} -@httmock.urlmatch( - netloc=r"api\.modoboa\.org$", path=r"^/1/versions/", method="get") +@httmock.urlmatch(netloc=r"api\.modoboa\.org$", path=r"^/1/versions/", method="get") def modo_api_versions(url, request): """Simulate versions check.""" return { "status_code": 200, "content": [ {"name": "modoboa", "version": "9.0.0", "url": ""}, - ] + ], } -@httmock.urlmatch( - netloc=r"api\.modoboa\.org$", path=r"^/1/versions/", method="get") +@httmock.urlmatch(netloc=r"api\.modoboa\.org$", path=r"^/1/versions/", method="get") def modo_api_versions_no_update(url, request): """Simulate versions check.""" return { "status_code": 200, "content": [ {"name": "modoboa", "version": "0.0.0", "url": ""}, - ] + ], } diff --git a/modoboa/core/models.py b/modoboa/core/models.py index 5b86c2d6d..6aa8466f2 100644 --- a/modoboa/core/models.py +++ b/modoboa/core/models.py @@ -20,20 +20,23 @@ from reversion import revisions as reversion from modoboa.core.password_hashers import get_password_hasher from modoboa.lib.exceptions import ( - BadRequest, Conflict, InternalError, PermDeniedException + BadRequest, + Conflict, + InternalError, + PermDeniedException, ) from modoboa.parameters import tools as param_tools from . import constants, signals try: from modoboa.lib.ldap_utils import LDAPAuthBackend + ldap_available = True except ImportError: ldap_available = False class User(AbstractUser): - """Custom User model. It overloads the way passwords are stored into the database. The @@ -49,27 +52,28 @@ class User(AbstractUser): is_active = models.BooleanField(default=True, db_index=True) is_local = models.BooleanField(default=True, db_index=True) master_user = models.BooleanField( - gettext_lazy("Allow mailboxes access"), default=False, - help_text=gettext_lazy( - "Allow this administrator to access user mailboxes" - ) + gettext_lazy("Allow mailboxes access"), + default=False, + help_text=gettext_lazy("Allow this administrator to access user mailboxes"), ) password = models.CharField(gettext_lazy("password"), max_length=256) language = models.CharField( gettext_lazy("language"), - max_length=10, default="en", choices=constants.LANGUAGES, - help_text=gettext_lazy( - "Prefered language to display pages." - ) + max_length=10, + default="en", + choices=constants.LANGUAGES, + help_text=gettext_lazy("Prefered language to display pages."), ) - phone_number = PhoneNumberField( - gettext_lazy("Phone number"), blank=True, null=True) + phone_number = PhoneNumberField(gettext_lazy("Phone number"), blank=True, null=True) secondary_email = models.EmailField( - gettext_lazy("Secondary email"), max_length=254, - blank=True, null=True, + gettext_lazy("Secondary email"), + max_length=254, + blank=True, + null=True, help_text=gettext_lazy( - "An alternative e-mail address, can be used for recovery needs.") + "An alternative e-mail address, can be used for recovery needs." + ), ) tfa_enabled = models.BooleanField(default=False) @@ -80,7 +84,7 @@ class User(AbstractUser): ordering = ["username"] indexes = [models.Index(fields=["email", "is_active"])] - password_expr = re.compile(r'\{([\w\-]+)\}(.+)') + password_expr = re.compile(r"\{([\w\-]+)\}(.+)") def __init__(self, *args, **kwargs): """Load parameter manager.""" @@ -96,12 +100,15 @@ class User(AbstractUser): """ scheme = param_tools.get_global_parameter( - "password_scheme", raise_exception=False) + "password_scheme", raise_exception=False + ) if scheme is None: from modoboa.core.apps import load_core_settings + load_core_settings() scheme = param_tools.get_global_parameter( - "password_scheme", raise_exception=False) + "password_scheme", raise_exception=False + ) raw_value = smart_bytes(raw_value) return get_password_hasher(scheme.upper())().encrypt(raw_value) @@ -123,12 +130,13 @@ class User(AbstractUser): raise InternalError( _("Failed to update password: LDAP module not installed") ) - LDAPAuthBackend().update_user_password( - self.username, curvalue, raw_value - ) + LDAPAuthBackend().update_user_password(self.username, curvalue, raw_value) signals.account_password_updated.send( sender=self.__class__, - account=self, password=raw_value, created=self.pk is None) + account=self, + password=raw_value, + created=self.pk is None, + ) def check_password(self, raw_value): """Compare raw_value to current password.""" @@ -154,9 +162,10 @@ class User(AbstractUser): @property def tags(self): - return [{"name": "account", "label": _("account"), "type": "idt"}, - {"name": self.role, "label": self.role, - "type": "grp", "color": "info"}] + return [ + {"name": "account", "label": _("account"), "type": "idt"}, + {"name": self.role, "label": self.role, "type": "grp", "color": "info"}, + ] @property def fullname(self): @@ -187,7 +196,8 @@ class User(AbstractUser): def encoded_address(self): if self.first_name != "" or self.last_name != "": return '"{}" <{}>'.format( - Header(self.fullname, "utf8").encode(), self.email) + Header(self.fullname, "utf8").encode(), self.email + ) return self.email def is_owner(self, obj): @@ -198,8 +208,7 @@ class User(AbstractUser): """ ct = ContentType.objects.get_for_model(obj) try: - ooentry = self.objectaccess_set.get( - content_type=ct, object_id=obj.id) + ooentry = self.objectaccess_set.get(content_type=ct, object_id=obj.id) except ObjectAccess.DoesNotExist: return False return ooentry.is_owner @@ -220,8 +229,7 @@ class User(AbstractUser): ct = ContentType.objects.get_for_model(obj) try: - ooentry = self.objectaccess_set.get( - content_type=ct, object_id=obj.id) + ooentry = self.objectaccess_set.get(content_type=ct, object_id=obj.id) except ObjectAccess.DoesNotExist: pass else: @@ -258,7 +266,8 @@ class User(AbstractUser): if role is None or self.role == role: return signals.account_role_changed.send( - sender=self.__class__, account=self, role=role) + sender=self.__class__, account=self, role=role + ) self.groups.clear() if role == "SuperAdmins": self.is_superuser = True @@ -272,6 +281,7 @@ class User(AbstractUser): self.groups.add(Group.objects.get(name="SimpleUsers")) if role != "SimpleUsers" and not self.can_access(self): from modoboa.lib.permissions import grant_access_to_object + grant_access_to_object(self, self) self.save() self._role = role @@ -291,6 +301,7 @@ class User(AbstractUser): def post_create(self, creator): """Grant permission on this user to creator.""" from modoboa.lib.permissions import grant_access_to_object + grant_access_to_object(creator, self, is_owner=True) def save(self, *args, **kwargs): @@ -322,10 +333,9 @@ class User(AbstractUser): allowed_roles = get_account_roles(user) allowed_roles = [role[0] for role in allowed_roles] if desired_role not in allowed_roles: - raise PermDeniedException(_( - "You can't import an account with a role greater than " - "yours" - )) + raise PermDeniedException( + _("You can't import an account with a role greater than " "yours") + ) self.username = row[1].strip().lower() try: @@ -338,13 +348,17 @@ class User(AbstractUser): if desired_role == "SimpleUsers": if len(row) < 8 or not row[7].strip(): raise BadRequest( - _("The simple user '%s' must have a valid email address" - % self.username) + _( + "The simple user '%s' must have a valid email address" + % self.username + ) ) if self.username != row[7].strip(): raise BadRequest( - _("username and email fields must not differ for '%s'" - % self.username) + _( + "username and email fields must not differ for '%s'" + % self.username + ) ) if crypt_password: @@ -353,7 +367,7 @@ class User(AbstractUser): self.password = row[2].strip() self.first_name = row[3].strip() self.last_name = row[4].strip() - self.is_active = (row[5].strip().lower() in ["true", "1", "yes", "y"]) + self.is_active = row[5].strip().lower() in ["true", "1", "yes", "y"] self.language = settings.LANGUAGE_CODE self.save() self.role = desired_role @@ -361,7 +375,8 @@ class User(AbstractUser): if len(row) < 8: return signals.account_imported.send( - sender=self.__class__, user=user, account=self, row=row[7:]) + sender=self.__class__, user=user, account=self, row=row[7:] + ) def to_csv_row(self): """Return row that can be included in a CSV file.""" @@ -373,10 +388,9 @@ class User(AbstractUser): smart_str(self.last_name), smart_str(self.is_active), smart_str(self.role), - smart_str(self.email) + smart_str(self.email), ] - results = signals.account_exported.send( - sender=self.__class__, user=self) + results = signals.account_exported.send(sender=self.__class__, user=self) for result in results: row += result[1] return row @@ -411,8 +425,7 @@ def populate_callback(user, group="SimpleUsers"): user.post_create(sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, user) - signals.account_auto_created.send( - sender="populate_callback", user=user) + signals.account_auto_created.send(sender="populate_callback", user=user) class ObjectAccess(models.Model): @@ -426,9 +439,7 @@ class ObjectAccess(models.Model): unique_together = (("user", "content_type", "object_id"),) def __str__(self): - return "%s => %s (%s)" % ( - self.user, self.content_object, self.content_type - ) + return "%s => %s (%s)" % (self.user, self.content_object, self.content_type) class Log(models.Model): diff --git a/modoboa/core/password_hashers/__init__.py b/modoboa/core/password_hashers/__init__.py index a0e29dda8..5bc8bd086 100644 --- a/modoboa/core/password_hashers/__init__.py +++ b/modoboa/core/password_hashers/__init__.py @@ -3,11 +3,19 @@ Password hashers for Modoboa. """ from modoboa.core.password_hashers.advanced import ( # NOQA:F401 - BLFCRYPTHasher, MD5CRYPTHasher, SHA256CRYPTHasher, SHA512CRYPTHasher, - ARGON2IDHasher, SSHAHasher + BLFCRYPTHasher, + MD5CRYPTHasher, + SHA256CRYPTHasher, + SHA512CRYPTHasher, + ARGON2IDHasher, + SSHAHasher, ) from modoboa.core.password_hashers.base import ( # NOQA:F401 - CRYPTHasher, MD5Hasher, PLAINHasher, SHA256Hasher, PasswordHasher + CRYPTHasher, + MD5Hasher, + PLAINHasher, + SHA256Hasher, + PasswordHasher, ) diff --git a/modoboa/core/password_hashers/advanced.py b/modoboa/core/password_hashers/advanced.py index 721c54f6f..8b44d0367 100644 --- a/modoboa/core/password_hashers/advanced.py +++ b/modoboa/core/password_hashers/advanced.py @@ -52,6 +52,7 @@ class MD5CRYPTHasher(PasswordHasher): This scheme can't be considered as secure anymore. """ + _weak = True @property @@ -117,6 +118,7 @@ class SSHAHasher(PasswordHasher): """ Salted SHA1 password hasher. """ + _weak = True @property @@ -129,10 +131,11 @@ class SSHAHasher(PasswordHasher): def verify(self, clearvalue, hashed_value): # We have to add the scheme for the hashed_value to be validated - return ldap_salted_sha1.verify(clearvalue, f'{{SSHA}}{hashed_value}') + return ldap_salted_sha1.verify(clearvalue, f"{{SSHA}}{hashed_value}") if argon2_hasher is not None: + class ARGON2IDHasher(PasswordHasher): """ argon2 password hasher. @@ -142,7 +145,9 @@ if argon2_hasher is not None: but can only be used with dovecot >= 2.3 and libsodium >= 1.0.13 """ - def __init__(self,): + def __init__( + self, + ): super(ARGON2IDHasher, self).__init__() parameters = dict() @@ -175,9 +180,9 @@ if argon2_hasher is not None: return False def needs_rehash(self, hashed_value): - return self.hasher.check_needs_rehash( - hashed_value.strip(self.scheme) - ) + return self.hasher.check_needs_rehash(hashed_value.strip(self.scheme)) + else: + class ARGON2IDHasher: pass diff --git a/modoboa/core/password_hashers/base.py b/modoboa/core/password_hashers/base.py index 2b2bba139..0d355ac63 100644 --- a/modoboa/core/password_hashers/base.py +++ b/modoboa/core/password_hashers/base.py @@ -19,10 +19,11 @@ class MetaHasher(type): PasswordHasher Metaclass Allow classmethod to be properties """ + @property def name(cls): """Returns the name of the hasher""" - return cls.__name__.rstrip('Hasher').lower() + return cls.__name__.rstrip("Hasher").lower() @property def label(cls): @@ -34,6 +35,7 @@ class PasswordHasher(metaclass=MetaHasher): """ Base class of all hashers. """ + _weak = False def __init__(self, target="local"): @@ -76,8 +78,7 @@ class PasswordHasher(metaclass=MetaHasher): :return: True if passwords match, False otherwise """ return constant_time_compare( - self._b64encode(self._encrypt(clearvalue, hashed_value)), - hashed_value + self._b64encode(self._encrypt(clearvalue, hashed_value)), hashed_value ) def needs_rehash(self, hashed_value): @@ -100,6 +101,7 @@ class PLAINHasher(PasswordHasher): """ Plain (ie. clear) password hasher. """ + _weak = True @property @@ -116,6 +118,7 @@ class CRYPTHasher(PasswordHasher): Uses python `crypt` standard module. """ + _weak = True @property @@ -124,13 +127,7 @@ class CRYPTHasher(PasswordHasher): def _encrypt(self, clearvalue, salt=None): if salt is None: - salt = "".join( - Random().sample( - string.ascii_letters + - string.digits, - 2 - ) - ) + salt = "".join(Random().sample(string.ascii_letters + string.digits, 2)) return crypt.crypt(clearvalue, salt) @@ -140,6 +137,7 @@ class MD5Hasher(PasswordHasher): Uses python `hashlib` standard module. """ + _weak = True @property @@ -157,6 +155,7 @@ class SHA256Hasher(PasswordHasher): Uses python `hashlib` and `base64` standard modules. """ + _weak = True @property diff --git a/modoboa/core/password_hashers/utils.py b/modoboa/core/password_hashers/utils.py index 356c77823..25b1155b4 100644 --- a/modoboa/core/password_hashers/utils.py +++ b/modoboa/core/password_hashers/utils.py @@ -42,12 +42,10 @@ def get_dovecot_schemes(): status = 0 # Manage alarms if needed - doveadm_alarms = Alarm.objects.filter( - internal_name=DOVEADM_PASS_SCHEME_ALARM) + doveadm_alarms = Alarm.objects.filter(internal_name=DOVEADM_PASS_SCHEME_ALARM) doveadm_alarm = doveadm_alarms.first() if status == 0: - condition = (doveadm_alarm is not None and - doveadm_alarm.status == ALARM_OPENED) + condition = doveadm_alarm is not None and doveadm_alarm.status == ALARM_OPENED if condition: doveadm_alarm.close() elif status == 2: @@ -57,21 +55,19 @@ def get_dovecot_schemes(): else: Alarm.objects.create( title="Failed to retrieve available dovecot schemes", - internal_name=DOVEADM_PASS_SCHEME_ALARM) + internal_name=DOVEADM_PASS_SCHEME_ALARM, + ) - return ["{{{}}}".format(smart_str(scheme)) - for scheme in schemes.split()], status + return ["{{{}}}".format(smart_str(scheme)) for scheme in schemes.split()], status def cache_available_password_hasher(bypass_cache=False): available_schemes, status = get_dovecot_schemes() password_scheme_choice = [ - (hasher.name, hasher.label) - for hasher in PasswordHasher.get_password_hashers() - if hasher().scheme in available_schemes - ] + (hasher.name, hasher.label) + for hasher in PasswordHasher.get_password_hashers() + if hasher().scheme in available_schemes + ] if status == 0 and not bypass_cache: - cache.set("password_scheme_choice", - password_scheme_choice, - 2592000) + cache.set("password_scheme_choice", password_scheme_choice, 2592000) return password_scheme_choice diff --git a/modoboa/core/password_validation.py b/modoboa/core/password_validation.py index 47522897d..e21fc3f06 100644 --- a/modoboa/core/password_validation.py +++ b/modoboa/core/password_validation.py @@ -16,51 +16,56 @@ class ComplexityValidator(object): def validate(self, password, user=None): special_characters = "~!@#$%^&*()_+{}\":;,'[]" condition = ( - self.digits > 0 and - sum(1 for char in password if char.isdigit()) < self.digits) + self.digits > 0 + and sum(1 for char in password if char.isdigit()) < self.digits + ) if condition: raise ValidationError( ngettext( "Password must contain at least {} digit.", "Password must contain at least {} digits.", - self.digits - ).format(self.digits)) + self.digits, + ).format(self.digits) + ) condition = ( - self.lower > 0 and - sum(1 for char in password if char.islower()) < self.lower) + self.lower > 0 + and sum(1 for char in password if char.islower()) < self.lower + ) if condition: raise ValidationError( ngettext( "Password must contain at least {} lowercase letter.", "Password must contain at least {} lowercase letters.", - self.lower - ) - .format(self.lower)) + self.lower, + ).format(self.lower) + ) condition = ( - self.upper > 0 and - sum(1 for char in password if char.isupper()) < self.upper) + self.upper > 0 + and sum(1 for char in password if char.isupper()) < self.upper + ) if condition: raise ValidationError( ngettext( "Password must contain at least {} uppercase letter.", "Password must contain at least {} uppercase letters.", - self.upper - ) - .format(self.upper)) + self.upper, + ).format(self.upper) + ) condition = ( - self.specials > 0 and - sum(1 for char in password if char in special_characters) < - self.specials) + self.specials > 0 + and sum(1 for char in password if char in special_characters) + < self.specials + ) if condition: raise ValidationError( ngettext( "Password must contain at least {} special character.", "Password must contain at least {} special characters.", - self.specials - ) - .format(self.specials)) + self.specials, + ).format(self.specials) + ) def get_help_text(self): return _( - "Your password must contain a combination of different " - "character types.") + "Your password must contain a combination of different " "character types." + ) diff --git a/modoboa/core/signals.py b/modoboa/core/signals.py index 05107d396..ca5118f35 100644 --- a/modoboa/core/signals.py +++ b/modoboa/core/signals.py @@ -2,25 +2,27 @@ import django.dispatch -account_auto_created = django.dispatch.Signal() # Provides user -account_exported = django.dispatch.Signal() # Provides account -account_imported = django.dispatch.Signal() # Provides user, account, row -account_deleted = django.dispatch.Signal() # Provides user -account_role_changed = django.dispatch.Signal() # Provides account, role -account_password_updated = django.dispatch.Signal() # Provides account password created -allow_password_change = django.dispatch.Signal() # Provides user -can_create_object = django.dispatch.Signal() # Provides context, klass, object_type, count, instance -extra_account_actions = django.dispatch.Signal() # Provides account -extra_admin_dashboard_widgets = django.dispatch.Signal() # Provides user -extra_admin_menu_entries = django.dispatch.Signal() # Provides location, user -extra_role_permissions = django.dispatch.Signal() # Provides role -extra_static_content = django.dispatch.Signal() # Provides caller, st_type, user +account_auto_created = django.dispatch.Signal() # Provides user +account_exported = django.dispatch.Signal() # Provides account +account_imported = django.dispatch.Signal() # Provides user, account, row +account_deleted = django.dispatch.Signal() # Provides user +account_role_changed = django.dispatch.Signal() # Provides account, role +account_password_updated = django.dispatch.Signal() # Provides account password created +allow_password_change = django.dispatch.Signal() # Provides user +can_create_object = ( + django.dispatch.Signal() +) # Provides context, klass, object_type, count, instance +extra_account_actions = django.dispatch.Signal() # Provides account +extra_admin_dashboard_widgets = django.dispatch.Signal() # Provides user +extra_admin_menu_entries = django.dispatch.Signal() # Provides location, user +extra_role_permissions = django.dispatch.Signal() # Provides role +extra_static_content = django.dispatch.Signal() # Provides caller, st_type, user extra_uprefs_routes = django.dispatch.Signal() -extra_user_menu_entries = django.dispatch.Signal() # Provides location, user -get_announcements = django.dispatch.Signal() # Provides location -get_top_notifications = django.dispatch.Signal() # Provides include_all -initial_data_loaded = django.dispatch.Signal() # Provides extname +extra_user_menu_entries = django.dispatch.Signal() # Provides location, user +get_announcements = django.dispatch.Signal() # Provides location +get_top_notifications = django.dispatch.Signal() # Provides include_all +initial_data_loaded = django.dispatch.Signal() # Provides extname register_postfix_maps = django.dispatch.Signal() -user_can_set_role = django.dispatch.Signal() # Provides user, role, account -user_login = django.dispatch.Signal() # Provides username, password +user_can_set_role = django.dispatch.Signal() # Provides user, role, account +user_login = django.dispatch.Signal() # Provides username, password user_logout = django.dispatch.Signal() diff --git a/modoboa/core/sms_backends/__init__.py b/modoboa/core/sms_backends/__init__.py index 9ac1ee8a1..f3abe9648 100644 --- a/modoboa/core/sms_backends/__init__.py +++ b/modoboa/core/sms_backends/__init__.py @@ -24,11 +24,9 @@ class SMSBackend: def get_backend_class(name): """Return class for given backend.""" - backend_module = import_module( - "modoboa.core.sms_backends.{}".format(name)) + backend_module = import_module("modoboa.core.sms_backends.{}".format(name)) try: - backend_class = getattr( - backend_module, "{}Backend".format(name.upper())) + backend_class = getattr(backend_module, "{}Backend".format(name.upper())) except AttributeError: return None else: diff --git a/modoboa/core/sms_backends/ovh.py b/modoboa/core/sms_backends/ovh.py index ae86a9d7b..a1c260ebe 100644 --- a/modoboa/core/sms_backends/ovh.py +++ b/modoboa/core/sms_backends/ovh.py @@ -28,32 +28,29 @@ class OVHBackend(SMSBackend): ("soyoustart-ca", _("So you Start North America")), ("kimsufi-eu", _("Kimsufi Europe")), ("kimsufi-ca", _("Kimsufi North America")), - ) - } + ), + }, }, "sms_ovh_application_key": { "type": forms.CharField, - "attrs": { - "label": _("Application key"), - "required": False - } + "attrs": {"label": _("Application key"), "required": False}, }, "sms_ovh_application_secret": { "type": forms.CharField, "attrs": { "label": _("Application secret"), "widget": forms.widgets.PasswordInput(render_value=True), - "required": False - } + "required": False, + }, }, "sms_ovh_consumer_key": { "type": forms.CharField, "attrs": { "label": _("Consumer key"), "widget": forms.widgets.PasswordInput(render_value=True), - "required": False - } - } + "required": False, + }, + }, } serializer_settings = { @@ -69,8 +66,8 @@ class OVHBackend(SMSBackend): ("soyoustart-ca", _("So you Start North America")), ("kimsufi-eu", _("Kimsufi Europe")), ("kimsufi-ca", _("Kimsufi North America")), - ) - } + ), + }, }, "sms_ovh_application_key": { "type": serializers.CharField, @@ -78,7 +75,7 @@ class OVHBackend(SMSBackend): "required": False, "allow_blank": True, "allow_null": True, - } + }, }, "sms_ovh_application_secret": { "type": serializers.CharField, @@ -86,7 +83,7 @@ class OVHBackend(SMSBackend): "required": False, "allow_blank": True, "allow_null": True, - } + }, }, "sms_ovh_consumer_key": { "type": serializers.CharField, @@ -94,36 +91,48 @@ class OVHBackend(SMSBackend): "required": False, "allow_blank": True, "allow_null": True, - } - } + }, + }, } structure = [ - ("sms_ovh_endpoint", { - "label": _("API endpoint"), - "display": "sms_password_recovery=true&sms_provider=ovh", - }), - ("sms_ovh_application_key", { - "label": _("Application key"), - "display": "sms_password_recovery=true&sms_provider=ovh" - }), - ("sms_ovh_application_secret", { - "label": _("Appication secret"), - "display": "sms_password_recovery=true&sms_provider=ovh", - "password": True - }), - ("sms_ovh_consumer_key", { - "label": _("Consumer key"), - "display": "sms_password_recovery=true&sms_provider=ovh", - "password": True - }), + ( + "sms_ovh_endpoint", + { + "label": _("API endpoint"), + "display": "sms_password_recovery=true&sms_provider=ovh", + }, + ), + ( + "sms_ovh_application_key", + { + "label": _("Application key"), + "display": "sms_password_recovery=true&sms_provider=ovh", + }, + ), + ( + "sms_ovh_application_secret", + { + "label": _("Appication secret"), + "display": "sms_password_recovery=true&sms_provider=ovh", + "password": True, + }, + ), + ( + "sms_ovh_consumer_key", + { + "label": _("Consumer key"), + "display": "sms_password_recovery=true&sms_provider=ovh", + "password": True, + }, + ), ] visibility_rules = { "sms_ovh_endpoint": "sms_provider=ovh", "sms_ovh_application_key": "sms_provider=ovh", "sms_ovh_application_secret": "sms_provider=ovh", - "sms_ovh_consumer_key": "sms_provider=ovh" + "sms_ovh_consumer_key": "sms_provider=ovh", } @cached_property @@ -132,7 +141,7 @@ class OVHBackend(SMSBackend): endpoint=self._params.get_value("sms_ovh_endpoint"), application_key=self._params.get_value("sms_ovh_application_key"), application_secret=self._params.get_value("sms_ovh_application_secret"), - consumer_key=self._params.get_value("sms_ovh_consumer_key") + consumer_key=self._params.get_value("sms_ovh_consumer_key"), ) def send(self, text, recipients): @@ -144,7 +153,7 @@ class OVHBackend(SMSBackend): receivers=recipients, priority="high", noStopClause=True, - senderForResponse=True + senderForResponse=True, ) if result["totalCreditsRemoved"] != len(recipients): return False diff --git a/modoboa/core/templatetags/core_tags.py b/modoboa/core/templatetags/core_tags.py index f8820e6ca..859996d0d 100644 --- a/modoboa/core/templatetags/core_tags.py +++ b/modoboa/core/templatetags/core_tags.py @@ -26,126 +26,149 @@ register = template.Library() def core_menu(selection, user): """Build the top level menu.""" entries = signals.extra_admin_menu_entries.send( - sender="core_menu", location="top_menu", user=user) + sender="core_menu", location="top_menu", user=user + ) entries = reduce(lambda a, b: a + b, [entry[1] for entry in entries]) if user.is_superuser: entries += [ - {"name": "settings", - "label": _("Modoboa"), - "url": reverse("core:index")} + {"name": "settings", "label": _("Modoboa"), "url": reverse("core:index")} ] if not len(entries): return "" - return render_to_string("common/menulist.html", { - "entries": entries, - "selection": selection, - "user": user} + return render_to_string( + "common/menulist.html", + {"entries": entries, "selection": selection, "user": user}, ) @register.simple_tag def extensions_menu(selection, user): menu = signals.extra_user_menu_entries.send( - sender="core_menu", location="top_menu", user=user) + sender="core_menu", location="top_menu", user=user + ) menu = reduce(lambda a, b: a + b, [entry[1] for entry in menu]) - return render_to_string("common/menulist.html", { - "selection": selection, "entries": menu, "user": user - }) + return render_to_string( + "common/menulist.html", {"selection": selection, "entries": menu, "user": user} + ) @register.simple_tag def admin_menu(selection, user): entries = [ - {"name": "info", - "class": "ajaxnav", - "url": "info/", - "label": _("Information")}, - {"name": "logs", - "class": "ajaxnav", - "url": "logs/?sort_order=-date_created", - "label": _("Logs")}, - {"name": "parameters", - "class": "ajaxnav", - "url": "parameters/", - "img": "", - "label": _("Parameters")}, + {"name": "info", "class": "ajaxnav", "url": "info/", "label": _("Information")}, + { + "name": "logs", + "class": "ajaxnav", + "url": "logs/?sort_order=-date_created", + "label": _("Logs"), + }, + { + "name": "parameters", + "class": "ajaxnav", + "url": "parameters/", + "img": "", + "label": _("Parameters"), + }, ] - return render_to_string("common/menu.html", { - "entries": entries, - "css": "nav nav-sidebar", - "selection": selection, - "user": user - }) + return render_to_string( + "common/menu.html", + { + "entries": entries, + "css": "nav nav-sidebar", + "selection": selection, + "user": user, + }, + ) @register.simple_tag def user_menu(request, selection): entries = [ - {"name": "user", - "img": "fa fa-user", - "label": request.user.fullname, - "menu": [ - {"name": "settings", - "img": "fa fa-list", - "label": _("Settings"), - "url": reverse("core:user_index")} - ]} + { + "name": "user", + "img": "fa fa-user", + "label": request.user.fullname, + "menu": [ + { + "name": "settings", + "img": "fa fa-list", + "label": _("Settings"), + "url": reverse("core:user_index"), + } + ], + } ] extra_entries = signals.extra_user_menu_entries.send( - sender="user_menu", location="options_menu", user=request.user) - extra_entries = reduce( - lambda a, b: a + b, [entry[1] for entry in extra_entries]) - entries[0]["menu"] += ( - extra_entries + [{ + sender="user_menu", location="options_menu", user=request.user + ) + extra_entries = reduce(lambda a, b: a + b, [entry[1] for entry in extra_entries]) + entries[0]["menu"] += extra_entries + [ + { "name": "logout", "url": reverse("core:logout"), "label": _("Logout"), "img": "fa fa-sign-out", - "method": "post" - }] + "method": "post", + } + ] + return render_to_string( + "common/menulist.html", + { + "request": request, + "selection": selection, + "entries": entries, + "user": request.user, + }, ) - return render_to_string("common/menulist.html", { - "request": request, "selection": selection, - "entries": entries, "user": request.user - }) @register.simple_tag def uprefs_menu(selection, user): entries = [ - {"name": "profile", - "class": "ajaxnav", - "url": "profile/", - "label": _("Profile")}, - {"name": "preferences", - "class": "ajaxnav", - "url": "preferences/", - "label": _("Preferences")}, - {"name": "security", - "class": "ajaxnav", - "url": "security/", - "label": _("Security")}, + { + "name": "profile", + "class": "ajaxnav", + "url": "profile/", + "label": _("Profile"), + }, + { + "name": "preferences", + "class": "ajaxnav", + "url": "preferences/", + "label": _("Preferences"), + }, + { + "name": "security", + "class": "ajaxnav", + "url": "security/", + "label": _("Security"), + }, ] if user.is_superuser: - entries.append({ - "name": "api", - "class": "ajaxnav", - "url": "api/", - "label": _("API"), - }) + entries.append( + { + "name": "api", + "class": "ajaxnav", + "url": "api/", + "label": _("API"), + } + ) extra_entries = signals.extra_user_menu_entries.send( - sender="user_menu", location="uprefs_menu", user=user) - extra_entries = reduce( - lambda a, b: a + b, [entry[1] for entry in extra_entries]) + sender="user_menu", location="uprefs_menu", user=user + ) + extra_entries = reduce(lambda a, b: a + b, [entry[1] for entry in extra_entries]) entries += extra_entries entries = sorted(entries, key=lambda e: e["label"]) - return render_to_string("common/menu.html", { - "entries": entries, - "css": "nav nav-sidebar", - "selection": selection, - "user": user - }) + return render_to_string( + "common/menu.html", + { + "entries": entries, + "css": "nav nav-sidebar", + "selection": selection, + "user": user, + }, + ) @register.filter @@ -154,7 +177,7 @@ def colorize_level(level): classes = { "INFO": "text-info", "WARNING": "text-warning", - "CRITICAL": "text-danger" + "CRITICAL": "text-danger", } if level not in classes: return level @@ -169,14 +192,18 @@ def tohtml(message): @register.simple_tag def visirule(field): - if not hasattr(field, "form") or \ - not hasattr(field.form, "visirules") or \ - field.html_name not in field.form.visirules: + if ( + not hasattr(field, "form") + or not hasattr(field.form, "visirules") + or field.html_name not in field.form.visirules + ): return "" rule = field.form.visirules[field.html_name] return mark_safe( - " data-visibility-field='{}' data-visibility-value='{}' " - .format(rule["field"], rule["value"])) + " data-visibility-field='{}' data-visibility-value='{}' ".format( + rule["field"], rule["value"] + ) + ) @register.simple_tag @@ -200,8 +227,7 @@ class ConnectedUsers(template.Node): uid_list.append(uid) # Query all logged in users based on id list - context[self.varname] = ( - models.User.objects.filter(pk__in=uid_list).distinct()) + context[self.varname] = models.User.objects.filter(pk__in=uid_list).distinct() return "" @@ -230,12 +256,11 @@ def get_modoboa_logo(): @register.simple_tag def load_optionalmenu(user): menu = signals.extra_user_menu_entries.send( - sender="user_menu", location="top_menu_middle", user=user) - menu = reduce( - lambda a, b: a + b, [entry[1] for entry in menu]) + sender="user_menu", location="top_menu_middle", user=user + ) + menu = reduce(lambda a, b: a + b, [entry[1] for entry in menu]) return template.loader.render_to_string( - "common/menulist.html", - {"entries": menu, "user": user} + "common/menulist.html", {"entries": menu, "user": user} ) @@ -253,13 +278,16 @@ def display_messages(msgs): else: timeout = "undefined" - return mark_safe(""" + return mark_safe( + """ -""" % (level, text, timeout)) +""" + % (level, text, timeout) + ) @register.filter @@ -267,5 +295,5 @@ def currencyfmt(amount): """Simple temp. filter to replace babel.""" lang = get_language() if lang == "fr": - return u"{} €".format(amount) - return u"€{}".format(amount) + return "{} €".format(amount) + return "€{}".format(amount) diff --git a/modoboa/core/tests/stupid_extension_2/urls.py b/modoboa/core/tests/stupid_extension_2/urls.py index a4098f372..9a604dfdf 100644 --- a/modoboa/core/tests/stupid_extension_2/urls.py +++ b/modoboa/core/tests/stupid_extension_2/urls.py @@ -4,6 +4,4 @@ from django.urls import re_path from . import views -urlpatterns = [ - re_path("^$", views.test_view, name="index") -] +urlpatterns = [re_path("^$", views.test_view, name="index")] diff --git a/modoboa/core/tests/test_authentication.py b/modoboa/core/tests/test_authentication.py index 425b3e11e..80d0ba416 100644 --- a/modoboa/core/tests/test_authentication.py +++ b/modoboa/core/tests/test_authentication.py @@ -95,7 +95,7 @@ class AuthenticationTestCase(ModoTestCase): password = "toto" data = {"username": username, "password": password} user = models.User.objects.get(username=username) - pw_hash = get_password_hasher('fallback_scheme')() + pw_hash = get_password_hasher("fallback_scheme")() self.client.logout() self.set_global_parameter("password_scheme", "sha512crypt") @@ -154,9 +154,7 @@ class AuthenticationTestCase(ModoTestCase): self.client.post(reverse("core:login"), data) user.refresh_from_db() self.assertTrue(user.password.startswith("{ARGON2ID}")) - parameters = argon2.extract_parameters( - user.password.lstrip("{ARGON2ID}") - ) + parameters = argon2.extract_parameters(user.password.lstrip("{ARGON2ID}")) self.assertEqual(parameters.time_cost, 4) self.assertEqual(parameters.memory_cost, 10000) self.assertEqual(parameters.parallelism, 4) @@ -170,8 +168,7 @@ class AuthenticationTestCase(ModoTestCase): self.client.post(reverse("core:login"), data) user.refresh_from_db() self.assertTrue(user.password.startswith("{ARGON2ID}")) - parameters = argon2.extract_parameters( - user.password.lstrip("{ARGON2ID}")) + parameters = argon2.extract_parameters(user.password.lstrip("{ARGON2ID}")) self.assertEqual(parameters.time_cost, 3) self.assertEqual(parameters.memory_cost, 1000) self.assertEqual(parameters.parallelism, 2) @@ -184,41 +181,45 @@ class AuthenticationTestCase(ModoTestCase): "MD5 MD5-CRYPT SHA SHA1 SSHA SHA256 SHA512 SMD5 SSHA SSHA256 SSHA512 " "PLAIN CLEAR CLEARTEXT PLAIN-TRUNC CRAM-MD5 SCRAM-SHA-1 HMAC-MD5 " "DIGEST-MD5 PLAIN-MD4 PLAIN-MD5 LDAP-MD5 LANMAN NTLM OTP SKEY RPA " - "PBKDF2 CRYPT SHA256-CRYPT SHA512-CRYPT" + "PBKDF2 CRYPT SHA256-CRYPT SHA512-CRYPT", ) supported_schemes = get_dovecot_schemes()[0] - self.assertEqual(supported_schemes, - ["{MD5}", - "{MD5-CRYPT}", - "{SHA}", - "{SHA1}", - "{SSHA}", - "{SHA256}", - "{SHA512}", - "{SMD5}", - "{SSHA}", - "{SSHA256}", - "{SSHA512}", - "{PLAIN}", - "{CLEAR}", - "{CLEARTEXT}", - "{PLAIN-TRUNC}", - "{CRAM-MD5}", - "{SCRAM-SHA-1}", - "{HMAC-MD5}", - "{DIGEST-MD5}", - "{PLAIN-MD4}", - "{PLAIN-MD5}", - "{LDAP-MD5}", - "{LANMAN}", - "{NTLM}", - "{OTP}", - "{SKEY}", - "{RPA}", - "{PBKDF2}", - "{CRYPT}", - "{SHA256-CRYPT}", - "{SHA512-CRYPT}"]) + self.assertEqual( + supported_schemes, + [ + "{MD5}", + "{MD5-CRYPT}", + "{SHA}", + "{SHA1}", + "{SSHA}", + "{SHA256}", + "{SHA512}", + "{SMD5}", + "{SSHA}", + "{SSHA256}", + "{SSHA512}", + "{PLAIN}", + "{CLEAR}", + "{CLEARTEXT}", + "{PLAIN-TRUNC}", + "{CRAM-MD5}", + "{SCRAM-SHA-1}", + "{HMAC-MD5}", + "{DIGEST-MD5}", + "{PLAIN-MD4}", + "{PLAIN-MD5}", + "{LDAP-MD5}", + "{LANMAN}", + "{NTLM}", + "{OTP}", + "{SKEY}", + "{RPA}", + "{PBKDF2}", + "{CRYPT}", + "{SHA256-CRYPT}", + "{SHA512-CRYPT}", + ], + ) @override_settings(DOVECOT_SUPPORTED_SCHEMES="SHA1 SHA512-CRYPT") def test_dovecot_supported_schemes_from_settings(self): @@ -240,9 +241,10 @@ class PasswordResetTestCase(ModoTestCase): """Create test data.""" super(PasswordResetTestCase, cls).setUpTestData() cls.account_ok = factories.UserFactory( - username="user@test.com", secondary_email="test@ext.com", + username="user@test.com", + secondary_email="test@ext.com", phone_number="+33612345678", - groups=("SimpleUsers",) + groups=("SimpleUsers",), ) cls.account_ko = factories.UserFactory( username="user2@test.com", groups=("SimpleUsers",) @@ -255,8 +257,8 @@ class PasswordResetTestCase(ModoTestCase): data = {"email": self.account_ok.email} response = self.client.post(url, data, follow=True) self.assertContains( - response, - "We've emailed you instructions for setting your password") + response, "We've emailed you instructions for setting your password" + ) self.assertEqual(len(mail.outbox), 1) def test_reset_password_no_secondary_email(self): @@ -266,8 +268,8 @@ class PasswordResetTestCase(ModoTestCase): data = {"email": self.account_ko.email} response = self.client.post(url, data, follow=True) self.assertContains( - response, - "We've emailed you instructions for setting your password") + response, "We've emailed you instructions for setting your password" + ) self.assertEqual(len(mail.outbox), 0) def test_reset_password_announcement(self): @@ -286,13 +288,15 @@ class PasswordResetTestCase(ModoTestCase): """Test reset password by SMS.""" client_get.return_value = ["service"] client_post.return_value = {"totalCreditsRemoved": 1} - self.set_global_parameters({ - "sms_password_recovery": True, - "sms_provider": "ovh", - "sms_ovh_application_key": "key", - "sms_ovh_application_secret": "secret", - "sms_ovh_consumer_key": "consumer" - }) + self.set_global_parameters( + { + "sms_password_recovery": True, + "sms_provider": "ovh", + "sms_ovh_application_key": "key", + "sms_ovh_application_secret": "secret", + "sms_ovh_consumer_key": "consumer", + } + ) self.client.logout() url = reverse("password_reset") data = {"email": self.account_ok.email} @@ -318,13 +322,16 @@ class PasswordResetTestCase(ModoTestCase): response = self.client.get(url) self.assertEqual(response.status_code, 404) - self.set_global_parameters({ - "sms_password_recovery": True, - "sms_provider": "ovh", - "sms_ovh_application_key": "key", - "sms_ovh_application_secret": "secret", - "sms_ovh_consumer_key": "consumer" - }, app="core") + self.set_global_parameters( + { + "sms_password_recovery": True, + "sms_provider": "ovh", + "sms_ovh_application_key": "key", + "sms_ovh_application_secret": "secret", + "sms_ovh_consumer_key": "consumer", + }, + app="core", + ) # No user pk in session response = self.client.get(url) self.assertEqual(response.status_code, 404) @@ -340,10 +347,12 @@ class PasswordResetTestCase(ModoTestCase): @skipIf(NO_SMTP, "No SMTP server available") -@override_settings(AUTHENTICATION_BACKENDS=( - "modoboa.lib.authbackends.SMTPBackend", - "django.contrib.auth.backends.ModelBackend" -)) +@override_settings( + AUTHENTICATION_BACKENDS=( + "modoboa.lib.authbackends.SMTPBackend", + "django.contrib.auth.backends.ModelBackend", + ) +) class SMTPAuthenticationTestCase(ModoTestCase): """Validate SMTP authentication scenarios.""" @@ -356,10 +365,8 @@ class SMTPAuthenticationTestCase(ModoTestCase): response = self.client.post(reverse("core:login"), data) self.assertEqual(response.status_code, 302) self.assertTrue(response.url.endswith(reverse("core:user_index"))) - mock_smtp.return_value.login.assert_called_once_with( - username, password) - self.assertTrue( - models.User.objects.filter(username=username).exists()) + mock_smtp.return_value.login.assert_called_once_with(username, password) + self.assertTrue(models.User.objects.filter(username=username).exists()) @mock.patch("smtplib.SMTP") def test_smtp_authentication(self, mock_smtp): @@ -383,14 +390,13 @@ class SMTPAuthenticationTestCase(ModoTestCase): """Check SMTP authentication failure.""" instance = mock_smtp.return_value instance.login.side_effect = smtplib.SMTPAuthenticationError( - 450, "User not found") + 450, "User not found" + ) self.client.logout() username = "user@unknown.test" password = "toto" data = {"username": username, "password": password} response = self.client.post(reverse("core:login"), data) self.assertEqual(response.status_code, 401) - mock_smtp.return_value.login.assert_called_once_with( - username, password) - self.assertFalse( - models.User.objects.filter(username=username).exists()) + mock_smtp.return_value.login.assert_called_once_with(username, password) + self.assertFalse(models.User.objects.filter(username=username).exists()) diff --git a/modoboa/core/tests/test_checks.py b/modoboa/core/tests/test_checks.py index 06ab8ad58..02bdfeb60 100644 --- a/modoboa/core/tests/test_checks.py +++ b/modoboa/core/tests/test_checks.py @@ -9,8 +9,7 @@ class CheckSessionCookieSecureTest(SimpleTestCase): def test_use_tz_false(self): """If USE_TZ is off provide one warning.""" self.assertEqual( - settings_checks.check_use_tz_enabled(None), - [settings_checks.W001] + settings_checks.check_use_tz_enabled(None), [settings_checks.W001] ) @override_settings(USE_TZ=True) diff --git a/modoboa/core/tests/test_core.py b/modoboa/core/tests/test_core.py index c722432da..d1adf8feb 100644 --- a/modoboa/core/tests/test_core.py +++ b/modoboa/core/tests/test_core.py @@ -16,7 +16,6 @@ from .. import factories, mocks, models class AuthenticationTestCase(ModoTestCase): - """Validate authentication scenarios.""" @classmethod @@ -49,10 +48,8 @@ class ManagementCommandsTestCase(SimpleModoTestCase): def test_change_default_admin(self): """Use dedicated option.""" - management.call_command( - "load_initial_data", "--admin-username", "modoadmin") - self.assertTrue( - self.client.login(username="modoadmin", password="password")) + management.call_command("load_initial_data", "--admin-username", "modoadmin") + self.assertTrue(self.client.login(username="modoadmin", password="password")) def test_clean_logs(self): """Run cleanlogs command.""" @@ -72,8 +69,7 @@ class ManagementCommandsTestCase(SimpleModoTestCase): last_login = timezone.now() - relativedelta(days=45) account = factories.UserFactory( - username="user1@domain.test", groups=("SimpleUsers", ), - last_login=last_login + username="user1@domain.test", groups=("SimpleUsers",), last_login=last_login ) management.call_command("clean_inactive_accounts", "--dry-run") account.refresh_from_db() @@ -81,16 +77,15 @@ class ManagementCommandsTestCase(SimpleModoTestCase): out = StringIO() management.call_command( - "clean_inactive_accounts", "--verbose", "--dry-run", stdout=out) + "clean_inactive_accounts", "--verbose", "--dry-run", stdout=out + ) self.assertIn("user1@domain.test", out.getvalue()) # Disable account account threshold self.set_global_parameter("enable_inactive_accounts", False) out = StringIO() - management.call_command( - "clean_inactive_accounts", "--verbose", stdout=out) - self.assertIn("Inactive accounts detection is disabled.", - out.getvalue()) + management.call_command("clean_inactive_accounts", "--verbose", stdout=out) + self.assertIn("Inactive accounts detection is disabled.", out.getvalue()) self.set_global_parameter("enable_inactive_accounts", True) management.call_command("clean_inactive_accounts", "--silent") @@ -100,8 +95,7 @@ class ManagementCommandsTestCase(SimpleModoTestCase): account.is_active = True account.save(update_fields=["is_active"]) - management.call_command( - "clean_inactive_accounts", "--silent", "--delete") + management.call_command("clean_inactive_accounts", "--silent", "--delete") with self.assertRaises(models.User.DoesNotExist): account.refresh_from_db() @@ -120,8 +114,10 @@ class ProfileTestCase(ModoTestCase): def test_update_profile(self): """Update profile without password.""" data = { - "first_name": "Homer", "last_name": "Simpson", - "phone_number": "+33612345678", "language": "en" + "first_name": "Homer", + "last_name": "Simpson", + "phone_number": "+33612345678", + "language": "en", } self.ajax_post(reverse("core:user_profile"), data) admin = models.User.objects.get(username="admin") @@ -134,47 +130,53 @@ class ProfileTestCase(ModoTestCase): * The default admin changes his password (no associated Mailbox) * A normal user changes his password """ - self.ajax_post(reverse("core:user_profile"), - {"language": "en", "oldpassword": "password", - "newpassword": "12345Toi", "confirmation": "12345Toi"}) + self.ajax_post( + reverse("core:user_profile"), + { + "language": "en", + "oldpassword": "password", + "newpassword": "12345Toi", + "confirmation": "12345Toi", + }, + ) self.client.logout() - self.assertEqual( - self.client.login(username="admin", password="12345Toi"), True - ) + self.assertEqual(self.client.login(username="admin", password="12345Toi"), True) self.assertEqual( self.client.login(username="user@test.com", password="toto"), True ) self.ajax_post( reverse("core:user_profile"), - {"language": "en", - "oldpassword": "toto", - "confirmation": "tutu"}, - status=400 + {"language": "en", "oldpassword": "toto", "confirmation": "tutu"}, + status=400, ) self.ajax_post( reverse("core:user_profile"), - {"language": "en", - "oldpassword": "toto", - "newpassword": "tutu"}, - status=400 + {"language": "en", "oldpassword": "toto", "newpassword": "tutu"}, + status=400, ) self.ajax_post( reverse("core:user_profile"), - {"language": "en", - "oldpassword": "toto", - "newpassword": "tutu", - "confirmation": "tutu"}, - status=400 + { + "language": "en", + "oldpassword": "toto", + "newpassword": "tutu", + "confirmation": "tutu", + }, + status=400, ) self.ajax_post( reverse("core:user_profile"), - {"language": "en", "oldpassword": "toto", - "newpassword": "Toto1234", "confirmation": "Toto1234"} + { + "language": "en", + "oldpassword": "toto", + "newpassword": "Toto1234", + "confirmation": "Toto1234", + }, ) self.client.logout() self.assertTrue( @@ -184,9 +186,13 @@ class ProfileTestCase(ModoTestCase): def test_update_password_restrictions(self): self.ajax_post( reverse("core:user_profile"), - {"language": "en", "oldpassword": "", - "newpassword": "12345Toi", "confirmation": "12345Toi"}, - status=400 + { + "language": "en", + "oldpassword": "", + "newpassword": "12345Toi", + "confirmation": "12345Toi", + }, + status=400, ) self.client.logout() @@ -196,11 +202,9 @@ class ProfileTestCase(ModoTestCase): def test_update_password_url(self): """Check if external is used when defined.""" - self.set_global_parameter( - "update_password_url", "http://update.password") + self.set_global_parameter("update_password_url", "http://update.password") non_local_user = factories.UserFactory( - username="user@external.com", groups=("SimpleUsers",), - is_local=False + username="user@external.com", groups=("SimpleUsers",), is_local=False ) self.client.force_login(non_local_user) url = reverse("core:user_profile") @@ -213,7 +217,6 @@ class ProfileTestCase(ModoTestCase): class APIAccessFormTestCase(ModoTestCase): - """Check form access.""" @classmethod @@ -250,10 +253,11 @@ class APICommunicationTestCase(ModoTestCase): def test_management_command(self): """Check command.""" with httmock.HTTMock( - mocks.modo_api_instance_search, - mocks.modo_api_instance_create, - mocks.modo_api_instance_update, - mocks.modo_api_versions): + mocks.modo_api_instance_search, + mocks.modo_api_instance_create, + mocks.modo_api_instance_update, + mocks.modo_api_versions, + ): management.call_command("communicate_with_public_api") self.assertEqual(models.LocalConfig.objects.first().api_pk, 100) self.assertEqual(len(mail.outbox), 0) @@ -265,28 +269,31 @@ class APICommunicationTestCase(ModoTestCase): # Enable notifications self.set_global_parameter("send_new_versions_email", True) with httmock.HTTMock( - mocks.modo_api_instance_search, - mocks.modo_api_instance_create, - mocks.modo_api_instance_update, - mocks.modo_api_versions): + mocks.modo_api_instance_search, + mocks.modo_api_instance_create, + mocks.modo_api_instance_update, + mocks.modo_api_versions, + ): management.call_command("communicate_with_public_api") self.assertEqual(len(mail.outbox), 1) # Call once again and check no new notification has been sent self.set_global_parameter("send_new_versions_email", True) with httmock.HTTMock( - mocks.modo_api_instance_search, - mocks.modo_api_instance_create, - mocks.modo_api_instance_update, - mocks.modo_api_versions): + mocks.modo_api_instance_search, + mocks.modo_api_instance_create, + mocks.modo_api_instance_update, + mocks.modo_api_versions, + ): management.call_command("communicate_with_public_api") self.assertEqual(len(mail.outbox), 1) # Make sure no new notification is sent when no updates with httmock.HTTMock( - mocks.modo_api_instance_search, - mocks.modo_api_instance_create, - mocks.modo_api_instance_update, - mocks.modo_api_versions_no_update): + mocks.modo_api_instance_search, + mocks.modo_api_instance_create, + mocks.modo_api_instance_update, + mocks.modo_api_versions_no_update, + ): management.call_command("communicate_with_public_api") self.assertEqual(len(mail.outbox), 1) diff --git a/modoboa/core/tests/test_extensions.py b/modoboa/core/tests/test_extensions.py index 3ef1ec764..8d41df2f5 100644 --- a/modoboa/core/tests/test_extensions.py +++ b/modoboa/core/tests/test_extensions.py @@ -56,12 +56,18 @@ class ExtensionTestCase(TestCase): """Check getter method.""" self.assertIsNone(self.pool.get_extension_infos("toto")) infos = self.pool.get_extension_infos("stupid_extension_1") - compare(infos, { - "name": "stupid_extension_1", "label": "Stupid extension", - "version": "1.0.0", "description": "A stupid extension", - "url": "stupid_extension_1", "always_active": False, - "topredirection_url": None - }) + compare( + infos, + { + "name": "stupid_extension_1", + "label": "Stupid extension", + "version": "1.0.0", + "description": "A stupid extension", + "url": "stupid_extension_1", + "always_active": False, + "topredirection_url": None, + }, + ) def test_list_all(self): """Check list_all method.""" diff --git a/modoboa/core/tests/test_ldap.py b/modoboa/core/tests/test_ldap.py index bc666ccca..d91d11359 100644 --- a/modoboa/core/tests/test_ldap.py +++ b/modoboa/core/tests/test_ldap.py @@ -20,21 +20,25 @@ class LDAPTestCaseMixin(object): def ldapauthbackend(self): """Return LDAPAuthBackend instance.""" from modoboa.lib.ldap_utils import LDAPAuthBackend + return LDAPAuthBackend() def activate_ldap_authentication(self): """Modify settings.""" - self.set_global_parameters({ - "authentication_type": "ldap", - "ldap_server_port": settings.LDAP_SERVER_PORT - }) + self.set_global_parameters( + { + "authentication_type": "ldap", + "ldap_server_port": settings.LDAP_SERVER_PORT, + } + ) def restore_user_password(self, username, new_password): """Restore user password to its initial state.""" for password in ["Toto1234", "test"]: try: self.ldapauthbackend.update_user_password( - username, password, new_password) + username, password, new_password + ) except exceptions.InternalError: pass else: @@ -46,30 +50,35 @@ class LDAPTestCaseMixin(object): self.client.logout() if restore_before: self.restore_user_password(user, password) - self.assertTrue( - self.client.login(username=user, password=password)) + self.assertTrue(self.client.login(username=user, password=password)) def searchbind_mode(self): """Apply settings required by the searchbind mode.""" - self.set_global_parameters({ - "ldap_auth_method": "searchbind", - "ldap_bind_dn": "cn=admin,dc=example,dc=com", - "ldap_bind_password": "test", - "ldap_search_base": "ou=users,dc=example,dc=com" - }) + self.set_global_parameters( + { + "ldap_auth_method": "searchbind", + "ldap_bind_dn": "cn=admin,dc=example,dc=com", + "ldap_bind_password": "test", + "ldap_search_base": "ou=users,dc=example,dc=com", + } + ) def directbind_mode(self): """Apply settings required by the directbind mode.""" - self.set_global_parameters({ - "ldap_auth_method": "directbind", - "ldap_user_dn_template": "cn=%(user)s,ou=users,dc=example,dc=com" - }) + self.set_global_parameters( + { + "ldap_auth_method": "directbind", + "ldap_user_dn_template": "cn=%(user)s,ou=users,dc=example,dc=com", + } + ) -@override_settings(AUTHENTICATION_BACKENDS=( - "modoboa.lib.authbackends.LDAPBackend", - "django.contrib.auth.backends.ModelBackend" -)) +@override_settings( + AUTHENTICATION_BACKENDS=( + "modoboa.lib.authbackends.LDAPBackend", + "django.contrib.auth.backends.ModelBackend", + ) +) class LDAPAuthenticationTestCase(LDAPTestCaseMixin, ModoTestCase): """Validate LDAP authentication scenarios.""" @@ -95,10 +104,12 @@ class LDAPAuthenticationTestCase(LDAPTestCaseMixin, ModoTestCase): self.authenticate(username, "test") self.check_created_user(username) - self.set_global_parameters({ - "ldap_admin_groups": "admins", - "ldap_groups_search_base": "ou=groups,dc=example,dc=com" - }) + self.set_global_parameters( + { + "ldap_admin_groups": "admins", + "ldap_groups_search_base": "ou=groups,dc=example,dc=com", + } + ) username = "mailadmin@example.com" self.authenticate(username, "test", False) self.check_created_user(username, "DomainAdmins") @@ -114,10 +125,12 @@ class LDAPAuthenticationTestCase(LDAPTestCaseMixin, ModoTestCase): # 1: must work because usernames of domain admins are not # always email addresses - self.set_global_parameters({ - "ldap_admin_groups": "admins", - "ldap_groups_search_base": "ou=groups,dc=example,dc=com" - }) + self.set_global_parameters( + { + "ldap_admin_groups": "admins", + "ldap_groups_search_base": "ou=groups,dc=example,dc=com", + } + ) username = "mailadmin" self.authenticate(username, "test", False) self.check_created_user("mailadmin@example.com", "DomainAdmins", False) @@ -134,10 +147,12 @@ class ProfileTestCase(LDAPTestCaseMixin, ModoTestCase): username="user@test.com", groups=("SimpleUsers",) ) - @override_settings(AUTHENTICATION_BACKENDS=( - "modoboa.lib.authbackends.LDAPBackend", - "django.contrib.auth.backends.ModelBackend" - )) + @override_settings( + AUTHENTICATION_BACKENDS=( + "modoboa.lib.authbackends.LDAPBackend", + "django.contrib.auth.backends.ModelBackend", + ) + ) def test_update_password_ldap(self): """Update password for an LDAP user.""" self.activate_ldap_authentication() @@ -147,7 +162,11 @@ class ProfileTestCase(LDAPTestCaseMixin, ModoTestCase): self.authenticate(username, "test") self.ajax_post( reverse("core:user_profile"), - {"language": "en", "oldpassword": "test", - "newpassword": "Toto1234", "confirmation": "Toto1234"} + { + "language": "en", + "oldpassword": "test", + "newpassword": "Toto1234", + "confirmation": "Toto1234", + }, ) self.authenticate(username, "Toto1234", False) diff --git a/modoboa/core/tests/test_views.py b/modoboa/core/tests/test_views.py index b91f9b9a8..5448f6c02 100644 --- a/modoboa/core/tests/test_views.py +++ b/modoboa/core/tests/test_views.py @@ -169,7 +169,8 @@ class DashboardTestCase(ModoTestCase): self.assertContains(response, "https://modoboa.org") self.set_global_parameter( - "rss_feed_url", "https://www.djangoproject.com/rss/weblog/") + "rss_feed_url", "https://www.djangoproject.com/rss/weblog/" + ) self.client.force_login(self.dadmin) response = self.client.get(url) self.assertContains(response, "djangoproject") @@ -200,7 +201,7 @@ class DashboardTestCase(ModoTestCase): """Load dashboard with DISABLE_DASHBOARD_EXTERNAL_QUERIES = True""" url = reverse("core:dashboard") response = self.client.get(url) - self.assertNotContains(response, 'https://modoboa.org/en/weblog/') + self.assertNotContains(response, "https://modoboa.org/en/weblog/") def test_root_dispatch(self): """Check root dispatching.""" @@ -236,19 +237,29 @@ class SettingsTestCase(ModoTestCase): settings["core-password_scheme"] = "magic_password_scheme" response = self.client.post(url, settings, format="json") self.assertEqual(response.status_code, 400) - compare(response.json(), { - "form_errors": {"password_scheme": ["Select a valid choice. \ -magic_password_scheme is not one of the available choices."]}, - "prefix": "core" - }) + compare( + response.json(), + { + "form_errors": { + "password_scheme": [ + "Select a valid choice. \ +magic_password_scheme is not one of the available choices." + ] + }, + "prefix": "core", + }, + ) settings["core-password_scheme"] = "plain" settings["core-rounds_number"] = "" response = self.client.post(url, settings, format="json") self.assertEqual(response.status_code, 400) - compare(response.json(), { - "form_errors": {"rounds_number": ["This field is required."]}, - "prefix": "core" - }) + compare( + response.json(), + { + "form_errors": {"rounds_number": ["This field is required."]}, + "prefix": "core", + }, + ) def test_sms_settings_clean(self): """Check sms settings validation.""" @@ -262,8 +273,7 @@ magic_password_scheme is not one of the available choices."]}, response = self.client.post(url, settings, format="json") self.assertEqual(response.status_code, 400) errors = response.json() - self.assertIn( - "sms_ovh_application_secret", errors["form_errors"]) + self.assertIn("sms_ovh_application_secret", errors["form_errors"]) def test_mx_check_settings_clean(self): settings = SETTINGS_SAMPLE.copy() @@ -275,6 +285,7 @@ magic_password_scheme is not one of the available choices."]}, param_tools.get_global_parameter("enable_ipv6_mx_checks", "admin") ) + class UserSettings(param_forms.UserParametersForm): """Stupid user settings form.""" @@ -286,10 +297,7 @@ class UserSettings(param_forms.UserParametersForm): def extra_user_menu(sender, location, user, **kwargs): """Return extra menu entry.""" return [ - {"name": "test_menu_entry", - "class": "ajaxnav", - "url": "toto/", - "label": "Test"} + {"name": "test_menu_entry", "class": "ajaxnav", "url": "toto/", "label": "Test"} ] diff --git a/modoboa/core/tests/utils.py b/modoboa/core/tests/utils.py index b9c841f64..74106e195 100644 --- a/modoboa/core/tests/utils.py +++ b/modoboa/core/tests/utils.py @@ -1,4 +1,5 @@ import os + def get_doveadm_test_path(): return "{}/doveadm".format(os.path.dirname(__file__)) diff --git a/modoboa/core/urls.py b/modoboa/core/urls.py index c6c6e4609..76b6e31fa 100644 --- a/modoboa/core/urls.py +++ b/modoboa/core/urls.py @@ -8,29 +8,34 @@ from . import views app_name = "core" urlpatterns = [ - path('', views.RootDispatchView.as_view(), name="root"), - path('dashboard/', views.DashboardView.as_view(), name="dashboard"), - - path('accounts/login/', views.dologin, name="login"), - path('accounts/logout/', views.dologout, name="logout"), - path('accounts/2fa_verify/', - views.TwoFactorCodeVerifyView.as_view(), - name='2fa_verify'), - - path('core/', views.viewsettings, name="index"), - path('core/parameters/', views.parameters, name="parameters"), - path('core/info/', views.information, name="information"), - path('core/logs/', views.logs, name="log_list"), - path('core/logs/page/', views.logs_page, name="logs_page"), - path('core/top_notifications/check/', - views.check_top_notifications, - name="top_notifications_check"), - - path('user/', views.index, name="user_index"), - path('user/preferences/', views.preferences, - name="user_preferences"), - path('user/profile/', views.profile, name="user_profile"), - path('user/api/', views.api_access, name="user_api_access"), - path('user/security/', views.security, name="user_security"), - path('robots.txt', TemplateView.as_view(template_name="core/robots.txt", content_type="text/plain")), + path("", views.RootDispatchView.as_view(), name="root"), + path("dashboard/", views.DashboardView.as_view(), name="dashboard"), + path("accounts/login/", views.dologin, name="login"), + path("accounts/logout/", views.dologout, name="logout"), + path( + "accounts/2fa_verify/", + views.TwoFactorCodeVerifyView.as_view(), + name="2fa_verify", + ), + path("core/", views.viewsettings, name="index"), + path("core/parameters/", views.parameters, name="parameters"), + path("core/info/", views.information, name="information"), + path("core/logs/", views.logs, name="log_list"), + path("core/logs/page/", views.logs_page, name="logs_page"), + path( + "core/top_notifications/check/", + views.check_top_notifications, + name="top_notifications_check", + ), + path("user/", views.index, name="user_index"), + path("user/preferences/", views.preferences, name="user_preferences"), + path("user/profile/", views.profile, name="user_profile"), + path("user/api/", views.api_access, name="user_api_access"), + path("user/security/", views.security, name="user_security"), + path( + "robots.txt", + TemplateView.as_view( + template_name="core/robots.txt", content_type="text/plain" + ), + ), ] diff --git a/modoboa/core/utils.py b/modoboa/core/utils.py index 9509e22ed..1ef002d64 100644 --- a/modoboa/core/utils.py +++ b/modoboa/core/utils.py @@ -26,12 +26,14 @@ def check_for_updates(): local_config = models.LocalConfig.objects.first() client = ModoAPIClient() extensions = exts_pool.list_all() - extensions = [{ - "label": "Modoboa", - "name": "modoboa", - "description": _("The core part of Modoboa"), - "version": client.local_core_version - }] + extensions + extensions = [ + { + "label": "Modoboa", + "name": "modoboa", + "description": _("The core part of Modoboa"), + "version": client.local_core_version, + } + ] + extensions update_avail = False for extension in extensions: pkgname = extension["name"].replace("_", "-") @@ -39,9 +41,8 @@ def check_for_updates(): if api_extension["name"] != pkgname: continue extension["last_version"] = api_extension["version"] - if ( - parse_version(api_extension["version"]) > - parse_version(extension["version"]) + if parse_version(api_extension["version"]) > parse_version( + extension["version"] ): extension["update"] = True extension["changelog_url"] = api_extension["url"] diff --git a/modoboa/core/views/__init__.py b/modoboa/core/views/__init__.py index 1036e8308..eb728b210 100644 --- a/modoboa/core/views/__init__.py +++ b/modoboa/core/views/__init__.py @@ -1,17 +1,24 @@ """Core views.""" from .admin import ( - check_top_notifications, information, logs, logs_page, parameters, - viewsettings + check_top_notifications, + information, + logs, + logs_page, + parameters, + viewsettings, ) from .auth import ( - PasswordResetView, dologin, dologout, VerifySMSCodeView, - ResendSMSCodeView, TwoFactorCodeVerifyView + PasswordResetView, + dologin, + dologout, + VerifySMSCodeView, + ResendSMSCodeView, + TwoFactorCodeVerifyView, ) from .base import RootDispatchView from .dashboard import DashboardView -from .user import ( - api_access, index, preferences, profile, security) +from .user import api_access, index, preferences, profile, security __all__ = [ "DashboardView", @@ -32,5 +39,5 @@ __all__ = [ "preferences", "profile", "viewsettings", - "security" + "security", ] diff --git a/modoboa/core/views/admin.py b/modoboa/core/views/admin.py index b4681dec7..7cd2bb21b 100644 --- a/modoboa/core/views/admin.py +++ b/modoboa/core/views/admin.py @@ -18,9 +18,7 @@ from .. import signals @login_required @user_passes_test(lambda u: u.is_superuser) def viewsettings(request, tplname="core/settings_header.html"): - return render(request, tplname, { - "selection": "settings" - }) + return render(request, tplname, {"selection": "settings"}) @login_required @@ -29,7 +27,8 @@ def parameters(request, tplname="core/parameters.html"): """View to display and save global parameters.""" if request.method == "POST": forms = param_tools.registry.get_forms( - "global", request.POST, localconfig=request.localconfig) + "global", request.POST, localconfig=request.localconfig + ) for formdef in forms: form = formdef["form"] if form.is_valid(): @@ -41,40 +40,52 @@ def parameters(request, tplname="core/parameters.html"): ) request.localconfig.save() return render_to_json_response(_("Parameters saved")) - return render_to_json_response({ - "left_selection": "parameters", - "content": render_to_string(tplname, { - "forms": param_tools.registry.get_forms( - "global", localconfig=request.localconfig) - }, request) - }) + return render_to_json_response( + { + "left_selection": "parameters", + "content": render_to_string( + tplname, + { + "forms": param_tools.registry.get_forms( + "global", localconfig=request.localconfig + ) + }, + request, + ), + } + ) @login_required @user_passes_test(lambda u: u.is_superuser) def information(request, tplname="core/information.html"): status, extensions = check_for_updates() - return render_to_json_response({ - "content": render_to_string(tplname, { - "update_avail": status, - "extensions": extensions, - }), - }) + return render_to_json_response( + { + "content": render_to_string( + tplname, + { + "update_avail": status, + "extensions": extensions, + }, + ), + } + ) def get_logs_page(request, page_id=None): """Return a page of logs.""" sort_order, sort_dir = get_sort_order( - request.GET, "date_created", - allowed_values=["date_created", "level", "logger", "message"] + request.GET, + "date_created", + allowed_values=["date_created", "level", "logger", "message"], ) if page_id is None: page_id = request.GET.get("page", None) if page_id is None: return None return get_listing_page( - Log.objects.all().order_by("%s%s" % (sort_dir, sort_order)), - page_id + Log.objects.all().order_by("%s%s" % (sort_dir, sort_order)), page_id ) @@ -87,11 +98,13 @@ def logs(request, tplname="core/logs.html"): """ page = get_logs_page(request, 1) - return render_to_json_response({ - "callback": "logs", - "content": render_to_string(tplname, {"logs": page.object_list}), - "page": page.number - }) + return render_to_json_response( + { + "callback": "logs", + "content": render_to_string(tplname, {"logs": page.object_list}), + "page": page.number, + } + ) @login_required @@ -104,7 +117,7 @@ def logs_page(request, tplname="core/logs_page.html"): else: context = { "rows": render_to_string(tplname, {"logs": page.object_list}), - "pages": [page.number] + "pages": [page.number], } return render_to_json_response(context) @@ -113,7 +126,7 @@ def logs_page(request, tplname="core/logs_page.html"): def check_top_notifications(request): """AJAX service to check for new top notifications to display.""" notifications = signals.get_top_notifications.send( - sender="top_notifications", include_all=True) - notifications = reduce( - lambda a, b: a + b, [notif[1] for notif in notifications]) + sender="top_notifications", include_all=True + ) + notifications = reduce(lambda a, b: a + b, [notif[1] for notif in notifications]) return render_to_json_response(notifications) diff --git a/modoboa/core/views/auth.py b/modoboa/core/views/auth.py index 3cd254d1d..708708064 100644 --- a/modoboa/core/views/auth.py +++ b/modoboa/core/views/auth.py @@ -5,8 +5,7 @@ import logging import oath from django.conf import settings -from django.http import ( - HttpResponse, HttpResponseRedirect, Http404, JsonResponse) +from django.http import HttpResponse, HttpResponseRedirect, Http404, JsonResponse from django.template.loader import render_to_string from django.urls import reverse from django.utils import translation @@ -18,9 +17,7 @@ from django.views import generic from django.views.decorators.cache import never_cache from django.views.decorators.http import require_http_methods -from django.contrib.auth import ( - authenticate, login, logout, views as auth_views -) +from django.contrib.auth import authenticate, login, logout, views as auth_views from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.tokens import default_token_generator @@ -47,35 +44,38 @@ def dologin(request): form = forms.LoginForm(request.POST) if form.is_valid(): logger = logging.getLogger("modoboa.auth") - user = authenticate(username=form.cleaned_data["username"], - password=form.cleaned_data["password"]) + user = authenticate( + username=form.cleaned_data["username"], + password=form.cleaned_data["password"], + ) if user and user.is_active: - condition = ( - user.is_local and - param_tools.get_global_parameter( - "update_scheme", raise_exception=False) + condition = user.is_local and param_tools.get_global_parameter( + "update_scheme", raise_exception=False ) if condition: # check if password scheme is correct scheme = param_tools.get_global_parameter( - "password_scheme", raise_exception=False) + "password_scheme", raise_exception=False + ) # use SHA512CRYPT as default fallback if scheme is None: - pwhash = get_password_hasher('sha512crypt')() + pwhash = get_password_hasher("sha512crypt")() else: pwhash = get_password_hasher(scheme)() if not user.password.startswith(pwhash.scheme): logging.info( _("Password scheme mismatch. Updating %s password"), - user.username + user.username, ) user.set_password(form.cleaned_data["password"]) user.save() if pwhash.needs_rehash(user.password): logging.info( - _("Password hash parameter missmatch. " - "Updating %s password"), - user.username + _( + "Password hash parameter missmatch. " + "Updating %s password" + ), + user.username, ) user.set_password(form.cleaned_data["password"]) user.save() @@ -86,23 +86,25 @@ def dologin(request): translation.activate(request.user.language) - logger.info( - _("User '%s' successfully logged in") % user.username - ) + logger.info(_("User '%s' successfully logged in") % user.username) signals.user_login.send( sender="dologin", username=form.cleaned_data["username"], - password=form.cleaned_data["password"]) + password=form.cleaned_data["password"], + ) response = HttpResponseRedirect(find_nextlocation(request, user)) - response.set_cookie(settings.LANGUAGE_COOKIE_NAME, request.user.language) + response.set_cookie( + settings.LANGUAGE_COOKIE_NAME, request.user.language + ) return response - error = _( - "Your username and password didn't match. Please try again.") + error = _("Your username and password didn't match. Please try again.") logger.warning( "Failed connection attempt from '%(addr)s' as user '%(user)s'" - % {"addr": request.META["REMOTE_ADDR"], - "user": escape(form.cleaned_data["username"])} + % { + "addr": request.META["REMOTE_ADDR"], + "user": escape(form.cleaned_data["username"]), + } ) nextlocation = request.POST.get("next", "") @@ -112,16 +114,21 @@ def dologin(request): nextlocation = request.GET.get("next", "") httpcode = 200 - announcements = signals.get_announcements.send( - sender="login", location="loginpage") + announcements = signals.get_announcements.send(sender="login", location="loginpage") announcements = [announcement[1] for announcement in announcements] return HttpResponse( render_to_string( - "registration/login.html", { - "form": form, "error": error, "next": nextlocation, - "annoucements": announcements}, - request), - status=httpcode) + "registration/login.html", + { + "form": form, + "error": error, + "next": nextlocation, + "annoucements": announcements, + }, + request, + ), + status=httpcode, + ) dologin = never_cache(dologin) @@ -134,8 +141,8 @@ def dologout(request): signals.user_logout.send(sender="dologout", request=request) logger = logging.getLogger("modoboa.auth") logger.info( - _("User '{}' successfully logged out").format( - request.user.username)) + _("User '{}' successfully logged out").format(request.user.username) + ) logout(request) return HttpResponseRedirect(reverse("core:login")) @@ -147,24 +154,20 @@ class PasswordResetView(auth_views.PasswordResetView): def setup(self, request, *args, **kwargs): super().setup(request, *args, **kwargs) - self.from_email = request.localconfig.parameters.get_value( - "sender_address" - ) + self.from_email = request.localconfig.parameters.get_value("sender_address") def get_context_data(self, **kwargs): """Include help text.""" context = super().get_context_data(**kwargs) - context["announcement"] = ( - self.request.localconfig.parameters - .get_value("password_recovery_msg") + context["announcement"] = self.request.localconfig.parameters.get_value( + "password_recovery_msg" ) return context def form_valid(self, form): """Redirect to code verification page if needed.""" - sms_password_recovery = ( - self.request.localconfig.parameters - .get_value("sms_password_recovery") + sms_password_recovery = self.request.localconfig.parameters.get_value( + "sms_password_recovery" ) if not sms_password_recovery: return super().form_valid(form) @@ -174,13 +177,13 @@ class PasswordResetView(auth_views.PasswordResetView): if not user: # Fallback to email return super().form_valid(form) - backend = sms_backends.get_active_backend( - self.request.localconfig.parameters) + backend = sms_backends.get_active_backend(self.request.localconfig.parameters) secret = cryptutils.random_hex_key(20) code = oath.totp(secret) text = _( - "Please use the following code to recover your Modoboa password: {}" - .format(code) + "Please use the following code to recover your Modoboa password: {}".format( + code + ) ) if not backend.send(text, [str(user.phone_number)]): return super().form_valid(form) @@ -218,24 +221,22 @@ class ResendSMSCodeView(generic.View): """A view to resend validation code.""" def get(self, request, *args, **kwargs): - sms_password_recovery = ( - self.request.localconfig.parameters - .get_value("sms_password_recovery") + sms_password_recovery = self.request.localconfig.parameters.get_value( + "sms_password_recovery" ) if not sms_password_recovery: raise Http404 try: - user = models.User._default_manager.get( - pk=self.request.session["user_pk"]) + user = models.User._default_manager.get(pk=self.request.session["user_pk"]) except KeyError: raise Http404 - backend = sms_backends.get_active_backend( - self.request.localconfig.parameters) + backend = sms_backends.get_active_backend(self.request.localconfig.parameters) secret = cryptutils.random_hex_key(20) code = oath.totp(secret) text = _( - "Please use the following code to recover your Modoboa password: {}" - .format(code) + "Please use the following code to recover your Modoboa password: {}".format( + code + ) ) if not backend.send(text, [user.phone_number]): raise Http404 @@ -243,9 +244,9 @@ class ResendSMSCodeView(generic.View): return JsonResponse({"status": "ok"}) -class TwoFactorCodeVerifyView(LoginRequiredMixin, - UserFormKwargsMixin, - generic.FormView): +class TwoFactorCodeVerifyView( + LoginRequiredMixin, UserFormKwargsMixin, generic.FormView +): """View to verify a 2FA code after login.""" form_class = forms.Verify2FACodeForm @@ -254,6 +255,4 @@ class TwoFactorCodeVerifyView(LoginRequiredMixin, def form_valid(self, form): """Login user.""" django_otp.login(self.request, form.cleaned_data["tfa_code"]) - return HttpResponseRedirect( - find_nextlocation(self.request, self.request.user) - ) + return HttpResponseRedirect(find_nextlocation(self.request, self.request.user)) diff --git a/modoboa/core/views/base.py b/modoboa/core/views/base.py index 0de677140..483944af2 100644 --- a/modoboa/core/views/base.py +++ b/modoboa/core/views/base.py @@ -14,15 +14,13 @@ def find_nextlocation(request, user): # Redirect to profile on first login return reverse("core:user_index") nextlocation = request.POST.get("next", request.GET.get("next")) - condition = ( - nextlocation and - url_has_allowed_host_and_scheme(nextlocation, request.get_host()) + condition = nextlocation and url_has_allowed_host_and_scheme( + nextlocation, request.get_host() ) if condition: return nextlocation if request.user.role == "SimpleUsers": - topredir = request.localconfig.parameters.get_value( - "default_top_redirection") + topredir = request.localconfig.parameters.get_value("default_top_redirection") if topredir != "user": infos = exts_pool.get_extension_infos(topredir) nextlocation = infos["topredirection_url"] diff --git a/modoboa/core/views/dashboard.py b/modoboa/core/views/dashboard.py index 5443e9f90..be9e01e89 100644 --- a/modoboa/core/views/dashboard.py +++ b/modoboa/core/views/dashboard.py @@ -24,14 +24,12 @@ class DashboardView(auth_mixins.AccessMixin, generic.TemplateView): """Check if user can access dashboard.""" if not request.user.is_authenticated or not request.user.is_admin: return self.handle_no_permission() - return super(DashboardView, self).dispatch(request, *args, **kwargs) + return super().dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): """Add context variables.""" - context = super(DashboardView, self).get_context_data(**kwargs) - context.update({ - "selection": "dashboard", "widgets": {"left": [], "right": []} - }) + context = super().get_context_data(**kwargs) + context.update({"selection": "dashboard", "widgets": {"left": [], "right": []}}) # Fetch latest news if self.request.user.language == "fr": lang = "fr" @@ -41,8 +39,9 @@ class DashboardView(auth_mixins.AccessMixin, generic.TemplateView): feed_url = "{}{}/weblog/feeds/".format(MODOBOA_WEBSITE_URL, lang) if self.request.user.role != "SuperAdmins": - custom_feed_url = ( - self.request.localconfig.parameters.get_value("rss_feed_url")) + custom_feed_url = self.request.localconfig.parameters.get_value( + "rss_feed_url" + ) if custom_feed_url: feed_url = custom_feed_url entries = [] @@ -55,10 +54,10 @@ class DashboardView(auth_mixins.AccessMixin, generic.TemplateView): context.update({"news": entries}) hide_features_widget = self.request.localconfig.parameters.get_value( - "hide_features_widget") + "hide_features_widget" + ) if self.request.user.is_superuser or not hide_features_widget: - url = "{}{}/api/projects/?featured=true".format( - MODOBOA_WEBSITE_URL, lang) + url = "{}{}/api/projects/?featured=true".format(MODOBOA_WEBSITE_URL, lang) features = [] if not settings.DISABLE_DASHBOARD_EXTERNAL_QUERIES: try: @@ -73,11 +72,11 @@ class DashboardView(auth_mixins.AccessMixin, generic.TemplateView): # Extra widgets result = signals.extra_admin_dashboard_widgets.send( - sender=self.__class__, user=self.request.user) + sender=self.__class__, user=self.request.user + ) for _receiver, widgets in result: for widget in widgets: - context["widgets"][widget["column"]].append( - widget["template"]) + context["widgets"][widget["column"]].append(widget["template"]) # FIXME: can raise conflicts... context.update(widget["context"]) diff --git a/modoboa/core/views/user.py b/modoboa/core/views/user.py index 9c5e6ae52..ce97e1698 100644 --- a/modoboa/core/views/user.py +++ b/modoboa/core/views/user.py @@ -34,27 +34,23 @@ def index(request, tplname="core/user_index.html"): def profile(request, tplname="core/user_profile.html"): """Profile detail/update view.""" update_password = True - results = signals.allow_password_change.send( - sender="profile", user=request.user) + results = signals.allow_password_change.send(sender="profile", user=request.user) if True in [result[1] for result in results]: update_password = False - password_url = request.localconfig.parameters.get_value( - "update_password_url") + password_url = request.localconfig.parameters.get_value("update_password_url") show_password_url = False if not request.user.is_local and password_url: show_password_url = True update_password = False if request.method == "POST": - form = ProfileForm( - update_password, request.POST, instance=request.user - ) + form = ProfileForm(update_password, request.POST, instance=request.user) if form.is_valid(): form.save() if update_password and form.cleaned_data["confirmation"] != "": - request.session["password"] = force_str(encrypt( - form.cleaned_data["confirmation"] - )) + request.session["password"] = force_str( + encrypt(form.cleaned_data["confirmation"]) + ) translation.activate(request.user.language) response = render_to_json_response(_("Profile updated")) response.set_cookie(settings.LANGUAGE_COOKIE_NAME, request.user.language) @@ -62,38 +58,50 @@ def profile(request, tplname="core/user_profile.html"): return render_to_json_response({"form_errors": form.errors}, status=400) form = ProfileForm(update_password, instance=request.user) - return render_to_json_response({ - "content": render_to_string(tplname, { - "form": form, - "show_password_url": show_password_url, - "password_url": password_url - }, request) - }) + return render_to_json_response( + { + "content": render_to_string( + tplname, + { + "form": form, + "show_password_url": show_password_url, + "password_url": password_url, + }, + request, + ) + } + ) @login_required def preferences(request): if request.method == "POST": - forms = param_tools.registry.get_forms( - "user", request.POST, user=request.user) + forms = param_tools.registry.get_forms("user", request.POST, user=request.user) for formdef in forms: form = formdef["form"] if form.is_valid(): form.save() continue - return render_to_json_response({ - "prefix": form.app, "form_errors": form.errors - }, status=400) + return render_to_json_response( + {"prefix": form.app, "form_errors": form.errors}, status=400 + ) request.user.save() return render_to_json_response(_("Preferences saved")) - return render_to_json_response({ - "content": render_to_string("core/user_preferences.html", { - "forms": param_tools.registry.get_forms( - "user", user=request.user, first_app="general") - }, request), - "onload_cb": "preferencesCallback", - }) + return render_to_json_response( + { + "content": render_to_string( + "core/user_preferences.html", + { + "forms": param_tools.registry.get_forms( + "user", user=request.user, first_app="general" + ) + }, + request, + ), + "onload_cb": "preferencesCallback", + } + ) @login_required @@ -108,14 +116,11 @@ def api_access(request): else: Token.objects.filter(user=request.user).delete() return render_to_json_response(_("Access updated")) - return render_to_json_response({ - "form_errors": form.errors - }, status=400) + return render_to_json_response({"form_errors": form.errors}, status=400) form = APIAccessForm(user=request.user) - return render_to_json_response({ - "content": render_to_string( - "core/api_access.html", {"form": form}, request) - }) + return render_to_json_response( + {"content": render_to_string("core/api_access.html", {"form": form}, request)} + ) @login_required @@ -139,8 +144,7 @@ def security(request): img.save(buf) context.update({"qrcode": buf.getvalue().decode()}) resp = { - "content": render_to_string( - "core/user_security.html", context, request), - "callback": "security" + "content": render_to_string("core/user_security.html", context, request), + "callback": "security", } return render_to_json_response(resp) diff --git a/modoboa/dmarc/api/v2/viewsets.py b/modoboa/dmarc/api/v2/viewsets.py index 652df877f..1bbb1455e 100644 --- a/modoboa/dmarc/api/v2/viewsets.py +++ b/modoboa/dmarc/api/v2/viewsets.py @@ -12,7 +12,7 @@ from . import serializers class DMARCViewSet(GetThrottleViewsetMixin, viewsets.GenericViewSet): - permission_classes = (permissions.IsAuthenticated, ) + permission_classes = (permissions.IsAuthenticated,) def get_queryset(self): """Filter queryset based on current user.""" @@ -22,7 +22,7 @@ class DMARCViewSet(GetThrottleViewsetMixin, viewsets.GenericViewSet): methods=["get"], detail=True, serializer_class=serializers.DMARCAligmentSerializer, - url_path="dmarc/alignment_stats" + url_path="dmarc/alignment_stats", ) def alignment_stats(self, request, **kwargs): domain = self.get_object() diff --git a/modoboa/dmarc/constants.py b/modoboa/dmarc/constants.py index 56cfdf7f7..914efdd9a 100644 --- a/modoboa/dmarc/constants.py +++ b/modoboa/dmarc/constants.py @@ -6,5 +6,5 @@ ALLOWED_REASON_TYPES = ( "trusted_forwarder", "mailing_list", "local_policy", - "other" + "other", ) diff --git a/modoboa/dmarc/forms.py b/modoboa/dmarc/forms.py index ca374b925..859a17358 100644 --- a/modoboa/dmarc/forms.py +++ b/modoboa/dmarc/forms.py @@ -16,10 +16,8 @@ class ReportOptionsForm(forms.Form): current_year = forms.IntegerField(widget=forms.widgets.HiddenInput) current_week = forms.IntegerField() - query = forms.ChoiceField( - choices=[("previous", "Previous"), ("next", "Next")]) - resolve_hostnames = forms.BooleanField( - initial=False, required=False) + query = forms.ChoiceField(choices=[("previous", "Previous"), ("next", "Next")]) + resolve_hostnames = forms.BooleanField(initial=False, required=False) def __init__(self, *args, **kwargs): """Constructor.""" @@ -40,36 +38,45 @@ class ParametersForm(param_forms.AdminParametersForm): enable_rlookups = form_utils.YesNoField( label=_("Enable reverse lookups"), initial=False, - help_text=_( - "Enable reverse DNS lookups (reports will be longer to display)" - ) + help_text=_("Enable reverse DNS lookups (reports will be longer to display)"), ) -GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([ - ("dns", { - "label": _("DNS settings"), - "params": collections.OrderedDict([ - ("enable_rlookups", { - "label": _("Enable reverse lookups"), - "help_text": _( - "Enable reverse DNS lookups (reports will be longer to display)" - ) - }) - ]) - }) -]) +GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict( + [ + ( + "dns", + { + "label": _("DNS settings"), + "params": collections.OrderedDict( + [ + ( + "enable_rlookups", + { + "label": _("Enable reverse lookups"), + "help_text": _( + "Enable reverse DNS lookups (reports will be longer to display)" + ), + }, + ) + ] + ), + }, + ) + ] +) def load_settings(): """Load app settings.""" from modoboa.parameters import tools as param_tools - param_tools.registry.add( - "global", ParametersForm, _("DMARC")) + param_tools.registry.add("global", ParametersForm, _("DMARC")) param_tools.registry.add2( - "global", "dmarc", _("DMARC"), + "global", + "dmarc", + _("DMARC"), GLOBAL_PARAMETERS_STRUCT, serializers.DmarcGlobalParametersSerializer, - True + True, ) diff --git a/modoboa/dmarc/handlers.py b/modoboa/dmarc/handlers.py index fcd89e7a7..992bb7a65 100644 --- a/modoboa/dmarc/handlers.py +++ b/modoboa/dmarc/handlers.py @@ -14,9 +14,11 @@ def dmarc_domain_actions(sender, user, domain, **kwargs): """Return a link to access domain report.""" if not models.Record.objects.filter(header_from=domain).exists(): return [] - return [{ - "name": "dmarc_report", - "url": reverse("dmarc:domain_report", args=[domain.pk]), - "title": _("Show DMARC report for {}").format(domain.name), - "img": "fa fa-pie-chart" - }] + return [ + { + "name": "dmarc_report", + "url": reverse("dmarc:domain_report", args=[domain.pk]), + "title": _("Show DMARC report for {}").format(domain.name), + "img": "fa fa-pie-chart", + } + ] diff --git a/modoboa/dmarc/lib.py b/modoboa/dmarc/lib.py index ee9e9aa63..565cfacd5 100644 --- a/modoboa/dmarc/lib.py +++ b/modoboa/dmarc/lib.py @@ -66,8 +66,7 @@ def import_record(xml_node, report): header_from = identifiers.find("header_from").text.split(".") domain = None while len(header_from) >= 2: - domain = admin_models.Domain.objects.filter( - name=".".join(header_from)).first() + domain = admin_models.Domain.objects.filter(name=".".join(header_from)).first() if domain is not None: record.header_from = domain break @@ -83,8 +82,11 @@ def import_record(xml_node, report): if not rnode: continue models.Result.objects.create( - record=record, type=rtype, domain=rnode.find("domain").text, - result=rnode.find("result").text) + record=record, + type=rtype, + domain=rnode.find("domain").text, + result=rnode.find("result").text, + ) @transaction.atomic @@ -94,15 +96,16 @@ def import_report(content): metadata = root.find("report_metadata") print( "Importing report {} received from {}".format( - metadata.find("report_id").text, - metadata.find("org_name").text) + metadata.find("report_id").text, metadata.find("org_name").text + ) ) reporter, created = models.Reporter.objects.get_or_create( email=metadata.find("email").text, - defaults={"org_name": metadata.find("org_name").text} + defaults={"org_name": metadata.find("org_name").text}, ) qs = models.Report.objects.filter( - reporter=reporter, report_id=metadata.find("report_id").text) + reporter=reporter, report_id=metadata.find("report_id").text + ) if qs.exists(): print("Report already imported.") return @@ -122,7 +125,7 @@ def import_report(content): node = policy_published.find(attr) if node is None or not node.text: if attr == "sp": - node = fromstring('unstated', forbid_dtd=True) + node = fromstring("unstated", forbid_dtd=True) else: print(f"Report skipped because of malformed data (empty {attr})") return @@ -165,12 +168,14 @@ def import_report_from_email(content): fpo = six.BytesIO(part.get_payload(decode=True)) # Try to get the actual file type of the buffer # required to make sure we are dealing with an XML file - file_type = magic.Magic(uncompress=True, mime=True).from_buffer(fpo.read(2048)) + file_type = magic.Magic(uncompress=True, mime=True).from_buffer( + fpo.read(2048) + ) fpo.seek(0) if file_type in FILE_TYPES: import_archive(fpo, content_type=part.get_content_type()) except (OSError, IOError): - print('Error: the attachment does not match the mimetype') + print("Error: the attachment does not match the mimetype") err = True else: fpo.close() @@ -214,10 +219,8 @@ def week_range(year, weeknumber): """Return start and end dates of a given week.""" tz = timezone.get_current_timezone() fmt = "%Y-%W-%w" - start_week = datetime.datetime.strptime( - "{}-{}-{}".format(year, weeknumber, 1), fmt) - end_week = datetime.datetime.strptime( - "{}-{}-{}".format(year, weeknumber, 0), fmt) + start_week = datetime.datetime.strptime("{}-{}-{}".format(year, weeknumber, 1), fmt) + end_week = datetime.datetime.strptime("{}-{}-{}".format(year, weeknumber, 0), fmt) return start_week.replace(tzinfo=tz), end_week.replace(tzinfo=tz) @@ -230,7 +233,7 @@ def insert_record(target: dict, record, name: str) -> None: target[name][record.source_ip] = { "total": 0, "spf": {"success": 0, "failure": 0}, - "dkim": {"success": 0, "failure": 0} + "dkim": {"success": 0, "failure": 0}, } target[name][record.source_ip]["total"] += record.count for typ in ["spf", "dkim"]: @@ -252,19 +255,11 @@ def get_aligment_stats(domain, period=None) -> dict: daterange = week_range(year, week) qargs = ( - (Q(report__start_date__gte=daterange[0], - report__start_date__lte=daterange[1]) | - Q(report__end_date__gte=daterange[0], - report__end_date__lte=daterange[1])) & - Q(header_from=domain) - ) + Q(report__start_date__gte=daterange[0], report__start_date__lte=daterange[1]) + | Q(report__end_date__gte=daterange[0], report__end_date__lte=daterange[1]) + ) & Q(header_from=domain) all_records = models.Record.objects.filter(qargs) - stats: dict = { - "aligned": {}, - "trusted": {}, - "forwarded": {}, - "failed": {} - } + stats: dict = {"aligned": {}, "trusted": {}, "forwarded": {}, "failed": {}} dns_names = {} if param_tools.get_global_parameter("enable_rlookups"): @@ -279,16 +274,21 @@ def get_aligment_stats(domain, period=None) -> dict: ext = tldextract.extract(str(resp[0].target)) if not ext.suffix: # invalid PTR record raise resolver.NXDOMAIN() - return (ip, '.'.join((ext.domain, ext.suffix)).lower()) - except (resolver.NXDOMAIN, resolver.YXDOMAIN, - resolver.NoAnswer, resolver.NoNameservers, - resolver.Timeout): + return (ip, ".".join((ext.domain, ext.suffix)).lower()) + except ( + resolver.NXDOMAIN, + resolver.YXDOMAIN, + resolver.NoAnswer, + resolver.NoNameservers, + resolver.Timeout, + ): return (None, None) ips = (r.source_ip for r in all_records) with concurrent.futures.ThreadPoolExecutor(max_workers=16) as pool: - dns_names = {i: n for (i, n) in - list(pool.map(get_domain_name_from_ip, ips))} + dns_names = { + i: n for (i, n) in list(pool.map(get_domain_name_from_ip, ips)) + } for record in all_records: name = dns_names.get(record.source_ip, _("Not resolved")) @@ -296,7 +296,9 @@ def get_aligment_stats(domain, period=None) -> dict: insert_record(stats["aligned"], record, name) elif record.dkim_result == "pass" or record.spf_result == "pass": insert_record(stats["trusted"], record, name) - elif record.reason_type == "local_policy" and record.reason_comment.startswith("arc=pass"): + elif record.reason_type == "local_policy" and record.reason_comment.startswith( + "arc=pass" + ): insert_record(stats["forwarded"], record, name) else: insert_record(stats["failed"], record, name) diff --git a/modoboa/dmarc/management/commands/import_aggregated_report.py b/modoboa/dmarc/management/commands/import_aggregated_report.py index 28d211ee9..fd16c7ac0 100644 --- a/modoboa/dmarc/management/commands/import_aggregated_report.py +++ b/modoboa/dmarc/management/commands/import_aggregated_report.py @@ -15,20 +15,24 @@ class Command(BaseCommand): def add_arguments(self, parser): """Add extra arguments to parser.""" parser.add_argument( - "--pipe", action="store_true", default=False, - help="Import a report from an email given on stdin") + "--pipe", + action="store_true", + default=False, + help="Import a report from an email given on stdin", + ) parser.add_argument( - "--imap", action="store_true", default=False, - help="Import a report from an IMAP mailbox") + "--imap", + action="store_true", + default=False, + help="Import a report from an IMAP mailbox", + ) + parser.add_argument("--host", default="localhost", help="IMAP host") parser.add_argument( - "--host", default="localhost", - help="IMAP host") + "--ssl", action="store_true", default=False, help="Connect using SSL" + ), parser.add_argument( - "--ssl", action="store_true", default=False, - help="Connect using SSL"), - parser.add_argument( - "--mailbox", default="INBOX", - help="IMAP mailbox to import reports from") + "--mailbox", default="INBOX", help="IMAP mailbox to import reports from" + ) def handle(self, *args, **options): """Entry point.""" diff --git a/modoboa/dmarc/migrations/0001_initial.py b/modoboa/dmarc/migrations/0001_initial.py index 4ce5a8b2a..a9be64344 100644 --- a/modoboa/dmarc/migrations/0001_initial.py +++ b/modoboa/dmarc/migrations/0001_initial.py @@ -7,84 +7,162 @@ from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ - ('admin', '0002_migrate_from_modoboa_admin'), + ("admin", "0002_migrate_from_modoboa_admin"), ] operations = [ migrations.CreateModel( - name='Record', + name="Record", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('source_ip', models.GenericIPAddressField()), - ('count', models.IntegerField()), - ('disposition', models.CharField(max_length=10, choices=[(b'none', 'None'), (b'quarantine', 'Quarantine'), (b'reject', 'Reject')])), - ('dkim_result', models.CharField(max_length=9, choices=[(b'none', 'None'), (b'neutral', 'Neutral'), (b'pass', 'Pass'), (b'fail', 'Fail'), (b'temperror', 'Temporary error'), (b'permerror', 'Permanent error'), (b'policy', 'Policy')])), - ('spf_result', models.CharField(max_length=9, choices=[(b'none', 'None'), (b'neutral', 'Neutral'), (b'pass', 'Pass'), (b'fail', 'Fail'), (b'temperror', 'Temporary error'), (b'permerror', 'Permanent error'), (b'softfail', 'Soft failure')])), - ('reason_type', models.CharField(max_length=15, blank=True)), - ('reason_comment', models.CharField(max_length=100, blank=True)), - ('header_from', models.ForeignKey(to='admin.Domain', on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("source_ip", models.GenericIPAddressField()), + ("count", models.IntegerField()), + ( + "disposition", + models.CharField( + max_length=10, + choices=[ + (b"none", "None"), + (b"quarantine", "Quarantine"), + (b"reject", "Reject"), + ], + ), + ), + ( + "dkim_result", + models.CharField( + max_length=9, + choices=[ + (b"none", "None"), + (b"neutral", "Neutral"), + (b"pass", "Pass"), + (b"fail", "Fail"), + (b"temperror", "Temporary error"), + (b"permerror", "Permanent error"), + (b"policy", "Policy"), + ], + ), + ), + ( + "spf_result", + models.CharField( + max_length=9, + choices=[ + (b"none", "None"), + (b"neutral", "Neutral"), + (b"pass", "Pass"), + (b"fail", "Fail"), + (b"temperror", "Temporary error"), + (b"permerror", "Permanent error"), + (b"softfail", "Soft failure"), + ], + ), + ), + ("reason_type", models.CharField(max_length=15, blank=True)), + ("reason_comment", models.CharField(max_length=100, blank=True)), + ( + "header_from", + models.ForeignKey(to="admin.Domain", on_delete=models.CASCADE), + ), + ], + options={}, + bases=(models.Model,), + ), + migrations.CreateModel( + name="Report", + fields=[ + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("report_id", models.CharField(max_length=100)), + ("start_date", models.DateTimeField()), + ("end_date", models.DateTimeField()), + ("policy_domain", models.CharField(max_length=100)), + ("policy_adkim", models.CharField(max_length=1)), + ("policy_aspf", models.CharField(max_length=1)), + ("policy_p", models.CharField(max_length=10)), + ("policy_sp", models.CharField(max_length=10)), + ("policy_pct", models.SmallIntegerField()), ], options={ + "permissions": (("view_report", "Can view report"),), }, bases=(models.Model,), ), migrations.CreateModel( - name='Report', + name="Reporter", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('report_id', models.CharField(max_length=100)), - ('start_date', models.DateTimeField()), - ('end_date', models.DateTimeField()), - ('policy_domain', models.CharField(max_length=100)), - ('policy_adkim', models.CharField(max_length=1)), - ('policy_aspf', models.CharField(max_length=1)), - ('policy_p', models.CharField(max_length=10)), - ('policy_sp', models.CharField(max_length=10)), - ('policy_pct', models.SmallIntegerField()), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("org_name", models.CharField(max_length=100)), + ("email", models.EmailField(unique=True, max_length=254)), ], - options={ - 'permissions': (('view_report', 'Can view report'),), - }, + options={}, bases=(models.Model,), ), migrations.CreateModel( - name='Reporter', + name="Result", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('org_name', models.CharField(max_length=100)), - ('email', models.EmailField(unique=True, max_length=254)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ( + "type", + models.CharField( + max_length=4, choices=[(b"dkim", b"DKIM"), (b"spf", b"SPF")] + ), + ), + ("domain", models.CharField(max_length=100)), + ("result", models.CharField(max_length=9)), + ( + "record", + models.ForeignKey(to="dmarc.Record", on_delete=models.CASCADE), + ), ], - options={ - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='Result', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('type', models.CharField(max_length=4, choices=[(b'dkim', b'DKIM'), (b'spf', b'SPF')])), - ('domain', models.CharField(max_length=100)), - ('result', models.CharField(max_length=9)), - ('record', models.ForeignKey(to='dmarc.Record', on_delete=models.CASCADE)), - ], - options={ - }, + options={}, bases=(models.Model,), ), migrations.AddField( - model_name='report', - name='reporter', - field=models.ForeignKey(to='dmarc.Reporter', on_delete=models.CASCADE), + model_name="report", + name="reporter", + field=models.ForeignKey(to="dmarc.Reporter", on_delete=models.CASCADE), preserve_default=True, ), migrations.AlterUniqueTogether( - name='report', - unique_together=set([('reporter', 'report_id')]), + name="report", + unique_together=set([("reporter", "report_id")]), ), migrations.AddField( - model_name='record', - name='report', - field=models.ForeignKey(to='dmarc.Report', on_delete=models.CASCADE), + model_name="record", + name="report", + field=models.ForeignKey(to="dmarc.Report", on_delete=models.CASCADE), preserve_default=True, ), ] diff --git a/modoboa/dmarc/migrations/0002_auto_20180124_2311.py b/modoboa/dmarc/migrations/0002_auto_20180124_2311.py index bcaee13bc..b55e07d27 100644 --- a/modoboa/dmarc/migrations/0002_auto_20180124_2311.py +++ b/modoboa/dmarc/migrations/0002_auto_20180124_2311.py @@ -8,28 +8,59 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('dmarc', '0001_initial'), + ("dmarc", "0001_initial"), ] operations = [ migrations.AlterField( - model_name='record', - name='disposition', - field=models.CharField(choices=[('none', 'None'), ('quarantine', 'Quarantine'), ('reject', 'Reject')], max_length=10), + model_name="record", + name="disposition", + field=models.CharField( + choices=[ + ("none", "None"), + ("quarantine", "Quarantine"), + ("reject", "Reject"), + ], + max_length=10, + ), ), migrations.AlterField( - model_name='record', - name='dkim_result', - field=models.CharField(choices=[('none', 'None'), ('neutral', 'Neutral'), ('pass', 'Pass'), ('fail', 'Fail'), ('temperror', 'Temporary error'), ('permerror', 'Permanent error'), ('policy', 'Policy')], max_length=9), + model_name="record", + name="dkim_result", + field=models.CharField( + choices=[ + ("none", "None"), + ("neutral", "Neutral"), + ("pass", "Pass"), + ("fail", "Fail"), + ("temperror", "Temporary error"), + ("permerror", "Permanent error"), + ("policy", "Policy"), + ], + max_length=9, + ), ), migrations.AlterField( - model_name='record', - name='spf_result', - field=models.CharField(choices=[('none', 'None'), ('neutral', 'Neutral'), ('pass', 'Pass'), ('fail', 'Fail'), ('temperror', 'Temporary error'), ('permerror', 'Permanent error'), ('softfail', 'Soft failure')], max_length=9), + model_name="record", + name="spf_result", + field=models.CharField( + choices=[ + ("none", "None"), + ("neutral", "Neutral"), + ("pass", "Pass"), + ("fail", "Fail"), + ("temperror", "Temporary error"), + ("permerror", "Permanent error"), + ("softfail", "Soft failure"), + ], + max_length=9, + ), ), migrations.AlterField( - model_name='result', - name='type', - field=models.CharField(choices=[('dkim', 'DKIM'), ('spf', 'SPF')], max_length=4), + model_name="result", + name="type", + field=models.CharField( + choices=[("dkim", "DKIM"), ("spf", "SPF")], max_length=4 + ), ), ] diff --git a/modoboa/dmarc/migrations/0003_auto_20200227_0936.py b/modoboa/dmarc/migrations/0003_auto_20200227_0936.py index ec57fc0c5..90a6fc871 100644 --- a/modoboa/dmarc/migrations/0003_auto_20200227_0936.py +++ b/modoboa/dmarc/migrations/0003_auto_20200227_0936.py @@ -6,12 +6,12 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('dmarc', '0002_auto_20180124_2311'), + ("dmarc", "0002_auto_20180124_2311"), ] operations = [ migrations.AlterModelOptions( - name='report', + name="report", options={}, ), ] diff --git a/modoboa/dmarc/migrations/0004_auto_20220926_0913.py b/modoboa/dmarc/migrations/0004_auto_20220926_0913.py index 287dd0e91..73b236c42 100644 --- a/modoboa/dmarc/migrations/0004_auto_20220926_0913.py +++ b/modoboa/dmarc/migrations/0004_auto_20220926_0913.py @@ -6,28 +6,36 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('dmarc', '0003_auto_20200227_0936'), + ("dmarc", "0003_auto_20200227_0936"), ] operations = [ migrations.AlterField( - model_name='record', - name='id', - field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + model_name="record", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), ), migrations.AlterField( - model_name='report', - name='id', - field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + model_name="report", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), ), migrations.AlterField( - model_name='reporter', - name='id', - field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + model_name="reporter", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), ), migrations.AlterField( - model_name='result', - name='id', - field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + model_name="result", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), ), ] diff --git a/modoboa/dmarc/migrations/0005_auto_20230418_1201.py b/modoboa/dmarc/migrations/0005_auto_20230418_1201.py index 548179458..89fac5ea1 100644 --- a/modoboa/dmarc/migrations/0005_auto_20230418_1201.py +++ b/modoboa/dmarc/migrations/0005_auto_20230418_1201.py @@ -6,28 +6,36 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('dmarc', '0004_auto_20220926_0913'), + ("dmarc", "0004_auto_20220926_0913"), ] operations = [ migrations.AlterField( - model_name='record', - name='id', - field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + model_name="record", + name="id", + field=models.AutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), ), migrations.AlterField( - model_name='report', - name='id', - field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + model_name="report", + name="id", + field=models.AutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), ), migrations.AlterField( - model_name='reporter', - name='id', - field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + model_name="reporter", + name="id", + field=models.AutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), ), migrations.AlterField( - model_name='result', - name='id', - field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + model_name="result", + name="id", + field=models.AutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), ), ] diff --git a/modoboa/dmarc/models.py b/modoboa/dmarc/models.py index baf57a849..08fef1f78 100644 --- a/modoboa/dmarc/models.py +++ b/modoboa/dmarc/models.py @@ -9,7 +9,7 @@ from modoboa.admin import models as admin_models POLICY_DISPOSITIONS = [ ("none", _("None")), ("quarantine", _("Quarantine")), - ("reject", _("Reject")) + ("reject", _("Reject")), ] COMMON_RESULTS = [ @@ -18,16 +18,12 @@ COMMON_RESULTS = [ ("pass", _("Pass")), ("fail", _("Fail")), ("temperror", _("Temporary error")), - ("permerror", _("Permanent error")) + ("permerror", _("Permanent error")), ] -DKIM_RESULTS = COMMON_RESULTS + [ - ("policy", _("Policy")) -] +DKIM_RESULTS = COMMON_RESULTS + [("policy", _("Policy"))] -SPF_RESULTS = COMMON_RESULTS + [ - ("softfail", _("Soft failure")) -] +SPF_RESULTS = COMMON_RESULTS + [("softfail", _("Soft failure"))] RECORD_TYPES = [ ("dkim", "DKIM"), @@ -36,7 +32,6 @@ RECORD_TYPES = [ class Reporter(models.Model): - """Report issuers.""" org_name = models.CharField(max_length=100) @@ -48,7 +43,6 @@ class Reporter(models.Model): class Report(models.Model): - """Aggregated reports.""" report_id = models.CharField(max_length=100) @@ -69,12 +63,10 @@ class Report(models.Model): def __str__(self): """Display provider and dates.""" - return "{}: {} -> {}".format( - self.reporter, self.start_date, self.end_date) + return "{}: {} -> {}".format(self.reporter, self.start_date, self.end_date) class Record(models.Model): - """Report records.""" report = models.ForeignKey(Report, on_delete=models.CASCADE) @@ -82,20 +74,15 @@ class Record(models.Model): count = models.IntegerField() # Policy evaluated - disposition = models.CharField( - max_length=10, choices=POLICY_DISPOSITIONS) - dkim_result = models.CharField( - max_length=9, choices=DKIM_RESULTS) - spf_result = models.CharField( - max_length=9, choices=SPF_RESULTS) - header_from = models.ForeignKey(admin_models.Domain, - on_delete=models.CASCADE) + disposition = models.CharField(max_length=10, choices=POLICY_DISPOSITIONS) + dkim_result = models.CharField(max_length=9, choices=DKIM_RESULTS) + spf_result = models.CharField(max_length=9, choices=SPF_RESULTS) + header_from = models.ForeignKey(admin_models.Domain, on_delete=models.CASCADE) reason_type = models.CharField(max_length=15, blank=True) reason_comment = models.CharField(max_length=100, blank=True) class Result(models.Model): - """Record results.""" record = models.ForeignKey(Record, on_delete=models.CASCADE) diff --git a/modoboa/dmarc/templatetags/dmarc_tags.py b/modoboa/dmarc/templatetags/dmarc_tags.py index 7112ee490..74c5b2eb4 100644 --- a/modoboa/dmarc/templatetags/dmarc_tags.py +++ b/modoboa/dmarc/templatetags/dmarc_tags.py @@ -16,17 +16,22 @@ def next_period(period): """Return next period.""" current = period.split("-") if int(current[1]) == 52: - week0 = datetime.datetime.strptime("{}-0-1".format(int(current[0]) + 1 ), "%Y-%W-%w") - week1 = datetime.datetime.strptime("{}-1-1".format(int(current[0]) + 1 ), "%Y-%W-%w") + week0 = datetime.datetime.strptime( + "{}-0-1".format(int(current[0]) + 1), "%Y-%W-%w" + ) + week1 = datetime.datetime.strptime( + "{}-1-1".format(int(current[0]) + 1), "%Y-%W-%w" + ) week52 = datetime.datetime.strptime("{}-52-1".format(current[0]), "%Y-%W-%w") - if week0 == week52 or week0 == week1 : - parts = (int(current[0]) + 1, 1 ) + if week0 == week52 or week0 == week1: + parts = (int(current[0]) + 1, 1) else: - parts = (int(current[0]) + 1, 0 ) + parts = (int(current[0]) + 1, 0) else: - parts = (current[0], int(current[1]) + 1 ) + parts = (current[0], int(current[1]) + 1) return mark_safe("{}-{}".format(parts[0], parts[1])) + @register.simple_tag def previous_period(period): """Return previous period.""" @@ -35,18 +40,20 @@ def previous_period(period): week0 = datetime.datetime.strptime("{}-0-1".format(current[0]), "%Y-%W-%w") week1 = datetime.datetime.strptime("{}-1-1".format(current[0]), "%Y-%W-%w") if week0 == week1: - parts = (int(current[0]) - 1, 52 ) + parts = (int(current[0]) - 1, 52) else: - parts = (current[0], 0 ) + parts = (current[0], 0) elif int(current[1]) == 0: week0 = datetime.datetime.strptime("{}-0-1".format(current[0]), "%Y-%W-%w") - week52 = datetime.datetime.strptime("{}-52-1".format(int(current[0]) - 1 ), "%Y-%W-%w") + week52 = datetime.datetime.strptime( + "{}-52-1".format(int(current[0]) - 1), "%Y-%W-%w" + ) if week0 == week52: - parts = (int(current[0]) - 1, 51 ) + parts = (int(current[0]) - 1, 51) else: - parts = (int(current[0]) - 1, 52 ) + parts = (int(current[0]) - 1, 52) else: - parts = (current[0], int(current[1]) - 1 ) + parts = (current[0], int(current[1]) - 1) return mark_safe("{}-{}".format(parts[0], parts[1])) @@ -55,7 +62,8 @@ def domain_sorted_items(domain_dict): """Return a list of tuples ordered alphabetically by domain names.""" if isinstance(domain_dict, dict): sorted_domain_dict = OrderedDict( - sorted(domain_dict.items(), key=lambda t: t[0])) + sorted(domain_dict.items(), key=lambda t: t[0]) + ) unresolved_label = _("Not resolved") unresolved = sorted_domain_dict.pop(unresolved_label, None) if unresolved: diff --git a/modoboa/dmarc/tests/mixins.py b/modoboa/dmarc/tests/mixins.py index 29c3a5de7..3f27def1a 100644 --- a/modoboa/dmarc/tests/mixins.py +++ b/modoboa/dmarc/tests/mixins.py @@ -43,5 +43,5 @@ class CallCommandMixin(object): fpath = os.path.join(path, f) if f.startswith(".") or not os.path.isfile(fpath): continue - with self.assertRaisesMessage(SystemExit, '65'): + with self.assertRaisesMessage(SystemExit, "65"): self.import_report(fpath) diff --git a/modoboa/dmarc/tests/test_management_command.py b/modoboa/dmarc/tests/test_management_command.py index 7a4b9fc33..1a23be9ed 100644 --- a/modoboa/dmarc/tests/test_management_command.py +++ b/modoboa/dmarc/tests/test_management_command.py @@ -21,8 +21,8 @@ class ManagementCommandTestCase(mixins.CallCommandMixin, ModoTestCase): self.import_fail_reports() self.assertTrue(self.domain.record_set.exists()) self.assertTrue( - models.Reporter.objects.filter( - org_name="FastMail Pty Ltd").exists()) + models.Reporter.objects.filter(org_name="FastMail Pty Ltd").exists() + ) # Ensure that reports from Yahoo are processed successfully. # These do not contain a sp attribute in policy_published self.assertTrue( diff --git a/modoboa/dmarc/urls.py b/modoboa/dmarc/urls.py index be59ad665..8c9859f92 100644 --- a/modoboa/dmarc/urls.py +++ b/modoboa/dmarc/urls.py @@ -7,6 +7,5 @@ from . import views app_name = "dmarc" urlpatterns = [ - path("domains//", views.DomainReportView.as_view(), - name="domain_report"), + path("domains//", views.DomainReportView.as_view(), name="domain_report"), ] diff --git a/modoboa/dmarc/views.py b/modoboa/dmarc/views.py index 45dad1161..547308bea 100644 --- a/modoboa/dmarc/views.py +++ b/modoboa/dmarc/views.py @@ -29,7 +29,7 @@ def insert_record(target, record, name): target[name][record.source_ip] = { "total": 0, "spf": {"pass": 0, "fail": 0}, - "dkim": {"pass": 0, "fail": 0} + "dkim": {"pass": 0, "fail": 0}, } target[name][record.source_ip]["total"] += record.count for typ in ["spf", "dkim"]: @@ -41,16 +41,12 @@ def week_range(year, weeknumber): """Return start and end dates of a given week.""" tz = timezone.get_current_timezone() fmt = "%Y-%W-%w" - start_week = datetime.datetime.strptime( - "{}-{}-{}".format(year, weeknumber, 1), fmt) - end_week = datetime.datetime.strptime( - "{}-{}-{}".format(year, weeknumber, 0), fmt) + start_week = datetime.datetime.strptime("{}-{}-{}".format(year, weeknumber, 1), fmt) + end_week = datetime.datetime.strptime("{}-{}-{}".format(year, weeknumber, 0), fmt) return start_week.replace(tzinfo=tz), end_week.replace(tzinfo=tz) -class DomainReportView( - auth_mixins.PermissionRequiredMixin, - generic.TemplateView): +class DomainReportView(auth_mixins.PermissionRequiredMixin, generic.TemplateView): """ListView for Report.""" permission_required = "dmarc.view_report" @@ -69,26 +65,22 @@ class DomainReportView( self.daterange = week_range(year, week) self.domain = admin_models.Domain.objects.get(pk=self.kwargs["pk"]) qargs = ( - (Q(report__start_date__gte=self.daterange[0], - report__start_date__lte=self.daterange[1]) | - Q(report__end_date__gte=self.daterange[0], - report__end_date__lte=self.daterange[1])) & - Q(header_from=self.domain) - ) + Q( + report__start_date__gte=self.daterange[0], + report__start_date__lte=self.daterange[1], + ) + | Q( + report__end_date__gte=self.daterange[0], + report__end_date__lte=self.daterange[1], + ) + ) & Q(header_from=self.domain) return models.Record.objects.select_related().filter(qargs) def get_context_data(self, *args, **kwargs): """Extra context data.""" - context = super(DomainReportView, self).get_context_data( - *args, **kwargs) + context = super(DomainReportView, self).get_context_data(*args, **kwargs) qset = self.get_queryset() - stats = { - "total": 0, - "aligned": 0, - "trusted": 0, - "forwarded": 0, - "failed": 0 - } + stats = {"total": 0, "aligned": 0, "trusted": 0, "forwarded": 0, "failed": 0} aligned = {} trusted = {} forwarded = {} @@ -107,16 +99,21 @@ class DomainReportView( ext = tldextract.extract(str(resp[0].target)) if not ext.suffix: # invalid PTR record raise resolver.NXDOMAIN() - return (ip, '.'.join((ext.domain, ext.suffix)).lower()) - except (resolver.NXDOMAIN, resolver.YXDOMAIN, - resolver.NoAnswer, resolver.NoNameservers, - resolver.Timeout): + return (ip, ".".join((ext.domain, ext.suffix)).lower()) + except ( + resolver.NXDOMAIN, + resolver.YXDOMAIN, + resolver.NoAnswer, + resolver.NoNameservers, + resolver.Timeout, + ): return (None, None) ips = (r.source_ip for r in all_records) with concurrent.futures.ThreadPoolExecutor(max_workers=16) as pool: - dns_names = {i: n for (i, n) in - list(pool.map(get_domain_name_from_ip, ips))} + dns_names = { + i: n for (i, n) in list(pool.map(get_domain_name_from_ip, ips)) + } for record in all_records: stats["total"] += record.count @@ -127,7 +124,10 @@ class DomainReportView( elif record.dkim_result == "pass" or record.spf_result == "pass": stats["trusted"] += record.count insert_record(trusted, record, name) - elif record.reason_type == "local_policy" and record.reason_comment.startswith("arc=pass"): + elif ( + record.reason_type == "local_policy" + and record.reason_comment.startswith("arc=pass") + ): stats["forwarded"] += record.count insert_record(forwarded, record, name) else: @@ -136,16 +136,26 @@ class DomainReportView( pie_data = {} if stats["total"]: - pie_data.update({ - "faligned": stats["aligned"] / float(stats["total"]) * 100, - "paligned": stats["trusted"] / float(stats["total"]) * 100, - "forwarded": stats["forwarded"] / float(stats["total"]) * 100, - "failed": stats["failed"] / float(stats["total"]) * 100 - }) + pie_data.update( + { + "faligned": stats["aligned"] / float(stats["total"]) * 100, + "paligned": stats["trusted"] / float(stats["total"]) * 100, + "forwarded": stats["forwarded"] / float(stats["total"]) * 100, + "failed": stats["failed"] / float(stats["total"]) * 100, + } + ) - context.update({ - "stats": stats, "aligned": aligned, "trusted": trusted, "forwarded": forwarded, "threats": threats, - "period": self.period, "daterange": self.daterange, - "domain": self.domain, "pie_data": pie_data - }) + context.update( + { + "stats": stats, + "aligned": aligned, + "trusted": trusted, + "forwarded": forwarded, + "threats": threats, + "period": self.period, + "daterange": self.daterange, + "domain": self.domain, + "pie_data": pie_data, + } + ) return context diff --git a/modoboa/dnstools/api/v2/serializers.py b/modoboa/dnstools/api/v2/serializers.py index b6f8d90c6..b8df2f1d9 100644 --- a/modoboa/dnstools/api/v2/serializers.py +++ b/modoboa/dnstools/api/v2/serializers.py @@ -46,6 +46,11 @@ class DNSDetailSerializer(serializers.ModelSerializer): class Meta: model = admin_models.Domain fields = ( - "mx_records", "dnsbl_results", "autoconfig_record", - "autodiscover_record", "spf_record", "dkim_record", "dmarc_record" + "mx_records", + "dnsbl_results", + "autoconfig_record", + "autodiscover_record", + "spf_record", + "dkim_record", + "dmarc_record", ) diff --git a/modoboa/dnstools/api/v2/tests.py b/modoboa/dnstools/api/v2/tests.py index 773f3e5c8..55faea932 100644 --- a/modoboa/dnstools/api/v2/tests.py +++ b/modoboa/dnstools/api/v2/tests.py @@ -16,22 +16,24 @@ class DNSViewSetTestCase(ModoAPITestCase): super().setUpTestData() admin_factories.populate_database() cls.spf_rec = factories.DNSRecordFactory( - type="spf", value="v=SPF1 mx -all", is_valid=True, - domain__name="test.com" + type="spf", value="v=SPF1 mx -all", is_valid=True, domain__name="test.com" ) cls.dmarc_rec = factories.DNSRecordFactory( - type="dmarc", value="XXX", is_valid=False, + type="dmarc", + value="XXX", + is_valid=False, error="Not a DMARC record", - domain__name="test.com" + domain__name="test.com", ) cls.dkim_rec = factories.DNSRecordFactory( - type="dkim", value="12345", is_valid=False, + type="dkim", + value="12345", + is_valid=False, error="Public key mismatchs", - domain__name="test.com" + domain__name="test.com", ) cls.ac_rec = factories.DNSRecordFactory( - type="autoconfig", value="1.2.3.4", is_valid=True, - domain__name="test.com" + type="autoconfig", value="1.2.3.4", is_valid=True, domain__name="test.com" ) def test_dns_detail(self): diff --git a/modoboa/dnstools/api/v2/viewsets.py b/modoboa/dnstools/api/v2/viewsets.py index 881844d79..365a9d3cc 100644 --- a/modoboa/dnstools/api/v2/viewsets.py +++ b/modoboa/dnstools/api/v2/viewsets.py @@ -12,15 +12,15 @@ from . import serializers class DNSViewSet(GetThrottleViewsetMixin, viewsets.GenericViewSet): """A viewset to provide extra routes related to DNS information.""" - permission_classes = (permissions.IsAuthenticated, ) + permission_classes = (permissions.IsAuthenticated,) def get_queryset(self): """Filter queryset based on current user.""" return admin_models.Domain.objects.get_for_admin(self.request.user) - @action(methods=["get"], - detail=True, - serializer_class=serializers.DNSDetailSerializer) + @action( + methods=["get"], detail=True, serializer_class=serializers.DNSDetailSerializer + ) def dns_detail(self, request, **kwargs): domain = self.get_object() serializer = self.get_serializer(domain) diff --git a/modoboa/dnstools/apps.py b/modoboa/dnstools/apps.py index cc7cbcead..af3257cd8 100644 --- a/modoboa/dnstools/apps.py +++ b/modoboa/dnstools/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class DnstoolsConfig(AppConfig): - name = 'modoboa.dnstools' + name = "modoboa.dnstools" diff --git a/modoboa/dnstools/constants.py b/modoboa/dnstools/constants.py index c579193ee..1ca6e6a45 100644 --- a/modoboa/dnstools/constants.py +++ b/modoboa/dnstools/constants.py @@ -25,5 +25,5 @@ DMARC_TAGS = { "ri": {"type": "int"}, "rua": {"type": "list", "regex": DMARC_URI_REGEX}, "ruf": {"type": "list", "regex": DMARC_URI_REGEX}, - "sp": {"values": ["none", "quarantine", "reject"]} + "sp": {"values": ["none", "quarantine", "reject"]}, } diff --git a/modoboa/dnstools/lib.py b/modoboa/dnstools/lib.py index e9edbb7f1..eb48b5068 100644 --- a/modoboa/dnstools/lib.py +++ b/modoboa/dnstools/lib.py @@ -16,8 +16,8 @@ def _get_record_type_value(records, rr_type): for record in records: # Multiple strings are separated by a space as described in: # https://tools.ietf.org/html/rfc4408#section-3.1.3 - value = str(record).replace('" "', '').strip('"') - if value.startswith('v={}'.format(rr_type)): + value = str(record).replace('" "', "").strip('"') + if value.startswith("v={}".format(rr_type)): return value return None @@ -25,21 +25,21 @@ def _get_record_type_value(records, rr_type): def get_spf_record(domain): """Return SPF record for domain (if any).""" records = admin_lib.get_dns_records(domain, "TXT") - return _get_record_type_value(records, 'spf1') + return _get_record_type_value(records, "spf1") def get_dkim_record(domain, selector): """Return DKIM records form domain (if any).""" name = "{}._domainkey.{}".format(selector, domain) records = admin_lib.get_dns_records(name, "TXT") - return _get_record_type_value(records, 'DKIM1') + return _get_record_type_value(records, "DKIM1") def get_dmarc_record(domain): """Return DMARC record for domain (if any).""" name = "_dmarc.{}".format(domain) records = admin_lib.get_dns_records(name, "TXT") - return _get_record_type_value(records, 'DMARC1') + return _get_record_type_value(records, "DMARC1") def _get_simple_record(name): @@ -108,8 +108,7 @@ def _check_domain_and_mask(value, mechanism): elif "/" in value: mechanism, mask = value.split("/") else: - raise DNSSyntaxError( - _("Invalid syntax for {} mechanism").format(mechanism)) + raise DNSSyntaxError(_("Invalid syntax for {} mechanism").format(mechanism)) if mask and (not mask.isdigit() or int(mask) > 32): raise DNSSyntaxError(_("Invalid mask found {}").format(mask)) @@ -134,8 +133,7 @@ def _check_simple(value, mechanism): return parts = value.split(":") if len(parts) != 2: - raise DNSSyntaxError( - _("Invalid syntax for {} mechanism").format(mechanism)) + raise DNSSyntaxError(_("Invalid syntax for {} mechanism").format(mechanism)) def check_spf_ptr(value): @@ -180,11 +178,11 @@ def check_spf_syntax(record): if len(modifier) != 2: raise DNSSyntaxError(_("Unknown mechanism {}").format(part)) if modifier[0] not in ["redirect", "exp"]: - raise DNSSyntaxError(_("Unknown modifier {}").format( - modifier[0])) + raise DNSSyntaxError(_("Unknown modifier {}").format(modifier[0])) if modifier[0] in modifiers: - raise DNSSyntaxError(_("Duplicate modifier {} found").format( - modifier[0])) + raise DNSSyntaxError( + _("Duplicate modifier {} found").format(modifier[0]) + ) modifiers.append(modifier[0]) if not len(mechanisms) and not len(modifiers): raise DNSSyntaxError(_("No mechanism found")) @@ -235,11 +233,11 @@ def check_dmarc_tag(tag, value): except ValueError: raise DNSSyntaxError(error + _(" not an integer")) if "min_value" in tdef and value < tdef["min_value"]: - raise DNSSyntaxError( - error + _(" less than {}").format(tdef["min_value"])) + raise DNSSyntaxError(error + _(" less than {}").format(tdef["min_value"])) if "max_value" in tdef and value > tdef["max_value"]: raise DNSSyntaxError( - error + _(" greater than {}").format(tdef["max_value"])) + error + _(" greater than {}").format(tdef["max_value"]) + ) else: check_dmarc_tag_string_value(tag, value) diff --git a/modoboa/dnstools/migrations/0001_initial.py b/modoboa/dnstools/migrations/0001_initial.py index 794895dbb..5ac4a06b9 100644 --- a/modoboa/dnstools/migrations/0001_initial.py +++ b/modoboa/dnstools/migrations/0001_initial.py @@ -9,20 +9,45 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('admin', '0014_auto_20181017_1628'), + ("admin", "0014_auto_20181017_1628"), ] operations = [ migrations.CreateModel( - name='DNSRecord', + name="DNSRecord", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('type', models.CharField(choices=[('spf', 'SPF'), ('dkim', 'DKIM'), ('dmarc', 'DMARC'), ('autoconfig', 'Autoconfig'), ('autodiscover', 'Autodiscover')], max_length=15)), - ('value', models.TextField(blank=True)), - ('is_valid', models.BooleanField(default=False)), - ('error', models.CharField(blank=True, max_length=50, null=True)), - ('updated', models.DateTimeField(default=django.utils.timezone.now)), - ('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='admin.Domain')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "type", + models.CharField( + choices=[ + ("spf", "SPF"), + ("dkim", "DKIM"), + ("dmarc", "DMARC"), + ("autoconfig", "Autoconfig"), + ("autodiscover", "Autodiscover"), + ], + max_length=15, + ), + ), + ("value", models.TextField(blank=True)), + ("is_valid", models.BooleanField(default=False)), + ("error", models.CharField(blank=True, max_length=50, null=True)), + ("updated", models.DateTimeField(default=django.utils.timezone.now)), + ( + "domain", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="admin.Domain" + ), + ), ], ), ] diff --git a/modoboa/dnstools/models.py b/modoboa/dnstools/models.py index 73fad5ecf..e74e495c7 100644 --- a/modoboa/dnstools/models.py +++ b/modoboa/dnstools/models.py @@ -19,8 +19,11 @@ class DNSRecordManager(models.Manager): DNS queries are not performed while `ttl` (in seconds) is still valid. """ now = timezone.now() - record = self.get_queryset().filter( - domain=domain, type=rtype, updated__gt=now).first() + record = ( + self.get_queryset() + .filter(domain=domain, type=rtype, updated__gt=now) + .first() + ) if record: return record @@ -38,8 +41,7 @@ class DNSRecord(models.Model): """A model to store DNS records for Domain.""" domain = models.ForeignKey("admin.Domain", on_delete=models.CASCADE) - type = models.CharField( - max_length=15, choices=constants.DNS_RECORD_TYPES) + type = models.CharField(max_length=15, choices=constants.DNS_RECORD_TYPES) value = models.TextField(blank=True) is_valid = models.BooleanField(default=False) error = models.CharField(max_length=50, null=True, blank=True) @@ -54,7 +56,8 @@ class DNSRecord(models.Model): """Retrieve corresponding DNS record.""" if self.type == "dkim": self.value = lib.get_dkim_record( - self.domain.name, self.domain.dkim_key_selector) + self.domain.name, self.domain.dkim_key_selector + ) else: func = getattr(lib, "get_{}_record".format(self.type)) self.value = func(self.domain.name) diff --git a/modoboa/dnstools/tests.py b/modoboa/dnstools/tests.py index 0bf8d4f62..a3e57430d 100644 --- a/modoboa/dnstools/tests.py +++ b/modoboa/dnstools/tests.py @@ -30,8 +30,10 @@ BAD_SPF_RECORDS = [ ("v=spf1 mx/1000", "Invalid mask found 1000"), ("v=spf1 ptr|test.com", "Invalid syntax for ptr mechanism"), ("v=spf1 forward=test.com ~all", "Unknown modifier forward"), - ("v=spf1 redirect=test.com redirect=test.com ~all", - "Duplicate modifier redirect found"), + ( + "v=spf1 redirect=test.com redirect=test.com ~all", + "Duplicate modifier redirect found", + ), ("v=spf1", "No mechanism found"), ] @@ -62,8 +64,7 @@ BAD_DMARC_RECORDS = [ ("v=DMARC1; test", "Invalid tag test"), ("v=DMARC1; test=toto", "Unknown tag test"), ("v=DMARC1; adkim=g", "Wrong value g for tag adkim"), - ("v=DMARC1; rua=mail:toto@test.com", - "Wrong value mail:toto@test.com for tag rua"), + ("v=DMARC1; rua=mail:toto@test.com", "Wrong value mail:toto@test.com for tag rua"), ("v=DMARC1; rf=afrf,toto", "Wrong value toto for tag rf"), ("v=DMARC1; ri=XXX", "Wrong value XXX for tag ri: not an integer"), ("v=DMARC1; pct=-1", "Wrong value -1 for tag pct: less than 0"), @@ -75,7 +76,7 @@ GOOD_DMARC_RECORDS = [ "v=DMARC1; p=reject;; pct=100", "v=DMARC1; p=quarantine; sp=none; adkim=s; aspf=s; " "rua=mailto:dmarc-aggrep@ngyn.org; ruf=mailto:toto@test.com!24m; " - "rf=afrf; pct=100; ri=86400" + "rf=afrf; pct=100; ri=86400", ] BAD_DKIM_RECORDS = [ @@ -88,22 +89,18 @@ BAD_DKIM_RECORDS = [ class LibTestCase(SimpleTestCase): """TestCase for library methods.""" - @mock.patch('modoboa.admin.lib.get_dns_records') + @mock.patch("modoboa.admin.lib.get_dns_records") def test_get_record_type_value(self, mock_get_dns_records): mock_get_dns_records.return_value = [ TXT("IN", "TXT", ["v=spf1 mx -all"]), TXT("IN", "TXT", ["v=DKIM1 p=XXXXX", "YYYYY"]), TXT("IN", "TXT", ["v=DMARC1 p=reject"]), ] - self.assertEqual( - lib.get_spf_record("example.com"), "v=spf1 mx -all" - ) + self.assertEqual(lib.get_spf_record("example.com"), "v=spf1 mx -all") self.assertEqual( lib.get_dkim_record("example.com", "mail"), "v=DKIM1 p=XXXXXYYYYY" ) - self.assertEqual( - lib.get_dmarc_record("example.com"), "v=DMARC1 p=reject" - ) + self.assertEqual(lib.get_dmarc_record("example.com"), "v=DMARC1 p=reject") def test_check_spf_syntax(self): for record in BAD_SPF_RECORDS: @@ -138,44 +135,44 @@ class ViewsTestCase(ModoTestCase): """Create some records.""" super(ViewsTestCase, cls).setUpTestData() cls.spf_rec = factories.DNSRecordFactory( - type="spf", value="v=SPF1 mx -all", is_valid=True, - domain__name="test.com" + type="spf", value="v=SPF1 mx -all", is_valid=True, domain__name="test.com" ) cls.dmarc_rec = factories.DNSRecordFactory( - type="dmarc", value="XXX", is_valid=False, + type="dmarc", + value="XXX", + is_valid=False, error="Not a DMARC record", - domain__name="test.com" + domain__name="test.com", ) cls.dkim_rec = factories.DNSRecordFactory( - type="dkim", value="12345", is_valid=False, + type="dkim", + value="12345", + is_valid=False, error="Public key mismatchs", - domain__name="test.com" + domain__name="test.com", ) cls.ac_rec = factories.DNSRecordFactory( - type="autoconfig", value="1.2.3.4", is_valid=True, - domain__name="test.com" + type="autoconfig", value="1.2.3.4", is_valid=True, domain__name="test.com" ) def test_record_detail_view(self): url = reverse("dnstools:dns_record_detail", args=[self.spf_rec.pk]) response = self.client.get(url) - self.assertContains( - response, "A DNS record has been found and is valid") + self.assertContains(response, "A DNS record has been found and is valid") url = reverse("dnstools:dns_record_detail", args=[self.dmarc_rec.pk]) response = self.client.get(url) self.assertContains(response, "Not a DMARC record") def test_autoconfig_record_status_view(self): url = reverse( - "dnstools:autoconfig_records_status", args=[self.ac_rec.domain.pk]) + "dnstools:autoconfig_records_status", args=[self.ac_rec.domain.pk] + ) response = self.client.get(url) self.assertContains(response, "autoconfig record (Mozilla) found") - self.assertContains( - response, "autodiscover record (Microsoft) not found") + self.assertContains(response, "autodiscover record (Microsoft) not found") def test_domain_dns_configuration(self): - url = reverse( - "dnstools:domain_dns_configuration", args=[self.ac_rec.domain.pk]) + url = reverse("dnstools:domain_dns_configuration", args=[self.ac_rec.domain.pk]) response = self.client.get(url) self.assertContains(response, "[IP address of your Modoboa server]") @@ -184,37 +181,32 @@ class DomainTestCase(ModoTestCase): def test_dns_global_status(self): admin_factories.MXRecordFactory.create( - domain__name="test.com", name="mail.test.com", - updated=timezone.now()) + domain__name="test.com", name="mail.test.com", updated=timezone.now() + ) domain = admin_models.Domain.objects.get(name="test.com") self.assertEqual(domain.dns_global_status, "critical") factories.DNSRecordFactory.create( - type="spf", value="v=SPF1 mx -all", is_valid=True, - domain__name="test.com" + type="spf", value="v=SPF1 mx -all", is_valid=True, domain__name="test.com" ) self.assertEqual(domain.dns_global_status, "critical") factories.DNSRecordFactory( - type="dkim", value="12345", is_valid=True, - domain__name="test.com" + type="dkim", value="12345", is_valid=True, domain__name="test.com" ) self.assertEqual(domain.dns_global_status, "critical") factories.DNSRecordFactory( - type="dmarc", value="XXX", is_valid=True, - domain__name="test.com" + type="dmarc", value="XXX", is_valid=True, domain__name="test.com" ) self.assertEqual(domain.dns_global_status, "critical") factories.DNSRecordFactory( - type="autoconfig", value="1.2.3.4", is_valid=True, - domain__name="test.com" + type="autoconfig", value="1.2.3.4", is_valid=True, domain__name="test.com" ) self.assertEqual(domain.dns_global_status, "critical") factories.DNSRecordFactory( - type="autodiscover", value="1.2.3.4", is_valid=True, - domain__name="test.com" + type="autodiscover", value="1.2.3.4", is_valid=True, domain__name="test.com" ) self.assertEqual(domain.dns_global_status, "ok") diff --git a/modoboa/dnstools/urls.py b/modoboa/dnstools/urls.py index 2c43d053f..aa6369bfa 100644 --- a/modoboa/dnstools/urls.py +++ b/modoboa/dnstools/urls.py @@ -7,12 +7,19 @@ from . import views app_name = "dnstools" urlpatterns = [ - path('dnsrecords//', views.DNSRecordDetailView.as_view(), - name="dns_record_detail"), - path('dnsrecords/autoconfig//', - views.AutoConfigRecordsStatusView.as_view(), - name="autoconfig_records_status"), - path('configuration//', - views.DomainDNSConfigurationView.as_view(), - name="domain_dns_configuration"), + path( + "dnsrecords//", + views.DNSRecordDetailView.as_view(), + name="dns_record_detail", + ), + path( + "dnsrecords/autoconfig//", + views.AutoConfigRecordsStatusView.as_view(), + name="autoconfig_records_status", + ), + path( + "configuration//", + views.DomainDNSConfigurationView.as_view(), + name="domain_dns_configuration", + ), ] diff --git a/modoboa/dnstools/views.py b/modoboa/dnstools/views.py index dd2297e01..c8871c783 100644 --- a/modoboa/dnstools/views.py +++ b/modoboa/dnstools/views.py @@ -16,14 +16,12 @@ class DomainAccessRequiredMixin(auth_mixins.AccessMixin): def dispatch(self, request, *args, **kwargs): if not request.user.can_access(self.get_object()): return self.handle_no_permission() - return super(DomainAccessRequiredMixin, self).dispatch( - request, *args, **kwargs) + return super(DomainAccessRequiredMixin, self).dispatch(request, *args, **kwargs) class DNSRecordDetailView( - auth_mixins.LoginRequiredMixin, - DomainAccessRequiredMixin, - generic.DetailView): + auth_mixins.LoginRequiredMixin, DomainAccessRequiredMixin, generic.DetailView +): """View to display MX records.""" model = models.DNSRecord @@ -32,17 +30,21 @@ class DNSRecordDetailView( def get_context_data(self, **kwargs): """Add extra variables.""" context = super(DNSRecordDetailView, self).get_context_data(**kwargs) - context.update({ - "title": _("{} record of {}").format( - self.object.type.upper(), self.object.domain) - }) + context.update( + { + "title": _("{} record of {}").format( + self.object.type.upper(), self.object.domain + ) + } + ) return context class AutoConfigRecordsStatusView( - auth_mixins.LoginRequiredMixin, - auth_mixins.PermissionRequiredMixin, - generic.DetailView): + auth_mixins.LoginRequiredMixin, + auth_mixins.PermissionRequiredMixin, + generic.DetailView, +): """Autoconfig records status view.""" model = admin_models.Domain @@ -51,26 +53,22 @@ class AutoConfigRecordsStatusView( def get_queryset(self): """Add some prefetching.""" - return ( - admin_models.Domain.objects.get_for_admin(self.request.user) - .prefetch_related("dnsrecord_set") - ) + return admin_models.Domain.objects.get_for_admin( + self.request.user + ).prefetch_related("dnsrecord_set") def get_context_data(self, **kwargs): """Add extra data to context.""" - context = super(AutoConfigRecordsStatusView, self).get_context_data( - **kwargs) - context.update({ - "title": _("Auto configuration records for {}").format( - self.object.name) - }) + context = super(AutoConfigRecordsStatusView, self).get_context_data(**kwargs) + context.update( + {"title": _("Auto configuration records for {}").format(self.object.name)} + ) return context class DomainDNSConfigurationView( - auth_mixins.LoginRequiredMixin, - DomainAccessRequiredMixin, - generic.DetailView): + auth_mixins.LoginRequiredMixin, DomainAccessRequiredMixin, generic.DetailView +): """Page to display DNS configuration for a domain.""" model = admin_models.Domain @@ -78,9 +76,6 @@ class DomainDNSConfigurationView( def get_context_data(self, **kwargs): """Add extra variables.""" - context = super(DomainDNSConfigurationView, self).get_context_data( - **kwargs) - context.update({ - "title": _("DNS configuration for {}").format(self.object) - }) + context = super(DomainDNSConfigurationView, self).get_context_data(**kwargs) + context.update({"title": _("DNS configuration for {}").format(self.object)}) return context diff --git a/modoboa/imap_migration/api/v2/serializers.py b/modoboa/imap_migration/api/v2/serializers.py index f86616fdb..e94f67982 100644 --- a/modoboa/imap_migration/api/v2/serializers.py +++ b/modoboa/imap_migration/api/v2/serializers.py @@ -21,12 +21,12 @@ class IMAPMigrationSettingsSerializer(serializers.Serializer): # OfflineIMAP Filter settings create_folders = serializers.BooleanField(default=True) - folder_filter_exclude = serializers.CharField(required=False, - allow_blank=True, - default="") - folder_filter_include = serializers.CharField(required=False, - allow_blank=True, - default="") + folder_filter_exclude = serializers.CharField( + required=False, allow_blank=True, default="" + ) + folder_filter_include = serializers.CharField( + required=False, allow_blank=True, default="" + ) class EmailProviderDomainSerializer(serializers.ModelSerializer): @@ -35,11 +35,7 @@ class EmailProviderDomainSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) class Meta: - extra_kwargs = { - "name": { - "validators": [] - } - } + extra_kwargs = {"name": {"validators": []}} fields = ("id", "name", "new_domain") model = models.EmailProviderDomain @@ -61,8 +57,9 @@ class EmailProviderSerializer(serializers.ModelSerializer): if domains: to_create = [] for domain in domains: - to_create.append(models.EmailProviderDomain( - provider=provider, **domain)) + to_create.append( + models.EmailProviderDomain(provider=provider, **domain) + ) models.EmailProviderDomain.objects.bulk_create(to_create) return provider @@ -87,11 +84,13 @@ class EmailProviderSerializer(serializers.ModelSerializer): break to_create = [] for new_domain in domains: - to_create.append(models.EmailProviderDomain( - name=new_domain["name"], - new_domain=new_domain.get("new_domain"), - provider=instance - )) + to_create.append( + models.EmailProviderDomain( + name=new_domain["name"], + new_domain=new_domain.get("new_domain"), + provider=instance, + ) + ) models.EmailProviderDomain.objects.bulk_create(to_create) return instance @@ -108,14 +107,12 @@ class CheckAssociatedDomainSerializer(serializers.Serializer): """A serializer for checking associated domains.""" name = serializers.CharField() - new_domain = serializers.PrimaryKeyRelatedField( - read_only=True, required=False) + new_domain = serializers.PrimaryKeyRelatedField(read_only=True, required=False) def validate_new_domain(self, value): - domain_ids = ( - Domain.objects.get_for_admin(self.context["request"].user) - .values_list("id", flat=True) - ) + domain_ids = Domain.objects.get_for_admin( + self.context["request"].user + ).values_list("id", flat=True) if value not in domain_ids: raise serializers.ValidationError(_("Access denied")) return value @@ -138,4 +135,3 @@ class MigrationSerializer(serializers.ModelSerializer): depth = 1 fields = ("id", "provider", "mailbox", "username") model = models.Migration - diff --git a/modoboa/imap_migration/api/v2/viewsets.py b/modoboa/imap_migration/api/v2/viewsets.py index 0f52bcd05..ef069ac20 100644 --- a/modoboa/imap_migration/api/v2/viewsets.py +++ b/modoboa/imap_migration/api/v2/viewsets.py @@ -16,13 +16,13 @@ from . import serializers class EmailProviderViewSet(GetThrottleViewsetMixin, viewsets.ModelViewSet): """ViewSet class for EmailProvider.""" - filter_backends = (filters.SearchFilter, ) + filter_backends = (filters.SearchFilter,) permission_classes = ( permissions.IsAuthenticated, - permissions.DjangoModelPermissions + permissions.DjangoModelPermissions, ) queryset = models.EmailProvider.objects.all().prefetch_related("domains") - search_fields = ("name", ) + search_fields = ("name",) serializer_class = serializers.EmailProviderSerializer @action(methods=["post"], detail=False) @@ -39,7 +39,7 @@ class EmailProviderViewSet(GetThrottleViewsetMixin, viewsets.ModelViewSet): else: imaplib.IMAP4(address, port) except (socket.error, imaplib.IMAP4.error, ssl.SSLError): - return response.Response({'status': 'failed'}, 400) + return response.Response({"status": "failed"}, 400) return response.Response(status=200) @action(methods=["post"], detail=False) @@ -52,21 +52,27 @@ class EmailProviderViewSet(GetThrottleViewsetMixin, viewsets.ModelViewSet): return response.Response(status=200) -class MigrationViewSet(GetThrottleViewsetMixin, - mixins.ListModelMixin, - mixins.RetrieveModelMixin, - mixins.DestroyModelMixin, - viewsets.GenericViewSet): +class MigrationViewSet( + GetThrottleViewsetMixin, + mixins.ListModelMixin, + mixins.RetrieveModelMixin, + mixins.DestroyModelMixin, + viewsets.GenericViewSet, +): """ViewSet class for Migration.""" - filter_backends = (filters.SearchFilter, ) + filter_backends = (filters.SearchFilter,) permission_classes = ( permissions.IsAuthenticated, - permissions.DjangoModelPermissions + permissions.DjangoModelPermissions, ) queryset = models.Migration.objects.all().select_related( - "provider", "mailbox__domain") + "provider", "mailbox__domain" + ) search_fields = ( - "username", "provider__name", "mailbox__address", - "mailbox__domain__name") + "username", + "provider__name", + "mailbox__address", + "mailbox__domain__name", + ) serializer_class = serializers.MigrationSerializer diff --git a/modoboa/imap_migration/app_settings.py b/modoboa/imap_migration/app_settings.py index d73d194da..ba3e90bf6 100644 --- a/modoboa/imap_migration/app_settings.py +++ b/modoboa/imap_migration/app_settings.py @@ -9,51 +9,86 @@ from modoboa.lib import form_utils from modoboa.parameters import forms as param_forms -IMAP_MIGRATION_PARAMETERS_STRUCT = collections.OrderedDict([ - ("general", { - "label": _("General"), - "params": collections.OrderedDict([ - ("enabled_imapmigration", { - "label": _("Enable IMAP Migration"), - "help_text": _( - "Enable IMAP Migration."), - }) - ]) - }), - ("offlineimap", { - "label": _("OfflineIMAP"), - "params": collections.OrderedDict([ - ("max_sync_accounts", { - "label": _("Concurrent sync jobs"), - "help_text": _( - "The maximum number of concurrent synchronization jobs") - }) - ]) - }), - ("offlineimapfilter", { - "label": _("OfflineIMAP Filter"), - "params": collections.OrderedDict([ - ("create_folders", { - "label": _("Create Folders"), - "help_text": _( - "Allow Creation of missing folders during sync"), - }), - ("folder_filter_exclude", { - "label": _("Folder Filter Exclusions"), - "help_text": _( - "Use a regular expression to explicitly include folders in sync. " - "Example: ^Trash$|Del") - }), - ("folder_filter_include", { - "label": _("Folder Filter Inclusions"), - "help_text": _( - "A comma seperated list of folders to explicitly include in sync " - "even if filtered by the Folder Filter Exclusions. Example: " - "debian.user, debian.personal ") - }) - ]) - }) -]) +IMAP_MIGRATION_PARAMETERS_STRUCT = collections.OrderedDict( + [ + ( + "general", + { + "label": _("General"), + "params": collections.OrderedDict( + [ + ( + "enabled_imapmigration", + { + "label": _("Enable IMAP Migration"), + "help_text": _("Enable IMAP Migration."), + }, + ) + ] + ), + }, + ), + ( + "offlineimap", + { + "label": _("OfflineIMAP"), + "params": collections.OrderedDict( + [ + ( + "max_sync_accounts", + { + "label": _("Concurrent sync jobs"), + "help_text": _( + "The maximum number of concurrent synchronization jobs" + ), + }, + ) + ] + ), + }, + ), + ( + "offlineimapfilter", + { + "label": _("OfflineIMAP Filter"), + "params": collections.OrderedDict( + [ + ( + "create_folders", + { + "label": _("Create Folders"), + "help_text": _( + "Allow Creation of missing folders during sync" + ), + }, + ), + ( + "folder_filter_exclude", + { + "label": _("Folder Filter Exclusions"), + "help_text": _( + "Use a regular expression to explicitly include folders in sync. " + "Example: ^Trash$|Del" + ), + }, + ), + ( + "folder_filter_include", + { + "label": _("Folder Filter Inclusions"), + "help_text": _( + "A comma seperated list of folders to explicitly include in sync " + "even if filtered by the Folder Filter Exclusions. Example: " + "debian.user, debian.personal " + ), + }, + ), + ] + ), + }, + ), + ] +) class ParametersForm(param_forms.AdminParametersForm): @@ -66,7 +101,7 @@ class ParametersForm(param_forms.AdminParametersForm): enabled_imapmigration = form_utils.YesNoField( label=_("Enable IMAP Migration"), initial=True, - help_text=_("Enable IMAP Migration.") + help_text=_("Enable IMAP Migration."), ) sep2 = form_utils.SeparatorField(label=_("OfflineIMAP settings")) @@ -74,7 +109,7 @@ class ParametersForm(param_forms.AdminParametersForm): max_sync_accounts = forms.IntegerField( label=_("Concurrent sync jobs"), initial=1, - help_text=_("The maximum number of concurrent synchronization jobs") + help_text=_("The maximum number of concurrent synchronization jobs"), ) sep3 = form_utils.SeparatorField(label=_("OfflineIMAP Filter settings")) @@ -82,7 +117,7 @@ class ParametersForm(param_forms.AdminParametersForm): create_folders = form_utils.YesNoField( label=_("Create Folders"), initial=True, - help_text=_("Allow Creation of missing folders during sync") + help_text=_("Allow Creation of missing folders during sync"), ) folder_filter_exclude = forms.CharField( @@ -92,7 +127,7 @@ class ParametersForm(param_forms.AdminParametersForm): help_text=_( "Use a regular expression to explicitly include folders in sync. " "Example: ^Trash$|Del" - ) + ), ) folder_filter_include = forms.CharField( @@ -103,5 +138,5 @@ class ParametersForm(param_forms.AdminParametersForm): "A comma seperated list of folders to explicitly include in sync " "even if filtered by the Folder Filter Exclusions. Example: " "debian.user, debian.personal " - ) + ), ) diff --git a/modoboa/imap_migration/apps.py b/modoboa/imap_migration/apps.py index e3cf9fb5e..73dc71835 100644 --- a/modoboa/imap_migration/apps.py +++ b/modoboa/imap_migration/apps.py @@ -15,12 +15,16 @@ def load_imapmigration_settings(): from .api.v2 import serializers param_tools.registry.add( - "global", app_settings.ParametersForm, gettext_lazy("IMAP Migration")) + "global", app_settings.ParametersForm, gettext_lazy("IMAP Migration") + ) param_tools.registry.add2( - "global", "imap_migration", gettext_lazy("IMAP Migration"), + "global", + "imap_migration", + gettext_lazy("IMAP Migration"), app_settings.IMAP_MIGRATION_PARAMETERS_STRUCT, serializers.IMAPMigrationSettingsSerializer, - True) + True, + ) class IMAPMigrationConfig(AppConfig): diff --git a/modoboa/imap_migration/auth_backends.py b/modoboa/imap_migration/auth_backends.py index ac6afe3b7..1765e8fda 100644 --- a/modoboa/imap_migration/auth_backends.py +++ b/modoboa/imap_migration/auth_backends.py @@ -23,14 +23,18 @@ class IMAPBackend: if not param_tools.get_global_parameter("enabled_imapmigration"): return None condition = not param_tools.get_global_parameter( - "auto_create_domain_and_mailbox", "admin") + "auto_create_domain_and_mailbox", "admin" + ) if condition: # Automatic domain/mailbox is disabled. Deny auth to # prevent further issues... return None self.address, domain = email_utils.split_mailbox(username) - provider_domain = models.EmailProviderDomain.objects.filter( - name=domain).select_related("provider").first() + provider_domain = ( + models.EmailProviderDomain.objects.filter(name=domain) + .select_related("provider") + .first() + ) if not provider_domain: # Domain not allowed for migration: failure return None @@ -42,12 +46,10 @@ class IMAPBackend: else: conn = imaplib.IMAP4(address, port) except (socket.error, imaplib.IMAP4.error, ssl.SSLError) as error: - raise ModoboaException( - _("Connection to IMAP server failed: %s") % error) + raise ModoboaException(_("Connection to IMAP server failed: %s") % error) try: - typ, data = conn.login( - smart_bytes(username), smart_str(password)) + typ, data = conn.login(smart_bytes(username), smart_str(password)) except imaplib.IMAP4.error: typ = "NO" conn.logout() @@ -66,12 +68,12 @@ class IMAPBackend: orig_username = username # Check if old addresses must be converted if self.provider_domain.new_domain: - username = u"{}@{}".format( - self.address, self.provider_domain.new_domain.name) + username = "{}@{}".format( + self.address, self.provider_domain.new_domain.name + ) user, created = core_models.User.objects.get_or_create( - username__iexact=username, defaults={ - "username": username.lower(), "email": username.lower() - } + username__iexact=username, + defaults={"username": username.lower(), "email": username.lower()}, ) if created: user.set_password(password) @@ -81,7 +83,7 @@ class IMAPBackend: provider=self.provider_domain.provider, mailbox=user.mailbox, username=orig_username, - password=password + password=password, ) else: # What happens if an account already exists? diff --git a/modoboa/imap_migration/checks.py b/modoboa/imap_migration/checks.py index 9ace9a5ea..9d34064d4 100644 --- a/modoboa/imap_migration/checks.py +++ b/modoboa/imap_migration/checks.py @@ -8,11 +8,14 @@ from modoboa.core import models as core_models W001 = Warning( - _("Automatic domain/mailbox creation is disabled which means IMAP " - "authentication won't work."), - hint=_("Go to the online parameters panel (admin tab) and activate " - "this feature."), - id="modoboa-imap-migration.W001" + _( + "Automatic domain/mailbox creation is disabled which means IMAP " + "authentication won't work." + ), + hint=_( + "Go to the online parameters panel (admin tab) and activate " "this feature." + ), + id="modoboa-imap-migration.W001", ) @@ -23,7 +26,6 @@ def check_auto_creation_is_enabled(app_configs, **kwargs): if not lc: return [] errors = [] - if not lc.parameters.get_value( - "auto_create_domain_and_mailbox", app="admin"): + if not lc.parameters.get_value("auto_create_domain_and_mailbox", app="admin"): errors.append(W001) return errors diff --git a/modoboa/imap_migration/management/commands/generate_offlineimap_config.py b/modoboa/imap_migration/management/commands/generate_offlineimap_config.py index 6e3cdc90a..7d18d77ef 100644 --- a/modoboa/imap_migration/management/commands/generate_offlineimap_config.py +++ b/modoboa/imap_migration/management/commands/generate_offlineimap_config.py @@ -20,25 +20,26 @@ class Command(BaseCommand): def add_arguments(self, parser): """Add extra arguments to command line.""" parser.add_argument( - "--output", default="/tmp/offlineimap.conf", - help="Path of the generated file") + "--output", + default="/tmp/offlineimap.conf", + help="Path of the generated file", + ) def handle(self, *args, **options): """Entry point.""" load_admin_settings() - conf = dict( - param_tools.get_global_parameters("imap_migration")) + conf = dict(param_tools.get_global_parameters("imap_migration")) context = { "imap_create_folders": conf["create_folders"], "imap_folder_filter_exclude": conf["folder_filter_exclude"], "imap_folder_filter_include": ", ".join( - "'{0}'".format(w) - for w in conf["folder_filter_include"].split(",")), + "'{0}'".format(w) for w in conf["folder_filter_include"].split(",") + ), "migrations": Migration.objects.select_related( - "provider", "mailbox__domain"), + "provider", "mailbox__domain" + ), } with open(options["output"], "w") as fpo: - content = render_to_string( - "imap_migration/offlineimap.conf", context) + content = render_to_string("imap_migration/offlineimap.conf", context) fpo.write(content) os.chmod(options["output"], stat.S_IRUSR | stat.S_IWUSR) diff --git a/modoboa/imap_migration/migrations/0001_initial.py b/modoboa/imap_migration/migrations/0001_initial.py index 416ae4c91..f0d7a70ca 100644 --- a/modoboa/imap_migration/migrations/0001_initial.py +++ b/modoboa/imap_migration/migrations/0001_initial.py @@ -7,19 +7,29 @@ from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ - ('admin', '__first__'), + ("admin", "__first__"), ] operations = [ migrations.CreateModel( - name='Migration', + name="Migration", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('_password', models.CharField(max_length=100)), - ('mailbox', models.ForeignKey(to='admin.Mailbox', on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("_password", models.CharField(max_length=100)), + ( + "mailbox", + models.ForeignKey(to="admin.Mailbox", on_delete=models.CASCADE), + ), ], - options={ - }, + options={}, bases=(models.Model,), ), ] diff --git a/modoboa/imap_migration/migrations/0002_password.py b/modoboa/imap_migration/migrations/0002_password.py index 83c455926..a6d4786d1 100644 --- a/modoboa/imap_migration/migrations/0002_password.py +++ b/modoboa/imap_migration/migrations/0002_password.py @@ -7,13 +7,13 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('imap_migration', '0001_initial'), + ("imap_migration", "0001_initial"), ] operations = [ migrations.AlterField( - model_name='migration', - name='_password', + model_name="migration", + name="_password", field=models.CharField(max_length=255), ), ] diff --git a/modoboa/imap_migration/migrations/0003_auto_20190207_0919.py b/modoboa/imap_migration/migrations/0003_auto_20190207_0919.py index eb0867b77..9e274868a 100644 --- a/modoboa/imap_migration/migrations/0003_auto_20190207_0919.py +++ b/modoboa/imap_migration/migrations/0003_auto_20190207_0919.py @@ -21,12 +21,13 @@ def create_default_provider(apps, schema_editor): name="Default", address=params["server_address"], port=params["server_port"], - secured=params["secured"] + secured=params["secured"], ) for migration in Migration.objects.select_related("mailbox__domain"): migration.provider = provider migration.username = ( - migration.mailbox.address + "@" + migration.mailbox.domain.name) + migration.mailbox.address + "@" + migration.mailbox.domain.name + ) migration.save(update_fields=["provider", "username"]) @@ -37,45 +38,79 @@ def backwards(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('admin', '0014_auto_20181017_1628'), - ('imap_migration', '0002_password'), + ("admin", "0014_auto_20181017_1628"), + ("imap_migration", "0002_password"), ] operations = [ migrations.CreateModel( - name='EmailProvider', + name="EmailProvider", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=50)), - ('address', models.CharField(max_length=200)), - ('port', models.PositiveIntegerField(default=143)), - ('secured', models.BooleanField(default=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=50)), + ("address", models.CharField(max_length=200)), + ("port", models.PositiveIntegerField(default=143)), + ("secured", models.BooleanField(default=False)), ], options={ - 'ordering': ['name'], + "ordering": ["name"], }, ), migrations.CreateModel( - name='EmailProviderDomain', + name="EmailProviderDomain", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100, unique=True)), - ('new_domain', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='admin.Domain')), - ('provider', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='imap_migration.EmailProvider')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=100, unique=True)), + ( + "new_domain", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="admin.Domain", + ), + ), + ( + "provider", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="imap_migration.EmailProvider", + ), + ), ], options={ - 'ordering': ['provider', 'name'], + "ordering": ["provider", "name"], }, ), migrations.AddField( - model_name='migration', - name='username', + model_name="migration", + name="username", field=models.CharField(max_length=254, null=True), ), migrations.AddField( - model_name='migration', - name='provider', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='imap_migration.EmailProvider'), + model_name="migration", + name="provider", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="imap_migration.EmailProvider", + ), ), - migrations.RunPython(create_default_provider, backwards) + migrations.RunPython(create_default_provider, backwards), ] diff --git a/modoboa/imap_migration/migrations/0004_auto_20190207_0939.py b/modoboa/imap_migration/migrations/0004_auto_20190207_0939.py index 4b1f5f59b..f2a03ec49 100644 --- a/modoboa/imap_migration/migrations/0004_auto_20190207_0939.py +++ b/modoboa/imap_migration/migrations/0004_auto_20190207_0939.py @@ -9,18 +9,21 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('imap_migration', '0003_auto_20190207_0919'), + ("imap_migration", "0003_auto_20190207_0919"), ] operations = [ migrations.AlterField( - model_name='migration', - name='provider', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='imap_migration.EmailProvider'), + model_name="migration", + name="provider", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="imap_migration.EmailProvider", + ), ), migrations.AlterField( - model_name='migration', - name='username', + model_name="migration", + name="username", field=models.CharField(max_length=254), ), ] diff --git a/modoboa/imap_migration/migrations/0005_auto_20210401_0938.py b/modoboa/imap_migration/migrations/0005_auto_20210401_0938.py index f49ac7383..328128c3d 100644 --- a/modoboa/imap_migration/migrations/0005_auto_20210401_0938.py +++ b/modoboa/imap_migration/migrations/0005_auto_20210401_0938.py @@ -7,18 +7,22 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('imap_migration', '0004_auto_20190207_0939'), + ("imap_migration", "0004_auto_20190207_0939"), ] operations = [ migrations.AlterField( - model_name='emailproviderdomain', - name='provider', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='domains', to='imap_migration.EmailProvider'), + model_name="emailproviderdomain", + name="provider", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="domains", + to="imap_migration.EmailProvider", + ), ), migrations.AlterField( - model_name='migration', - name='username', + model_name="migration", + name="username", field=models.CharField(max_length=254, unique=True), ), ] diff --git a/modoboa/imap_migration/models.py b/modoboa/imap_migration/models.py index d3660acfa..eda2fe41c 100644 --- a/modoboa/imap_migration/models.py +++ b/modoboa/imap_migration/models.py @@ -24,10 +24,12 @@ class EmailProviderDomain(models.Model): """Email provider domain class.""" provider = models.ForeignKey( - EmailProvider, on_delete=models.CASCADE, related_name="domains") + EmailProvider, on_delete=models.CASCADE, related_name="domains" + ) name = models.CharField(max_length=100, unique=True) new_domain = models.ForeignKey( - "admin.Domain", on_delete=models.SET_NULL, null=True, blank=True) + "admin.Domain", on_delete=models.SET_NULL, null=True, blank=True + ) class Meta: ordering = ["provider", "name"] diff --git a/modoboa/imap_migration/tests.py b/modoboa/imap_migration/tests.py index d87480174..8093f9d5f 100644 --- a/modoboa/imap_migration/tests.py +++ b/modoboa/imap_migration/tests.py @@ -28,10 +28,10 @@ class DataMixin(object): def setUpTestData(cls): super(DataMixin, cls).setUpTestData() admin_factories.populate_database() - cls.mb = admin_models.Mailbox.objects.get( - user__username="user@test.com") + cls.mb = admin_models.Mailbox.objects.get(user__username="user@test.com") cls.migration = factories.MigrationFactory( - password="Toto1234", mailbox=cls.mb, username="user@test.com") + password="Toto1234", mailbox=cls.mb, username="user@test.com" + ) # class ViewsTestCase(DataMixin, ModoTestCase): @@ -69,8 +69,7 @@ class AuthenticationTestCase(DataMixin, ModoTestCase): response = self.client.post(url, data) self.assertEqual(response.status_code, 401) - self.set_global_parameter( - "auto_create_domain_and_mailbox", False, app="admin") + self.set_global_parameter("auto_create_domain_and_mailbox", False, app="admin") data = {"username": "new_user2@test.com", "password": "Toto1234"} response = self.client.post(url, data) self.assertEqual(response.status_code, 401) @@ -79,8 +78,7 @@ class AuthenticationTestCase(DataMixin, ModoTestCase): def test_authenticate_and_rename(self, mock_imap): """Check address renaming.""" domain = admin_models.Domain.objects.get(name="test.com") - factories.EmailProviderDomainFactory( - name="gmail.com", new_domain=domain) + factories.EmailProviderDomainFactory(name="gmail.com", new_domain=domain) mock_imap.return_value.login.return_value = ["OK", b""] url = reverse("core:login") data = {"username": "new_user@gmail.com", "password": "Toto1234"} @@ -93,12 +91,10 @@ class AuthenticationTestCase(DataMixin, ModoTestCase): def test_authenticate_conflicts(self, mock_imap): """Check potential conflicts.""" core_factories.UserFactory( - username="admin2@test.com", groups=("DomainAdmins", ), - password="{PLAIN}toto" + username="admin2@test.com", groups=("DomainAdmins",), password="{PLAIN}toto" ) domain = admin_models.Domain.objects.get(name="test.com") - factories.EmailProviderDomainFactory( - name="gmail.com", new_domain=domain) + factories.EmailProviderDomainFactory(name="gmail.com", new_domain=domain) mock_imap.return_value.login.return_value = ["OK", b""] url = reverse("core:login") data = {"username": "admin@gmail.com", "password": "Toto1234"} @@ -140,51 +136,42 @@ class ViewSetTestCase(DataMixin, ModoAPITestCase): "address": "imap.google.com", "port": 143, "secured": True, - "domains": [ - {"id": 1000, - "name": "gmail.com"} - ] + "domains": [{"id": 1000, "name": "gmail.com"}], } response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 201) self.assertTrue( - models.EmailProviderDomain.objects.filter(name="gmail.com") - .exists() + models.EmailProviderDomain.objects.filter(name="gmail.com").exists() ) def test_update_provider(self): - provider_domain = factories.EmailProviderDomainFactory( - name="outlook.com") - url = reverse( - "v2:emailprovider-detail", args=[provider_domain.provider.pk]) + provider_domain = factories.EmailProviderDomainFactory(name="outlook.com") + url = reverse("v2:emailprovider-detail", args=[provider_domain.provider.pk]) data = { "id": provider_domain.provider.id, "name": provider_domain.provider.name, "address": provider_domain.provider.address, "port": provider_domain.provider.port, "domains": [ - {"id": provider_domain.id, - "name": "hotmail.com", - "new_domain": None}, - {"name": "gmail.com", - "new_domain": admin_models.Domain.objects.get( - name="test.com").pk} - ] + {"id": provider_domain.id, "name": "hotmail.com", "new_domain": None}, + { + "name": "gmail.com", + "new_domain": admin_models.Domain.objects.get(name="test.com").pk, + }, + ], } response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) provider_domain.refresh_from_db() self.assertEqual(provider_domain.name, data["domains"][0]["name"]) self.assertTrue( - models.EmailProviderDomain.objects.filter(name="gmail.com") - .exists() + models.EmailProviderDomain.objects.filter(name="gmail.com").exists() ) data["domains"].pop() response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) self.assertFalse( - models.EmailProviderDomain.objects.filter(name="gmail.com") - .exists() + models.EmailProviderDomain.objects.filter(name="gmail.com").exists() ) @@ -192,13 +179,6 @@ class ChecksTestCase(ModoTestCase): """Deploy checks test case.""" def test_auto_creation_check(self): - self.assertEqual( - checks.check_auto_creation_is_enabled(None), - [] - ) - self.set_global_parameter( - "auto_create_domain_and_mailbox", False, app="admin") - self.assertEqual( - checks.check_auto_creation_is_enabled(None), - [checks.W001] - ) + self.assertEqual(checks.check_auto_creation_is_enabled(None), []) + self.set_global_parameter("auto_create_domain_and_mailbox", False, app="admin") + self.assertEqual(checks.check_auto_creation_is_enabled(None), [checks.W001]) diff --git a/modoboa/imap_migration/views.py b/modoboa/imap_migration/views.py index d50cf61d3..334518a21 100644 --- a/modoboa/imap_migration/views.py +++ b/modoboa/imap_migration/views.py @@ -5,9 +5,11 @@ from django.contrib.auth import mixins as auth_mixins from django.views import generic -class IndexView(auth_mixins.LoginRequiredMixin, - auth_mixins.PermissionRequiredMixin, - generic.TemplateView): +class IndexView( + auth_mixins.LoginRequiredMixin, + auth_mixins.PermissionRequiredMixin, + generic.TemplateView, +): """Index view.""" permission_required = "modoboa.imap_migration.add_migration" diff --git a/modoboa/ldapsync/apps.py b/modoboa/ldapsync/apps.py index 4ccad8839..a39f85d45 100644 --- a/modoboa/ldapsync/apps.py +++ b/modoboa/ldapsync/apps.py @@ -2,7 +2,7 @@ from django.apps import AppConfig class LdapsyncConfig(AppConfig): - name = 'modoboa.ldapsync' + name = "modoboa.ldapsync" def ready(self): from . import handlers # noqa diff --git a/modoboa/ldapsync/lib.py b/modoboa/ldapsync/lib.py index ae2c87120..441c3dbc8 100644 --- a/modoboa/ldapsync/lib.py +++ b/modoboa/ldapsync/lib.py @@ -15,8 +15,7 @@ from modoboa.lib.exceptions import InternalError def create_connection(srv_address, srv_port, config, username, password): """Create a new connection with given server.""" uri = "{}:{}".format(srv_address, srv_port) - uri = "{}://{}".format( - "ldaps" if config["ldap_secured"] == "ssl" else "ldap", uri) + uri = "{}://{}".format("ldaps" if config["ldap_secured"] == "ssl" else "ldap", uri) conn = ldap.initialize(uri) conn.protocol_version = 3 conn.set_option(ldap.OPT_X_TLS_DEMAND, True) @@ -24,7 +23,7 @@ def create_connection(srv_address, srv_port, config, username, password): conn.set_option(ldap.OPT_REFERRALS, 0) conn.simple_bind_s( force_str(username if username else config["ldap_sync_bind_dn"]), - force_str(password if password else config["ldap_sync_bind_password"]) + force_str(password if password else config["ldap_sync_bind_password"]), ) return conn @@ -33,8 +32,11 @@ def get_connection(config, username=None, password=None): """Get a new connection to the LDAP directory.""" try: conn = create_connection( - config["ldap_server_address"], config["ldap_server_port"], - config, username, password + config["ldap_server_address"], + config["ldap_server_port"], + config, + username, + password, ) except ldap.LDAPError: if not config["ldap_enable_secondary_server"]: @@ -42,7 +44,9 @@ def get_connection(config, username=None, password=None): conn = create_connection( config["ldap_secondary_server_address"], config["ldap_secondary_server_port"], - config, username, password + config, + username, + password, ) return conn @@ -50,27 +54,22 @@ def get_connection(config, username=None, password=None): def get_user_password(user, disable=False): """Return ready-to-use password from user instance.""" scheme, password = user.password.split("}") - return ( - force_bytes(scheme) + - b"}" + - b"#" if disable else b"" + - force_bytes(password) - ) + return force_bytes(scheme) + b"}" + b"#" if disable else b"" + force_bytes(password) def create_ldap_account(user, dn, conn): """Create new account.""" attrs = { "objectClass": [ - force_bytes("inetOrgPerson"), force_bytes("organizationalPerson") + force_bytes("inetOrgPerson"), + force_bytes("organizationalPerson"), ], "uid": [force_bytes(user.username)], "sn": [force_bytes(user.last_name)], "givenName": [force_bytes(user.first_name)], "cn": [force_bytes(user.username)], "displayName": [force_bytes(user.fullname)], - "mail": [ - force_bytes(user.email), force_bytes(user.secondary_email)], + "mail": [force_bytes(user.email), force_bytes(user.secondary_email)], "homePhone": [force_bytes(user.phone_number)], } if user.password: @@ -80,17 +79,16 @@ def create_ldap_account(user, dn, conn): try: conn.add_s(dn, ldif) except ldap.LDAPError as e: - raise InternalError( - _("Failed to create LDAP account: {}").format(e) - ) + raise InternalError(_("Failed to create LDAP account: {}").format(e)) def check_if_dn_exists(conn, dn): """Check if DN already exists in directory.""" try: res = conn.search_s( - force_str(dn), ldap.SCOPE_SUBTREE, - force_str("(&(objectClass=inetOrgPerson))") + force_str(dn), + ldap.SCOPE_SUBTREE, + force_str("(&(objectClass=inetOrgPerson))"), ) res = res[0][0] except ldap.LDAPError: @@ -120,8 +118,7 @@ def update_ldap_account(user, config): try: conn.modify_s(dn, ldif) except ldap.LDAPError as e: - raise InternalError( - _("Failed to update LDAP account: {}").format(e)) + raise InternalError(_("Failed to update LDAP account: {}").format(e)) def delete_ldap_account(user, config): @@ -134,42 +131,33 @@ def delete_ldap_account(user, config): try: conn.delete_s(dn) except ldap.LDAPError as e: - raise InternalError( - _("Failed to delete LDAP account: {}").format(e) - ) + raise InternalError(_("Failed to delete LDAP account: {}").format(e)) else: password = get_user_password(user, True) - ldif = [ - (ldap.MOD_REPLACE, "userPassword", password) - ] + ldif = [(ldap.MOD_REPLACE, "userPassword", password)] try: conn.modify_s(dn, ldif) except ldap.LDAPError as e: - raise InternalError( - _("Failed to disable LDAP account: {}").format(e)) + raise InternalError(_("Failed to disable LDAP account: {}").format(e)) def find_user_groups(conn, config, dn, entry): """Retrieve groups for given user.""" condition = ( - config["ldap_is_active_directory"] or - config["ldap_group_type"] == "groupofnames" + config["ldap_is_active_directory"] + or config["ldap_group_type"] == "groupofnames" ) if condition: flt = "(member={})".format(dn) elif config["ldap_group_type"] == "posixgroup": flt = "(memberUid={})".format(force_str(entry["uid"][0])) - result = conn.search_s( - config["ldap_groups_search_base"], - ldap.SCOPE_SUBTREE, - flt - ) + result = conn.search_s(config["ldap_groups_search_base"], ldap.SCOPE_SUBTREE, flt) groups = [] for dn, entry in result: if not dn: continue - groups.append(dn.split(',')[0].split('=')[1]) + groups.append(dn.split(",")[0].split("=")[1]) return groups @@ -189,7 +177,7 @@ def import_accounts_from_ldap(config): result = conn.search_s( config["ldap_import_search_base"], ldap.SCOPE_SUBTREE, - config["ldap_import_search_filter"] + config["ldap_import_search_filter"], ) admin_groups = config["ldap_admin_groups"].split(";") for dn, entry in result: @@ -219,20 +207,15 @@ def import_accounts_from_ldap(config): defaults = { "username": username.lower(), "is_local": False, - "language": settings.LANGUAGE_CODE + "language": settings.LANGUAGE_CODE, } user, created = core_models.User.objects.get_or_create( - username__iexact=username, - defaults=defaults + username__iexact=username, defaults=defaults ) if created: core_models.populate_callback(user, role) - attr_map = { - "first_name": "givenName", - "email": "mail", - "last_name": "sn" - } + attr_map = {"first_name": "givenName", "email": "mail", "last_name": "sn"} for attr, ldap_attr in attr_map.items(): if ldap_attr in entry: setattr(user, attr, force_str(entry[ldap_attr][0])) @@ -243,13 +226,13 @@ def import_accounts_from_ldap(config): def build_ldap_uri(config, node=""): - """ Building LDAP uris for dovecot conf """ + """Building LDAP uris for dovecot conf""" if node: node += "_" return "{}://{}:{}".format( "ldaps" if config["ldap_secured"] == "ssl" else "ldap", config["ldap_{}server_address".format(node)], - config["ldap_{}server_port".format(node)] + config["ldap_{}server_port".format(node)], ) @@ -271,12 +254,19 @@ def update_dovecot_config_file(config): user_filter = config["ldap_search_filter"].replace("(user)s", "u") with open(conf_file, "w") as fp: - fp.write("""uris = {uris} + fp.write( + """uris = {uris} dn = "{bind_dn}" dnpass = '{bind_pwd}' base = {base} user_filter = {user_filter} pass_filter = {pass_filter} -""".format(uris=uris, bind_dn=bind_dn, bind_pwd=bind_pwd, base=base, - user_filter=user_filter, pass_filter=user_filter) +""".format( + uris=uris, + bind_dn=bind_dn, + bind_pwd=bind_pwd, + base=base, + user_filter=user_filter, + pass_filter=user_filter, + ) ) diff --git a/modoboa/ldapsync/management/commands/update_dovecot_conf.py b/modoboa/ldapsync/management/commands/update_dovecot_conf.py index dc476beeb..a1c3f9402 100644 --- a/modoboa/ldapsync/management/commands/update_dovecot_conf.py +++ b/modoboa/ldapsync/management/commands/update_dovecot_conf.py @@ -20,8 +20,7 @@ class Command(BaseCommand): return config = dict(param_tools.get_global_parameters("core")) condition = ( - config["authentication_type"] == "ldap" and - config["ldap_dovecot_sync"] + config["authentication_type"] == "ldap" and config["ldap_dovecot_sync"] ) if condition: lib.update_dovecot_config_file(config) diff --git a/modoboa/ldapsync/tests.py b/modoboa/ldapsync/tests.py index 0429cebdb..5da55337b 100644 --- a/modoboa/ldapsync/tests.py +++ b/modoboa/ldapsync/tests.py @@ -22,19 +22,22 @@ class LDAPExportTestCase(ModoTestCase): def setUp(self): super().setUp() - self.set_global_parameters({ - "ldap_enable_sync": True, - "ldap_server_port": settings.LDAP_SERVER_PORT, - "ldap_sync_bind_dn": "cn=admin,dc=example,dc=com", - "ldap_sync_bind_password": "test", - "ldap_sync_account_dn_template": ( - "cn=%(user)s,ou=users,dc=example,dc=com"), - }, app="core") + self.set_global_parameters( + { + "ldap_enable_sync": True, + "ldap_server_port": settings.LDAP_SERVER_PORT, + "ldap_sync_bind_dn": "cn=admin,dc=example,dc=com", + "ldap_sync_bind_password": "test", + "ldap_sync_account_dn_template": ( + "cn=%(user)s,ou=users,dc=example,dc=com" + ), + }, + app="core", + ) self.config = dict(param_tools.get_global_parameters("core")) self.conn = lib.get_connection(self.config) self.username = "testldap@test.com" - self.dn = self.config["ldap_sync_account_dn_template"] % { - "user": self.username} + self.dn = self.config["ldap_sync_account_dn_template"] % {"user": self.username} def reset_ldap_directory(self): try: @@ -48,7 +51,7 @@ class LDAPExportTestCase(ModoTestCase): username=self.username, first_name="Test", last_name="LDAP", - groups=("SimpleUsers",) + groups=("SimpleUsers",), ) self.assertTrue(lib.check_if_dn_exists(self.conn, self.dn)) @@ -59,8 +62,9 @@ class LDAPExportTestCase(ModoTestCase): lib.get_connection(self.config, self.dn, "toto") res = self.conn.search_s( - force_str(self.dn), ldap.SCOPE_SUBTREE, - force_str("(&(objectClass=inetOrgPerson))") + force_str(self.dn), + ldap.SCOPE_SUBTREE, + force_str("(&(objectClass=inetOrgPerson))"), ) self.assertIn(force_bytes(user.last_name), res[0][1]["sn"]) @@ -70,7 +74,7 @@ class LDAPExportTestCase(ModoTestCase): username=self.username, first_name="Test", last_name="LDAP", - groups=("DomainAdmins", ) + groups=("DomainAdmins",), ) self.assertFalse(lib.check_if_dn_exists(self.conn, self.dn)) @@ -80,12 +84,13 @@ class LDAPExportTestCase(ModoTestCase): username=self.username, first_name="Test", last_name="LDAP", - groups=("SimpleUsers",) + groups=("SimpleUsers",), ) user.delete() ldap_record = self.conn.search_s( - force_str(self.dn), ldap.SCOPE_SUBTREE, - force_str("(&(objectClass=inetOrgPerson))") + force_str(self.dn), + ldap.SCOPE_SUBTREE, + force_str("(&(objectClass=inetOrgPerson))"), ) password = ldap_record[0][1]["userPassword"][0].split(b"}")[1] self.assertTrue(password.startswith(b"#")) @@ -96,10 +101,9 @@ class LDAPExportTestCase(ModoTestCase): username=self.username, first_name="Test", last_name="LDAP", - groups=("SimpleUsers",) + groups=("SimpleUsers",), ) - self.set_global_parameter( - "ldap_sync_delete_remote_account", True, app="core") + self.set_global_parameter("ldap_sync_delete_remote_account", True, app="core") user.delete() self.assertFalse(lib.check_if_dn_exists(self.conn, self.dn)) @@ -110,23 +114,27 @@ class LDAPImportTestCase(ModoTestCase): def setUp(self): super().setUp() - self.set_global_parameters({ - "ldap_enable_import": True, - "ldap_server_port": settings.LDAP_SERVER_PORT, - "ldap_sync_bind_dn": "cn=admin,dc=example,dc=com", - "ldap_sync_bind_password": "test", - "ldap_import_search_base": "ou=users,dc=example,dc=com", - "ldap_import_search_filter": "(objectClass=person)", - "ldap_groups_search_base": "ou=groups,dc=example,dc=com", - "ldap_admin_groups": "admins", - }, app="core") + self.set_global_parameters( + { + "ldap_enable_import": True, + "ldap_server_port": settings.LDAP_SERVER_PORT, + "ldap_sync_bind_dn": "cn=admin,dc=example,dc=com", + "ldap_sync_bind_password": "test", + "ldap_import_search_base": "ou=users,dc=example,dc=com", + "ldap_import_search_filter": "(objectClass=person)", + "ldap_groups_search_base": "ou=groups,dc=example,dc=com", + "ldap_admin_groups": "admins", + }, + app="core", + ) self.config = dict(param_tools.get_global_parameters("core")) self.conn = lib.get_connection(self.config) def test_import_from_ldap(self): """Check management command.""" call_command("import_from_ldap_directory") - self.assertTrue(core_models.User.objects.filter( - username="testuser@example.com").exists()) + self.assertTrue( + core_models.User.objects.filter(username="testuser@example.com").exists() + ) admin = core_models.User.objects.get(username="mailadmin@example.com") self.assertEqual(admin.role, "DomainAdmins") diff --git a/modoboa/lib/api_client.py b/modoboa/lib/api_client.py index e47b38cf1..1f485fd55 100644 --- a/modoboa/lib/api_client.py +++ b/modoboa/lib/api_client.py @@ -13,13 +13,13 @@ logger = logging.getLogger("modoboa.admin") class ModoAPIClient(object): - """A simple client for the public API.""" def __init__(self, api_url=None): """Constructor.""" if api_url is None: from django.conf import settings + self._api_url = settings.MODOBOA_API_URL else: self._api_url = api_url @@ -32,9 +32,7 @@ class ModoAPIClient(object): try: resp = requests.get(url, params=params) except RequestException as err: - logger.critical( - _("Failed to communicate with public API: %s"), str(err) - ) + logger.critical(_("Failed to communicate with public API: %s"), str(err)) return None if resp.status_code != 200: return None @@ -46,7 +44,8 @@ class ModoAPIClient(object): if self._local_core_version is None: try: self._local_core_version = pkg_resources.get_distribution( - "modoboa").version + "modoboa" + ).version except pkg_resources.DistributionNotFound: self._local_core_version = "unknown" return self._local_core_version @@ -58,13 +57,11 @@ class ModoAPIClient(object): def register_instance(self, hostname): """Register this instance.""" - url = "{}instances/search/?hostname={}".format( - self._api_url, hostname) + url = "{}instances/search/?hostname={}".format(self._api_url, hostname) instance = self.__send_request(url) if instance is None: url = "{}instances/".format(self._api_url) - data = { - "hostname": hostname, "known_version": self.local_core_version} + data = {"hostname": hostname, "known_version": self.local_core_version} try: response = requests.post(url, data=data) except RequestException as err: @@ -83,9 +80,7 @@ class ModoAPIClient(object): try: response = requests.put(url, data=data) except RequestException as err: - logger.critical( - _("Failed to communicate with public API: %s"), str(err) - ) + logger.critical(_("Failed to communicate with public API: %s"), str(err)) return if response.status_code != 200: logger.critical( diff --git a/modoboa/lib/authbackends.py b/modoboa/lib/authbackends.py index 34b64641e..543efd0f8 100644 --- a/modoboa/lib/authbackends.py +++ b/modoboa/lib/authbackends.py @@ -37,11 +37,12 @@ class SMTPBackend(object): We assume the username is a valid email address. """ user, created = User.objects.get_or_create( - username__iexact=username, defaults={ + username__iexact=username, + defaults={ "username": username.lower(), "email": username.lower(), - "language": settings.LANGUAGE_CODE - } + "language": settings.LANGUAGE_CODE, + }, ) if created: populate_callback(user) @@ -58,9 +59,7 @@ class SMTPBackend(object): try: - from django_auth_ldap.backend import ( - LDAPBackend as orig_LDAPBackend, _LDAPUser - ) + from django_auth_ldap.backend import LDAPBackend as orig_LDAPBackend, _LDAPUser class LDAPBackendBase(orig_LDAPBackend): @@ -68,8 +67,7 @@ try: """Load LDAP settings.""" param_tools.apply_to_django_settings() super().__init__(*args, **kwargs) - self.global_params = dict( - param_tools.get_global_parameters("core")) + self.global_params = dict(param_tools.get_global_parameters("core")) def get_or_build_user(self, username, ldap_user): """ @@ -88,7 +86,7 @@ try: if domain is None: # Try to find associated email email = None - for attr in ['mail', 'userPrincipalName']: + for attr in ["mail", "userPrincipalName"]: if attr in ldap_user.attrs: email = ldap_user.attrs[attr][0] break @@ -104,8 +102,8 @@ try: defaults={ "username": username.lower(), "is_local": False, - "language": settings.LANGUAGE_CODE - } + "language": settings.LANGUAGE_CODE, + }, ) if created: populate_callback(user, group) @@ -130,7 +128,6 @@ try: """Return fullname for given setting.""" return "{}{}".format(cls.settings_prefix, setting) - class LDAPBackend(LDAPBackendBase): """Primary LDAP backend.""" @@ -138,7 +135,6 @@ try: srv_address_setting_name = "ldap_server_address" srv_port_setting_name = "ldap_server_port" - class LDAPSecondaryBackend(LDAPBackendBase): """Secondary LDAP backend.""" @@ -146,6 +142,5 @@ try: srv_address_setting_name = "ldap_secondary_server_address" srv_port_setting_name = "ldap_secondary_server_port" - except ImportError: pass diff --git a/modoboa/lib/connections.py b/modoboa/lib/connections.py index fcc1b51eb..d830d509c 100644 --- a/modoboa/lib/connections.py +++ b/modoboa/lib/connections.py @@ -2,7 +2,6 @@ from modoboa.lib.cryptutils import decrypt class ConnectionsManager(type): - """ Singleton pattern implementation. @@ -25,8 +24,7 @@ class ConnectionsManager(type): kwargs["password"] = decrypt(kwargs["password"]) if self.instances[key] is None: - self.instances[key] = \ - super(ConnectionsManager, self).__call__(**kwargs) + self.instances[key] = super(ConnectionsManager, self).__call__(**kwargs) else: self.instances[key].refresh(key, kwargs["password"]) return self.instances[key] diff --git a/modoboa/lib/db_utils.py b/modoboa/lib/db_utils.py index 03b279f80..6c3f0e575 100644 --- a/modoboa/lib/db_utils.py +++ b/modoboa/lib/db_utils.py @@ -19,8 +19,7 @@ def db_type(cname="default"): :return: a string or None """ if cname not in settings.DATABASES: - raise InternalError( - _("Connection to database %s not configured" % cname)) + raise InternalError(_("Connection to database %s not configured" % cname)) for t in ["postgres", "mysql", "sqlite"]: if settings.DATABASES[cname]["ENGINE"].find(t) != -1: return t diff --git a/modoboa/lib/email_utils.py b/modoboa/lib/email_utils.py index ffb102ec3..793304d8b 100644 --- a/modoboa/lib/email_utils.py +++ b/modoboa/lib/email_utils.py @@ -68,8 +68,7 @@ class Email(object): # updated to use True or False. self.links = bool(links) elif links == "0": - raise TypeError("links == \"0\" is not valid, did you mean True or " - "False?") + raise TypeError('links == "0" is not valid, did you mean True or ' "False?") else: raise TypeError("links should be a boolean value") @@ -102,10 +101,7 @@ class Email(object): if self._msg is not None: for header in self._basic_headers: value = self.get_header(self.msg, header) - self._headers.append({ - "name": header, - "value": value - }) + self._headers.append({"name": header, "value": value}) return self._headers @@ -173,11 +169,9 @@ class Email(object): self._parse_inline_image(msg, level) if self.contents["plain"]: - self.contents["plain"] = self._post_process_plain( - self.contents["plain"]) + self.contents["plain"] = self._post_process_plain(self.contents["plain"]) if self.contents["html"]: - self.contents["html"] = self._post_process_html( - self.contents["html"]) + self.contents["html"] = self._post_process_html(self.contents["html"]) def _parse_text(self, msg, level=0): content_type = msg.get_content_subtype() @@ -222,12 +216,12 @@ class Email(object): return self._images[cid] = "data:%s;base64,%s" % ( - content_type, "".join(msg.get_payload().splitlines(False))) + content_type, + "".join(msg.get_payload().splitlines(False)), + ) def _post_process_plain(self, content): - mail_text = ( - _RE_REMOVE_EXTRA_WHITESPACE.sub("\n\n", content).strip() - ) + mail_text = _RE_REMOVE_EXTRA_WHITESPACE.sub("\n\n", content).strip() mail_text = escape(mail_text) return smart_str(mail_text) @@ -249,10 +243,9 @@ class Email(object): embedded=True, frames=True, add_nofollow=True, - safe_attrs=safe_attrs + safe_attrs=safe_attrs, ) - mail_text = lxml.html.tostring( - cleaner.clean_html(html), encoding="unicode") + mail_text = lxml.html.tostring(cleaner.clean_html(html), encoding="unicode") return smart_str(mail_text) def _map_cid(self, url): @@ -288,8 +281,7 @@ class Email(object): def split_address(address): """Split an e-mail address into local part and domain.""" - assert isinstance(address, str),\ - "address should be of type str" + assert isinstance(address, str), "address should be of type str" if "@" not in address: local_part = address domain = None @@ -300,27 +292,25 @@ def split_address(address): def split_local_part(local_part, delimiter=None): """Split a local part into local part and extension.""" - assert isinstance(local_part, str),\ - "local_part should be of type str" - assert isinstance(delimiter, str) or delimiter is None,\ - "delimiter should be of type str" + assert isinstance(local_part, str), "local_part should be of type str" + assert ( + isinstance(delimiter, str) or delimiter is None + ), "delimiter should be of type str" extension = None if local_part.lower() in ["mailer-daemon", "double-bounce"]: # never split these special addresses pass - elif ( - delimiter == "-" and - (local_part.startswith("owner-") or - local_part.endswith("-request")) + elif delimiter == "-" and ( + local_part.startswith("owner-") or local_part.endswith("-request") ): # don't split owner-* or *-request if - is the delimiter, they are # special addresses used by mail lists. pass elif ( - delimiter and - delimiter in local_part and - local_part[0] != delimiter and - local_part[-1] != delimiter + delimiter + and delimiter in local_part + and local_part[0] != delimiter + and local_part[-1] != delimiter ): local_part, extension = local_part.split(delimiter, 1) @@ -345,8 +335,7 @@ def split_mailbox(mailbox, return_extension=False): def decode(value_bytes, encoding, append_to_error=""): """Try to decode the given string.""" - assert isinstance(value_bytes, bytes),\ - "value_bytes should be of type bytes" + assert isinstance(value_bytes, bytes), "value_bytes should be of type bytes" if len(value_bytes) == 0: # short circuit for empty strings return "" @@ -355,13 +344,10 @@ def decode(value_bytes, encoding, append_to_error=""): except (UnicodeDecodeError, LookupError): encoding = chardet.detect(value_bytes) try: - value = value_bytes.decode( - encoding["encoding"], "replace" - ) + value = value_bytes.decode(encoding["encoding"], "replace") except (TypeError, UnicodeDecodeError) as exc: raise InternalError( - _("unable to determine encoding of string") + - append_to_error + _("unable to determine encoding of string") + append_to_error ) from exc return value @@ -399,8 +385,9 @@ def set_email_headers(msg, subject, sender, rcpt): msg["From"] = sender msg["To"] = prepare_addresses(rcpt) msg["Message-ID"] = make_msgid() - msg["User-Agent"] = "Modoboa %s" % \ - (pkg_resources.get_distribution("modoboa").version) + msg["User-Agent"] = "Modoboa %s" % ( + pkg_resources.get_distribution("modoboa").version + ) msg["Date"] = formatdate(time.time(), True) @@ -426,8 +413,7 @@ def _sendmail(sender, rcpt, msgstring, server="localhost", port=25): return True, None -def sendmail_simple( - sender, rcpt, subject="Sample message", content="", **kwargs): +def sendmail_simple(sender, rcpt, subject="Sample message", content="", **kwargs): """Simple way to send a text message Send a text/plain message with basic headers (msg-id, date). @@ -465,7 +451,10 @@ def sendmail_fromfile(sender, rcpt, fname): content = """From: %s To: %s -""" % (sender, rcpt) +""" % ( + sender, + rcpt, + ) content += fp.read() fp.close() @@ -475,11 +464,13 @@ To: %s def send_notification(recipient, subject, tpl, sender=None, **kwargs): """Send notification by email.""" if not sender: - local_config = ( - core_models.LocalConfig.objects.select_related("site").first()) + local_config = core_models.LocalConfig.objects.select_related("site").first() sender = local_config.parameters.get_value("sender_address") content = render_to_string(tpl, kwargs) msg = EmailMessage( - subject, content.strip(), sender, [recipient], + subject, + content.strip(), + sender, + [recipient], ) msg.send() diff --git a/modoboa/lib/exceptions.py b/modoboa/lib/exceptions.py index 8b6dc22fe..25eae6697 100644 --- a/modoboa/lib/exceptions.py +++ b/modoboa/lib/exceptions.py @@ -11,6 +11,7 @@ class ModoboaException(Exception): """ Base class for Modoboa custom exceptions. """ + http_code = None def __init__(self, *args, **kwargs): @@ -24,6 +25,7 @@ class InternalError(ModoboaException): """ Use this exception for system errors, missing dependencies, etc. """ + http_code = 500 @@ -33,6 +35,7 @@ class BadRequest(ModoboaException): format (example: wrong CSV line) or doesn't respect validation rules. """ + http_code = 400 @@ -41,6 +44,7 @@ class NotFound(ModoboaException): Use this exception to indicate the requested resource could not be found. """ + http_code = 404 @@ -49,6 +53,7 @@ class Conflict(ModoboaException): Use this exception to indicate that the request could not be processed because of conflict in the request. """ + http_code = 409 @@ -67,6 +72,7 @@ class PermDeniedException(ModoboaException): Use this exception when a user tries to do something he is not allowed to. """ + http_code = 403 def __init__(self, msg=None): diff --git a/modoboa/lib/fields.py b/modoboa/lib/fields.py index 19941473c..65fa08ac0 100644 --- a/modoboa/lib/fields.py +++ b/modoboa/lib/fields.py @@ -11,9 +11,7 @@ from . import validators class DomainNameField(forms.fields.CharField): """A subclass of CharField that only accepts a valid domain name.""" - default_error_messages = { - "invalid": gettext_lazy("Enter a valid domain name") - } + default_error_messages = {"invalid": gettext_lazy("Enter a valid domain name")} default_validators = [validators.validate_hostname] @@ -40,26 +38,24 @@ class UTF8AndEmptyUserEmailField(forms.fields.EmailField): class DRFEmailFieldUTF8(serializers.CharField): """Custom DRF email field to support UTF8.""" - default_error_messages = { - "invalid": gettext_lazy("Enter a valid email address.") - } + default_error_messages = {"invalid": gettext_lazy("Enter a valid email address.")} def __init__(self, **kwargs): super(DRFEmailFieldUTF8, self).__init__(**kwargs) validator = validators.UTF8EmailValidator( - message=self.error_messages["invalid"]) + message=self.error_messages["invalid"] + ) self.validators.append(validator) class DRFEmailFieldUTF8AndEmptyUser(serializers.CharField): """Custom DRF email field to support UTF8 and empty local part.""" - default_error_messages = { - "invalid": gettext_lazy("Enter a valid email address.") - } + default_error_messages = {"invalid": gettext_lazy("Enter a valid email address.")} def __init__(self, **kwargs): super(DRFEmailFieldUTF8AndEmptyUser, self).__init__(**kwargs) validator = validators.UTF8AndEmptyUserEmailValidator( - message=self.error_messages["invalid"]) + message=self.error_messages["invalid"] + ) self.validators.append(validator) diff --git a/modoboa/lib/form_utils.py b/modoboa/lib/form_utils.py index 1118fc8f0..0b6d3e750 100644 --- a/modoboa/lib/form_utils.py +++ b/modoboa/lib/form_utils.py @@ -124,10 +124,13 @@ class WizardForm(ABC): if self.steps[stepid].check_access(self): break stepid -= 1 - return render_to_json_response({ - "title": self.steps[stepid].title, "id": self.steps[stepid].uid, - "stepid": stepid - }) + return render_to_json_response( + { + "title": self.steps[stepid].title, + "id": self.steps[stepid].uid, + "stepid": stepid, + } + ) def next_step(self): """Go to the next step if previous forms are valid.""" @@ -138,24 +141,30 @@ class WizardForm(ABC): if self.steps[cpt].check_access(self): statuses.append(self.steps[cpt].form.is_valid()) if False in statuses: - return render_to_json_response({ - "stepid": stepid, "id": self.steps[stepid - 1].uid, - "form_errors": self.errors - }, status=400) + return render_to_json_response( + { + "stepid": stepid, + "id": self.steps[stepid - 1].uid, + "form_errors": self.errors, + }, + status=400, + ) while stepid < len(self.steps): if self.steps[stepid].check_access(self): break stepid += 1 if stepid == len(self.steps): return self.done() - return render_to_json_response({ - "title": self.steps[stepid].title, "id": self.steps[stepid].uid, - "stepid": stepid - }) + return render_to_json_response( + { + "title": self.steps[stepid].title, + "id": self.steps[stepid].uid, + "stepid": stepid, + } + ) def extra_context(self, context): - """Provide additional information to template's context. - """ + """Provide additional information to template's context.""" pass def process(self): @@ -180,7 +189,6 @@ class WizardForm(ABC): class DynamicForm(object): - """ A form which accepts dynamic fields. @@ -193,8 +201,7 @@ class DynamicForm(object): data = {} def _create_field(self, typ, name, value=None, pos=None): - """Create a new form field. - """ + """Create a new form field.""" self.fields[name] = typ(label="", required=False) if value is not None: self.fields[name].initial = value @@ -211,7 +218,7 @@ class DynamicForm(object): :param string pattern: pattern used to find field instances :param typ: a form field class """ - expr = re.compile(r'%s_\d+' % pattern) + expr = re.compile(r"%s_\d+" % pattern) values = [] for k, v in list(qdict.items()): if k == pattern or expr.match(k): @@ -292,8 +299,7 @@ class TabForms(object): """ to_remove = [] for f in self.forms: - if mandatory_only and \ - ("mandatory" not in f or not f["mandatory"]): + if mandatory_only and ("mandatory" not in f or not f["mandatory"]): continue elif optional_only and ("mandatory" in f and f["mandatory"]): continue @@ -308,8 +314,7 @@ class TabForms(object): @abc.abstractmethod def save(self): - """Save objects here. - """ + """Save objects here.""" def remove_tab(self, tabid): for f in self.forms: @@ -325,8 +330,7 @@ class TabForms(object): yield form def extra_context(self, context): - """"Provide additional information to template's context. - """ + """ "Provide additional information to template's context.""" pass @abc.abstractmethod @@ -337,23 +341,22 @@ class TabForms(object): """ def process(self): - """Process the received request. - """ + """Process the received request.""" if self.request.method == "POST": if self.is_valid(): self.save() return self.done() - return render_to_json_response( - {"form_errors": self.errors}, status=400 - ) + return render_to_json_response({"form_errors": self.errors}, status=400) context = { "tabs": self, } if self.forms: - context.update({ - "action_label": _("Update"), - "action_classes": "submit", - }) + context.update( + { + "action_label": _("Update"), + "action_classes": "submit", + } + ) self.extra_context(context) active_tab_id = self.request.GET.get("active_tab", "default") if active_tab_id != "default": @@ -368,6 +371,7 @@ class UserKwargModelFormMixin: self.user = kwargs.pop("user") super().__init__(*args, **kwargs) + # # Custom fields from here # @@ -391,12 +395,11 @@ class YesNoField(TypedChoiceField): def __init__(self, *args, **kwargs): """Constructor.""" - kwargs.update({ - "choices": ( - (True, gettext_lazy("Yes")), - (False, gettext_lazy("No")) - ), - "widget": HorizontalRadioSelect(), - "coerce": lambda x: x == "True" - }) + kwargs.update( + { + "choices": ((True, gettext_lazy("Yes")), (False, gettext_lazy("No"))), + "widget": HorizontalRadioSelect(), + "coerce": lambda x: x == "True", + } + ) super(YesNoField, self).__init__(*args, **kwargs) diff --git a/modoboa/lib/imap_utf7.py b/modoboa/lib/imap_utf7.py index c40348ab8..ea0a757b2 100644 --- a/modoboa/lib/imap_utf7.py +++ b/modoboa/lib/imap_utf7.py @@ -55,7 +55,7 @@ import codecs # encoding -PRINTABLE = set(range(0x20, 0x26)) | set(range(0x27, 0x7f)) +PRINTABLE = set(range(0x20, 0x26)) | set(range(0x27, 0x7F)) def modified_utf7(s): @@ -135,6 +135,7 @@ codecs.register(imap4_utf_7) # testing methods + def imapUTF7Encode(ust): # NOQA:N802 "Returns imap utf-7 encoded version of string" return ust.encode("imap4-utf-7") @@ -165,7 +166,10 @@ def utf7SequenceToUTF8(seq): # NOQA:N802 return [itm.decode("imap4-utf-7").encode("utf-8") for itm in seq] -__all__ = ["imapUTF7Encode", "imapUTF7Decode", ] +__all__ = [ + "imapUTF7Encode", + "imapUTF7Decode", +] if __name__ == "__main__": diff --git a/modoboa/lib/ldap_utils.py b/modoboa/lib/ldap_utils.py index cbadc8e1e..8c0219c9f 100644 --- a/modoboa/lib/ldap_utils.py +++ b/modoboa/lib/ldap_utils.py @@ -48,9 +48,7 @@ class LDAPAuthBackend(object): def __init__(self): param_tools.apply_to_django_settings() self.global_params = dict(param_tools.get_global_parameters("core")) - self.server_uri = self._setting( - "AUTH_LDAP_SERVER_URI", "ldap://localhost" - ) + self.server_uri = self._setting("AUTH_LDAP_SERVER_URI", "ldap://localhost") self.pwd_attr = self._setting("LDAP_PASSWORD_ATTR", "userPassword") self.ldap_ad = self._setting("LDAP_ACTIVE_DIRECTORY", False) self.conn = None @@ -68,9 +66,7 @@ class LDAPAuthBackend(object): conn = ldap.initialize(self.server_uri) conn.set_option(ldap.OPT_X_TLS_DEMAND, True) conn.set_option(ldap.OPT_DEBUG_LEVEL, 255) - conn.simple_bind_s( - force_str(dn), force_str(password) - ) + conn.simple_bind_s(force_str(dn), force_str(password)) return conn def connect_to_server(self, user, password): @@ -116,14 +112,15 @@ class LDAPAuthBackend(object): self.connect_to_server(user, password) user_dn = self._find_user_dn(user) if self.ldap_ad: - newpassword = ( - ('"%s"' % newpassword).encode("utf-16").lstrip("\377\376") + newpassword = ('"%s"' % newpassword).encode("utf-16").lstrip("\377\376") + ldif = [ + ( + ldap.MOD_REPLACE, + force_str(self.pwd_attr), + force_bytes(self._crypt_password(newpassword)), ) - ldif = [(ldap.MOD_REPLACE, - force_str(self.pwd_attr), - force_bytes(self._crypt_password(newpassword)))] + ] try: self.conn.modify_s(force_str(user_dn), ldif) except ldap.LDAPError as e: - raise InternalError( - _("Failed to update password: {}").format(e)) + raise InternalError(_("Failed to update password: {}").format(e)) diff --git a/modoboa/lib/listing.py b/modoboa/lib/listing.py index 3e5f432d1..7d1f9799d 100644 --- a/modoboa/lib/listing.py +++ b/modoboa/lib/listing.py @@ -36,7 +36,7 @@ def get_listing_page(objects, pagenum): paginator = Paginator( objects, param_tools.get_global_parameter("items_per_page", app="core"), - allow_empty_first_page=False + allow_empty_first_page=False, ) try: page = paginator.page(int(pagenum)) diff --git a/modoboa/lib/middleware.py b/modoboa/lib/middleware.py index 4d02b7f15..db93f0fc5 100644 --- a/modoboa/lib/middleware.py +++ b/modoboa/lib/middleware.py @@ -6,13 +6,11 @@ from django.utils.encoding import smart_str from modoboa.lib import signals as lib_signals from modoboa.lib.exceptions import ModoboaException -from modoboa.lib.web_utils import ( - _render_error, ajax_response, render_to_json_response -) +from modoboa.lib.web_utils import _render_error, ajax_response, render_to_json_response def is_ajax(request): - return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest' + return request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest" class AjaxLoginRedirect(MiddlewareMixin): @@ -34,15 +32,12 @@ class CommonExceptionCatcher(MiddlewareMixin): if is_ajax(request) or "/api/" in request.path: if exception.http_code is None: return ajax_response( - request, status="ko", respmsg=smart_str(exception), - norefresh=True + request, status="ko", respmsg=smart_str(exception), norefresh=True ) return render_to_json_response( smart_str(exception), status=exception.http_code ) - return _render_error( - request, user_context={"error": smart_str(exception)} - ) + return _render_error(request, user_context={"error": smart_str(exception)}) class RequestCatcherMiddleware(MiddlewareMixin): diff --git a/modoboa/lib/migrations/0001_initial.py b/modoboa/lib/migrations/0001_initial.py index 7ffa0a642..b4898789e 100644 --- a/modoboa/lib/migrations/0001_initial.py +++ b/modoboa/lib/migrations/0001_initial.py @@ -10,26 +10,45 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name='Parameter', + name="Parameter", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=255)), - ('value', models.CharField(max_length=255)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("name", models.CharField(max_length=255)), + ("value", models.CharField(max_length=255)), ], - options={ - }, + options={}, bases=(models.Model,), ), migrations.CreateModel( - name='UserParameter', + name="UserParameter", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=255)), - ('value', models.CharField(max_length=255)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("name", models.CharField(max_length=255)), + ("value", models.CharField(max_length=255)), + ( + "user", + models.ForeignKey( + to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE + ), + ), ], - options={ - }, + options={}, bases=(models.Model,), ), ] diff --git a/modoboa/lib/migrations/0002_rename_parameters.py b/modoboa/lib/migrations/0002_rename_parameters.py index 90dcb9647..1127cd699 100644 --- a/modoboa/lib/migrations/0002_rename_parameters.py +++ b/modoboa/lib/migrations/0002_rename_parameters.py @@ -12,13 +12,12 @@ APPLICATIONS = [ ("webmail", "modoboa_webmail"), ] + def rename_app_parameters(app, model): """Rename all parameters for a given app.""" qset = model.objects.filter(name__startswith=app[0]) for param in qset: - param.name = param.name.replace( - "{}.".format(app[0]), "{}.".format(app[1]) - ) + param.name = param.name.replace("{}.".format(app[0]), "{}.".format(app[1])) param.save() @@ -34,9 +33,7 @@ def rename_parameters(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('lib', '0001_initial'), + ("lib", "0001_initial"), ] - operations = [ - migrations.RunPython(rename_parameters) - ] + operations = [migrations.RunPython(rename_parameters)] diff --git a/modoboa/lib/migrations/0003_rename_parameters.py b/modoboa/lib/migrations/0003_rename_parameters.py index 4dd10cdff..be11772ce 100644 --- a/modoboa/lib/migrations/0003_rename_parameters.py +++ b/modoboa/lib/migrations/0003_rename_parameters.py @@ -23,10 +23,8 @@ def rename_parameters(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('lib', '0002_rename_parameters'), - ('admin', '0001_initial'), + ("lib", "0002_rename_parameters"), + ("admin", "0001_initial"), ] - operations = [ - migrations.RunPython(rename_parameters) - ] + operations = [migrations.RunPython(rename_parameters)] diff --git a/modoboa/lib/migrations/0004_auto_20151114_1409.py b/modoboa/lib/migrations/0004_auto_20151114_1409.py index 5c62719ba..2804d63ed 100644 --- a/modoboa/lib/migrations/0004_auto_20151114_1409.py +++ b/modoboa/lib/migrations/0004_auto_20151114_1409.py @@ -13,8 +13,8 @@ def move_language_preference(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('lib', '0003_rename_parameters'), - ('core', '0005_user_language'), + ("lib", "0003_rename_parameters"), + ("core", "0005_user_language"), ] operations = [ diff --git a/modoboa/lib/migrations/0005_auto_20160416_1449.py b/modoboa/lib/migrations/0005_auto_20160416_1449.py index 250bc6be7..6d96cc5c9 100644 --- a/modoboa/lib/migrations/0005_auto_20160416_1449.py +++ b/modoboa/lib/migrations/0005_auto_20160416_1449.py @@ -12,9 +12,7 @@ def rename_limits_parameters(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('lib', '0004_auto_20151114_1409'), + ("lib", "0004_auto_20151114_1409"), ] - operations = [ - migrations.RunPython(rename_limits_parameters) - ] + operations = [migrations.RunPython(rename_limits_parameters)] diff --git a/modoboa/lib/migrations/0006_auto_20161104_2206.py b/modoboa/lib/migrations/0006_auto_20161104_2206.py index 10bf96658..89e745294 100644 --- a/modoboa/lib/migrations/0006_auto_20161104_2206.py +++ b/modoboa/lib/migrations/0006_auto_20161104_2206.py @@ -5,18 +5,18 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('lib', '0005_auto_20160416_1449'), + ("lib", "0005_auto_20160416_1449"), ] operations = [ migrations.DeleteModel( - name='Parameter', + name="Parameter", ), migrations.RemoveField( - model_name='userparameter', - name='user', + model_name="userparameter", + name="user", ), migrations.DeleteModel( - name='UserParameter', + name="UserParameter", ), ] diff --git a/modoboa/lib/paginator.py b/modoboa/lib/paginator.py index 3dfc8f54a..36f534879 100644 --- a/modoboa/lib/paginator.py +++ b/modoboa/lib/paginator.py @@ -2,8 +2,8 @@ Custom pagination tools. """ -class Page(object): +class Page(object): """Class to represent a page.""" def __init__(self, paginator, pageid, id_start, id_stop, baseurl=None): @@ -45,9 +45,7 @@ class Page(object): def has_next(self): """Tell if a next page is available or not.""" if self._has_next is None: - self._has_next = ( - True if self.id_stop < self.paginator.total else False - ) + self._has_next = True if self.id_stop < self.paginator.total else False return self._has_next @property @@ -69,7 +67,6 @@ class Page(object): class Paginator(object): - """Pagination class.""" def __init__(self, total, elems_per_page): diff --git a/modoboa/lib/permissions.py b/modoboa/lib/permissions.py index 2c5efb4bb..61dc3fb7f 100644 --- a/modoboa/lib/permissions.py +++ b/modoboa/lib/permissions.py @@ -20,16 +20,15 @@ def get_account_roles(user, account=None): """ result = [core_constants.SIMPLEUSERS_ROLE] filters = core_signals.user_can_set_role.send( - sender="get_account_roles", user=user, role="DomainAdmins", - account=account) - condition = ( - user.has_perm("admin.add_domain") and - (not filters or True in [flt[1] for flt in filters])) + sender="get_account_roles", user=user, role="DomainAdmins", account=account + ) + condition = user.has_perm("admin.add_domain") and ( + not filters or True in [flt[1] for flt in filters] + ) if condition: result += [core_constants.DOMAINADMINS_ROLE] if user.is_superuser: - result += [ - core_constants.RESELLERS_ROLE, core_constants.SUPERADMINS_ROLE] + result += [core_constants.RESELLERS_ROLE, core_constants.SUPERADMINS_ROLE] return sorted(result, key=lambda role: role[1]) @@ -51,7 +50,8 @@ def grant_access_to_object(user, obj, is_owner=False): """ ct = ContentType.objects.get_for_model(obj) entry, created = ObjectAccess.objects.get_or_create( - user=user, content_type=ct, object_id=obj.id) + user=user, content_type=ct, object_id=obj.id + ) entry.is_owner = is_owner entry.save() if not created or not is_owner: @@ -59,9 +59,7 @@ def grant_access_to_object(user, obj, is_owner=False): for su in User.objects.filter(is_superuser=True): if su == user: continue - ObjectAccess.objects.get_or_create( - user=su, content_type=ct, object_id=obj.id - ) + ObjectAccess.objects.get_or_create(user=su, content_type=ct, object_id=obj.id) def grant_access_to_objects(user, objects, ct): @@ -75,8 +73,7 @@ def grant_access_to_objects(user, objects, ct): :param ct: the content type """ for obj in objects: - ObjectAccess.objects.get_or_create( - user=user, content_type=ct, object_id=obj.id) + ObjectAccess.objects.get_or_create(user=user, content_type=ct, object_id=obj.id) def ungrant_access_to_object(obj, user=None): @@ -100,17 +97,11 @@ def ungrant_access_to_object(obj, user=None): except ObjectAccess.DoesNotExist: pass try: - ObjectAccess.objects.get( - content_type=ct, object_id=obj.id, is_owner=True - ) + ObjectAccess.objects.get(content_type=ct, object_id=obj.id, is_owner=True) except ObjectAccess.DoesNotExist: - grant_access_to_object( - User.objects.filter(is_superuser=True)[0], obj, True - ) + grant_access_to_object(User.objects.filter(is_superuser=True)[0], obj, True) else: - ObjectAccess.objects.filter( - content_type=ct, object_id=obj.id - ).delete() + ObjectAccess.objects.filter(content_type=ct, object_id=obj.id).delete() def ungrant_access_to_objects(objects): @@ -146,8 +137,7 @@ def add_permissions_to_group(group, permissions): for appname, modelname, permname in permissions: ct = ContentType.objects.get_by_natural_key(appname, modelname) - if group.permissions.filter( - content_type=ct, codename=permname).exists(): + if group.permissions.filter(content_type=ct, codename=permname).exists(): continue group.permissions.add( Permission.objects.get(content_type=ct, codename=permname) diff --git a/modoboa/lib/singleton.py b/modoboa/lib/singleton.py index 977a8590b..e49acc309 100644 --- a/modoboa/lib/singleton.py +++ b/modoboa/lib/singleton.py @@ -4,8 +4,7 @@ class _Singleton(type): def __call__(self, *args, **kwargs): if self not in self._instances: - self._instances[self] = \ - super(_Singleton, self).__call__(*args, **kwargs) + self._instances[self] = super(_Singleton, self).__call__(*args, **kwargs) return self._instances[self] diff --git a/modoboa/lib/sysutils.py b/modoboa/lib/sysutils.py index 6877b3fd0..ded7c0a55 100644 --- a/modoboa/lib/sysutils.py +++ b/modoboa/lib/sysutils.py @@ -62,8 +62,9 @@ def doveadm_cmd(params, pinput=None, capture_output=True, **kwargs): dpath = force_str(output).strip() else: known_paths = getattr( - settings, "DOVEADM_LOOKUP_PATH", - ("/usr/bin/doveadm", "/usr/local/bin/doveadm") + settings, + "DOVEADM_LOOKUP_PATH", + ("/usr/bin/doveadm", "/usr/local/bin/doveadm"), ) for fpath in known_paths: if os.path.isfile(fpath) and os.access(fpath, os.X_OK): @@ -73,11 +74,13 @@ def doveadm_cmd(params, pinput=None, capture_output=True, **kwargs): curuser = pwd.getpwuid(os.getuid()).pw_name sudo_user = dovecot_user if curuser != dovecot_user else None if dpath: - return exec_cmd("{} {}".format(dpath, params), - sudo_user=sudo_user, - pinput=pinput, - capture_output=capture_output, - **kwargs) + return exec_cmd( + "{} {}".format(dpath, params), + sudo_user=sudo_user, + pinput=pinput, + capture_output=capture_output, + **kwargs, + ) raise OSError("doveadm command not found") diff --git a/modoboa/lib/templatetags/form_tags.py b/modoboa/lib/templatetags/form_tags.py index 869f9fdd5..4bd43ceb7 100644 --- a/modoboa/lib/templatetags/form_tags.py +++ b/modoboa/lib/templatetags/form_tags.py @@ -26,8 +26,9 @@ def render_form(form, tpl=None): def configure_field_classes(field): """Add required CSS classes to field.""" - if isinstance(field.field.widget, forms.CheckboxInput) or \ - isinstance(field.field.widget, forms.RadioSelect): + if isinstance(field.field.widget, forms.CheckboxInput) or isinstance( + field.field.widget, forms.RadioSelect + ): return if "class" in field.field.widget.attrs: field.field.widget.attrs["class"] += " form-control" @@ -36,9 +37,7 @@ def configure_field_classes(field): @register.simple_tag -def render_field( - field, help_display_mode="tooltip", label_width="col-sm-4", - **options): +def render_field(field, help_display_mode="tooltip", label_width="col-sm-4", **options): """Render a field.""" from modoboa.core.templatetags.core_tags import visirule @@ -46,8 +45,10 @@ def render_field( return "%s" % (visirule(field), smart_str(field.label)) configure_field_classes(field) context = { - "field": field, "help_display_mode": help_display_mode, - "label_width": label_width, "deactivate_if_empty": True + "field": field, + "help_display_mode": help_display_mode, + "label_width": label_width, + "deactivate_if_empty": True, } context.update(options) return render_to_string("common/generic_field.html", context) @@ -75,8 +76,13 @@ def render_fields_group(form, pattern): return render_to_string( "common/generic_fields_group.html", - {"label": label, "help_text": first.help_text, "group": group, - "haserror": haserror, "pattern": pattern} + { + "label": label, + "help_text": first.help_text, + "group": group, + "haserror": haserror, + "pattern": pattern, + }, ) diff --git a/modoboa/lib/templatetags/lib_tags.py b/modoboa/lib/templatetags/lib_tags.py index 2ca57dcbe..64e931f15 100644 --- a/modoboa/lib/templatetags/lib_tags.py +++ b/modoboa/lib/templatetags/lib_tags.py @@ -29,16 +29,19 @@ def tolist(values): @register.simple_tag def alert(msg, typ): - t = Template("""""" + ) # NOQA:E501 return t.render(Context({"type": typ, "msg": msg})) @register.simple_tag def render_link(linkdef, mdclass=""): - t = Template(""" {% if link.img %}{% endif %} -{{ link.label }}""") # NOQA:E501 +{{ link.label }}""" + ) # NOQA:E501 return t.render(Context({"link": linkdef, "mdclass": mdclass})) @register.simple_tag def render_post_link(linkdef, request): - t = Template("""
+ t = Template( + """ {% csrf_token %} {% if link.img %}{% endif %}{{ link.label }} -
""") +""" + ) return t.render(RequestContext(request, {"link": linkdef})) @@ -77,12 +83,14 @@ def fromunix(value): @register.simple_tag def render_tags(tags): - t = Template("""{% for tag in tags %} + t = Template( + """{% for tag in tags %} {{ tag.label }} {% endfor %} -""") # NOQA:E501 +""" + ) # NOQA:E501 return t.render(Context({"tags": tags})) @@ -94,25 +102,21 @@ def extra_static_content(caller, st_type, user): :param str st_type: content type (css or js) :param ``User`` user: connected user """ - tpl = template.Template( - "{% for sc in static_content %}{{ sc|safe }}{% endfor %}" - ) + tpl = template.Template("{% for sc in static_content %}{{ sc|safe }}{% endfor %}") static_content = core_signals.extra_static_content.send( - sender="extra_static_content", - caller=caller, st_type=st_type, user=user) - static_content = [result[1] for result in static_content] - return tpl.render( - template.Context({"static_content": static_content}) + sender="extra_static_content", caller=caller, st_type=st_type, user=user ) + static_content = [result[1] for result in static_content] + return tpl.render(template.Context({"static_content": static_content})) @register.filter(name="localize_header_name") def localize_header_name(headername): - """ Localizes the header names """ + """Localizes the header names""" names = { "From": _("From"), "To": _("To"), "Date": _("Date"), - "Subject": _("Subject") + "Subject": _("Subject"), } return names.get(headername, headername) diff --git a/modoboa/lib/test_utils.py b/modoboa/lib/test_utils.py index e4bb1e4d9..60fc012fd 100644 --- a/modoboa/lib/test_utils.py +++ b/modoboa/lib/test_utils.py @@ -23,8 +23,8 @@ class MapFilesTestCaseMixin(object): def _test_maps_generation(self, engine): dburl = "{0}://user:password@localhost/testdb".format(engine) call_command( - "generate_postfix_maps", - "--dburl", dburl, "--destdir", self.workdir) + "generate_postfix_maps", "--dburl", dburl, "--destdir", self.workdir + ) for mapfile in self.MAP_FILES: path = "{0}/{1}".format(self.workdir, mapfile) diff --git a/modoboa/lib/tests/__init__.py b/modoboa/lib/tests/__init__.py index f37024fab..85363577a 100644 --- a/modoboa/lib/tests/__init__.py +++ b/modoboa/lib/tests/__init__.py @@ -24,6 +24,7 @@ except socket.error: try: import ldap # noqa + NO_LDAP = False except ImportError: NO_LDAP = True @@ -52,6 +53,7 @@ class ParametersMixin(object): self.localconfig.parameters.set_values(parameters, app=app) self.localconfig.save() + class SimpleModoTestCase(ParametersMixin, TestCase): """Simple class to add parameters editing.""" @@ -67,8 +69,7 @@ class ModoTestCase(ParametersMixin, TestCase): def setUp(self, username="admin", password="password"): """Initiate test context.""" - self.assertEqual( - self.client.login(username=username, password=password), True) + self.assertEqual(self.client.login(username=username, password=password), True) self.workdir = tempfile.mkdtemp() self.set_global_parameter("storage_dir", self.workdir, app="pdfcredentials") @@ -76,7 +77,8 @@ class ModoTestCase(ParametersMixin, TestCase): if params is None: params = {} response = getattr(self.client, method)( - url, params, HTTP_X_REQUESTED_WITH="XMLHttpRequest") + url, params, HTTP_X_REQUESTED_WITH="XMLHttpRequest" + ) self.assertEqual(response.status_code, status) return response.json() @@ -102,7 +104,8 @@ class ModoAPITestCase(ParametersMixin, APITestCase): super(ModoAPITestCase, cls).setUpTestData() management.call_command("load_initial_data") cls.token = Token.objects.create( - user=core_models.User.objects.get(username="admin")) + user=core_models.User.objects.get(username="admin") + ) def setUp(self): """Setup.""" diff --git a/modoboa/lib/tests/test_cryptutils.py b/modoboa/lib/tests/test_cryptutils.py index e50c3adac..adc1f6d20 100644 --- a/modoboa/lib/tests/test_cryptutils.py +++ b/modoboa/lib/tests/test_cryptutils.py @@ -6,10 +6,10 @@ from django.test.utils import override_settings from modoboa.lib import cryptutils -@override_settings(SECRET_KEY="!8o(-dbbl3e+*bh7nx-^xysdt)1gso*%@4ze4-9_9o+i&" - ";t--u_") +@override_settings( + SECRET_KEY="!8o(-dbbl3e+*bh7nx-^xysdt)1gso*%@4ze4-9_9o+i&" ";t--u_" +) class CryptUtilsTest(SimpleTestCase): - """Tests for modoboa.lib.cryptutils""" def test_valid_secret_key_generated(self): @@ -27,8 +27,10 @@ class CryptUtilsTest(SimpleTestCase): def test_decrypt(self): """Decrypt a string""" - value = "gAAAAABaXSWk4Via-aYP7diek9MmfknUiEY8szrgxIytdXrbfc"\ - "YlbOYiNG01zqkn3a06P1xPXe5XD2SP4UrIvCWzhLs-FO19Cw==" + value = ( + "gAAAAABaXSWk4Via-aYP7diek9MmfknUiEY8szrgxIytdXrbfc" + "YlbOYiNG01zqkn3a06P1xPXe5XD2SP4UrIvCWzhLs-FO19Cw==" + ) expected_output = "test" output = cryptutils.decrypt(value) self.assertEqual(output, expected_output) diff --git a/modoboa/lib/tests/test_email_utils.py b/modoboa/lib/tests/test_email_utils.py index 405cec905..1bb1572ea 100644 --- a/modoboa/lib/tests/test_email_utils.py +++ b/modoboa/lib/tests/test_email_utils.py @@ -5,12 +5,11 @@ import os from django.test import SimpleTestCase from django.utils.encoding import smart_bytes, smart_str -from ..email_utils import ( - Email, prepare_addresses, split_address, split_local_part -) +from ..email_utils import Email, prepare_addresses, split_address, split_local_part SAMPLES_DIR = os.path.realpath( - os.path.join(os.path.dirname(__file__), "sample_messages")) + os.path.join(os.path.dirname(__file__), "sample_messages") +) class EmailTestImplementation(Email): @@ -38,8 +37,7 @@ class EmailTests(SimpleTestCase): 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, - "%s-output-%s.txt" % (message_id, ext)) + message_path = os.path.join(SAMPLES_DIR, "%s-output-%s.txt" % (message_id, ext)) assert os.path.isfile(message_path), "%s does not exist." % message_path with open(message_path, "rb") as fp: @@ -56,19 +54,18 @@ class EmailTests(SimpleTestCase): def test_invalid_links_value(self): """modoboa-amavis set links = "0"; in python "0" == True, fixed in PR 79 - https://github.com/modoboa/modoboa-amavis/pull/79""" + https://github.com/modoboa/modoboa-amavis/pull/79""" with self.assertRaises(TypeError) as cm: EmailTestImplementation("text_plain", links="0") ex_message = cm.exception.messages self.assertEqual( - ex_message, - "links == \"0\" is not valid, did you mean True or False?" + ex_message, 'links == "0" is not valid, did you mean True or False?' ) def test_links_value_for_webmail(self): """modoboa-webmail sets links = 0 or 1 - TODO: this should be fixed in modoboa-webmail to use True/False""" + TODO: this should be fixed in modoboa-webmail to use True/False""" email = EmailTestImplementation("text_plain", links=0) self.assertFalse(email.links) @@ -108,7 +105,6 @@ class EmailTests(SimpleTestCase): class EmailAddressParserTests(SimpleTestCase): - """Tests for split_address() and split_local_part().""" def test_split_address_with_domain(self): @@ -157,13 +153,15 @@ class EmailAddressParserTests(SimpleTestCase): """Check a list of e-mail addresses is sepearted correctly.""" # value is an array with one long string not 3 sepearte values. value = [ - "\"Doe, John\" ;" - "\"John Smith\" ," + '"Doe, John" ;' + '"John Smith" ,' "admin@sub.example.com" ] - expected_output = "\"Doe, John\" ,"\ - "John Smith ,"\ - "admin@sub.example.com" + expected_output = ( + '"Doe, John" ,' + "John Smith ," + "admin@sub.example.com" + ) output = prepare_addresses(value) self.assertEqual(output, expected_output) @@ -171,8 +169,8 @@ class EmailAddressParserTests(SimpleTestCase): """Check a list of e-mail addresses is sepearted correctly.""" # value is an array with one long string not 3 sepearte values. value = [ - "\"Doe, John\" ;" - "\"John Smith\" ," + '"Doe, John" ;' + '"John Smith" ,' "admin@sub.example.com" ] expected_output = [ @@ -188,8 +186,8 @@ class EmailAddressParserTests(SimpleTestCase): # value is one long string not 3 sepearte values, prepare_addresses # should convert it to a list. value = ( - "\"Doe, John\" ;" - "\"John Smith\" ," + '"Doe, John" ;' + '"John Smith" ,' "admin@sub.example.com" ) expected_output = [ diff --git a/modoboa/lib/tests/test_u2u_decode.py b/modoboa/lib/tests/test_u2u_decode.py index 464aa4a24..c96d59d58 100644 --- a/modoboa/lib/tests/test_u2u_decode.py +++ b/modoboa/lib/tests/test_u2u_decode.py @@ -11,14 +11,20 @@ class U2UTestCase(TestCase): def test_header_decoding(self): """Simple decoding.""" samples = [ - ("=?ISO-8859-15?Q?=20Profitez de tous les services en ligne sur " - "impots.gouv.fr?=", - "Profitez de tous les services en ligne sur impots.gouv.fr"), - ("=?ISO-8859-1?Q?Accus=E9?= de =?ISO-8859-1?Q?r=E9ception?= de " - "votre annonce", - "Accusé de réception de votre annonce"), - ("Sm=?ISO-8859-1?B?9g==?=rg=?ISO-8859-1?B?5Q==?=sbord", - "Sm\xf6rg\xe5sbord"), + ( + "=?ISO-8859-15?Q?=20Profitez de tous les services en ligne sur " + "impots.gouv.fr?=", + "Profitez de tous les services en ligne sur impots.gouv.fr", + ), + ( + "=?ISO-8859-1?Q?Accus=E9?= de =?ISO-8859-1?Q?r=E9ception?= de " + "votre annonce", + "Accusé de réception de votre annonce", + ), + ( + "Sm=?ISO-8859-1?B?9g==?=rg=?ISO-8859-1?B?5Q==?=sbord", + "Sm\xf6rg\xe5sbord", + ), # The following case currently fails because of the way we split # encoded words to parse them separately, which can lead to # unexpected unicode decode errors... I think it will work fine on @@ -35,22 +41,22 @@ class U2UTestCase(TestCase): """Check address decoding.""" mailsploit_sample = ( "=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?==?utf-8?Q?=00?=" - "=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?=@mailsploit.com") + "=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?=@mailsploit.com" + ) expected_result = ( "=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?==?utf-8?Q??=" - "=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?=@mailsploit.com") + "=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?=@mailsploit.com" + ) self.assertEqual( - u2u_decode.decode_address(mailsploit_sample), - ("", expected_result) + u2u_decode.decode_address(mailsploit_sample), ("", expected_result) ) mailsploit_sample = ( '"=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?==?utf-8?Q?=0A=00?="\n' "<=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?==?utf-8?Q?=0A=00?=" - "@mailsploit.com>") + "@mailsploit.com>" + ) expected_result = ( "potus@whitehouse.gov", - "=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?==?utf-8?Q??=" - "@mailsploit.com") - self.assertEqual( - u2u_decode.decode_address(mailsploit_sample), - expected_result) + "=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?==?utf-8?Q??=" "@mailsploit.com", + ) + self.assertEqual(u2u_decode.decode_address(mailsploit_sample), expected_result) diff --git a/modoboa/lib/throttle.py b/modoboa/lib/throttle.py index d972742be..46a830386 100644 --- a/modoboa/lib/throttle.py +++ b/modoboa/lib/throttle.py @@ -8,7 +8,7 @@ class UserDdosPerView(SimpleRateThrottle): applied on a per view basis for authentificated users. """ - scope = 'ddos' + scope = "ddos" def get_cache_key(self, request, view): if request.user and request.user.is_authenticated: @@ -16,8 +16,8 @@ class UserDdosPerView(SimpleRateThrottle): else: ident = self.get_ident(request) return self.cache_format % { - 'scope': hash(resolve(request.path).url_name), - 'ident': ident + "scope": hash(resolve(request.path).url_name), + "ident": ident, } @@ -27,18 +27,18 @@ class UserLesserDdosUser(UserDdosPerView): applied on a per view basis for authentificated users. """ - scope = 'ddos_lesser' + scope = "ddos_lesser" class LoginThrottle(SimpleRateThrottle): """Custom throttle to reset the cache counter on success.""" - scope = 'login' + scope = "login" def get_cache_key(self, request, view): return self.cache_format % { - 'scope': self.scope, - 'ident': self.get_ident(request) + "scope": self.scope, + "ident": self.get_ident(request), } def reset_cache(self, request): @@ -48,17 +48,17 @@ class LoginThrottle(SimpleRateThrottle): class PasswordResetRequestThrottle(LoginThrottle): - scope = 'password_recovery_request' + scope = "password_recovery_request" class PasswordResetTotpThrottle(LoginThrottle): - scope = 'password_recovery_totp_check' + scope = "password_recovery_totp_check" class PasswordResetApplyThrottle(LoginThrottle): - scope = 'password_recovery_apply' + scope = "password_recovery_apply" class GetThrottleViewsetMixin: @@ -72,8 +72,14 @@ class GetThrottleViewsetMixin: throttles = [UserRateThrottle()] actions = [ - "list", "retrieve", "validate", "dns_detail", "me", - "dns_detail", "applications", "structure" + "list", + "retrieve", + "validate", + "dns_detail", + "me", + "dns_detail", + "applications", + "structure", ] if self.action in actions: throttles.append(UserLesserDdosUser()) diff --git a/modoboa/lib/validators.py b/modoboa/lib/validators.py index 645e18dfa..e54c48ca5 100644 --- a/modoboa/lib/validators.py +++ b/modoboa/lib/validators.py @@ -8,7 +8,6 @@ from django.utils.translation import gettext_lazy class HostnameValidator(object): - """Validator for fqdn.""" message = gettext_lazy("Enter a valid domain name") @@ -37,7 +36,6 @@ validate_hostname = HostnameValidator() class UTF8EmailValidator(EmailValidator): - """Validator for addresses using non-ASCII characters.""" # unicode letters range (must be a unicode string, not a raw string) @@ -57,11 +55,9 @@ validate_utf8_email = UTF8EmailValidator() class UTF8AndEmptyUserEmailValidator(UTF8EmailValidator): - """Same as upper + allows empty local part.""" - user_regex = re.compile( - r"(^$|" + UTF8EmailValidator.user_regex_raw, re.IGNORECASE) + user_regex = re.compile(r"(^$|" + UTF8EmailValidator.user_regex_raw, re.IGNORECASE) validate_utf8_and_empty_user_email = UTF8AndEmptyUserEmailValidator() diff --git a/modoboa/lib/web_utils.py b/modoboa/lib/web_utils.py index 443da7f81..ae6333e79 100644 --- a/modoboa/lib/web_utils.py +++ b/modoboa/lib/web_utils.py @@ -16,15 +16,15 @@ from django.template.loader import render_to_string def _render_error(request, errortpl="error", user_context=None): if user_context is None: user_context = {} - return render( - request, "common/%s.html" % errortpl, user_context - ) + return render(request, "common/%s.html" % errortpl, user_context) def render_actions(actions): - t = template.Template("""{% load lib_tags %} + t = template.Template( + """{% load lib_tags %} {% for a in actions %}{% render_link a %}{% endfor %} -""") +""" + ) return t.render(template.Context({"actions": actions})) @@ -39,9 +39,16 @@ def getctx(status, level=1, callback=None, **kwargs): return ctx -def ajax_response(request, status="ok", respmsg=None, - url=None, ajaxnav=False, norefresh=False, - template=None, **kwargs): +def ajax_response( + request, + status="ok", + respmsg=None, + url=None, + ajaxnav=False, + norefresh=False, + template=None, + **kwargs, +): """Ajax response shortcut Simple shortcut that sends an JSON response. If a template is @@ -118,18 +125,18 @@ def size2integer(value, output_unit="B"): return 0 if output_unit == "B": if m.group(2)[0] in ["K", "k"]: - return int(m.group(1)) * 2 ** 10 + return int(m.group(1)) * 2**10 if m.group(2)[0] in ["M", "m"]: - return int(m.group(1)) * 2 ** 20 + return int(m.group(1)) * 2**20 if m.group(2)[0] in ["G", "g"]: - return int(m.group(1)) * 2 ** 30 + return int(m.group(1)) * 2**30 elif output_unit == "MB": if m.group(2)[0] in ["K", "k"]: - return int(int(m.group(1)) / 2 ** 10) + return int(int(m.group(1)) / 2**10) if m.group(2)[0] in ["M", "m"]: return int(m.group(1)) if m.group(2)[0] in ["G", "g"]: - return int(m.group(1)) * 2 ** 10 + return int(m.group(1)) * 2**10 else: raise ValueError("Unsupported output unit {}".format(output_unit)) return 0 @@ -143,8 +150,7 @@ class NavigationParameters(object): def __init__(self, request, sessionkey): self.request = request self.sessionkey = sessionkey - self.parameters = [("pattern", "", True), - ("criteria", "from_addr", False)] + self.parameters = [("pattern", "", True), ("criteria", "from_addr", False)] def __getitem__(self, key): """Retrieve an item.""" @@ -167,8 +173,7 @@ class NavigationParameters(object): self["page"] = int(self.request.GET.get("page", 1)) def store(self): - """Store navigation parameters into session. - """ + """Store navigation parameters into session.""" if self.sessionkey not in self.request.session: self.request.session[self.sessionkey] = {} self._store_page() diff --git a/modoboa/limits/api/v1/tests.py b/modoboa/limits/api/v1/tests.py index 5d3db87c8..8b6c0bcfe 100644 --- a/modoboa/limits/api/v1/tests.py +++ b/modoboa/limits/api/v1/tests.py @@ -22,21 +22,20 @@ class APIAdminLimitsTestCase(lib_tests.ModoAPITestCase): """Create test data.""" super(APIAdminLimitsTestCase, cls).setUpTestData() for name, _definition in utils.get_user_limit_templates(): - cls.localconfig.parameters.set_value( - "deflt_user_{0}_limit".format(name), 2) + cls.localconfig.parameters.set_value("deflt_user_{0}_limit".format(name), 2) cls.localconfig.save() populate_database() cls.user = User.objects.get(username="admin@test.com") cls.da_token = Token.objects.create(user=cls.user) cls.reseller = core_factories.UserFactory( - username="reseller", groups=("Resellers", ), + username="reseller", + groups=("Resellers",), ) cls.r_token = Token.objects.create(user=cls.reseller) def test_domadmins_limit(self): """Check domain admins limit.""" - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.r_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.r_token.key) limit = self.reseller.userobjectlimit_set.get(name="domain_admins") url = reverse("v1:account-list") @@ -66,18 +65,14 @@ class APIAdminLimitsTestCase(lib_tests.ModoAPITestCase): "username": user.username, "role": "DomainAdmins", "password": "Toto1234", - "mailbox": { - "full_address": user.username, - "quota": user.mailbox.quota - } + "mailbox": {"full_address": user.username, "quota": user.mailbox.quota}, } response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 400) def test_domains_limit(self): """Check domains limit.""" - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.r_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.r_token.key) limit = self.reseller.userobjectlimit_set.get(name="domains") quota = self.reseller.userobjectlimit_set.get(name="quota") quota.max_value = 3 @@ -98,25 +93,23 @@ class APIAdminLimitsTestCase(lib_tests.ModoAPITestCase): data["name"] = "test5.com" response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 403) - self.assertEqual( - response.content.decode("utf-8"), '"Domains: limit reached"' - ) + self.assertEqual(response.content.decode("utf-8"), '"Domains: limit reached"') resp = self.client.delete( - reverse("v1:domain-detail", - args=[Domain.objects.get(name="test4.com").pk])) + reverse("v1:domain-detail", args=[Domain.objects.get(name="test4.com").pk]) + ) self.assertEqual(resp.status_code, 204) data["quota"] = 0 response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 400) self.assertEqual( response.content.decode(), - '"You\'re not allowed to define unlimited values"') + '"You\'re not allowed to define unlimited values"', + ) def test_domain_aliases_limit(self): """Check domain aliases limit.""" - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.r_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.r_token.key) domain = Domain.objects.get(name="test.com") domain.add_admin(self.reseller) limit = self.reseller.userobjectlimit_set.get(name="domain_aliases") @@ -137,8 +130,7 @@ class APIAdminLimitsTestCase(lib_tests.ModoAPITestCase): def test_mailboxes_limit(self): """Check mailboxes limit.""" - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.da_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.da_token.key) limit = self.user.userobjectlimit_set.get(name="mailboxes") url = reverse("v1:account-list") @@ -146,10 +138,7 @@ class APIAdminLimitsTestCase(lib_tests.ModoAPITestCase): "username": "fromapi@test.com", "role": "SimpleUsers", "password": "Toto1234", - "mailbox": { - "full_address": "fromapi@test.com", - "quota": 10 - } + "mailbox": {"full_address": "fromapi@test.com", "quota": 10}, } response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 201) @@ -168,16 +157,17 @@ class APIAdminLimitsTestCase(lib_tests.ModoAPITestCase): def test_aliases_limit(self): """Check mailbox aliases limit.""" - self.client.credentials( - HTTP_AUTHORIZATION="Token " + self.da_token.key) + self.client.credentials(HTTP_AUTHORIZATION="Token " + self.da_token.key) limit = self.user.userobjectlimit_set.get(name="mailbox_aliases") url = reverse("v1:alias-list") data = { "address": "alias_fromapi@test.com", "recipients": [ - "user@test.com", "postmaster@test.com", "user_éé@nonlocal.com" - ] + "user@test.com", + "postmaster@test.com", + "user_éé@nonlocal.com", + ], } response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 201) @@ -200,11 +190,11 @@ class APIDomainLimitsTestCase(lib_tests.ModoAPITestCase): def setUpTestData(cls): # NOQA:N802 """Create test data.""" super(APIDomainLimitsTestCase, cls).setUpTestData() - cls.localconfig.parameters.set_value( - "enable_domain_limits", True) + cls.localconfig.parameters.set_value("enable_domain_limits", True) for name, _definition in utils.get_domain_limit_templates(): cls.localconfig.parameters.set_value( - "deflt_domain_{0}_limit".format(name), 2) + "deflt_domain_{0}_limit".format(name), 2 + ) cls.localconfig.save() populate_database() @@ -218,10 +208,7 @@ class APIDomainLimitsTestCase(lib_tests.ModoAPITestCase): "username": "fromapi@test.com", "role": "SimpleUsers", "password": "Toto1234", - "mailbox": { - "full_address": "fromapi@test.com", - "quota": 10 - } + "mailbox": {"full_address": "fromapi@test.com", "quota": 10}, } response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 400) @@ -251,8 +238,10 @@ class APIDomainLimitsTestCase(lib_tests.ModoAPITestCase): data = { "address": "alias_fromapi@test.com", "recipients": [ - "user@test.com", "postmaster@test.com", "user_éé@nonlocal.com" - ] + "user@test.com", + "postmaster@test.com", + "user_éé@nonlocal.com", + ], } response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 400) @@ -266,14 +255,14 @@ class ResourcesAPITestCase(lib_tests.ModoAPITestCase): """Create test data.""" super(ResourcesAPITestCase, cls).setUpTestData() for name, _definition in utils.get_user_limit_templates(): - cls.localconfig.parameters.set_value( - "deflt_user_{0}_limit".format(name), 2) + cls.localconfig.parameters.set_value("deflt_user_{0}_limit".format(name), 2) cls.localconfig.save() populate_database() cls.user = User.objects.get(username="admin@test.com") cls.da_token = Token.objects.create(user=cls.user) cls.reseller = core_factories.UserFactory( - username="reseller", groups=("Resellers", ), + username="reseller", + groups=("Resellers",), ) cls.r_token = Token.objects.create(user=cls.reseller) @@ -288,19 +277,17 @@ class ResourcesAPITestCase(lib_tests.ModoAPITestCase): "domain_admins": 2, "domain_aliases": 2, "domains": 2, - "mailbox_aliases": 2 + "mailbox_aliases": 2, } compare(expected, response.data) # As reseller => fails - self.client.credentials( - HTTP_AUTHORIZATION="Token {}".format(self.r_token.key)) + self.client.credentials(HTTP_AUTHORIZATION="Token {}".format(self.r_token.key)) response = self.client.get(url) self.assertEqual(response.status_code, 404) # As domain admin => fails - self.client.credentials( - HTTP_AUTHORIZATION="Token {}".format(self.da_token.key)) + self.client.credentials(HTTP_AUTHORIZATION="Token {}".format(self.da_token.key)) response = self.client.get(url) self.assertEqual(response.status_code, 404) @@ -313,12 +300,11 @@ class ResourcesAPITestCase(lib_tests.ModoAPITestCase): response = self.client.put(url, resources) self.assertEqual(response.status_code, 200) self.assertEqual( - self.reseller.userobjectlimit_set.get(name="domains").max_value, - 1000) + self.reseller.userobjectlimit_set.get(name="domains").max_value, 1000 + ) # As domain admin => fails - self.client.credentials( - HTTP_AUTHORIZATION="Token {}".format(self.da_token.key)) + self.client.credentials(HTTP_AUTHORIZATION="Token {}".format(self.da_token.key)) resources.update({"domains": 2, "mailboxes": 2}) url = reverse("v1:resources-detail", args=[self.user.pk]) response = self.client.put(url, resources) @@ -326,18 +312,17 @@ class ResourcesAPITestCase(lib_tests.ModoAPITestCase): # As reseller => ok permissions.grant_access_to_object(self.reseller, self.user, True) - self.client.credentials( - HTTP_AUTHORIZATION="Token {}".format(self.r_token.key)) + self.client.credentials(HTTP_AUTHORIZATION="Token {}".format(self.r_token.key)) resources.update({"domains": 500, "mailboxes": 500}) url = reverse("v1:resources-detail", args=[self.user.pk]) response = self.client.put(url, resources) self.assertEqual(response.status_code, 200) self.assertEqual( - self.user.userobjectlimit_set.get(name="domains").max_value, - 500) + self.user.userobjectlimit_set.get(name="domains").max_value, 500 + ) self.assertEqual( - self.reseller.userobjectlimit_set.get(name="domains").max_value, - 502) + self.reseller.userobjectlimit_set.get(name="domains").max_value, 502 + ) resources.update({"domains": 1003}) response = self.client.put(url, resources) self.assertEqual(response.status_code, 424) diff --git a/modoboa/limits/api/v1/urls.py b/modoboa/limits/api/v1/urls.py index 621a83286..637450c46 100644 --- a/modoboa/limits/api/v1/urls.py +++ b/modoboa/limits/api/v1/urls.py @@ -5,7 +5,6 @@ from rest_framework import routers from . import viewsets router = routers.SimpleRouter() -router.register( - r"resources", viewsets.ResourcesViewSet, basename="resources") +router.register(r"resources", viewsets.ResourcesViewSet, basename="resources") urlpatterns = router.urls diff --git a/modoboa/limits/api/v1/viewsets.py b/modoboa/limits/api/v1/viewsets.py index 006cb7454..7f4545977 100644 --- a/modoboa/limits/api/v1/viewsets.py +++ b/modoboa/limits/api/v1/viewsets.py @@ -11,10 +11,11 @@ from . import serializers class ResourcesViewSet( - GetThrottleViewsetMixin, - mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - viewsets.GenericViewSet): + GetThrottleViewsetMixin, + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + viewsets.GenericViewSet, +): """Resources viewset.""" permission_classes = [IsAuthenticated, DjangoModelPermissions] @@ -25,8 +26,9 @@ class ResourcesViewSet( user = self.request.user ids = list( user.objectaccess_set.filter( - content_type=ContentType.objects.get_for_model(user)) - .values_list("object_id", flat=True)) + content_type=ContentType.objects.get_for_model(user) + ).values_list("object_id", flat=True) + ) if not user.is_superuser and user.pk in ids: ids.remove(user.pk) return core_models.User.objects.filter(pk__in=ids) diff --git a/modoboa/limits/app_settings.py b/modoboa/limits/app_settings.py index 001a0ccf9..98ea522ae 100644 --- a/modoboa/limits/app_settings.py +++ b/modoboa/limits/app_settings.py @@ -19,7 +19,7 @@ class ParametersForm(param_forms.AdminParametersForm): enable_admin_limits = YesNoField( label=_("Enable per-admin limits"), initial=True, - help_text=_("Enable or disable per-admin limits") + help_text=_("Enable or disable per-admin limits"), ) deflt_user_domain_admins_limit = forms.IntegerField( @@ -30,8 +30,7 @@ class ParametersForm(param_forms.AdminParametersForm): "administrator. (0 to deny any creation, -1 to allow unlimited " "creations)" ), - widget=forms.widgets.TextInput( - attrs={"class": "col-md-1 form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "col-md-1 form-control"}), ) deflt_user_domains_limit = forms.IntegerField( label=_("Domains"), @@ -40,8 +39,7 @@ class ParametersForm(param_forms.AdminParametersForm): "Maximum number of allowed domains for a new administrator. " "(0 to deny any creation, -1 to allow unlimited creations)" ), - widget=forms.widgets.TextInput( - attrs={"class": "col-md-1 form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "col-md-1 form-control"}), ) deflt_user_domain_aliases_limit = forms.IntegerField( label=_("Domain aliases"), @@ -51,8 +49,7 @@ class ParametersForm(param_forms.AdminParametersForm): "administrator. (0 to deny any creation, -1 to allow " "unlimited creations)" ), - widget=forms.widgets.TextInput( - attrs={"class": "col-md-1 form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "col-md-1 form-control"}), ) deflt_user_mailboxes_limit = forms.IntegerField( label=_("Mailboxes"), @@ -61,8 +58,7 @@ class ParametersForm(param_forms.AdminParametersForm): "Maximum number of allowed mailboxes for a new administrator. " "(0 to deny any creation, -1 to allow unlimited creations)" ), - widget=forms.widgets.TextInput( - attrs={"class": "col-md-1 form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "col-md-1 form-control"}), ) deflt_user_mailbox_aliases_limit = forms.IntegerField( label=_("Mailbox aliases"), @@ -71,8 +67,7 @@ class ParametersForm(param_forms.AdminParametersForm): "Maximum number of allowed aliases for a new administrator. " "(0 to deny any creation, -1 to allow unlimited creations)" ), - widget=forms.widgets.TextInput( - attrs={"class": "col-md-1 form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "col-md-1 form-control"}), ) deflt_user_quota_limit = forms.IntegerField( label=_("Quota"), @@ -81,8 +76,7 @@ class ParametersForm(param_forms.AdminParametersForm): "The quota a reseller will be allowed to share between the " "domains he creates. (0 means no quota)" ), - widget=forms.widgets.TextInput( - attrs={"class": "col-md-1 form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "col-md-1 form-control"}), ) domain_limits_sep = SeparatorField(label=_("Default per-domain limits")) @@ -90,7 +84,7 @@ class ParametersForm(param_forms.AdminParametersForm): enable_domain_limits = YesNoField( label=_("Enable per-domain limits"), initial=False, - help_text=_("Enable or disable per-domain limits") + help_text=_("Enable or disable per-domain limits"), ) deflt_domain_domain_admins_limit = forms.IntegerField( @@ -101,8 +95,7 @@ class ParametersForm(param_forms.AdminParametersForm): "domain. (0 to deny any creation, -1 to allow unlimited " "creations)" ), - widget=forms.widgets.TextInput( - attrs={"class": "col-md-1 form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "col-md-1 form-control"}), ) deflt_domain_domain_aliases_limit = forms.IntegerField( label=_("Domain aliases"), @@ -112,8 +105,7 @@ class ParametersForm(param_forms.AdminParametersForm): "domain. (0 to deny any creation, -1 to allow " "unlimited creations)" ), - widget=forms.widgets.TextInput( - attrs={"class": "col-md-1 form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "col-md-1 form-control"}), ) deflt_domain_mailboxes_limit = forms.IntegerField( label=_("Mailboxes"), @@ -122,8 +114,7 @@ class ParametersForm(param_forms.AdminParametersForm): "Maximum number of allowed mailboxes for a new domain. " "(0 to deny any creation, -1 to allow unlimited creations)" ), - widget=forms.widgets.TextInput( - attrs={"class": "col-md-1 form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "col-md-1 form-control"}), ) deflt_domain_mailbox_aliases_limit = forms.IntegerField( label=_("Mailbox aliases"), @@ -132,8 +123,7 @@ class ParametersForm(param_forms.AdminParametersForm): "Maximum number of allowed aliases for a new domain. " "(0 to deny any creation, -1 to allow unlimited creations)" ), - widget=forms.widgets.TextInput( - attrs={"class": "col-md-1 form-control"}) + widget=forms.widgets.TextInput(attrs={"class": "col-md-1 form-control"}), ) visibility_rules = { @@ -149,107 +139,155 @@ class ParametersForm(param_forms.AdminParametersForm): } -GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([ - ("per_admin_limits", { - "label": _("Default per-admin limits"), - "params": collections.OrderedDict([ - ("enable_admin_limits", { - "label": _("Enable per-admin limits"), - "help_text": _("Enable or disable per-admin limits") - }), - ("deflt_user_domain_admins_limit", { - "label": _("Domain admins"), - "display": "enable_admin_limits=true", - "help_text": _( - "Maximum number of allowed domain administrators for a new " - "administrator. (0 to deny any creation, -1 to allow " - "unlimited creations)" +GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict( + [ + ( + "per_admin_limits", + { + "label": _("Default per-admin limits"), + "params": collections.OrderedDict( + [ + ( + "enable_admin_limits", + { + "label": _("Enable per-admin limits"), + "help_text": _("Enable or disable per-admin limits"), + }, + ), + ( + "deflt_user_domain_admins_limit", + { + "label": _("Domain admins"), + "display": "enable_admin_limits=true", + "help_text": _( + "Maximum number of allowed domain administrators for a new " + "administrator. (0 to deny any creation, -1 to allow " + "unlimited creations)" + ), + }, + ), + ( + "deflt_user_domains_limit", + { + "label": _("Domains"), + "display": "enable_admin_limits=true", + "help_text": _( + "Maximum number of allowed domains for a new administrator." + " (0 to deny any creation, -1 to allow unlimited creations)" + ), + }, + ), + ( + "deflt_user_domain_aliases_limit", + { + "label": _("Domain aliases"), + "display": "enable_admin_limits=true", + "help_text": _( + "Maximum number of allowed domain aliases for a new " + "administrator. (0 to deny any creation, -1 to allow " + "unlimited creations)" + ), + }, + ), + ( + "deflt_user_mailboxes_limit", + { + "label": _("Mailboxes"), + "display": "enable_admin_limits=true", + "help_text": _( + "Maximum number of allowed mailboxes for a new " + "administrator. (0 to deny any creation, -1 to allow " + "unlimited creations)" + ), + }, + ), + ( + "deflt_user_mailbox_aliases_limit", + { + "label": _("Mailbox aliases"), + "display": "enable_admin_limits=true", + "help_text": _( + "Maximum number of allowed aliases for a new administrator." + " (0 to deny any creation, -1 to allow unlimited creations)" + ), + }, + ), + ( + "deflt_user_quota_limit", + { + "label": _("Quota"), + "help_text": _( + "The quota a reseller will be allowed to share between the " + "domains he creates. (0 means no quota)" + ), + }, + ), + ] ), - }), - ("deflt_user_domains_limit", { - "label": _("Domains"), - "display": "enable_admin_limits=true", - "help_text": _( - "Maximum number of allowed domains for a new administrator." - " (0 to deny any creation, -1 to allow unlimited creations)" + }, + ), + ( + "per_domain_limits", + { + "label": _("Default per-domain limits"), + "params": collections.OrderedDict( + [ + ( + "enable_domain_limits", + { + "label": _("Enable per-domain limits"), + "help_text": _("Enable or disable per-domain limits"), + }, + ), + ( + "deflt_domain_domain_admins_limit", + { + "label": _("Domain admins"), + "display": "enable_domain_limits=true", + "help_text": _( + "Maximum number of allowed domain administrators for a new " + "domain. (0 to deny any creation, -1 to allow unlimited " + "creations)" + ), + }, + ), + ( + "deflt_domain_domain_aliases_limit", + { + "label": _("Domain aliases"), + "display": "enable_domain_limits=true", + "help_text": _( + "Maximum number of allowed domain aliases for a new " + "domain. (0 to deny any creation, -1 to allow " + "unlimited creations)" + ), + }, + ), + ( + "deflt_domain_mailboxes_limit", + { + "label": _("Mailboxes"), + "display": "enable_domain_limits=true", + "help_text": _( + "Maximum number of allowed mailboxes for a new domain. " + "(0 to deny any creation, -1 to allow unlimited creations)" + ), + }, + ), + ( + "deflt_domain_mailbox_aliases_limit", + { + "label": _("Mailbox aliases"), + "display": "enable_domain_limits=true", + "help_text": _( + "Maximum number of allowed aliases for a new domain. " + "(0 to deny any creation, -1 to allow unlimited creations)" + ), + }, + ), + ] ), - }), - ("deflt_user_domain_aliases_limit", { - "label": _("Domain aliases"), - "display": "enable_admin_limits=true", - "help_text": _( - "Maximum number of allowed domain aliases for a new " - "administrator. (0 to deny any creation, -1 to allow " - "unlimited creations)" - ), - }), - ("deflt_user_mailboxes_limit", { - "label": _("Mailboxes"), - "display": "enable_admin_limits=true", - "help_text": _( - "Maximum number of allowed mailboxes for a new " - "administrator. (0 to deny any creation, -1 to allow " - "unlimited creations)" - ), - }), - ("deflt_user_mailbox_aliases_limit", { - "label": _("Mailbox aliases"), - "display": "enable_admin_limits=true", - "help_text": _( - "Maximum number of allowed aliases for a new administrator." - " (0 to deny any creation, -1 to allow unlimited creations)" - ), - }), - ("deflt_user_quota_limit", { - "label": _("Quota"), - "help_text": _( - "The quota a reseller will be allowed to share between the " - "domains he creates. (0 means no quota)" - ), - }) - ]) - }), - ("per_domain_limits", { - "label": _("Default per-domain limits"), - "params": collections.OrderedDict([ - ("enable_domain_limits", { - "label": _("Enable per-domain limits"), - "help_text": _("Enable or disable per-domain limits") - }), - ("deflt_domain_domain_admins_limit", { - "label": _("Domain admins"), - "display": "enable_domain_limits=true", - "help_text": _( - "Maximum number of allowed domain administrators for a new " - "domain. (0 to deny any creation, -1 to allow unlimited " - "creations)" - ), - }), - ("deflt_domain_domain_aliases_limit", { - "label": _("Domain aliases"), - "display": "enable_domain_limits=true", - "help_text": _( - "Maximum number of allowed domain aliases for a new " - "domain. (0 to deny any creation, -1 to allow " - "unlimited creations)" - ), - }), - ("deflt_domain_mailboxes_limit", { - "label": _("Mailboxes"), - "display": "enable_domain_limits=true", - "help_text": _( - "Maximum number of allowed mailboxes for a new domain. " - "(0 to deny any creation, -1 to allow unlimited creations)" - ), - }), - ("deflt_domain_mailbox_aliases_limit", { - "label": _("Mailbox aliases"), - "display": "enable_domain_limits=true", - "help_text": _( - "Maximum number of allowed aliases for a new domain. " - "(0 to deny any creation, -1 to allow unlimited creations)" - ), - }) - ]) - }) -]) + }, + ), + ] +) diff --git a/modoboa/limits/apps.py b/modoboa/limits/apps.py index 2f204b0e3..6181a9ea9 100644 --- a/modoboa/limits/apps.py +++ b/modoboa/limits/apps.py @@ -12,8 +12,11 @@ def load_limits_settings(): param_tools.registry.add("global", app_settings.ParametersForm, _("Limits")) param_tools.registry.add2( - "global", "limits", _("Limits"), app_settings.GLOBAL_PARAMETERS_STRUCT, - serializers.LimitsGlobalParemetersSerializer + "global", + "limits", + _("Limits"), + app_settings.GLOBAL_PARAMETERS_STRUCT, + serializers.LimitsGlobalParemetersSerializer, ) diff --git a/modoboa/limits/constants.py b/modoboa/limits/constants.py index 970d9eef7..41de5c11b 100644 --- a/modoboa/limits/constants.py +++ b/modoboa/limits/constants.py @@ -4,54 +4,103 @@ import collections from django.utils.translation import gettext_lazy as _ -DEFAULT_USER_LIMITS = collections.OrderedDict(( - ("domains", { - "content_type": "admin.domain", "label": _("Domains"), - "help": _("Maximum number of domains this user can create"), - "required_role": "Resellers"}), - ("domain_aliases", { - "content_type": "admin.domainalias", "label": _("Domain aliases"), - "help": _("Maximum number of domain aliases this user can create"), - "required_role": "Resellers"}), - ("mailboxes", { - "content_type": "admin.mailbox", "label": _("Mailboxes"), - "help": _("Maximum number of mailboxes this user can create")}), - ("mailbox_aliases", { - "content_type": "admin.alias", "label": _("Mailbox aliases"), - "help": _("Maximum number of mailbox aliases this user " - "can create")}), - ("domain_admins", { - "content_type": "core.user", "label": _("Domain admins"), - "help": _("Maximum number of domain administrators this user " - "can create"), - "required_role": "Resellers", - "extra_filters": {"groups__name": "DomainAdmins"}}), - ("quota", { - "content_type": "admin.domain", "label": _("Quota"), - "help": _("Quota shared between domains of this reseller"), - "required_role": "Resellers", - "type": "sum", - "field": "quota" - }) -)) +DEFAULT_USER_LIMITS = collections.OrderedDict( + ( + ( + "domains", + { + "content_type": "admin.domain", + "label": _("Domains"), + "help": _("Maximum number of domains this user can create"), + "required_role": "Resellers", + }, + ), + ( + "domain_aliases", + { + "content_type": "admin.domainalias", + "label": _("Domain aliases"), + "help": _("Maximum number of domain aliases this user can create"), + "required_role": "Resellers", + }, + ), + ( + "mailboxes", + { + "content_type": "admin.mailbox", + "label": _("Mailboxes"), + "help": _("Maximum number of mailboxes this user can create"), + }, + ), + ( + "mailbox_aliases", + { + "content_type": "admin.alias", + "label": _("Mailbox aliases"), + "help": _("Maximum number of mailbox aliases this user " "can create"), + }, + ), + ( + "domain_admins", + { + "content_type": "core.user", + "label": _("Domain admins"), + "help": _( + "Maximum number of domain administrators this user " "can create" + ), + "required_role": "Resellers", + "extra_filters": {"groups__name": "DomainAdmins"}, + }, + ), + ( + "quota", + { + "content_type": "admin.domain", + "label": _("Quota"), + "help": _("Quota shared between domains of this reseller"), + "required_role": "Resellers", + "type": "sum", + "field": "quota", + }, + ), + ) +) -DEFAULT_DOMAIN_LIMITS = collections.OrderedDict(( - ("domain_aliases", { - "relation": "domainalias_set", "label": _("Domain aliases"), - "help": _("Maximum number of domain aliases allowed for this domain.") - }), - ("mailboxes", { - "relation": "mailbox_set", "label": _("Mailboxes"), - "help": _("Maximum number of mailboxes allowed for this domain.")}), - ("mailbox_aliases", { - "relation": "alias_set", "label": _("Mailbox aliases"), - "help": _( - "Maximum number of mailbox aliases allowed for this domain."), - "extra_filters": {"internal": False} - }), - ("domain_admins", { - "relation": "admins", "label": _("Domain admins"), - "help": _("Maximum number of domain admins allowed for this domain."), - }) -)) +DEFAULT_DOMAIN_LIMITS = collections.OrderedDict( + ( + ( + "domain_aliases", + { + "relation": "domainalias_set", + "label": _("Domain aliases"), + "help": _("Maximum number of domain aliases allowed for this domain."), + }, + ), + ( + "mailboxes", + { + "relation": "mailbox_set", + "label": _("Mailboxes"), + "help": _("Maximum number of mailboxes allowed for this domain."), + }, + ), + ( + "mailbox_aliases", + { + "relation": "alias_set", + "label": _("Mailbox aliases"), + "help": _("Maximum number of mailbox aliases allowed for this domain."), + "extra_filters": {"internal": False}, + }, + ), + ( + "domain_admins", + { + "relation": "admins", + "label": _("Domain admins"), + "help": _("Maximum number of domain admins allowed for this domain."), + }, + ), + ) +) diff --git a/modoboa/limits/forms.py b/modoboa/limits/forms.py index ddaf69f1d..6c226b842 100644 --- a/modoboa/limits/forms.py +++ b/modoboa/limits/forms.py @@ -17,8 +17,8 @@ class ResourcePoolForm(forms.Form): for name, tpl in utils.get_user_limit_templates(): if "required_role" in tpl: condition = ( - self.account is not None and - self.account.role != tpl["required_role"] + self.account is not None + and self.account.role != tpl["required_role"] ) if condition: continue @@ -42,8 +42,9 @@ class ResourcePoolForm(forms.Form): """Load limit values from given user.""" for fieldname in list(self.fields.keys()): lname = fieldname.replace("_limit", "") - self.fields[fieldname].initial = ( - user.userobjectlimit_set.get(name=lname).max_value) + self.fields[fieldname].initial = user.userobjectlimit_set.get( + name=lname + ).max_value def save(self): owner = get_object_owner(self.account) @@ -53,8 +54,7 @@ class ResourcePoolForm(forms.Form): continue limit = self.account.userobjectlimit_set.get(name=name) if not owner.is_superuser: - allocate_resources_from_user( - limit, owner, self.cleaned_data[fieldname]) + allocate_resources_from_user(limit, owner, self.cleaned_data[fieldname]) limit.max_value = self.cleaned_data[fieldname] limit.save(update_fields=["max_value"]) @@ -74,8 +74,9 @@ class DomainLimitsForm(forms.Form): return for fieldname in list(self.fields.keys()): lname = fieldname.replace("_limit", "") - self.fields[fieldname].initial = ( - self.domain.domainobjectlimit_set.get(name=lname).max_value) + self.fields[fieldname].initial = self.domain.domainobjectlimit_set.get( + name=lname + ).max_value def clean(self): """Ensure limit values are correct.""" diff --git a/modoboa/limits/handlers.py b/modoboa/limits/handlers.py index a2992db20..6b3bc325c 100644 --- a/modoboa/limits/handlers.py +++ b/modoboa/limits/handlers.py @@ -46,13 +46,15 @@ def create_user_limits(sender, instance, **kwargs): global_params = dict(param_tools.get_global_parameters("limits")) for name, definition in utils.get_user_limit_templates(): ct = ContentType.objects.get_by_natural_key( - *definition["content_type"].split(".")) + *definition["content_type"].split(".") + ) max_value = 0 # creator can be None if user was created by a factory if not creator or creator.is_superuser: max_value = global_params["deflt_user_{0}_limit".format(name)] models.UserObjectLimit.objects.create( - user=instance, name=name, content_type=ct, max_value=max_value) + user=instance, name=name, content_type=ct, max_value=max_value + ) @receiver(signals.post_save, sender=admin_models.Domain) @@ -64,7 +66,8 @@ def create_domain_limits(sender, instance, **kwargs): for name, _definition in utils.get_domain_limit_templates(): max_value = global_params["deflt_domain_{0}_limit".format(name)] models.DomainObjectLimit.objects.create( - domain=instance, name=name, max_value=max_value) + domain=instance, name=name, max_value=max_value + ) @receiver(admin_signals.extra_domain_dashboard_widgets) @@ -72,32 +75,32 @@ def display_domain_limits(sender, user, domain, **kwargs): """Display resources usage for domain.""" if not param_tools.get_global_parameter("enable_domain_limits"): return [] - return [{ - "column": "right", - "template": "limits/resources_widget.html", - "context": { - "limits": domain.domainobjectlimit_set.all() + return [ + { + "column": "right", + "template": "limits/resources_widget.html", + "context": {"limits": domain.domainobjectlimit_set.all()}, } - }] + ] @receiver(admin_signals.extra_account_dashboard_widgets) def display_admin_limits(sender, user, account, **kwargs): """Display resources usage for admin.""" - condition = ( - param_tools.get_global_parameter("enable_admin_limits") and - account.role in ["DomainAdmins", "Resellers"] - ) + condition = param_tools.get_global_parameter( + "enable_admin_limits" + ) and account.role in ["DomainAdmins", "Resellers"] if not condition: return [] - return [{ - "column": "right", - "template": "limits/resources_widget.html", - "context": { - "limits": ( - account.userobjectlimit_set.select_related("content_type")) + return [ + { + "column": "right", + "template": "limits/resources_widget.html", + "context": { + "limits": (account.userobjectlimit_set.select_related("content_type")) + }, } - }] + ] @receiver(admin_signals.extra_account_forms) @@ -108,16 +111,11 @@ def extra_account_form(sender, user, account=None, **kwargs): if user.role not in ["SuperAdmins", "Resellers"]: return [] condition = ( - (account is not None and - account.role not in ["Resellers", "DomainAdmins"]) or - user == account - ) + account is not None and account.role not in ["Resellers", "DomainAdmins"] + ) or user == account if condition: return [] - return [{ - "id": "resources", "title": _("Resources"), - "cls": forms.ResourcePoolForm - }] + return [{"id": "resources", "title": _("Resources"), "cls": forms.ResourcePoolForm}] @receiver(admin_signals.check_extra_account_form) @@ -134,9 +132,9 @@ def check_form_access(sender, account, form, **kwargs): def fill_account_instances(sender, user, account, **kwargs): """Set account instance for resources form.""" condition = ( - not param_tools.get_global_parameter("enable_admin_limits") or - (not user.is_superuser and user.role != "Resellers") or - account.role not in ["Resellers", "DomainAdmins"] + not param_tools.get_global_parameter("enable_admin_limits") + or (not user.is_superuser and user.role != "Resellers") + or account.role not in ["Resellers", "DomainAdmins"] ) if condition: return {} @@ -150,19 +148,15 @@ def extra_domain_form(sender, user, domain, **kwargs): return [] if not user.has_perm("admin.change_domain"): return [] - return [{ - "id": "resources", "title": _("Resources"), - "cls": forms.DomainLimitsForm - }] + return [{"id": "resources", "title": _("Resources"), "cls": forms.DomainLimitsForm}] @receiver(admin_signals.get_domain_form_instances) def fill_domain_instances(sender, user, domain, **kwargs): """Set domain instance for resources form.""" - condition = ( - not param_tools.get_global_parameter("enable_domain_limits") or - not user.has_perm("admin.change_domain") - ) + condition = not param_tools.get_global_parameter( + "enable_domain_limits" + ) or not user.has_perm("admin.change_domain") if condition: return {} return {"resources": domain} @@ -190,14 +184,14 @@ def user_can_set_role(sender, user, role, account=None, **kwargs): :param ``User`` account: account modified (None on creation) """ condition = ( - not param_tools.get_global_parameter("enable_admin_limits") or - role != "DomainAdmins") + not param_tools.get_global_parameter("enable_admin_limits") + or role != "DomainAdmins" + ) if condition: return True lname = "domain_admins" condition = ( - user.is_superuser or - not user.userobjectlimit_set.get(name=lname).is_exceeded() + user.is_superuser or not user.userobjectlimit_set.get(name=lname).is_exceeded() ) if condition: return True @@ -210,9 +204,9 @@ def user_can_set_role(sender, user, role, account=None, **kwargs): def get_static_content(sender, caller, st_type, user, **kwargs): """Add extra static content.""" condition = ( - not param_tools.get_global_parameter("enable_admin_limits") or - caller not in ["domains", "identities"] or - user.role in ["SuperAdmins", "SimpleUsers"] + not param_tools.get_global_parameter("enable_admin_limits") + or caller not in ["domains", "identities"] + or user.role in ["SuperAdmins", "SimpleUsers"] ) if condition: return "" @@ -244,8 +238,10 @@ $(document).ready(function() { def display_pool_usage(sender, user, location, currentpage, **kwargs): """Display current usage.""" condition = ( - not param_tools.get_global_parameter("enable_admin_limits") or - location != "leftcol" or user.is_superuser) + not param_tools.get_global_parameter("enable_admin_limits") + or location != "leftcol" + or user.is_superuser + ) if condition: return [] if currentpage == "identities": @@ -255,19 +251,16 @@ def display_pool_usage(sender, user, location, currentpage, **kwargs): else: exceptions = ["domain_admins", "mailboxes", "mailbox_aliases"] names = [ - name for name, tpl in utils.get_user_limit_templates() - if name not in exceptions and - ("required_role" not in tpl or - tpl["required_role"] == user.role) + name + for name, tpl in utils.get_user_limit_templates() + if name not in exceptions + and ("required_role" not in tpl or tpl["required_role"] == user.role) ] limits = user.userobjectlimit_set.filter(name__in=names, max_value__gt=0) if len(limits) == 0: return [] - return [ - render_to_string("limits/poolusage.html", - {"limits": limits}) - ] + return [render_to_string("limits/poolusage.html", {"limits": limits})] @receiver(core_signals.account_role_changed) diff --git a/modoboa/limits/lib.py b/modoboa/limits/lib.py index f186bc07f..22663c1ea 100644 --- a/modoboa/limits/lib.py +++ b/modoboa/limits/lib.py @@ -43,9 +43,7 @@ def allocate_resources_from_user(limit, user, value): """ ol = user.userobjectlimit_set.get(name=limit.name) if value == -1 and ol.max_value != -1: - raise BadLimitValue( - _("You're not allowed to define unlimited values") - ) + raise BadLimitValue(_("You're not allowed to define unlimited values")) if limit.max_value > -1: value -= limit.max_value diff --git a/modoboa/limits/migrations/0001_initial.py b/modoboa/limits/migrations/0001_initial.py index c40f69b92..986bbdea6 100644 --- a/modoboa/limits/migrations/0001_initial.py +++ b/modoboa/limits/migrations/0001_initial.py @@ -10,37 +10,58 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name='Limit', + name="Limit", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=255)), - ('curvalue', models.IntegerField(default=0)), - ('maxvalue', models.IntegerField(default=-2)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("name", models.CharField(max_length=255)), + ("curvalue", models.IntegerField(default=0)), + ("maxvalue", models.IntegerField(default=-2)), ], options={ - 'db_table': 'limits_limit', + "db_table": "limits_limit", }, bases=(models.Model,), ), migrations.CreateModel( - name='LimitsPool', + name="LimitsPool", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ( + "user", + models.OneToOneField( + to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE + ), + ), ], options={ - 'db_table': 'limits_limitspool', + "db_table": "limits_limitspool", }, bases=(models.Model,), ), migrations.AddField( - model_name='limit', - name='pool', - field=models.ForeignKey(to='limits.LimitsPool', on_delete=models.CASCADE), + model_name="limit", + name="pool", + field=models.ForeignKey(to="limits.LimitsPool", on_delete=models.CASCADE), preserve_default=True, ), migrations.AlterUniqueTogether( - name='limit', - unique_together=set([('name', 'pool')]), + name="limit", + unique_together=set([("name", "pool")]), ), ] diff --git a/modoboa/limits/migrations/0001_squashed_0004_auto_20160413_1312.py b/modoboa/limits/migrations/0001_squashed_0004_auto_20160413_1312.py index 0e7692443..78a2f789d 100644 --- a/modoboa/limits/migrations/0001_squashed_0004_auto_20160413_1312.py +++ b/modoboa/limits/migrations/0001_squashed_0004_auto_20160413_1312.py @@ -10,47 +10,78 @@ import modoboa.limits.models class Migration(migrations.Migration): replaces = [ - ('limits', '0001_initial'), - ('limits', '0002_auto_20151114_1518'), - ('limits', '0003_auto_20160413_1046'), - ('limits', '0004_auto_20160413_1312'), + ("limits", "0001_initial"), + ("limits", "0002_auto_20151114_1518"), + ("limits", "0003_auto_20160413_1046"), + ("limits", "0004_auto_20160413_1312"), ] initial = True dependencies = [ - ('admin', '0001_initial'), - ('contenttypes', '0002_remove_content_type_name'), + ("admin", "0001_initial"), + ("contenttypes", "0002_remove_content_type_name"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( - name='UserObjectLimit', + name="UserObjectLimit", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=254)), - ('max_value', models.IntegerField(default=0)), - ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=254)), + ("max_value", models.IntegerField(default=0)), + ( + "content_type", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="contenttypes.ContentType", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), ], ), migrations.AlterUniqueTogether( - name='userobjectlimit', - unique_together=set([('user', 'name')]), + name="userobjectlimit", + unique_together=set([("user", "name")]), ), migrations.CreateModel( - name='DomainObjectLimit', + name="DomainObjectLimit", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=254)), - ('max_value', models.IntegerField(default=0)), - ('domain', models.ForeignKey(to='admin.Domain', on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("name", models.CharField(max_length=254)), + ("max_value", models.IntegerField(default=0)), + ( + "domain", + models.ForeignKey(to="admin.Domain", on_delete=models.CASCADE), + ), ], bases=(modoboa.limits.models.ObjectLimitMixin, models.Model), ), migrations.AlterUniqueTogether( - name='domainobjectlimit', - unique_together=set([('domain', 'name')]), + name="domainobjectlimit", + unique_together=set([("domain", "name")]), ), ] diff --git a/modoboa/limits/migrations/0002_auto_20151114_1518.py b/modoboa/limits/migrations/0002_auto_20151114_1518.py index 7982519e0..f54808265 100644 --- a/modoboa/limits/migrations/0002_auto_20151114_1518.py +++ b/modoboa/limits/migrations/0002_auto_20151114_1518.py @@ -4,16 +4,16 @@ from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ - ('limits', '0001_initial'), + ("limits", "0001_initial"), ] operations = [ migrations.AlterModelTable( - name='limit', + name="limit", table=None, ), migrations.AlterModelTable( - name='limitspool', + name="limitspool", table=None, ), ] diff --git a/modoboa/limits/migrations/0003_auto_20160413_1046.py b/modoboa/limits/migrations/0003_auto_20160413_1046.py index 941802bb6..f33519bfc 100644 --- a/modoboa/limits/migrations/0003_auto_20160413_1046.py +++ b/modoboa/limits/migrations/0003_auto_20160413_1046.py @@ -13,28 +13,31 @@ def move_limits_to_user(apps, schema_editor): return name_to_content_type = { - "domains_limit": ( - ContentType.objects.get(app_label="admin", model="domain")), + "domains_limit": (ContentType.objects.get(app_label="admin", model="domain")), "domain_aliases_limit": ( - ContentType.objects.get(app_label="admin", model="domainalias")), + ContentType.objects.get(app_label="admin", model="domainalias") + ), "mailboxes_limit": ( - ContentType.objects.get(app_label="admin", model="mailbox")), + ContentType.objects.get(app_label="admin", model="mailbox") + ), "mailbox_aliases_limit": ( - ContentType.objects.get(app_label="admin", model="alias")), + ContentType.objects.get(app_label="admin", model="alias") + ), "domain_admins_limit": ( - ContentType.objects.get(app_label="core", model="user")), + ContentType.objects.get(app_label="core", model="user") + ), } to_create = [] - qset = ( - LimitsPool.objects.select_related("user") - .prefetch_related("limit_set")) + qset = LimitsPool.objects.select_related("user").prefetch_related("limit_set") for pool in qset: for limit in pool.limit_set.all(): objlimit = UserObjectLimit( - user=pool.user, max_value=limit.maxvalue, + user=pool.user, + max_value=limit.maxvalue, name=limit.name.replace("_limit", ""), - content_type=name_to_content_type[limit.name]) + content_type=name_to_content_type[limit.name], + ) to_create.append(objlimit) UserObjectLimit.objects.bulk_create(to_create) @@ -42,26 +45,44 @@ def move_limits_to_user(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('contenttypes', '0002_remove_content_type_name'), + ("contenttypes", "0002_remove_content_type_name"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('limits', '0002_auto_20151114_1518'), - ('admin', '0001_initial'), + ("limits", "0002_auto_20151114_1518"), + ("admin", "0001_initial"), ] operations = [ migrations.CreateModel( - name='UserObjectLimit', + name="UserObjectLimit", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=254)), - ('max_value', models.IntegerField(default=-2)), - ('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("name", models.CharField(max_length=254)), + ("max_value", models.IntegerField(default=-2)), + ( + "content_type", + models.ForeignKey( + to="contenttypes.ContentType", on_delete=models.CASCADE + ), + ), + ( + "user", + models.ForeignKey( + to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE + ), + ), ], ), migrations.AlterUniqueTogether( - name='userobjectlimit', - unique_together=set([('user', 'name')]), + name="userobjectlimit", + unique_together=set([("user", "name")]), ), - migrations.RunPython(move_limits_to_user) + migrations.RunPython(move_limits_to_user), ] diff --git a/modoboa/limits/migrations/0004_auto_20160413_1312.py b/modoboa/limits/migrations/0004_auto_20160413_1312.py index 1ec5502f7..cc5468074 100644 --- a/modoboa/limits/migrations/0004_auto_20160413_1312.py +++ b/modoboa/limits/migrations/0004_auto_20160413_1312.py @@ -4,26 +4,26 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('limits', '0003_auto_20160413_1046'), + ("limits", "0003_auto_20160413_1046"), ] operations = [ migrations.AlterUniqueTogether( - name='limit', + name="limit", unique_together=set([]), ), migrations.RemoveField( - model_name='limit', - name='pool', + model_name="limit", + name="pool", ), migrations.RemoveField( - model_name='limitspool', - name='user', + model_name="limitspool", + name="user", ), migrations.DeleteModel( - name='Limit', + name="Limit", ), migrations.DeleteModel( - name='LimitsPool', + name="LimitsPool", ), ] diff --git a/modoboa/limits/migrations/0005_auto_20160415_1654.py b/modoboa/limits/migrations/0005_auto_20160415_1654.py index 563b84e4f..b16f91d1d 100644 --- a/modoboa/limits/migrations/0005_auto_20160415_1654.py +++ b/modoboa/limits/migrations/0005_auto_20160415_1654.py @@ -10,18 +10,15 @@ def create_limits(apps, schema_editor): to_create = [] for domain in Domain.objects.all(): for name, tpl in utils.get_domain_limit_templates(): - to_create.append( - DomainObjectLimit(domain=domain, name=name, max_value=-1)) + to_create.append(DomainObjectLimit(domain=domain, name=name, max_value=-1)) DomainObjectLimit.objects.bulk_create(to_create) class Migration(migrations.Migration): dependencies = [ - ('admin', '0003_auto_20151118_1215'), - ('limits', '0004_auto_20160413_1312'), + ("admin", "0003_auto_20151118_1215"), + ("limits", "0004_auto_20160413_1312"), ] - operations = [ - migrations.RunPython(create_limits) - ] + operations = [migrations.RunPython(create_limits)] diff --git a/modoboa/limits/migrations/0006_auto_20170216_1112.py b/modoboa/limits/migrations/0006_auto_20170216_1112.py index a2ac72b32..d6314a98a 100644 --- a/modoboa/limits/migrations/0006_auto_20170216_1112.py +++ b/modoboa/limits/migrations/0006_auto_20170216_1112.py @@ -21,9 +21,7 @@ def create_quota_limits(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('limits', '0005_auto_20160415_1654'), + ("limits", "0005_auto_20160415_1654"), ] - operations = [ - migrations.RunPython(create_quota_limits) - ] + operations = [migrations.RunPython(create_quota_limits)] diff --git a/modoboa/limits/models.py b/modoboa/limits/models.py index 2f12d8285..e0f59b227 100644 --- a/modoboa/limits/models.py +++ b/modoboa/limits/models.py @@ -43,8 +43,7 @@ class ObjectLimitMixin(object): value = getattr(instance, field) if value == 0: # Do not allow unlimited value - raise lib.BadLimitValue( - _("You're not allowed to define unlimited values")) + raise lib.BadLimitValue(_("You're not allowed to define unlimited values")) try: old_value = instance._loaded_values[field] except (AttributeError, KeyError): @@ -63,12 +62,13 @@ class UserObjectLimit(ObjectLimitMixin, models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) name = models.CharField(max_length=254) - content_type = models.ForeignKey("contenttypes.ContentType", - on_delete=models.CASCADE) + content_type = models.ForeignKey( + "contenttypes.ContentType", on_delete=models.CASCADE + ) max_value = models.IntegerField(default=0) class Meta(object): - unique_together = (("user", "name"), ) + unique_together = (("user", "name"),) @property def definition(self): @@ -81,25 +81,23 @@ class UserObjectLimit(ObjectLimitMixin, models.Model): @property def current_value(self) -> int: """Return the current number of objects.""" - condition = ( - self.type == "count" and - "extra_filters" not in self.definition) + condition = self.type == "count" and "extra_filters" not in self.definition if condition: return core_models.ObjectAccess.objects.filter( - user=self.user, is_owner=True, - content_type=self.content_type).count() + user=self.user, is_owner=True, content_type=self.content_type + ).count() id_list = core_models.ObjectAccess.objects.filter( - user=self.user, is_owner=True, - content_type=self.content_type).values_list("object_id", flat=True) + user=self.user, is_owner=True, content_type=self.content_type + ).values_list("object_id", flat=True) model_class = self.content_type.model_class() if self.type == "count": return model_class.objects.filter( - pk__in=id_list, **self.definition["extra_filters"]).count() + pk__in=id_list, **self.definition["extra_filters"] + ).count() qset = model_class.objects.filter(pk__in=id_list) if not qset.exists(): return 0 - return qset.aggregate( - total=models.Sum(self.definition["field"]))["total"] + return qset.aggregate(total=models.Sum(self.definition["field"]))["total"] @property def label(self): @@ -130,7 +128,7 @@ class DomainObjectLimit(ObjectLimitMixin, models.Model): max_value = models.IntegerField(default=0) class Meta(object): - unique_together = (("domain", "name"), ) + unique_together = (("domain", "name"),) @property def definition(self): diff --git a/modoboa/limits/tests/test_domain_limits.py b/modoboa/limits/tests/test_domain_limits.py index 545105f0b..b34a4a072 100644 --- a/modoboa/limits/tests/test_domain_limits.py +++ b/modoboa/limits/tests/test_domain_limits.py @@ -17,13 +17,13 @@ class DomainLimitsTestCase(lib_tests.ModoTestCase): def setUpTestData(cls): # NOQA:N802 """Create test data.""" super(DomainLimitsTestCase, cls).setUpTestData() - cls.localconfig.parameters.set_values({ - "enable_admin_limits": False, - "enable_domain_limits": True - }) + cls.localconfig.parameters.set_values( + {"enable_admin_limits": False, "enable_domain_limits": True} + ) for name, _definition in utils.get_domain_limit_templates(): cls.localconfig.parameters.set_value( - "deflt_domain_{0}_limit".format(name), 2) + "deflt_domain_{0}_limit".format(name), 2 + ) cls.localconfig.save() admin_factories.populate_database() @@ -31,28 +31,30 @@ class DomainLimitsTestCase(lib_tests.ModoTestCase): """Try to set limits for a given domain.""" domain = Domain.objects.get(name="test.com") values = { - "name": domain.name, "quota": domain.quota, + "name": domain.name, + "quota": domain.quota, "default_mailbox_quota": domain.default_mailbox_quota, - "enabled": domain.enabled, "type": "domain", - "mailboxes_limit": 3, "mailbox_aliases_limit": 3, - "domain_aliases_limit": 3, "domain_admins_limit": 3 + "enabled": domain.enabled, + "type": "domain", + "mailboxes_limit": 3, + "mailbox_aliases_limit": 3, + "domain_aliases_limit": 3, + "domain_admins_limit": 3, } - self.ajax_post( - reverse("admin:domain_change", args=[domain.id]), - values - ) + self.ajax_post(reverse("admin:domain_change", args=[domain.id]), values) domain.refresh_from_db() self.assertEqual( - domain.domainobjectlimit_set.get(name="mailboxes").max_value, 3) + domain.domainobjectlimit_set.get(name="mailboxes").max_value, 3 + ) self.assertEqual( - domain.domainobjectlimit_set.get( - name="mailbox_aliases").max_value, 3) + domain.domainobjectlimit_set.get(name="mailbox_aliases").max_value, 3 + ) self.assertEqual( - domain.domainobjectlimit_set.get( - name="domain_aliases").max_value, 3) + domain.domainobjectlimit_set.get(name="domain_aliases").max_value, 3 + ) self.assertEqual( - domain.domainobjectlimit_set.get( - name="domain_admins").max_value, 3) + domain.domainobjectlimit_set.get(name="domain_admins").max_value, 3 + ) def test_domain_aliases_limit(self): """Try to exceed defined limit.""" @@ -60,23 +62,22 @@ class DomainLimitsTestCase(lib_tests.ModoTestCase): limit = domain.domainobjectlimit_set.get(name="domain_aliases") self.assertFalse(limit.is_exceeded()) values = { - "name": domain.name, "quota": domain.quota, + "name": domain.name, + "quota": domain.quota, "default_mailbox_quota": domain.default_mailbox_quota, - "enabled": domain.enabled, "type": "domain", - "mailboxes_limit": 2, "mailbox_aliases_limit": 2, - "domain_aliases_limit": 2, "domain_admins_limit": 2, - "aliases": "alias1.com", "aliases_1": "alias2.com" + "enabled": domain.enabled, + "type": "domain", + "mailboxes_limit": 2, + "mailbox_aliases_limit": 2, + "domain_aliases_limit": 2, + "domain_admins_limit": 2, + "aliases": "alias1.com", + "aliases_1": "alias2.com", } - self.ajax_post( - reverse("admin:domain_change", args=[domain.id]), - values - ) + self.ajax_post(reverse("admin:domain_change", args=[domain.id]), values) self.assertTrue(limit.is_exceeded()) values["aliases_2"] = "alias3.com" - self.ajax_post( - reverse("admin:domain_change", args=[domain.id]), - values, 403 - ) + self.ajax_post(reverse("admin:domain_change", args=[domain.id]), values, 403) def test_domain_admins_limit(self): """Try to exceed defined limit.""" @@ -85,37 +86,40 @@ class DomainLimitsTestCase(lib_tests.ModoTestCase): self.assertFalse(limit.is_exceeded()) user = User.objects.get(username="admin@test2.com") values = { - "username": user.username, "role": user.role, - "is_active": user.is_active, "email": user.email, - "quota_act": True, "domains": "test2.com", - "domains_1": "test.com", "language": "en" + "username": user.username, + "role": user.role, + "is_active": user.is_active, + "email": user.email, + "quota_act": True, + "domains": "test2.com", + "domains_1": "test.com", + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values) self.assertTrue(limit.is_exceeded()) user = core_factories.UserFactory( - username="admin1000@test.com", groups=("DomainAdmins", )) - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values, 400 + username="admin1000@test.com", groups=("DomainAdmins",) ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values, 400) def test_mailboxes_limit(self): """Try to exceed defined limits.""" domain = Domain.objects.get(name="test.com") - domain.domainobjectlimit_set.filter(name="mailboxes").update( - max_value=3) + domain.domainobjectlimit_set.filter(name="mailboxes").update(max_value=3) limit = domain.domainobjectlimit_set.get(name="mailboxes") self.assertFalse(limit.is_exceeded()) username = "toto@test.com" values = { "username": "toto@test.com", - "first_name": "Tester", "last_name": "Toto", - "password1": "Toto1234", "password2": "Toto1234", - "role": "SimpleUsers", "quota_act": True, - "is_active": True, "email": username, "stepid": "step2", + "first_name": "Tester", + "last_name": "Toto", + "password1": "Toto1234", + "password2": "Toto1234", + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": username, + "stepid": "step2", } self.ajax_post(reverse("admin:account_add"), values, 200) self.assertTrue(limit.is_exceeded()) @@ -139,29 +143,27 @@ class DomainLimitsTestCase(lib_tests.ModoTestCase): limit.save() self.assertFalse(limit.is_exceeded()) values = { - "username": user.username, "role": user.role, - "is_active": user.is_active, "email": user.email, + "username": user.username, + "role": user.role, + "is_active": user.is_active, + "email": user.email, "quota_act": True, - "aliases": "alias@test.com", "aliases_1": "alias1@test.com", - "language": "en" + "aliases": "alias@test.com", + "aliases_1": "alias1@test.com", + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values) self.assertTrue(limit.is_exceeded()) values["aliases_2"] = "alias2@test.com" - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values, 403 - ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values, 403) limit.max_value = 5 limit.save() values = { - "address": "forward2@test.com", "recipients": "user@test.com", - "enabled": True + "address": "forward2@test.com", + "recipients": "user@test.com", + "enabled": True, } self.ajax_post(reverse("admin:alias_add"), values) self.assertTrue(limit.is_exceeded()) diff --git a/modoboa/limits/tests/test_import.py b/modoboa/limits/tests/test_import.py index a1d868026..08b4a4edd 100644 --- a/modoboa/limits/tests/test_import.py +++ b/modoboa/limits/tests/test_import.py @@ -17,7 +17,8 @@ class LimitImportTestCase(ModoTestCase): super(LimitImportTestCase, cls).setUpTestData() admin_factories.populate_database() cls.reseller = core_factories.UserFactory( - username="reseller", groups=("Resellers", )) + username="reseller", groups=("Resellers",) + ) cls.dadmin = core_models.User.objects.get(username="admin@test.com") cls.domain = admin_models.Domain.objects.get(name="test.com") @@ -25,24 +26,22 @@ class LimitImportTestCase(ModoTestCase): """Check domain aliases limit.""" self.client.force_login(self.reseller) self.assertFalse(limit.is_exceeded()) - f = ContentFile("""domainalias; domalias1.com; {domain}; True + f = ContentFile( + """domainalias; domalias1.com; {domain}; True domainalias; domalias2.com; {domain}; True -""".format(domain=self.domain), name="domains.csv") - self.client.post( - reverse("admin:domain_import"), { - "sourcefile": f - } +""".format( + domain=self.domain + ), + name="domains.csv", ) + self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) self.assertTrue(limit.is_exceeded()) f = ContentFile( "domainalias; domalias3.com; {}; True".format(self.domain), - name="domains.csv") - response = self.client.post( - reverse("admin:domain_import"), { - "sourcefile": f - } + name="domains.csv", ) + response = self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) self.assertContains(response, "Domain aliases: limit reached") def _test_domain_admins_import(self, limit, initial_count=0): @@ -53,24 +52,22 @@ domainalias; domalias2.com; {domain}; True for cpt in range(initial_count, 2): content += ( "account; admin{cpt}@{domain}; toto; User; One; True; " - "DomainAdmins; user{cpt}@{domain}; 5; {domain}\n" - .format(domain=self.domain, cpt=cpt) + "DomainAdmins; user{cpt}@{domain}; 5; {domain}\n".format( + domain=self.domain, cpt=cpt + ) ) f = ContentFile(content, name="domain_admins.csv") - response = self.client.post( - reverse("admin:identity_import"), { - "sourcefile": f - } - ) + response = self.client.post(reverse("admin:identity_import"), {"sourcefile": f}) self.assertTrue(limit.is_exceeded()) - f = ContentFile("""account; admin3@{domain}; toto; User; One; True; DomainAdmins; admin3@{domain}; 5; {domain} -""".format(domain=self.domain), name="domain_admins.csv") # NOQA:E501 - response = self.client.post( - reverse("admin:identity_import"), { - "sourcefile": f - } - ) + f = ContentFile( + """account; admin3@{domain}; toto; User; One; True; DomainAdmins; admin3@{domain}; 5; {domain} +""".format( + domain=self.domain + ), + name="domain_admins.csv", + ) # NOQA:E501 + response = self.client.post(reverse("admin:identity_import"), {"sourcefile": f}) self.assertContains(response, "Permission denied") def _test_mailboxes_import(self, limit): @@ -82,48 +79,47 @@ domainalias; domalias2.com; {domain}; True "user1@{domain}; 5\r\n" "account; truc@{domain}; toto; René; Truc; True; SimpleUsers; " "truc@{domain}; 5\r\n".format(domain=self.domain), - name="domains.csv" - ) - response = self.client.post( - reverse("admin:identity_import"), { - "sourcefile": f - } + name="domains.csv", ) + response = self.client.post(reverse("admin:identity_import"), {"sourcefile": f}) self.assertTrue(limit.is_exceeded()) - f = ContentFile(""" + f = ContentFile( + """ account; user3@{domain}; toto; User; One; True; SimpleUsers; user3@{domain}; 5 -""".format(domain=self.domain), name="domains.csv") - response = self.client.post( - reverse("admin:identity_import"), { - "sourcefile": f - } +""".format( + domain=self.domain + ), + name="domains.csv", ) + response = self.client.post(reverse("admin:identity_import"), {"sourcefile": f}) self.assertContains(response, "Mailboxes: limit reached") def _test_mailbox_aliases_import(self, limit): """Check mailbox aliases limit.""" self.client.force_login(self.dadmin) self.assertFalse(limit.is_exceeded()) - f = ContentFile("""alias; alias1@{domain}; True; user@{domain} + f = ContentFile( + """alias; alias1@{domain}; True; user@{domain} alias; alias2@{domain}; True; user@{domain} -""".format(domain=self.domain), name="aliases.csv") - self.client.post( - reverse("admin:identity_import"), { - "sourcefile": f - } +""".format( + domain=self.domain + ), + name="aliases.csv", ) + self.client.post(reverse("admin:identity_import"), {"sourcefile": f}) self.assertTrue(limit.is_exceeded()) - f = ContentFile(""" + f = ContentFile( + """ alias; alias3@{domain}; True; user@{domain} -""".format(domain=self.domain), name="aliases.csv") +""".format( + domain=self.domain + ), + name="aliases.csv", + ) with self.assertRaises(exceptions.ValidationError): - self.client.post( - reverse("admin:identity_import"), { - "sourcefile": f - } - ) + self.client.post(reverse("admin:identity_import"), {"sourcefile": f}) class UserLimitImportTestCase(LimitImportTestCase): @@ -133,8 +129,7 @@ class UserLimitImportTestCase(LimitImportTestCase): """Create test data.""" localconfig = core_models.LocalConfig.objects.first() for name, _definition in utils.get_user_limit_templates(): - localconfig.parameters.set_value( - "deflt_user_{0}_limit".format(name), 2) + localconfig.parameters.set_value("deflt_user_{0}_limit".format(name), 2) localconfig.save() super(UserLimitImportTestCase, cls).setUpTestData() @@ -144,30 +139,24 @@ class UserLimitImportTestCase(LimitImportTestCase): limit = self.reseller.userobjectlimit_set.get(name="domains") self.assertFalse(limit.is_exceeded()) f = ContentFile("domain; domain1.com; 1; 1; True", name="domains.csv") - self.client.post( - reverse("admin:domain_import"), {"sourcefile": f} - ) + self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) self.assertFalse(limit.is_exceeded()) f = ContentFile("domain; domain2.com; 0; 1; True", name="domains.csv") - response = self.client.post( - reverse("admin:domain_import"), {"sourcefile": f} - ) - self.assertContains( - response, "not allowed to define unlimited values") + response = self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) + self.assertContains(response, "not allowed to define unlimited values") f = ContentFile("domain; domain2.com; 2; 1; True", name="domains.csv") - response = self.client.post( - reverse("admin:domain_import"), {"sourcefile": f} - ) + response = self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) self.assertContains(response, "Quota: limit reached") - f = ContentFile(b"""domain; domain2.com; 1; 1; True + f = ContentFile( + b"""domain; domain2.com; 1; 1; True domain; domain3.com; 1000; 100; True -""", name="domains.csv") - response = self.client.post( - reverse("admin:domain_import"), {"sourcefile": f} +""", + name="domains.csv", ) + response = self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) self.assertContains(response, "Domains: limit reached") def test_domain_alias_import(self): @@ -198,18 +187,16 @@ class DomainLimitImportTestCase(LimitImportTestCase): def setUpTestData(cls): # NOQA:N802 """Create test data.""" localconfig = core_models.LocalConfig.objects.first() - localconfig.parameters.set_values({ - "enable_domain_limits": True, - "enable_admin_limits": False - }) + localconfig.parameters.set_values( + {"enable_domain_limits": True, "enable_admin_limits": False} + ) for name, _definition in utils.get_domain_limit_templates(): - localconfig.parameters.set_value( - "deflt_domain_{0}_limit".format(name), 2) + localconfig.parameters.set_value("deflt_domain_{0}_limit".format(name), 2) localconfig.save() super(DomainLimitImportTestCase, cls).setUpTestData() mb = admin_factories.MailboxFactory( - user__username="user@test4.com", - domain__name="test4.com", address="user") + user__username="user@test4.com", domain__name="test4.com", address="user" + ) cls.domain = mb.domain def test_domain_alias_import(self): diff --git a/modoboa/limits/tests/test_user_limits.py b/modoboa/limits/tests/test_user_limits.py index 79f72a719..7349c6429 100644 --- a/modoboa/limits/tests/test_user_limits.py +++ b/modoboa/limits/tests/test_user_limits.py @@ -24,18 +24,22 @@ class PermissionsTestCase(lib_tests.ModoTestCase): Expected result: no. """ values = { - "username": "reseller@test.com", "first_name": "Reseller", - "last_name": "", "password1": "Toto1234", "password2": "Toto1234", - "role": "Resellers", "is_active": True, - "email": "reseller@test.com", "stepid": "step2" + "username": "reseller@test.com", + "first_name": "Reseller", + "last_name": "", + "password1": "Toto1234", + "password2": "Toto1234", + "role": "Resellers", + "is_active": True, + "email": "reseller@test.com", + "stepid": "step2", } self.ajax_post(reverse("admin:account_add"), values) account = User.objects.get(username="reseller@test.com") admin = User.objects.get(username="admin@test.com") self.client.force_login(admin) resp = self.ajax_post( - reverse("admin:account_delete", args=[account.id]), - {}, status=403 + reverse("admin:account_delete", args=[account.id]), {}, status=403 ) self.assertEqual(resp, "Permission denied") @@ -46,59 +50,63 @@ class ResourceTestCase(lib_tests.ModoTestCase): def setUpTestData(cls): # NOQA:N802 """Custom setUpTestData method.""" super(ResourceTestCase, cls).setUpTestData() - cls.localconfig.parameters.set_values({ - "enable_admin_limits": True, - "enable_domain_limits": False - }) + cls.localconfig.parameters.set_values( + {"enable_admin_limits": True, "enable_domain_limits": False} + ) for name, _definition in utils.get_user_limit_templates(): - cls.localconfig.parameters.set_value( - "deflt_user_{0}_limit".format(name), 2) + cls.localconfig.parameters.set_value("deflt_user_{0}_limit".format(name), 2) cls.localconfig.save() populate_database() - def _create_account( - self, username, role="SimpleUsers", status=200, **kwargs): + def _create_account(self, username, role="SimpleUsers", status=200, **kwargs): values = { - "username": username, "first_name": "Tester", "last_name": "Toto", - "password1": "Toto1234", "password2": "Toto1234", "role": role, - "quota_act": True, "is_active": True, "email": username, - "stepid": "step2" + "username": username, + "first_name": "Tester", + "last_name": "Toto", + "password1": "Toto1234", + "password2": "Toto1234", + "role": role, + "quota_act": True, + "is_active": True, + "email": username, + "stepid": "step2", } values.update(kwargs) - return self.ajax_post( - reverse("admin:account_add"), values, status - ) + return self.ajax_post(reverse("admin:account_add"), values, status) def _create_alias(self, email, rcpt="user@test.com", status=200): - values = { - "address": email, "recipients": rcpt, "enabled": True - } - return self.ajax_post( - reverse("admin:alias_add"), values, status - ) + values = {"address": email, "recipients": rcpt, "enabled": True} + return self.ajax_post(reverse("admin:alias_add"), values, status) def _create_domain(self, name, status=200, withtpl=False, **kwargs): values = { - "name": name, "quota": 100, "default_mailbox_quota": 10, - "create_dom_admin": False, "with_mailbox": True, - "create_aliases": False, "stepid": "step3", "type": "domain" + "name": name, + "quota": 100, + "default_mailbox_quota": 10, + "create_dom_admin": False, + "with_mailbox": True, + "create_aliases": False, + "stepid": "step3", + "type": "domain", } if withtpl: - values.update({ - "create_dom_admin": True, - "dom_admin_username": "admin", - "create_aliases": True - }) + values.update( + { + "create_dom_admin": True, + "dom_admin_username": "admin", + "create_aliases": True, + } + ) values.update(kwargs) - response = self.ajax_post( - reverse("admin:domain_add"), values, status - ) + response = self.ajax_post(reverse("admin:domain_add"), values, status) return response def _domain_alias_operation(self, optype, domain, name, status=200): dom = Domain.objects.get(name=domain) values = { - "name": dom.name, "quota": dom.quota, "enabled": dom.enabled, + "name": dom.name, + "quota": dom.quota, + "enabled": dom.enabled, "type": "domain", "default_mailbox_quota": dom.default_mailbox_quota, } @@ -110,10 +118,7 @@ class ResourceTestCase(lib_tests.ModoTestCase): for cpt, alias in enumerate(aliases): fname = "aliases" if not cpt else "aliases_%d" % cpt values[fname] = alias - self.ajax_post( - reverse("admin:domain_change", args=[dom.id]), - values, status - ) + self.ajax_post(reverse("admin:domain_change", args=[dom.id]), values, status) def _check_limit(self, name, curvalue, maxvalue): limit = self.user.userobjectlimit_set.get(name=name) @@ -129,7 +134,8 @@ class DomainAdminTestCase(ResourceTestCase): super(DomainAdminTestCase, cls).setUpTestData() cls.user = User.objects.get(username="admin@test.com") cls.user.userobjectlimit_set.filter( - name__in=["mailboxes", "mailbox_aliases"]).update(max_value=2) + name__in=["mailboxes", "mailbox_aliases"] + ).update(max_value=2) def setUp(self): """Test initialization.""" @@ -144,9 +150,11 @@ class DomainAdminTestCase(ResourceTestCase): self._create_account("tester3@test.com", status=403) self._check_limit("mailboxes", 2, 2) self.ajax_post( - reverse("admin:account_delete", - args=[User.objects.get(username="tester2@test.com").id]), - {} + reverse( + "admin:account_delete", + args=[User.objects.get(username="tester2@test.com").id], + ), + {}, ) self._check_limit("mailboxes", 1, 2) @@ -159,27 +167,29 @@ class DomainAdminTestCase(ResourceTestCase): self._check_limit("mailbox_aliases", 2, 2) # Set unlimited value self.user.userobjectlimit_set.filter(name="mailbox_aliases").update( - max_value=-1) + max_value=-1 + ) self._create_alias("alias3@test.com") self._check_limit("mailbox_aliases", 3, -1) self.ajax_delete( - reverse("admin:alias_delete") + "?selection=%d" - % Alias.objects.get(address="alias2@test.com").id + reverse("admin:alias_delete") + + "?selection=%d" % Alias.objects.get(address="alias2@test.com").id ) self._check_limit("mailbox_aliases", 2, -1) def test_aliases_limit_through_account_form(self): user = User.objects.get(username="user@test.com") values = { - "username": user.username, "role": user.role, - "is_active": user.is_active, "email": user.email, "quota_act": True, - "aliases": "alias1@test.com", "aliases_1": "alias2@test.com", - "language": "en" + "username": user.username, + "role": user.role, + "is_active": user.is_active, + "email": user.email, + "quota_act": True, + "aliases": "alias1@test.com", + "aliases_1": "alias2@test.com", + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values) Alias.objects.get(address="alias1@test.com") self._check_limit("mailbox_aliases", 2, 2) @@ -192,9 +202,7 @@ class ResellerTestCase(ResourceTestCase): super(ResellerTestCase, cls).setUpTestData() cls.localconfig.parameters.set_value("deflt_user_quota_limit", 1000) cls.localconfig.save() - cls.user = UserFactory( - username="reseller", groups=("Resellers",) - ) + cls.user = UserFactory(username="reseller", groups=("Resellers",)) def setUp(self): """Test initialization.""" @@ -212,9 +220,10 @@ class ResellerTestCase(ResourceTestCase): self._create_domain("domain3.tld", 403) self._check_limit("domains", 2, 2) self.ajax_post( - reverse("admin:domain_delete", - args=[Domain.objects.get(name="domain2.tld").id]), - {} + reverse( + "admin:domain_delete", args=[Domain.objects.get(name="domain2.tld").id] + ), + {}, ) self._check_limit("domains", 1, 2) @@ -224,12 +233,9 @@ class ResellerTestCase(ResourceTestCase): self._check_limit("domain_aliases", 1, 2) self._domain_alias_operation("add", "pouet.com", "domain-alias2.tld") self._check_limit("domain_aliases", 2, 2) - self._domain_alias_operation( - "add", "pouet.com", "domain-alias3.tld", 403 - ) + self._domain_alias_operation("add", "pouet.com", "domain-alias3.tld", 403) self._check_limit("domain_aliases", 2, 2) - self._domain_alias_operation( - "delete", "pouet.com", "domain-alias2.tld") + self._domain_alias_operation("delete", "pouet.com", "domain-alias2.tld") self._check_limit("domain_aliases", 1, 2) def test_domain_admins_limit(self): @@ -244,33 +250,33 @@ class ResellerTestCase(ResourceTestCase): self._create_account("admin2@domain.tld", role="DomainAdmins") self._check_limit("domain_admins", 2, 2) resp = self._create_account( - "admin3@domain.tld", - role="DomainAdmins", - status=400) + "admin3@domain.tld", role="DomainAdmins", status=400 + ) self.assertEqual( resp["form_errors"]["role"][0], "Select a valid choice. DomainAdmins is not one of the available " - "choices." + "choices.", ) self._check_limit("domain_admins", 2, 2) - self.user.userobjectlimit_set.filter( - name="mailboxes").update(max_value=3) + self.user.userobjectlimit_set.filter(name="mailboxes").update(max_value=3) self._create_account("user1@domain.tld") user = User.objects.get(username="user1@domain.tld") values = { - "username": user.username, "role": "DomainAdmins", - "quota_act": True, "is_active": user.is_active, - "email": user.email, "language": "en" + "username": user.username, + "role": "DomainAdmins", + "quota_act": True, + "is_active": user.is_active, + "email": user.email, + "language": "en", } resp = self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values, status=400 + reverse("admin:account_change", args=[user.id]), values, status=400 ) self.assertEqual( resp["form_errors"]["role"][0], "Select a valid choice. DomainAdmins is not one of the available " - "choices." + "choices.", ) self._check_limit("domain_admins", 2, 2) @@ -279,13 +285,10 @@ class ResellerTestCase(ResourceTestCase): self._create_account("admin1@domain.tld", role="DomainAdmins") domadmin = User.objects.get(username="admin1@domain.tld") for l in ["mailboxes", "mailbox_aliases"]: - self.assertEqual( - domadmin.userobjectlimit_set.get(name=l).max_value, 0 - ) + self.assertEqual(domadmin.userobjectlimit_set.get(name=l).max_value, 0) def test_domain_admins_limit_from_domain_tpl(self): - self.user.userobjectlimit_set.filter( - name="domains").update(max_value=3) + self.user.userobjectlimit_set.filter(name="domains").update(max_value=3) self._create_domain("domain1.tld", withtpl=True) self._create_domain("domain2.tld", withtpl=True) self._check_limit("domain_admins", 2, 2) @@ -298,14 +301,17 @@ class ResellerTestCase(ResourceTestCase): """Check quota resource.""" self._create_domain("domain1.tld", withtpl=True, quota=1000) response = self._create_domain( - "domain2.tld", status=403, withtpl=True, quota=1000) + "domain2.tld", status=403, withtpl=True, quota=1000 + ) self.assertEqual(response, "Quota: limit reached") dom1 = Domain.objects.get(name="domain1.tld") url = reverse("admin:domain_change", args=[dom1.pk]) values = { - "name": dom1.name, "type": dom1.type, "enabled": dom1.enabled, + "name": dom1.name, + "type": dom1.type, + "enabled": dom1.enabled, "default_mailbox_quota": dom1.default_mailbox_quota, - "quota": 500 + "quota": 500, } self.ajax_post(url, values) @@ -313,13 +319,13 @@ class ResellerTestCase(ResourceTestCase): """Check reseller can't define unlimited quota.""" response = self._create_domain("domain1.tld", 400, quota=0) self.assertEqual( - response["form_errors"]["quota"][0], - "You can't define an unlimited quota.") - response = self._create_domain( - "domain1.tld", 400, default_mailbox_quota=0) + response["form_errors"]["quota"][0], "You can't define an unlimited quota." + ) + response = self._create_domain("domain1.tld", 400, default_mailbox_quota=0) self.assertEqual( response["form_errors"]["default_mailbox_quota"][0], - "You can't define an unlimited quota.") + "You can't define an unlimited quota.", + ) self.user.userobjectlimit_set.filter(name="quota").update(max_value=0) response = self._create_domain("domain2.tld", quota=0) @@ -330,31 +336,33 @@ class ResellerTestCase(ResourceTestCase): # See https://github.com/modoboa/modoboa/issues/1223 self._create_domain("domain1.tld") self._create_account( - "admin@domain1.tld", role="DomainAdmins", - quota_act=False, quota=0, status=400) + "admin@domain1.tld", + role="DomainAdmins", + quota_act=False, + quota=0, + status=400, + ) self._create_domain("domain2.tld", withtpl=True) admin = User.objects.get(username="admin@domain2.tld") values = { - "username": admin.username, "role": admin.role, - "is_active": admin.is_active, "email": admin.email, - "mailboxes_limit": 1, "mailbox_aliases_limit": 2, - "language": "en", "quota_act": False, "quota": 0 + "username": admin.username, + "role": admin.role, + "is_active": admin.is_active, + "email": admin.email, + "mailboxes_limit": 1, + "mailbox_aliases_limit": 2, + "language": "en", + "quota_act": False, + "quota": 0, } - self.ajax_post( - reverse("admin:account_change", args=[admin.pk]), - values, - 400 - ) + self.ajax_post(reverse("admin:account_change", args=[admin.pk]), values, 400) def test_reseller_deletes_domain(self): """Check if all resources are restored after the deletion.""" self._create_domain("domain.tld", withtpl=True) dom = Domain.objects.get(name="domain.tld") - self.ajax_post( - reverse("admin:domain_delete", args=[dom.id]), - {} - ) + self.ajax_post(reverse("admin:domain_delete", args=[dom.id]), {}) self._check_limit("domains", 0, 2) self._check_limit("domain_admins", 1, 2) self._check_limit("mailboxes", 0, 2) @@ -367,9 +375,9 @@ class ResellerTestCase(ResourceTestCase): self.client.login(username="admin", password="password") self.ajax_delete( "{0}?domid={1}&daid={2}".format( - reverse("admin:permission_remove"), - dom.id, self.user.id - ), {} + reverse("admin:permission_remove"), dom.id, self.user.id + ), + {}, ) self._check_limit("domains", 0, 2) self._check_limit("domain_admins", 0, 2) @@ -383,24 +391,22 @@ class ResellerTestCase(ResourceTestCase): # Give 1 mailbox and 2 aliases to the admin -> should work values = { - "username": user.username, "role": user.role, "quota_act": True, - "is_active": user.is_active, "email": user.email, - "mailboxes_limit": 1, "mailbox_aliases_limit": 2, - "language": "en" + "username": user.username, + "role": user.role, + "quota_act": True, + "is_active": user.is_active, + "email": user.email, + "mailboxes_limit": 1, + "mailbox_aliases_limit": 2, + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values) self._check_limit("mailboxes", 1, 1) self._check_limit("mailbox_aliases", 0, 0) # Delete the admin -> resources should go back to the # reseller's pool - self.ajax_post( - reverse("admin:account_delete", args=[user.id]), - {} - ) + self.ajax_post(reverse("admin:account_delete", args=[user.id]), {}) self._check_limit("mailboxes", 0, 2) self._check_limit("mailbox_aliases", 0, 2) @@ -411,15 +417,16 @@ class ResellerTestCase(ResourceTestCase): self._create_account("admin1@domain.tld", role="DomainAdmins") user = User.objects.get(username="admin1@domain.tld") values = { - "username": user.username, "role": user.role, "quota_act": True, - "is_active": user.is_active, "email": user.email, - "mailboxes_limit": 1, "mailbox_aliases_limit": 2, - "language": "en" + "username": user.username, + "role": user.role, + "quota_act": True, + "is_active": user.is_active, + "email": user.email, + "mailboxes_limit": 1, + "mailbox_aliases_limit": 2, + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values) dom.add_admin(user) self.client.logout() self.client.login(username="admin1@domain.tld", password="Toto1234") @@ -430,10 +437,7 @@ class ResellerTestCase(ResourceTestCase): self.client.login(username="reseller", password="toto") # Delete the admin -> resources should go back to the # reseller's pool - self.ajax_post( - reverse("admin:account_delete", args=[user.id]), - {} - ) + self.ajax_post(reverse("admin:account_delete", args=[user.id]), {}) self._check_limit("mailboxes", 1, 2) self._check_limit("mailbox_aliases", 2, 2) @@ -444,30 +448,30 @@ class ResellerTestCase(ResourceTestCase): # Give 1 mailbox and 2 aliases to the admin -> should work values = { - "username": user.username, "role": user.role, "quota_act": True, - "is_active": user.is_active, "email": user.email, - "mailboxes_limit": 1, "mailbox_aliases_limit": 2, - "language": "en" + "username": user.username, + "role": user.role, + "quota_act": True, + "is_active": user.is_active, + "email": user.email, + "mailboxes_limit": 1, + "mailbox_aliases_limit": 2, + "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values) self._check_limit("mailboxes", 1, 1) self._check_limit("mailbox_aliases", 0, 0) # Change admin role to SimpleUser -> resources should go back # to the reseller. values = { - "username": user.username, "role": "SimpleUsers", + "username": user.username, + "role": "SimpleUsers", "quota_act": True, - "is_active": user.is_active, "email": user.email, + "is_active": user.is_active, + "email": user.email, "language": "en", } - self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values - ) + self.ajax_post(reverse("admin:account_change", args=[user.id]), values) self._check_limit("mailboxes", 1, 2) self._check_limit("mailbox_aliases", 0, 2) @@ -478,14 +482,17 @@ class ResellerTestCase(ResourceTestCase): # Give 2 mailboxes and 3 aliases to the admin -> should fail. values = { - "username": user.username, "role": user.role, "quota_act": True, - "is_active": user.is_active, "email": user.email, - "mailboxes_limit": 2, "mailbox_aliases_limit": 3, - "language": "en" + "username": user.username, + "role": user.role, + "quota_act": True, + "is_active": user.is_active, + "email": user.email, + "mailboxes_limit": 2, + "mailbox_aliases_limit": 3, + "language": "en", } resp = self.ajax_post( - reverse("admin:account_change", args=[user.id]), - values, 424 + reverse("admin:account_change", args=[user.id]), values, 424 ) self.assertEqual(resp, "Not enough resources") self._check_limit("mailboxes", 1, 2) diff --git a/modoboa/maillog/api/v2/serializers.py b/modoboa/maillog/api/v2/serializers.py index d61601a93..c7e68546a 100644 --- a/modoboa/maillog/api/v2/serializers.py +++ b/modoboa/maillog/api/v2/serializers.py @@ -12,7 +12,7 @@ PERIODS = [ ("week", "Week"), ("month", "Month"), ("year", "Year"), - ("custom", "Custom") + ("custom", "Custom"), ] @@ -27,9 +27,8 @@ class StatisticsInputSerializer(serializers.Serializer): end = serializers.DateField(required=False) def validate(self, data): - condition = ( - data["period"] == "custom" and - (not data.get("start") or not data.get("end")) + condition = data["period"] == "custom" and ( + not data.get("start") or not data.get("end") ) if condition: raise serializers.ValidationError( @@ -71,8 +70,14 @@ class MaillogSerializer(serializers.ModelSerializer): class Meta: fields = ( - "id", "queue_id", "date", "sender", "rcpt", "original_rcpt", - "size", "status" + "id", + "queue_id", + "date", + "sender", + "rcpt", + "original_rcpt", + "size", + "status", ) model = models.Maillog diff --git a/modoboa/maillog/api/v2/tests.py b/modoboa/maillog/api/v2/tests.py index 767716a3a..073b1aea8 100644 --- a/modoboa/maillog/api/v2/tests.py +++ b/modoboa/maillog/api/v2/tests.py @@ -12,15 +12,11 @@ class StatisticsViewSetTestCase(ModoAPITestCase): resp = self.client.get(url + "?gset=mailtraffic&period=day") self.assertEqual(resp.status_code, 200) - resp = self.client.get( - url + - "?gset=mailtraffic&period=custom&start=2021-05-01" - ) + resp = self.client.get(url + "?gset=mailtraffic&period=custom&start=2021-05-01") self.assertEqual(resp.status_code, 400) resp = self.client.get( - url + - "?gset=mailtraffic&period=custom&start=2021-05-01&end=2021-05-02" + url + "?gset=mailtraffic&period=custom&start=2021-05-01&end=2021-05-02" ) self.assertEqual(resp.status_code, 200) diff --git a/modoboa/maillog/api/v2/urls.py b/modoboa/maillog/api/v2/urls.py index 3fd2217c2..41e27834c 100644 --- a/modoboa/maillog/api/v2/urls.py +++ b/modoboa/maillog/api/v2/urls.py @@ -5,9 +5,7 @@ from rest_framework import routers from . import viewsets router = routers.SimpleRouter() -router.register( - r"statistics", viewsets.StatisticsViewSet, basename="statistics") -router.register( - r"logs/messages", viewsets.MaillogViewSet, basename="maillog") +router.register(r"statistics", viewsets.StatisticsViewSet, basename="statistics") +router.register(r"logs/messages", viewsets.MaillogViewSet, basename="maillog") urlpatterns = router.urls diff --git a/modoboa/maillog/api/v2/viewsets.py b/modoboa/maillog/api/v2/viewsets.py index 89d1d3c5a..58a60546d 100644 --- a/modoboa/maillog/api/v2/viewsets.py +++ b/modoboa/maillog/api/v2/viewsets.py @@ -16,33 +16,29 @@ from ... import signals from . import serializers -class StatisticsViewSet(GetThrottleViewsetMixin,viewsets.ViewSet): +class StatisticsViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): """A viewset to provide extra route related to mail statistics.""" - permission_classes = (permissions.IsAuthenticated, ) + permission_classes = (permissions.IsAuthenticated,) @extend_schema( parameters=[serializers.StatisticsInputSerializer], - responses={200: serializers.StatisticsSerializer} + responses={200: serializers.StatisticsSerializer}, ) def list(self, request, **kwargs): serializer = serializers.StatisticsInputSerializer(data=request.GET) serializer.is_valid(raise_exception=True) graph_sets = {} - for result in signals.get_graph_sets.send( - sender="index", user=request.user): + for result in signals.get_graph_sets.send(sender="index", user=request.user): graph_sets.update(result[1]) gset = serializer.validated_data["gset"] fname = graph_sets[gset].get_file_name( - request.user, serializer.validated_data.get("searchquery")) + request.user, serializer.validated_data.get("searchquery") + ) period = serializer.validated_data["period"] if period == "custom": - start = int( - time.mktime(serializer.validated_data["start"].timetuple()) - ) - end = int( - time.mktime(serializer.validated_data["end"].timetuple()) - ) + start = int(time.mktime(serializer.validated_data["start"].timetuple())) + end = int(time.mktime(serializer.validated_data["end"].timetuple())) else: end = int(time.mktime(time.localtime())) start = "-1{}".format(period) @@ -59,7 +55,7 @@ class MaillogViewSet(GetThrottleViewsetMixin, viewsets.ReadOnlyModelViewSet): ordering = ["-date"] ordering_fields = "__all__" pagination_class = pagination.CustomPageNumberPagination - permissions = (permissions.IsAuthenticated, ) + permissions = (permissions.IsAuthenticated,) search_fields = ["queue_id", "sender", "rcpt", "original_rcpt", "status"] serializer_class = serializers.MaillogSerializer diff --git a/modoboa/maillog/apps.py b/modoboa/maillog/apps.py index bcb8215d4..c264e4e2a 100644 --- a/modoboa/maillog/apps.py +++ b/modoboa/maillog/apps.py @@ -6,25 +6,47 @@ from django.apps import AppConfig from django.utils.translation import gettext, gettext_lazy as _ -GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([ - ("general", { - "label": _("General"), - "params": collections.OrderedDict([ - ("logfile", { - "label": _("Path to the log file"), - "help_text": _("Path to log file used to collect statistics") - }), - ("rrd_rootdir", { - "label": _("Directory to store RRD files"), - "help_text": _("Path to directory where RRD files are stored") - }), - ("greylist", { - "label": _("Show greylisted messages"), - "help_text": _("Differentiate between hard and soft rejects (greylisting)") - }) - ]) - }) -]) +GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict( + [ + ( + "general", + { + "label": _("General"), + "params": collections.OrderedDict( + [ + ( + "logfile", + { + "label": _("Path to the log file"), + "help_text": _( + "Path to log file used to collect statistics" + ), + }, + ), + ( + "rrd_rootdir", + { + "label": _("Directory to store RRD files"), + "help_text": _( + "Path to directory where RRD files are stored" + ), + }, + ), + ( + "greylist", + { + "label": _("Show greylisted messages"), + "help_text": _( + "Differentiate between hard and soft rejects (greylisting)" + ), + }, + ), + ] + ), + }, + ) + ] +) def load_maillog_settings(): @@ -33,11 +55,13 @@ def load_maillog_settings(): from modoboa.maillog.api.v2 import serializers from modoboa.parameters import tools as param_tools - param_tools.registry.add( - "global", forms.ParametersForm, gettext("Statistics")) + param_tools.registry.add("global", forms.ParametersForm, gettext("Statistics")) param_tools.registry.add2( - "global", "maillog", gettext("Statistics"), GLOBAL_PARAMETERS_STRUCT, - serializers.MaillogGlobalParemetersSerializer + "global", + "maillog", + gettext("Statistics"), + GLOBAL_PARAMETERS_STRUCT, + serializers.MaillogGlobalParemetersSerializer, ) diff --git a/modoboa/maillog/forms.py b/modoboa/maillog/forms.py index a7f386d05..7851ff8ec 100644 --- a/modoboa/maillog/forms.py +++ b/modoboa/maillog/forms.py @@ -23,22 +23,22 @@ class ParametersForm(param_forms.AdminParametersForm): label=gettext_lazy("Path to the log file"), initial="/var/log/mail.log", help_text=gettext_lazy("Path to log file used to collect statistics"), - widget=forms.TextInput(attrs={"class": "form-control"}) + widget=forms.TextInput(attrs={"class": "form-control"}), ) rrd_rootdir = forms.CharField( label=gettext_lazy("Directory to store RRD files"), initial="/tmp/modoboa", - help_text=gettext_lazy( - "Path to directory where RRD files are stored"), - widget=forms.TextInput(attrs={"class": "form-control"}) + help_text=gettext_lazy("Path to directory where RRD files are stored"), + widget=forms.TextInput(attrs={"class": "form-control"}), ) greylist = form_utils.YesNoField( label=gettext_lazy("Show greylisted messages"), initial=False, help_text=gettext_lazy( - "Differentiate between hard and soft rejects (greylisting)") + "Differentiate between hard and soft rejects (greylisting)" + ), ) def __init__(self, *args, **kwargs): diff --git a/modoboa/maillog/graphics.py b/modoboa/maillog/graphics.py index 2bac4c098..8b438153d 100644 --- a/modoboa/maillog/graphics.py +++ b/modoboa/maillog/graphics.py @@ -23,8 +23,7 @@ class Curve: """ def __init__(self, dsname, color, legend, cfunc="AVERAGE"): - """Constructor. - """ + """Constructor.""" self.dsname = dsname self.color = color self.legend = legend @@ -40,10 +39,9 @@ class Curve: param_tools.get_global_parameter("rrd_rootdir"), "%s.rrd" % rrdfile ) return [ - 'DEF:%s=%s:%s:%s' % - (self.dsname, rrdfile, self.dsname, self.cfunc), - 'CDEF:%(ds)spm=%(ds)s,UN,0,%(ds)s,IF,60,*' % {"ds": self.dsname}, - 'XPORT:%spm:"%s"' % (self.dsname, self.legend) + "DEF:%s=%s:%s:%s" % (self.dsname, rrdfile, self.dsname, self.cfunc), + "CDEF:%(ds)spm=%(ds)s,UN,0,%(ds)s,IF,60,*" % {"ds": self.dsname}, + 'XPORT:%spm:"%s"' % (self.dsname, self.legend), ] @@ -82,15 +80,15 @@ class Graphic: dpath = output.strip() else: known_paths = getattr( - settings, "RRDTOOL_LOOKUP_PATH", - ("/usr/bin/rrdtool", "/usr/local/bin/rrdtool") + settings, + "RRDTOOL_LOOKUP_PATH", + ("/usr/bin/rrdtool", "/usr/local/bin/rrdtool"), ) for fpath in known_paths: if os.path.isfile(fpath) and os.access(fpath, os.X_OK): dpath = fpath if dpath is None: - raise exceptions.InternalError( - _("Failed to locate rrdtool binary.")) + raise exceptions.InternalError(_("Failed to locate rrdtool binary.")) return smart_str(dpath) def export(self, rrdfile, start, end): @@ -98,27 +96,27 @@ class Graphic: result = [] cmdargs = [] for curve in self._curves: - result += [{ - "name": str(curve.legend), - "backgroundColor": curve.color, "data": [] - }] + result += [ + {"name": str(curve.legend), "backgroundColor": curve.color, "data": []} + ] cmdargs += curve.to_rrd_command_args(rrdfile) code = 0 cmd = "{} xport --json -t --start {} --end {} ".format( - self.rrdtool_binary, str(start), str(end)) + self.rrdtool_binary, str(start), str(end) + ) cmd += " ".join(cmdargs) code, output = exec_cmd(smart_bytes(cmd)) if code: return [] xport = json.loads(output) - for row in xport['data']: + for row in xport["data"]: timestamp = int(row[0]) - date = datetime.datetime.fromtimestamp(timestamp).isoformat(sep=' ') - for (vindex, value) in enumerate(row[1:]): - result[vindex]['data'].append( - {'x': date, 'y': value, 'timestamp': timestamp} + date = datetime.datetime.fromtimestamp(timestamp).isoformat(sep=" ") + for vindex, value in enumerate(row[1:]): + result[vindex]["data"].append( + {"x": date, "y": value, "timestamp": timestamp} ) return result @@ -159,7 +157,7 @@ class GraphicSet(object): if graphic is None or graphic == graph.display_name: result[graph.display_name] = { "title": str(graph.title), - "series": graph.export(rrdfile, start, end) + "series": graph.export(rrdfile, start, end), } return result @@ -167,7 +165,7 @@ class GraphicSet(object): class AverageTraffic(Graphic): """Average traffic.""" - title = gettext_lazy('Average traffic (msgs/min)') + title = gettext_lazy("Average traffic (msgs/min)") # Curve definitions sent = Curve("sent", "lawngreen", gettext_lazy("sent messages")) @@ -182,10 +180,16 @@ class AverageTraffic(Graphic): def __init__(self, greylist=False): if greylist: self.greylist = Curve( - "greylist", "dimgrey", gettext_lazy("greylisted messages")) + "greylist", "dimgrey", gettext_lazy("greylisted messages") + ) self.order = [ - "reject", "greylist", "bounced", "recv", "sent", "virus", - "spam" + "reject", + "greylist", + "bounced", + "recv", + "sent", + "virus", + "spam", ] super().__init__() @@ -193,13 +197,11 @@ class AverageTraffic(Graphic): class AverageTrafficSize(Graphic): """Average traffic size.""" - title = gettext_lazy('Average normal traffic size (bytes/min)') + title = gettext_lazy("Average normal traffic size (bytes/min)") # Curve definitions size_recv = Curve("size_recv", "orange", gettext_lazy("received size")) - size_sent = Curve( - "size_sent", "mediumturquoise", gettext_lazy("sent size") - ) + size_sent = Curve("size_sent", "mediumturquoise", gettext_lazy("sent size")) class MailTraffic(GraphicSet): @@ -232,8 +234,7 @@ class MailTraffic(GraphicSet): results = list( chain( admin_models.Domain.objects.filter(name__startswith=pattern), - admin_models.DomainAlias.objects.filter( - name__startswith=pattern) + admin_models.DomainAlias.objects.filter(name__startswith=pattern), ) ) if len(results) != 1: @@ -252,8 +253,7 @@ class AccountCreationGraphic(Graphic): title = gettext_lazy("Average account creation (account/hour)") - accounts = Curve( - "new_accounts", "steelblue", gettext_lazy("New accounts")) + accounts = Curve("new_accounts", "steelblue", gettext_lazy("New accounts")) class AccountGraphicSet(GraphicSet): diff --git a/modoboa/maillog/handlers.py b/modoboa/maillog/handlers.py index 99ff0c906..57286d2af 100644 --- a/modoboa/maillog/handlers.py +++ b/modoboa/maillog/handlers.py @@ -18,9 +18,7 @@ def menu(sender, location, user, **kwargs): if location != "top_menu" or user.role == "SimpleUsers": return [] return [ - {"name": "stats", - "label": _("Statistics"), - "url": reverse('maillog:fullindex')} + {"name": "stats", "label": _("Statistics"), "url": reverse("maillog:fullindex")} ] @@ -28,10 +26,9 @@ def menu(sender, location, user, **kwargs): def get_default_graphic_sets(sender, **kwargs): """Return graphic set.""" mail_traffic_gset = graphics.MailTraffic( - param_tools.get_global_parameter("greylist", raise_exception=False)) - result = { - mail_traffic_gset.html_id: mail_traffic_gset - } + param_tools.get_global_parameter("greylist", raise_exception=False) + ) + result = {mail_traffic_gset.html_id: mail_traffic_gset} if kwargs.get("user").is_superuser: account_gset = graphics.AccountGraphicSet() result.update({account_gset.html_id: account_gset}) diff --git a/modoboa/maillog/lib.py b/modoboa/maillog/lib.py index 5417ba542..fa5e04184 100644 --- a/modoboa/maillog/lib.py +++ b/modoboa/maillog/lib.py @@ -12,11 +12,9 @@ def date_to_timestamp(timetuple): :return: an integer """ date = " ".join( - [("%d" % elem) if isinstance(elem, int) else elem - for elem in timetuple] + [("%d" % elem) if isinstance(elem, int) else elem for elem in timetuple] ) - fmt = "%Y %m %d %H %M %S" \ - if timetuple[1].isdigit() else "%Y %b %d %H %M %S" + fmt = "%Y %m %d %H %M %S" if timetuple[1].isdigit() else "%Y %b %d %H %M %S" try: local = time.strptime(date, fmt) except ValueError: diff --git a/modoboa/maillog/management/commands/logparser.py b/modoboa/maillog/management/commands/logparser.py index 734722cfb..5212963c1 100644 --- a/modoboa/maillog/management/commands/logparser.py +++ b/modoboa/maillog/management/commands/logparser.py @@ -43,8 +43,16 @@ from ... import models rrdstep = 60 xpoints = 540 points_per_sample = 3 -variables = ["sent", "recv", "bounced", "reject", "spam", "virus", - "size_sent", "size_recv"] +variables = [ + "sent", + "recv", + "bounced", + "reject", + "spam", + "virus", + "size_sent", + "size_recv", +] class LogParser: @@ -73,10 +81,9 @@ class LogParser: # set up regular expression self._date_expressions = [ r"(?P\w+)\s+(?P\d+)\s+(?P\d+):(?P\d+):(?P\d+)(?P.*)", # noqa - r"(?P\d+)-(?P\d+)-(?P\d+)T(?P\d+):(?P\d+):(?P\d+)\.\d+\+\d+:\d+(?P.*)" # noqa + r"(?P\d+)-(?P\d+)-(?P\d+)T(?P\d+):(?P\d+):(?P\d+)\.\d+\+\d+:\d+(?P.*)", # noqa ] - self._date_expressions = [ - re.compile(v) for v in self._date_expressions] + self._date_expressions = [re.compile(v) for v in self._date_expressions] self.date_expr = None self._regex = { "line": r"\s+([-\w\.]+)\s+(\w+)/?(\w*)[[](\d+)[]]:\s+(.*)", @@ -91,14 +98,13 @@ class LogParser: "rmilter_msg_done": r"msg done: queue_id: <(?P[^>]+)>; message id: <(?P[^>]+)>.*; from: <(?P[^>]+)>; rcpt: <(?P[^>]+)>.*; spam scan: (?P[^;]+); virus scan:", # noqa "rmilter_spam": r"mlfi_eom: (rejecting spam|add spam header to message according to spamd action)", # noqa "rmilter_virus": r"mlfi_eom:.* virus found", - "rmilter_greylist": ( - r"GREYLIST\([0-9]+\.[0-9]{2}\)\[greylisted[^\]]*\]") + "rmilter_greylist": (r"GREYLIST\([0-9]+\.[0-9]{2}\)\[greylisted[^\]]*\]"), } self._regex = {k: re.compile(v) for k, v in self._regex.items()} self._srs_regex = { "detect_srs": "^SRS[01][+-=]", "reverse_srs0": r"^SRS0[+-=]\S+=\S{2}=(\S+)=(\S+)\@\S+$", - "reverse_srs1": r"^SRS1[+-=]\S+=\S+==\S+=\S{2}=(\S+)=(\S+)\@\S+$" + "reverse_srs1": r"^SRS1[+-=]\S+=\S+==\S+=\S{2}=(\S+)=(\S+)\@\S+$", } self._srs_regex = { k: re.compile(v, re.IGNORECASE) for k, v in self._srs_regex.items() @@ -192,7 +198,7 @@ class LogParser: """ ds_type = "ABSOLUTE" rows = xpoints / points_per_sample - realrows = int(rows * 1.1) # ensure that the full range is covered + realrows = int(rows * 1.1) # ensure that the full range is covered day_steps = int(3600 * 24 / (rrdstep * rows)) week_steps = day_steps * 7 month_steps = week_steps * 5 @@ -209,10 +215,7 @@ class LogParser: params += ["RRA:%s:0.5:%s:%s" % (cf, step, realrows)] # With those setup, we can now created the RRD - rrdtool.create(str(fname), - "--start", str(m), - "--step", str(rrdstep), - *params) + rrdtool.create(str(fname), "--start", str(m), "--step", str(rrdstep), *params) return m def add_datasource_to_rrd(self, fname, dsname): @@ -326,14 +329,13 @@ class LogParser: :param month: the month of the current record beeing parsed :return: an integer """ - month = time.strptime(month, "%b").tm_mon if not month.isdigit() \ - else int(month) + month = time.strptime(month, "%b").tm_mon if not month.isdigit() else int(month) if self.curmonth == 1 and month != self.curmonth: return self.__year - 1 return self.__year def is_srs_forward(self, mail_address): - """ Check if mail address has been mangled by SRS + """Check if mail address has been mangled by SRS Sender Rewriting Scheme (SRS) modifies mail adresses so that they always end in a local domain. @@ -344,7 +346,7 @@ class LogParser: return self._srs_regex["detect_srs"].match(mail_address) is not None def reverse_srs(self, mail_address): - """ Try to unwind a mail address rewritten by SRS + """Try to unwind a mail address rewritten by SRS Sender Rewriting Scheme (SRS) modifies mail adresses so that they always end in a local domain. Common Postfix implementations of SRS @@ -354,8 +356,7 @@ class LogParser: :return a str """ m = self._srs_regex["reverse_srs0"].match(mail_address) - m = self._srs_regex["reverse_srs1"].match(mail_address) \ - if m is None else m + m = self._srs_regex["reverse_srs1"].match(mail_address) if m is None else m if m is not None: return "%s@%s" % m.group(2, 1) @@ -363,7 +364,7 @@ class LogParser: return mail_address def _parse_amavis(self, log, host, pid, subprog): - """ Parse an Amavis log entry. + """Parse an Amavis log entry. :param str log: logged message :param str host: hostname @@ -384,7 +385,7 @@ class LogParser: return False def _parse_rmilter(self, log, host, pid, subprog): - """ Parse an Rmilter log entry. + """Parse an Rmilter log entry. :param str log: logged message :param str host: hostname @@ -400,24 +401,18 @@ class LogParser: # Virus check must come before spam check due to pattern similarity. m = self._regex["rmilter_virus"].match(msg) if m is not None: - self.workdict[workdict_key] = { - "action": "virus" - } + self.workdict[workdict_key] = {"action": "virus"} return True m = self._regex["rmilter_spam"].match(msg) if m is not None: - self.workdict[workdict_key] = { - "action": "spam" - } + self.workdict[workdict_key] = {"action": "spam"} return True # Greylisting if self.greylist: m = self._regex["rmilter_greylist"].search(msg) if m is not None: - self.workdict[workdict_key] = { - "action": "greylist" - } + self.workdict[workdict_key] = {"action": "greylist"} return True # Gather information about message sender and queue ID @@ -434,7 +429,7 @@ class LogParser: return False def _parse_postfix(self, log, host, pid, subprog): - """ Parse a log entry generated by Postfix. + """Parse a log entry generated by Postfix. :param str log: logged message :param str host: hostname @@ -452,10 +447,8 @@ class LogParser: m = self._regex["reject"].match(msg) dom = m.group(1) if m is not None else None if dom in self.domains: - condition = ( - self.greylist and ( - "Greylisted" in msg or - (subprog == "postscreen" and " 450 " in msg)) + condition = self.greylist and ( + "Greylisted" in msg or (subprog == "postscreen" and " 450 " in msg) ) if condition: self.inc_counter(dom, "greylist") @@ -474,7 +467,7 @@ class LogParser: if m is not None: self.workdict[queue_id] = { "from": self.reverse_srs(m.group(1)), - "size": int(m.group(2)) + "size": int(m.group(2)), } return True @@ -484,12 +477,12 @@ class LogParser: return False (msg_to, msg_status) = m.groups() if queue_id not in self.workdict: - self._dprint("[parser] inconsistent mail (%s: %s), skipping" - % (queue_id, msg_to)) + self._dprint( + "[parser] inconsistent mail (%s: %s), skipping" % (queue_id, msg_to) + ) return True if msg_status not in variables: - self._dprint("[parser] unsupported status %s, skipping" - % msg_status) + self._dprint("[parser] unsupported status %s, skipping" % msg_status) return True # orig_to is optional. @@ -500,15 +493,11 @@ class LogParser: from_domain = split_mailbox(self.workdict[queue_id]["from"])[1] if from_domain is not None and from_domain in self.domains: self.inc_counter(from_domain, "sent") - self.inc_counter(from_domain, "size_sent", - self.workdict[queue_id]["size"]) + self.inc_counter(from_domain, "size_sent", self.workdict[queue_id]["size"]) # Handle local "to" domains. to_domain = None - condition = ( - msg_orig_to is not None and - not self.is_srs_forward(msg_orig_to) - ) + condition = msg_orig_to is not None and not self.is_srs_forward(msg_orig_to) if condition: to_domain = split_mailbox(msg_orig_to)[1] if to_domain is None: @@ -516,8 +505,7 @@ class LogParser: if msg_status == "sent": self.inc_counter(to_domain, "recv") - self.inc_counter(to_domain, "size_recv", - self.workdict[queue_id]["size"]) + self.inc_counter(to_domain, "size_recv", self.workdict[queue_id]["size"]) else: self.inc_counter(to_domain, msg_status) @@ -525,26 +513,25 @@ class LogParser: cur_dt = datetime.fromtimestamp(self.orig_ts) tz = timezone.get_current_timezone() cur_dt = cur_dt.replace(tzinfo=tz) - condition = ( - last_message and ( - cur_dt < last_message.date or - (cur_dt == last_message.date and - models.Maillog.objects.filter( - date=cur_dt, queue_id=queue_id).exists()) + condition = last_message and ( + cur_dt < last_message.date + or ( + cur_dt == last_message.date + and models.Maillog.objects.filter( + date=cur_dt, queue_id=queue_id + ).exists() ) ) if not condition: if from_domain in self.domains: from_domain = Domain.objects.filter( - Q(name=from_domain) | - Q(domainalias__name=from_domain) + Q(name=from_domain) | Q(domainalias__name=from_domain) ).first() else: from_domain = None if to_domain in self.domains: to_domain = Domain.objects.filter( - Q(name=to_domain) | - Q(domainalias__name=to_domain) + Q(name=to_domain) | Q(domainalias__name=to_domain) ).first() else: to_domain = None @@ -559,7 +546,7 @@ class LogParser: size=self.workdict[queue_id]["size"], status=msg_status, from_domain=from_domain, - to_domain=to_domain + to_domain=to_domain, ) return True @@ -582,8 +569,7 @@ class LogParser: if not parser(log, host, pid, subprog): self._dprint("[parser] ignoring %r log: %r" % (prog, log)) except AttributeError: - self._dprint( - "[parser] no log handler for \"{}\": {}".format(prog, log)) + self._dprint('[parser] no log handler for "{}": {}'.format(prog, log)) def process(self): """Process the log file. @@ -611,14 +597,21 @@ class Command(BaseCommand): def add_arguments(self, parser): """Add extra arguments to command line.""" parser.add_argument( - "--logfile", default=None, - help="postfix log in syslog format", metavar="FILE") + "--logfile", + default=None, + help="postfix log in syslog format", + metavar="FILE", + ) parser.add_argument( - "--verbose", default=False, action="store_true", - dest="verbose", help="Set verbose mode") + "--verbose", + default=False, + action="store_true", + dest="verbose", + help="Set verbose mode", + ) parser.add_argument( - "--debug", default=False, action="store_true", - help="Set debug mode") + "--debug", default=False, action="store_true", help="Set debug mode" + ) def can_start(self): """Check if another process is already running or not.""" @@ -643,11 +636,10 @@ class Command(BaseCommand): sys.exit(2) if options["logfile"] is None: options["logfile"] = param_tools.get_global_parameter( - "logfile", app="maillog") - greylist = param_tools.get_global_parameter( - "greylist", raise_exception=False) + "logfile", app="maillog" + ) + greylist = param_tools.get_global_parameter("greylist", raise_exception=False) p = LogParser( - options, param_tools.get_global_parameter("rrd_rootdir"), - None, greylist + options, param_tools.get_global_parameter("rrd_rootdir"), None, greylist ) p.process() diff --git a/modoboa/maillog/management/commands/update_statistics.py b/modoboa/maillog/management/commands/update_statistics.py index d828acab9..031ddbc51 100644 --- a/modoboa/maillog/management/commands/update_statistics.py +++ b/modoboa/maillog/management/commands/update_statistics.py @@ -20,8 +20,10 @@ class Command(BaseCommand): def add_arguments(self, parser): """Add extra arguments to command line.""" parser.add_argument( - "--rebuild", action="store_true", - help="Rebuild statistics from the begining") + "--rebuild", + action="store_true", + help="Rebuild statistics from the begining", + ) def _create_new_accounts_rrd_file(self, fname, start): """Create RRD file.""" @@ -29,15 +31,12 @@ class Command(BaseCommand): ds_name = "new_accounts" params = ["DS:{}:ABSOLUTE:{}:0:U".format(ds_name, step * 2)] params += [ - "RRA:AVERAGE:0.5:1:48", # 48 hours with a 1h granularity - "RRA:AVERAGE:0.5:24:31", # 31 days with a 1d granularity - "RRA:AVERAGE:0.5:168:52", # 52 weeks with a 1w granularity + "RRA:AVERAGE:0.5:1:48", # 48 hours with a 1h granularity + "RRA:AVERAGE:0.5:24:31", # 31 days with a 1d granularity + "RRA:AVERAGE:0.5:168:52", # 52 weeks with a 1w granularity "RRA:AVERAGE:0.5:5208:24", # 24 months with a 1m granularity ] - rrdtool.create( - str(fname), "--start", str(start), "--step", str(step), - *params - ) + rrdtool.create(str(fname), "--start", str(start), "--step", str(step), *params) def update_account_creation_stats(self, rebuild=False): """Look for newly created accounts.""" @@ -47,15 +46,16 @@ class Command(BaseCommand): end = timezone.now().replace(minute=0, second=0, microsecond=0) start = end - relativedelta(hours=1) new_accounts = core_models.User.objects.filter( - date_joined__gte=start, date_joined__lt=end).count() - data.append( - "{}:{}".format(int(end.strftime("%s")), new_accounts * 60)) + date_joined__gte=start, date_joined__lt=end + ).count() + data.append("{}:{}".format(int(end.strftime("%s")), new_accounts * 60)) else: existing_stats = {} start = None for user in core_models.User.objects.all().order_by("date_joined"): hour = user.date_joined.replace( - minute=0, second=0, microsecond=0) + relativedelta(hours=1) + minute=0, second=0, microsecond=0 + ) + relativedelta(hours=1) if start is None: start = hour hour = int(hour.strftime("%s")) @@ -63,14 +63,14 @@ class Command(BaseCommand): existing_stats[hour] = 0 existing_stats[hour] += 1 end = timezone.now().replace( - minute=0, second=0, microsecond=0) + relativedelta(hours=1) + minute=0, second=0, microsecond=0 + ) + relativedelta(hours=1) if os.path.exists(db_path): os.unlink(db_path) hour = start while hour <= end: new_accounts = existing_stats.get(int(hour.strftime("%s")), 0) - data.append("{}:{}".format( - int(hour.strftime("%s")), new_accounts * 60)) + data.append("{}:{}".format(int(hour.strftime("%s")), new_accounts * 60)) hour += relativedelta(hours=1) if not os.path.exists(db_path): self._create_new_accounts_rrd_file( diff --git a/modoboa/maillog/migrations/0001_initial.py b/modoboa/maillog/migrations/0001_initial.py index 92e1122eb..6ff2e93c4 100644 --- a/modoboa/maillog/migrations/0001_initial.py +++ b/modoboa/maillog/migrations/0001_initial.py @@ -9,26 +9,50 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('admin', '0017_alarm'), + ("admin", "0017_alarm"), ] operations = [ migrations.CreateModel( - name='Maillog', + name="Maillog", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('queue_id', models.CharField(max_length=50)), - ('date', models.DateTimeField()), - ('sender', models.EmailField(max_length=254)), - ('rcpt', models.EmailField(max_length=254)), - ('original_rcpt', models.EmailField(max_length=254, null=True)), - ('size', models.PositiveIntegerField()), - ('status', models.CharField(max_length=15)), - ('from_domain', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sent_messages_log', to='admin.Domain')), - ('to_domain', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='recv_messages_log', to='admin.Domain')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("queue_id", models.CharField(max_length=50)), + ("date", models.DateTimeField()), + ("sender", models.EmailField(max_length=254)), + ("rcpt", models.EmailField(max_length=254)), + ("original_rcpt", models.EmailField(max_length=254, null=True)), + ("size", models.PositiveIntegerField()), + ("status", models.CharField(max_length=15)), + ( + "from_domain", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="sent_messages_log", + to="admin.Domain", + ), + ), + ( + "to_domain", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="recv_messages_log", + to="admin.Domain", + ), + ), ], options={ - 'ordering': ['date'], + "ordering": ["date"], }, ), ] diff --git a/modoboa/maillog/migrations/0002_auto_20200916_1346.py b/modoboa/maillog/migrations/0002_auto_20200916_1346.py index 7d6f6a821..34d451c6f 100644 --- a/modoboa/maillog/migrations/0002_auto_20200916_1346.py +++ b/modoboa/maillog/migrations/0002_auto_20200916_1346.py @@ -28,7 +28,7 @@ def backwards(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('maillog', '0001_initial'), + ("maillog", "0001_initial"), ] operations = [ diff --git a/modoboa/maillog/migrations/0003_auto_20211108_1652.py b/modoboa/maillog/migrations/0003_auto_20211108_1652.py index ba7f3a474..a36dc60dc 100644 --- a/modoboa/maillog/migrations/0003_auto_20211108_1652.py +++ b/modoboa/maillog/migrations/0003_auto_20211108_1652.py @@ -6,13 +6,13 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('maillog', '0002_auto_20200916_1346'), + ("maillog", "0002_auto_20200916_1346"), ] operations = [ migrations.AlterField( - model_name='maillog', - name='date', + model_name="maillog", + name="date", field=models.DateTimeField(db_index=True), ), ] diff --git a/modoboa/maillog/models.py b/modoboa/maillog/models.py index 689add82d..339a5fe45 100644 --- a/modoboa/maillog/models.py +++ b/modoboa/maillog/models.py @@ -15,13 +15,17 @@ class Maillog(models.Model): status = models.CharField(max_length=15) from_domain = models.ForeignKey( - "admin.Domain", on_delete=models.SET_NULL, null=True, - related_name="sent_messages_log" + "admin.Domain", + on_delete=models.SET_NULL, + null=True, + related_name="sent_messages_log", ) to_domain = models.ForeignKey( - "admin.Domain", on_delete=models.SET_NULL, null=True, - related_name="recv_messages_log" + "admin.Domain", + on_delete=models.SET_NULL, + null=True, + related_name="recv_messages_log", ) class Meta: - ordering = ['date'] + ordering = ["date"] diff --git a/modoboa/maillog/parser.py b/modoboa/maillog/parser.py index 4541247ec..093b91e56 100644 --- a/modoboa/maillog/parser.py +++ b/modoboa/maillog/parser.py @@ -33,10 +33,9 @@ class MaillogParser: # set up regular expression self._date_expressions = [ r"(?P\w+)\s+(?P\d+)\s+(?P\d+):(?P\d+):(?P\d+)(?P.*)", # noqa - r"(?P\d+)-(?P\d+)-(?P\d+)T(?P\d+):(?P\d+):(?P\d+)\.\d+\+\d+:\d+(?P.*)" # noqa + r"(?P\d+)-(?P\d+)-(?P\d+)T(?P\d+):(?P\d+):(?P\d+)\.\d+\+\d+:\d+(?P.*)", # noqa ] - self._date_expressions = [ - re.compile(v) for v in self._date_expressions] + self._date_expressions = [re.compile(v) for v in self._date_expressions] self.date_expr = None self._regex = { "line": r"\s+([-\w\.]+)\s+(\w+)/?(\w*)[[](\d+)[]]:\s+(.*)", @@ -51,7 +50,7 @@ class MaillogParser: self._srs_regex = { "detect_srs": "^SRS[01][+-=]", "reverse_srs0": r"^SRS0[+-=]\S+=\S{2}=(\S+)=(\S+)\@\S+$", - "reverse_srs1": r"^SRS1[+-=]\S+=\S+==\S+=\S{2}=(\S+)=(\S+)\@\S+$" + "reverse_srs1": r"^SRS1[+-=]\S+=\S+==\S+=\S{2}=(\S+)=(\S+)\@\S+$", } self._srs_regex = { k: re.compile(v, re.IGNORECASE) for k, v in self._srs_regex.items() @@ -97,10 +96,7 @@ class MaillogParser: :param month: the month of the current record beeing parsed :return: an integer """ - month = ( - time.strptime(month, "%b").tm_mon if not month.isdigit() - else int(month) - ) + month = time.strptime(month, "%b").tm_mon if not month.isdigit() else int(month) if self.curmonth == 1 and month != self.curmonth: return self.__year - 1 return self.__year @@ -143,7 +139,7 @@ class MaillogParser: return match.group("eol") def is_srs_forward(self, mail_address): - """ Check if mail address has been mangled by SRS + """Check if mail address has been mangled by SRS Sender Rewriting Scheme (SRS) modifies mail adresses so that they always end in a local domain. @@ -154,7 +150,7 @@ class MaillogParser: return self._srs_regex["detect_srs"].match(mail_address) is not None def reverse_srs(self, mail_address): - """ Try to unwind a mail address rewritten by SRS + """Try to unwind a mail address rewritten by SRS Sender Rewriting Scheme (SRS) modifies mail adresses so that they always end in a local domain. Common Postfix implementations of SRS @@ -164,8 +160,7 @@ class MaillogParser: :return a str """ m = self._srs_regex["reverse_srs0"].match(mail_address) - m = self._srs_regex["reverse_srs1"].match(mail_address) \ - if m is None else m + m = self._srs_regex["reverse_srs1"].match(mail_address) if m is None else m if m is not None: return "%s@%s" % m.group(2, 1) @@ -176,13 +171,13 @@ class MaillogParser: pass def new_message_processed( - self, queue_id, msg_status, from_domain, to_domain, msg_to, - msg_orig_to): + self, queue_id, msg_status, from_domain, to_domain, msg_to, msg_orig_to + ): """Store new message in local database.""" pass def _parse_postfix(self, log, host, pid, subprog): - """ Parse a log entry generated by Postfix. + """Parse a log entry generated by Postfix. :param str log: logged message :param str host: hostname @@ -200,13 +195,10 @@ class MaillogParser: m = self._regex["reject"].match(msg) dom = m.group(1) if m is not None else None if dom in self.domains: - condition = ( - self.greylist and ( - "Greylisted" in msg or - (subprog == "postscreen" and " 450 " in msg)) + condition = self.greylist and ( + "Greylisted" in msg or (subprog == "postscreen" and " 450 " in msg) ) - self.new_domain_event( - dom, "greylist" if condition else "reject") + self.new_domain_event(dom, "greylist" if condition else "reject") return True # Message acknowledged. @@ -220,7 +212,7 @@ class MaillogParser: if m is not None: self.workdict[queue_id] = { "from": self.reverse_srs(m.group(1)), - "size": int(m.group(2)) + "size": int(m.group(2)), } return True @@ -230,8 +222,9 @@ class MaillogParser: return False (msg_to, msg_status) = m.groups() if queue_id not in self.workdict: - self._dprint("[parser] inconsistent mail (%s: %s), skipping" - % (queue_id, msg_to)) + self._dprint( + "[parser] inconsistent mail (%s: %s), skipping" % (queue_id, msg_to) + ) return True # orig_to is optional. @@ -241,15 +234,11 @@ class MaillogParser: # Handle local "from" domains. from_domain = split_mailbox(self.workdict[queue_id]["from"])[1] if from_domain is not None and from_domain in self.domains: - self.new_domain_event( - from_domain, "sent", self.workdict[queue_id]["size"]) + self.new_domain_event(from_domain, "sent", self.workdict[queue_id]["size"]) # Handle local "to" domains. to_domain = None - condition = ( - msg_orig_to is not None and - not self.is_srs_forward(msg_orig_to) - ) + condition = msg_orig_to is not None and not self.is_srs_forward(msg_orig_to) if condition: to_domain = split_mailbox(msg_orig_to)[1] if to_domain is None: @@ -257,12 +246,12 @@ class MaillogParser: if msg_status == "sent": msg_status = "recv" - self.new_domain_event( - to_domain, "recv", self.workdict[queue_id]["size"]) + self.new_domain_event(to_domain, "recv", self.workdict[queue_id]["size"]) # Store log entry self.new_message_processed( - queue_id, msg_status, from_domain, to_domain, msg_to, msg_orig_to) + queue_id, msg_status, from_domain, to_domain, msg_to, msg_orig_to + ) return True @@ -284,8 +273,7 @@ class MaillogParser: if not parser(log, host, pid, subprog): self._dprint("[parser] ignoring %r log: %r" % (prog, log)) except AttributeError: - self._dprint( - "[parser] no log handler for \"%r\": %r".format(prog, log)) + self._dprint('[parser] no log handler for "%r": %r'.format(prog, log)) def parse(self, logfile): """Process the log file.""" diff --git a/modoboa/maillog/signals.py b/modoboa/maillog/signals.py index 28b476cae..227f0295b 100644 --- a/modoboa/maillog/signals.py +++ b/modoboa/maillog/signals.py @@ -2,4 +2,4 @@ import django.dispatch -get_graph_sets = django.dispatch.Signal() # Provides user +get_graph_sets = django.dispatch.Signal() # Provides user diff --git a/modoboa/maillog/tests/test_views.py b/modoboa/maillog/tests/test_views.py index 1610bb724..4da688cc9 100644 --- a/modoboa/maillog/tests/test_views.py +++ b/modoboa/maillog/tests/test_views.py @@ -31,11 +31,9 @@ class RunCommandsMixin(object): def run_logparser(self): """Run logparser command.""" - path = os.path.join( - os.path.dirname(__file__), "mail.log") + path = os.path.join(os.path.dirname(__file__), "mail.log") with open(path) as fp: - content = fp.read() % { - "day": datetime.date.today().strftime("%b %d")} + content = fp.read() % {"day": datetime.date.today().strftime("%b %d")} path = os.path.join(self.workdir, "mail.log") with open(path, "w") as fp: fp.write(content) @@ -84,7 +82,8 @@ class ViewsTestCase(RunCommandsMixin, ModoTestCase): self.assertIn("averagetraffic", response["graphs"]) for period in ["week", "month", "year"]: response = self.ajax_get( - "{}?gset=mailtraffic&period={}".format(url, period)) + "{}?gset=mailtraffic&period={}".format(url, period) + ) self.assertIn("averagetraffic", response["graphs"]) self.assertEqual(response["period_name"], period) @@ -93,15 +92,14 @@ class ViewsTestCase(RunCommandsMixin, ModoTestCase): start = "{} 11:00:00".format(today) end = "{} 11:40:00".format(today) response = self.ajax_get( - "{}?gset=mailtraffic&period=custom&start={}&end={}".format( - url, start, end) + "{}?gset=mailtraffic&period=custom&start={}&end={}".format(url, start, end) ) self.assertIn("averagetraffic", response["graphs"]) # unknown domain response = self.ajax_get( - "{}?gset=mailtraffic&searchquery=unknown.com".format(url), - status=400) + "{}?gset=mailtraffic&searchquery=unknown.com".format(url), status=400 + ) # check with greylist enabled self.set_global_parameter("greylist", True) @@ -113,8 +111,7 @@ class ViewsTestCase(RunCommandsMixin, ModoTestCase): self.run_update_statistics(rebuild=True) url = reverse("maillog:graph_list") response = self.ajax_get("{}?gset=accountgraphicset".format(url)) - data = ( - response["graphs"]["accountcreationgraphic"]["series"][0]["data"]) + data = response["graphs"]["accountcreationgraphic"]["series"][0]["data"] self.assertEqual(data[-1]["y"], 5.0) def test_graphs_as_domainadmin(self): @@ -128,8 +125,7 @@ class ViewsTestCase(RunCommandsMixin, ModoTestCase): response = self.ajax_get("{}&searchquery=test.com".format(url)) self.assertIn("averagetraffic", response["graphs"]) - response = self.ajax_get( - "{}&searchquery=test2.com".format(url), status=403) + response = self.ajax_get("{}&searchquery=test2.com".format(url), status=403) def test_get_domain_list(self): """Test get_domain_list view.""" diff --git a/modoboa/maillog/views.py b/modoboa/maillog/views.py index b2dcedb0e..15264d9b6 100644 --- a/modoboa/maillog/views.py +++ b/modoboa/maillog/views.py @@ -8,14 +8,14 @@ import time from django.shortcuts import render from django.utils.translation import gettext as _ from django.contrib.auth.decorators import ( - login_required, user_passes_test, permission_required + login_required, + user_passes_test, + permission_required, ) from modoboa.admin.models import Domain from modoboa.lib.exceptions import BadRequest, NotFound -from modoboa.lib.web_utils import ( - render_to_json_response -) +from modoboa.lib.web_utils import render_to_json_response from . import signals from .lib import date_to_timestamp @@ -33,22 +33,25 @@ def index(request): raise NotFound(_("No statistics available")) graph_sets = {} - for result in signals.get_graph_sets.send( - sender="index", user=request.user): + for result in signals.get_graph_sets.send(sender="index", user=request.user): graph_sets.update(result[1]) periods = [ {"name": "day", "label": _("Day")}, {"name": "week", "label": _("Week")}, {"name": "month", "label": _("Month")}, {"name": "year", "label": _("Year")}, - {"name": "custom", "label": _("Custom")} + {"name": "custom", "label": _("Custom")}, ] - return render(request, 'maillog/index.html', { - "periods": periods, - "selection": "stats", - "deflocation": deflocation, - "graph_sets": graph_sets - }) + return render( + request, + "maillog/index.html", + { + "periods": periods, + "selection": "stats", + "deflocation": deflocation, + "graph_sets": graph_sets, + }, + ) @login_required @@ -57,8 +60,7 @@ def graphs(request): gset = request.GET.get("gset", None) searchq = request.GET.get("searchquery", None) graph_sets = {} - for result in signals.get_graph_sets.send( - sender="index", user=request.user): + for result in signals.get_graph_sets.send(sender="index", user=request.user): graph_sets.update(result[1]) if gset not in graph_sets: raise NotFound(_("Unknown graphic set")) @@ -74,8 +76,8 @@ def graphs(request): raise BadRequest(_("Bad custom period")) start = request.GET["start"] end = request.GET["end"] - expr = re.compile(r'[:\- ]') - period_name = "%s_%s" % (expr.sub('', start), expr.sub('', end)) + expr = re.compile(r"[:\- ]") + period_name = "%s_%s" % (expr.sub("", start), expr.sub("", end)) start = date_to_timestamp(expr.split(start)) end = date_to_timestamp(expr.split(end)) else: diff --git a/modoboa/parameters/api/v2/tests.py b/modoboa/parameters/api/v2/tests.py index 34806feb1..e43efd549 100644 --- a/modoboa/parameters/api/v2/tests.py +++ b/modoboa/parameters/api/v2/tests.py @@ -43,7 +43,7 @@ class ParametersAPITestCase(ModoAPITestCase): "deflt_domain_domain_admins_limit": 0, "deflt_domain_domain_aliases_limit": 0, "deflt_domain_mailboxes_limit": 0, - "deflt_domain_mailbox_aliases_limit": 0 + "deflt_domain_mailbox_aliases_limit": 0, } url = reverse("v2:parameter-detail", args=["limits"]) resp = self.client.put(url, data, format="json") @@ -55,7 +55,7 @@ class ParametersAPITestCase(ModoAPITestCase): "default_mailbox_quota": -1, "valid_mxs": "mail.test.com", "custom_dns_server": "", - "dkim_keys_storage_dir": "/wrong" + "dkim_keys_storage_dir": "/wrong", } url = reverse("v2:parameter-detail", args=["admin"]) resp = self.client.put(url, data, format="json") @@ -63,40 +63,32 @@ class ParametersAPITestCase(ModoAPITestCase): errors = resp.json() self.assertEqual( errors["valid_mxs"], - ["This field only allows valid IP addresses (or networks)"] - ) - self.assertEqual( - errors["default_domain_quota"], ["Must be a positive integer"] + ["This field only allows valid IP addresses (or networks)"], ) + self.assertEqual(errors["default_domain_quota"], ["Must be a positive integer"]) self.assertEqual( errors["default_mailbox_quota"], ["Must be a positive integer"] ) - self.assertEqual( - errors["dkim_keys_storage_dir"], ["Directory not found."] - ) + self.assertEqual(errors["dkim_keys_storage_dir"], ["Directory not found."]) # Try to set dkim storage dir to a non-writable directory. - data = { - "dkim_keys_storage_dir": "/root" - } + data = {"dkim_keys_storage_dir": "/root"} url = reverse("v2:parameter-detail", args=["admin"]) resp = self.client.put(url, data, format="json") self.assertEqual(resp.status_code, 400) errors = resp.json() - self.assertEqual( - errors["dkim_keys_storage_dir"], ["Directory non-writable"] - ) + self.assertEqual(errors["dkim_keys_storage_dir"], ["Directory non-writable"]) data = { "enable_mx_checks": True, "domains_must_have_authorized_mx": True, "valid_mxs": "", "custom_dns_server": "", - "dkim_keys_storage_dir": "" + "dkim_keys_storage_dir": "", } resp = self.client.put(url, data, format="json") self.assertEqual(resp.status_code, 400) self.assertEqual( resp.json()["valid_mxs"], - ["Define at least one authorized network / address"] + ["Define at least one authorized network / address"], ) diff --git a/modoboa/parameters/api/v2/urls.py b/modoboa/parameters/api/v2/urls.py index 25ec41c04..418037966 100644 --- a/modoboa/parameters/api/v2/urls.py +++ b/modoboa/parameters/api/v2/urls.py @@ -6,6 +6,5 @@ from . import viewsets router = routers.SimpleRouter() -router.register( - r"parameters", viewsets.ParametersViewSet, basename="parameter") +router.register(r"parameters", viewsets.ParametersViewSet, basename="parameter") urlpatterns = router.urls diff --git a/modoboa/parameters/api/v2/viewsets.py b/modoboa/parameters/api/v2/viewsets.py index 3a670f02f..cb2d785fa 100644 --- a/modoboa/parameters/api/v2/viewsets.py +++ b/modoboa/parameters/api/v2/viewsets.py @@ -36,39 +36,41 @@ class ParametersViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): @extend_schema( parameters=[ OpenApiParameter( - name='id', location=OpenApiParameter.PATH, - description='A registered application name', - type=str, required=True + name="id", + location=OpenApiParameter.PATH, + description="A registered application name", + type=str, + required=True, ), ], - responses=serializers.AppParametersSerializer + responses=serializers.AppParametersSerializer, ) def retrieve(self, request, pk: str): """Return all parameters for given app.""" parameters = request.localconfig.parameters.get_values_dict(pk) - serializer = tools.registry.get_serializer_class("global", pk)( - parameters) - result = serializers.AppParametersSerializer({ - "label": tools.registry.get_label("global", pk), - "params": serializer.data - }) + serializer = tools.registry.get_serializer_class("global", pk)(parameters) + result = serializers.AppParametersSerializer( + {"label": tools.registry.get_label("global", pk), "params": serializer.data} + ) return response.Response(result.data) @extend_schema( parameters=[ OpenApiParameter( - name='id', location=OpenApiParameter.PATH, - description='A registered application name', - type=str, required=True + name="id", + location=OpenApiParameter.PATH, + description="A registered application name", + type=str, + required=True, ), ] ) def update(self, request, pk: str): """Save parameters for given app.""" serializer = tools.registry.get_serializer_class("global", pk)( - data=request.data) + data=request.data + ) serializer.is_valid(raise_exception=True) - request.localconfig.parameters.set_values( - serializer.validated_data, app=pk) + request.localconfig.parameters.set_values(serializer.validated_data, app=pk) request.localconfig.save(update_fields=["_parameters"]) return response.Response() diff --git a/modoboa/parameters/forms.py b/modoboa/parameters/forms.py index f35949b25..49a40eba4 100644 --- a/modoboa/parameters/forms.py +++ b/modoboa/parameters/forms.py @@ -10,6 +10,7 @@ class GenericParametersForm(forms.Form): Each extension has the possibility to define global parameters. """ + app = None visibility_rules = None @@ -35,9 +36,7 @@ class GenericParametersForm(forms.Form): """Add visibility rules to this form.""" for key, rule in list(rules.items()): field, value = rule.split("=") - visibility = { - "field": "id_%s-%s" % (self.app, field), "value": value - } + visibility = {"field": "id_%s-%s" % (self.app, field), "value": value} self.visirules["%s-%s" % (self.app, key)] = visibility def _add_dynamic_fields(self): @@ -66,8 +65,8 @@ class AdminParametersForm(GenericParametersForm): def _load_initial_values(self): """Load form initial values from database.""" condition = ( - not db_utils.db_table_exists("core_localconfig") or - not self.localconfig) + not db_utils.db_table_exists("core_localconfig") or not self.localconfig + ) if condition: return values = self.localconfig.parameters.get_values(app=self.app) diff --git a/modoboa/parameters/tools.py b/modoboa/parameters/tools.py index ed9e99667..69629fbc5 100644 --- a/modoboa/parameters/tools.py +++ b/modoboa/parameters/tools.py @@ -18,8 +18,7 @@ class NotDefined(exceptions.ModoboaException): def __str__(self): if self.name is None: return "Application {} not registered".format(self.app) - return "Parameter {} not defined for app {}".format( - self.name, self.app) + return "Parameter {} not defined for app {}".format(self.name, self.app) class Registry(object): @@ -27,28 +26,24 @@ class Registry(object): def __init__(self): """Constructor.""" - self._registry = { - "global": {}, - "user": {} - } - self._registry2 = { - "global": {}, - "user": {} - } + self._registry = {"global": {}, "user": {}} + self._registry2 = {"global": {}, "user": {}} def add(self, level, formclass, label): """Add a new class containing parameters.""" self._registry[level][formclass.app] = { - "label": label, "formclass": formclass, "defaults": {} + "label": label, + "formclass": formclass, + "defaults": {}, } - def add2(self, level, app, label, structure, serializer_class, - is_extension=False): + def add2(self, level, app, label, structure, serializer_class, is_extension=False): """Add new parameters for given app and level.""" self._registry2[level][app] = { - "label": label, "structure": structure, + "label": label, + "structure": structure, "serializer_class": serializer_class, - "is_extension": is_extension + "is_extension": is_extension, } def _load_default_values(self, level): @@ -62,9 +57,14 @@ class Registry(object): def get_applications(self, level): """Return all applications registered for level.""" - result = [{"name": key, "label": value["label"], - "is_extension": value["is_extension"]} - for key, value in self._registry2[level].items()] + result = [ + { + "name": key, + "label": value["label"], + "is_extension": value["is_extension"], + } + for key, value in self._registry2[level].items() + ] return result def get_label(self, level, app): @@ -77,22 +77,21 @@ class Registry(object): if first_app in self._registry[level]: sorted_apps.append(first_app) sorted_apps += sorted( - ( - a for a in self._registry[level] - if a != first_app - ), - key=lambda a: self._registry[level][a]["label"] + (a for a in self._registry[level] if a != first_app), + key=lambda a: self._registry[level][a]["label"], ) result = [] for app in sorted_apps: data = self._registry[level][app] if not data["formclass"].has_access(**kwargs): continue - result.append({ - "app": app, - "label": data["label"], - "form": data["formclass"](*args, **kwargs) - }) + result.append( + { + "app": app, + "label": data["label"], + "form": data["formclass"](*args, **kwargs), + } + ) return result def get_serializer_class(self, level, app): @@ -112,7 +111,7 @@ class Registry(object): item = { "label": sconfig["label"], "display": sconfig.get("display", ""), - "parameters": [] + "parameters": [], } for name, config in list(sconfig["params"].items()): data = { @@ -217,7 +216,8 @@ class Manager: raise NotDefined(app, parameter) if app not in self._parameters: self._parameters[app] = copy.deepcopy( - registry.get_defaults(self._level, app)) + registry.get_defaults(self._level, app) + ) self._parameters[app][parameter] = value def set_values(self, values, app=None): @@ -228,13 +228,15 @@ class Manager: raise NotDefined(app) if app not in self._parameters: self._parameters[app] = copy.deepcopy( - registry.get_defaults(self._level, app)) + registry.get_defaults(self._level, app) + ) self._parameters[app].update(values) def get_localconfig(): """Retrieve current LocalConfig instance.""" from modoboa.core import models as core_models + request = signals.get_request() if request: return request.localconfig diff --git a/modoboa/pdfcredentials/api/v2/serializers.py b/modoboa/pdfcredentials/api/v2/serializers.py index 2832f8ca5..867608c7c 100644 --- a/modoboa/pdfcredentials/api/v2/serializers.py +++ b/modoboa/pdfcredentials/api/v2/serializers.py @@ -31,36 +31,34 @@ class PDFCredentialsSettingsSerializer(serializers.Serializer): title = serializers.CharField(default=_("Personal account information")) webpanel_url = serializers.URLField() custom_message = serializers.CharField( - required=False, allow_blank=True, allow_null=True) + required=False, allow_blank=True, allow_null=True + ) include_connection_settings = serializers.BooleanField(default=False) smtp_server_address = serializers.CharField() smtp_server_port = serializers.IntegerField(default=587) smtp_connection_security = serializers.ChoiceField( - choices=CONNECTION_SECURITY_MODES, default="starttls") + choices=CONNECTION_SECURITY_MODES, default="starttls" + ) imap_server_address = serializers.CharField() imap_server_port = serializers.IntegerField(default=143) imap_connection_security = serializers.ChoiceField( - choices=CONNECTION_SECURITY_MODES, default="starttls") + choices=CONNECTION_SECURITY_MODES, default="starttls" + ) def validate(self, data): """Check that directory exists.""" enabled_pdfcredentials = data.get("enabled_pdfcredentials", None) - condition = (enabled_pdfcredentials or - (enabled_pdfcredentials is None and - param_tools.get_global_parameter("enabled_pdfcredentials") - ) - ) + condition = enabled_pdfcredentials or ( + enabled_pdfcredentials is None + and param_tools.get_global_parameter("enabled_pdfcredentials") + ) if condition: storage_dir = data.get("storage_dir", None) if storage_dir is not None: if not os.path.isdir(storage_dir): - raise serializers.ValidationError( - _("Directory not found.") - ) + raise serializers.ValidationError(_("Directory not found.")) if not os.access(storage_dir, os.W_OK): - raise serializers.ValidationError( - _("Directory is not writable") - ) + raise serializers.ValidationError(_("Directory is not writable")) return data @@ -81,8 +79,7 @@ class GetAccountCredentialsSerializer(serializers.Serializer): fname = get_creds_filename(self.context["account"]) if not os.path.exists(fname): raise APIException( - _("No document available for this user"), - status.HTTP_400_BAD_REQUEST + _("No document available for this user"), status.HTTP_400_BAD_REQUEST ) self.context["content"] = decrypt_file(fname) if param_tools.get_global_parameter("delete_first_dl"): diff --git a/modoboa/pdfcredentials/api/v2/tests.py b/modoboa/pdfcredentials/api/v2/tests.py index 88cb981c3..c35c1b765 100644 --- a/modoboa/pdfcredentials/api/v2/tests.py +++ b/modoboa/pdfcredentials/api/v2/tests.py @@ -28,9 +28,7 @@ class PDFCredentialViewTestCase(ModoAPITestCase): data = { "username": f"{username}", "role": "SimpleUsers", - "mailbox": { - "use_domain_quota": True - }, + "mailbox": {"use_domain_quota": True}, "password": "Toto12345", "language": "fr", } @@ -78,9 +76,7 @@ class PDFCredentialViewTestCase(ModoAPITestCase): self.assertTrue(assert_action_in_response) # Try to download the file - response = self.client.get( - reverse("v2:get-credentials", - args=[account.pk])) + response = self.client.get(reverse("v2:get-credentials", args=[account.pk])) self.assertEqual(response.status_code, 200) self.assertEqual(response["Content-Type"], "application/pdf") @@ -88,22 +84,21 @@ class PDFCredentialViewTestCase(ModoAPITestCase): self.assertFalse(os.path.exists(fname)) # Try to download a second time - response = self.client.get( - reverse("v2:get-credentials", - args=[account.pk])) - self.assertEqual(response.json()["detail"], - "No document available for this user") + response = self.client.get(reverse("v2:get-credentials", args=[account.pk])) + self.assertEqual( + response.json()["detail"], "No document available for this user" + ) # Update account values.update({"language": "en"}) self.client.patch( - reverse("v2:account-detail", args=[account.pk]), values, format='json' + reverse("v2:account-detail", args=[account.pk]), values, format="json" ) self.assertFalse(os.path.exists(fname)) self.set_global_parameter("generate_at_creation", False) self.client.patch( - reverse("v2:account-detail", args=[account.pk]), values, format='json' + reverse("v2:account-detail", args=[account.pk]), values, format="json" ) self.assertTrue(os.path.exists(fname)) @@ -146,9 +141,7 @@ class PDFCredentialViewTestCase(ModoAPITestCase): account = core_models.User.objects.get(username=values["username"]) # Try to download the file - response = self.client.get( - reverse("v2:get-credentials", - args=[account.pk])) + response = self.client.get(reverse("v2:get-credentials", args=[account.pk])) self.assertEqual(response.status_code, 200) self.assertEqual(response["Content-Type"], "application/pdf") @@ -171,10 +164,10 @@ class PDFCredentialViewTestCase(ModoAPITestCase): self.set_global_parameter("enabled_pdfcredentials", False) url = reverse("v2:parameter-detail", args=["pdfcredentials"]) data = { - "webpanel_url": "http://localhost", - "smtp_server_address": "mail.localhost", - "imap_server_address": "mail.localhost", - } + "webpanel_url": "http://localhost", + "smtp_server_address": "mail.localhost", + "imap_server_address": "mail.localhost", + } # Test that we can't activate it without providing a valid storage dir. data["enabled_pdfcredentials"] = True diff --git a/modoboa/pdfcredentials/api/v2/urls.py b/modoboa/pdfcredentials/api/v2/urls.py index 4b62a3ea0..6fb68a803 100644 --- a/modoboa/pdfcredentials/api/v2/urls.py +++ b/modoboa/pdfcredentials/api/v2/urls.py @@ -6,6 +6,9 @@ from django.urls import path from . import views urlpatterns = [ - path('credentials//', views.PDFCredentialView.as_view(), - name="get-credentials"), + path( + "credentials//", + views.PDFCredentialView.as_view(), + name="get-credentials", + ), ] diff --git a/modoboa/pdfcredentials/api/v2/views.py b/modoboa/pdfcredentials/api/v2/views.py index d7ddc1f03..15f7fc581 100644 --- a/modoboa/pdfcredentials/api/v2/views.py +++ b/modoboa/pdfcredentials/api/v2/views.py @@ -19,7 +19,8 @@ from ...lib import rfc_6266_content_disposition class PDFCredentialView(APIView): permission_classes = ( - permissions.IsAuthenticated, permissions.DjangoModelPermissions, + permissions.IsAuthenticated, + permissions.DjangoModelPermissions, ) serializer_class = GetAccountCredentialsSerializer @@ -33,7 +34,8 @@ class PDFCredentialView(APIView): """View to download a document.""" data = {"account_id": kwargs["account_id"]} serializer = GetAccountCredentialsSerializer( - data=data, context={'request': request}) + data=data, context={"request": request} + ) serializer.is_valid(raise_exception=True) serializer.save() diff --git a/modoboa/pdfcredentials/app_settings.py b/modoboa/pdfcredentials/app_settings.py index 54ec06f10..e6f81a745 100644 --- a/modoboa/pdfcredentials/app_settings.py +++ b/modoboa/pdfcredentials/app_settings.py @@ -15,104 +15,176 @@ from modoboa.parameters import forms as param_forms from . import constants -PDF_CREDENTIALS_PARAMETERS_STRUCT = collections.OrderedDict([ - ("general", { - "label": _("General"), - "params": collections.OrderedDict([ - ("enabled_pdfcredentials", { - "label": _("Enable PDF credentials"), - "help_text": _( - "Enabled PDF credentials document generation on account creation."), - }) - ]) - }), - ("docstore", { - "label": _("Documents storage"), - "params": collections.OrderedDict([ - ("storage_dir", { - "label": _("Directory to save documents into"), - "help_text": _( - "Path to a directory where PDF documents will be saved"), - }), - ]) - }), - ("security", { - "label": _("Security options"), - "params": collections.OrderedDict([ - ("delete_first_dl", { - "label": _("Delete documents after the first download"), - "help_text": _( - "Automatically delete a document just after its first download " - "from this interface" - ) - }), - ("generate_at_creation", { - "label": _("Generate documents only at account creation"), - "help_text": _( - "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." - ) - }) - ]) - }), - ("customization", { - "label": _("Customization options"), - "params": collections.OrderedDict([ - ("title", { - "label": _("Title"), - "help_text": _("The document's title") - }), - ("webpanel_url", { - "label": _("Web panel url"), - "help_text": _("URL of the Modoboa web panel") - }), - ("custom_message", { - "label": _("Custom message"), - "help_text": _( - "A custom message that will appear at the end of documents" - ) - }), - ("include_connection_settings", { - "label": _("Include mail client connection settings"), - "help_text": _( - "Include required SMTP and IMAP connection information to " - "configure a mail client, a tablet or a phone" - ) - }), - ("smtp_server_address", { - "label": _("SMTP server address"), - "display": "include_connection_settings=True", - "help_text": _("Address of the SMTP server (hostname or IP)") - }), - ("smtp_server_port", { - "label": _("SMTP server port"), - "display": "include_connection_settings=true", - "help_text": _("Listening port of the SMTP server") - }), - ("smtp_connection_security", { - "label": _("SMTP connection security"), - "display": "include_connection_settings=true", - "help_text": _("Connection security mechanism") - }), - ("imap_server_address", { - "label": _("IMAP server address"), - "display": "include_connection_settings=true", - "help_text": _("Address of the IMAP server (hostname or IP)") - }), - ("imap_server_port", { - "label": _("IMAP server port"), - "display": "include_connection_settings=true", - "help_text": _("Listening port of the IMAP server") - }), - ("imap_connection_security", { - "label": _("IMAP connection security"), - "display": "include_connection_settings=true", - "help_text": _("Connection security mechanism") - }) - ]) - }) -]) +PDF_CREDENTIALS_PARAMETERS_STRUCT = collections.OrderedDict( + [ + ( + "general", + { + "label": _("General"), + "params": collections.OrderedDict( + [ + ( + "enabled_pdfcredentials", + { + "label": _("Enable PDF credentials"), + "help_text": _( + "Enabled PDF credentials document generation on account creation." + ), + }, + ) + ] + ), + }, + ), + ( + "docstore", + { + "label": _("Documents storage"), + "params": collections.OrderedDict( + [ + ( + "storage_dir", + { + "label": _("Directory to save documents into"), + "help_text": _( + "Path to a directory where PDF documents will be saved" + ), + }, + ), + ] + ), + }, + ), + ( + "security", + { + "label": _("Security options"), + "params": collections.OrderedDict( + [ + ( + "delete_first_dl", + { + "label": _("Delete documents after the first download"), + "help_text": _( + "Automatically delete a document just after its first download " + "from this interface" + ), + }, + ), + ( + "generate_at_creation", + { + "label": _( + "Generate documents only at account creation" + ), + "help_text": _( + "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." + ), + }, + ), + ] + ), + }, + ), + ( + "customization", + { + "label": _("Customization options"), + "params": collections.OrderedDict( + [ + ( + "title", + { + "label": _("Title"), + "help_text": _("The document's title"), + }, + ), + ( + "webpanel_url", + { + "label": _("Web panel url"), + "help_text": _("URL of the Modoboa web panel"), + }, + ), + ( + "custom_message", + { + "label": _("Custom message"), + "help_text": _( + "A custom message that will appear at the end of documents" + ), + }, + ), + ( + "include_connection_settings", + { + "label": _("Include mail client connection settings"), + "help_text": _( + "Include required SMTP and IMAP connection information to " + "configure a mail client, a tablet or a phone" + ), + }, + ), + ( + "smtp_server_address", + { + "label": _("SMTP server address"), + "display": "include_connection_settings=True", + "help_text": _( + "Address of the SMTP server (hostname or IP)" + ), + }, + ), + ( + "smtp_server_port", + { + "label": _("SMTP server port"), + "display": "include_connection_settings=true", + "help_text": _("Listening port of the SMTP server"), + }, + ), + ( + "smtp_connection_security", + { + "label": _("SMTP connection security"), + "display": "include_connection_settings=true", + "help_text": _("Connection security mechanism"), + }, + ), + ( + "imap_server_address", + { + "label": _("IMAP server address"), + "display": "include_connection_settings=true", + "help_text": _( + "Address of the IMAP server (hostname or IP)" + ), + }, + ), + ( + "imap_server_port", + { + "label": _("IMAP server port"), + "display": "include_connection_settings=true", + "help_text": _("Listening port of the IMAP server"), + }, + ), + ( + "imap_connection_security", + { + "label": _("IMAP connection security"), + "display": "include_connection_settings=true", + "help_text": _("Connection security mechanism"), + }, + ), + ] + ), + }, + ), + ] +) class ParametersForm(param_forms.AdminParametersForm): @@ -125,7 +197,7 @@ class ParametersForm(param_forms.AdminParametersForm): enabled_pdfcredentials = form_utils.YesNoField( label=_("Enable PDF credentials"), initial=True, - help_text=_("Enabled PDF credentials document generation on account creation.") + help_text=_("Enabled PDF credentials document generation on account creation."), ) docstore = form_utils.SeparatorField(label=_("Documents storage")) @@ -144,7 +216,7 @@ class ParametersForm(param_forms.AdminParametersForm): help_text=_( "Automatically delete a document just after its first download " "from this interface" - ) + ), ) generate_at_creation = form_utils.YesNoField( @@ -154,7 +226,7 @@ class ParametersForm(param_forms.AdminParametersForm): "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." - ) + ), ) customization = form_utils.SeparatorField(label=_("Customization options")) @@ -162,19 +234,17 @@ class ParametersForm(param_forms.AdminParametersForm): title = forms.CharField( label=_("Title"), initial=_("Personal account information"), - help_text=_("The document's title") + help_text=_("The document's title"), ) webpanel_url = forms.URLField( - label=_("Web panel url"), - help_text=_("URL of the Modoboa web panel") + label=_("Web panel url"), help_text=_("URL of the Modoboa web panel") ) custom_message = forms.CharField( label=_("Custom message"), - help_text=_( - "A custom message that will appear at the end of documents"), - required=False + help_text=_("A custom message that will appear at the end of documents"), + required=False, ) include_connection_settings = form_utils.YesNoField( @@ -183,43 +253,43 @@ class ParametersForm(param_forms.AdminParametersForm): help_text=_( "Include required SMTP and IMAP connection information to " "configure a mail client, a tablet or a phone" - ) + ), ) smtp_server_address = forms.CharField( label=_("SMTP server address"), - help_text=_("Address of the SMTP server (hostname or IP)") + help_text=_("Address of the SMTP server (hostname or IP)"), ) smtp_server_port = forms.IntegerField( label=_("SMTP server port"), initial=587, - help_text=_("Listening port of the SMTP server") + help_text=_("Listening port of the SMTP server"), ) smtp_connection_security = forms.ChoiceField( label=_("SMTP connection security"), choices=constants.CONNECTION_SECURITY_MODES, initial="starttls", - help_text=_("Connection security mechanism") + help_text=_("Connection security mechanism"), ) imap_server_address = forms.CharField( label=_("IMAP server address"), - help_text=_("Address of the IMAP server (hostname or IP)") + help_text=_("Address of the IMAP server (hostname or IP)"), ) imap_server_port = forms.IntegerField( label=_("IMAP server port"), initial=143, - help_text=_("Listening port of the IMAP server") + help_text=_("Listening port of the IMAP server"), ) imap_connection_security = forms.ChoiceField( label=_("IMAP connection security"), choices=constants.CONNECTION_SECURITY_MODES, initial="starttls", - help_text=_("Connection security mechanism") + help_text=_("Connection security mechanism"), ) visibility_rules = { diff --git a/modoboa/pdfcredentials/apps.py b/modoboa/pdfcredentials/apps.py index cb47c6bb0..45439ef86 100644 --- a/modoboa/pdfcredentials/apps.py +++ b/modoboa/pdfcredentials/apps.py @@ -16,12 +16,16 @@ def load_pdfcredential_settings(): from .api.v2 import serializers param_tools.registry.add( - "global", app_settings.ParametersForm, gettext_lazy("PDF credentials")) + "global", app_settings.ParametersForm, gettext_lazy("PDF credentials") + ) param_tools.registry.add2( - "global", "pdfcredentials", gettext_lazy("PDF Credentials"), + "global", + "pdfcredentials", + gettext_lazy("PDF Credentials"), app_settings.PDF_CREDENTIALS_PARAMETERS_STRUCT, serializers.PDFCredentialsSettingsSerializer, - True) + True, + ) class PDFCredentialsConfig(AppConfig): diff --git a/modoboa/pdfcredentials/constants.py b/modoboa/pdfcredentials/constants.py index 0dd979ccc..e3e7511b6 100644 --- a/modoboa/pdfcredentials/constants.py +++ b/modoboa/pdfcredentials/constants.py @@ -6,5 +6,5 @@ from django.utils.translation import gettext_lazy CONNECTION_SECURITY_MODES = [ ("none", gettext_lazy("None")), ("starttls", "STARTTLS"), - ("tls", "TLS") + ("tls", "TLS"), ] diff --git a/modoboa/pdfcredentials/documents.py b/modoboa/pdfcredentials/documents.py index edc2bc973..6a35f608e 100644 --- a/modoboa/pdfcredentials/documents.py +++ b/modoboa/pdfcredentials/documents.py @@ -8,8 +8,13 @@ from reportlab.lib.units import cm from reportlab.lib.enums import TA_CENTER from reportlab.lib import utils from reportlab.platypus import ( - SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Frame, - Image + SimpleDocTemplate, + Paragraph, + Spacer, + Table, + TableStyle, + Frame, + Image, ) from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle @@ -20,25 +25,28 @@ from modoboa.parameters import tools as param_tools from . import lib styles = getSampleStyleSheet() -styles.add(ParagraphStyle( - name="Footer", alignment=TA_CENTER, fontName="Helvetica-Oblique", - textColor=colors.lightgrey -)) -styles.add(ParagraphStyle( - name="Warning", fontName="Helvetica-Oblique", - textColor=colors.red, fontSize=12 -)) -styles.add(ParagraphStyle( - name="Link", - textColor=colors.blue -)) -styles.add(ParagraphStyle( - name="Greeting", alignment=TA_CENTER, fontName="Helvetica-Oblique", - fontSize=14 -)) +styles.add( + ParagraphStyle( + name="Footer", + alignment=TA_CENTER, + fontName="Helvetica-Oblique", + textColor=colors.lightgrey, + ) +) +styles.add( + ParagraphStyle( + name="Warning", fontName="Helvetica-Oblique", textColor=colors.red, fontSize=12 + ) +) +styles.add(ParagraphStyle(name="Link", textColor=colors.blue)) +styles.add( + ParagraphStyle( + name="Greeting", alignment=TA_CENTER, fontName="Helvetica-Oblique", fontSize=14 + ) +) -def resized_image(path, width=1*cm): +def resized_image(path, width=1 * cm): img = utils.ImageReader(path) iw, ih = img.getSize() aspect = ih / float(iw) @@ -52,56 +60,74 @@ def credentials(account, password): canvas.setTitle(_("Personal account information")) canvas.setAuthor(account.fullname) canvas.setCreator("Modoboa") - footer = [Paragraph(_("Powered by Modoboa - Mail hosting made simple"), - styles["Footer"])] + footer = [ + Paragraph( + _("Powered by Modoboa - Mail hosting made simple"), styles["Footer"] + ) + ] Frame(0, 0, 21 * cm, 2 * cm).addFromList(footer, canvas) - conf = dict( - param_tools.get_global_parameters("pdfcredentials")) + conf = dict(param_tools.get_global_parameters("pdfcredentials")) filename = lib.get_creds_filename(account) buff = BytesIO() doc = SimpleDocTemplate(buff, pagesize=A4) story = [] logo = lib.get_document_logo() if logo is not None: - story.append(resized_image(logo, 8*cm)) + story.append(resized_image(logo, 8 * cm)) story.append(Spacer(1, 1 * cm)) story.append(Paragraph(conf["title"], styles["Title"])) story.append(Spacer(1, 1 * cm)) - story.append(Paragraph(_(""" + story.append( + Paragraph( + _( + """ Dear %s, this document contains the credentials you will need to connect to Modoboa. Learn the content and destroy the document as soon as possible. -""") % account.fullname, styles["Normal"])) +""" + ) + % account.fullname, + styles["Normal"], + ) + ) story.append(Spacer(1, 0.2 * cm)) story.append(Paragraph(_("Web panel:"), styles["h3"])) data = [ ["URL", conf["webpanel_url"]], [_("Username"), account.username], - [_("Password"), password] + [_("Password"), password], ] table = Table(data) - table.setStyle(TableStyle([ - ('TEXTCOLOR', (1, 0), (1, 0), colors.blue), - ('GRID', (0, 0), (-1, -1), 1, colors.black), - ('BACKGROUND', (0, 0), (0, -1), colors.lightgrey), - ])) + table.setStyle( + TableStyle( + [ + ("TEXTCOLOR", (1, 0), (1, 0), colors.blue), + ("GRID", (0, 0), (-1, -1), 1, colors.black), + ("BACKGROUND", (0, 0), (0, -1), colors.lightgrey), + ] + ) + ) story.append(table) story.append(Spacer(1, 0.5 * cm)) - story.append(Paragraph(_(""" + story.append( + Paragraph( + _( + """ Here you can view your emails anytime online, create filters or manage your contacts. -"""), styles["Normal"])) +""" + ), + styles["Normal"], + ) + ) story.append(Spacer(1, 0.2 * cm)) - story.append(Paragraph( - _("Please change your password!"), - styles["Warning"])) + story.append(Paragraph(_("Please change your password!"), styles["Warning"])) if conf["include_connection_settings"]: story.append(Spacer(1, 1 * cm)) - story.append(Paragraph( - _("PC/Tablet/Smartphone configuration:"), styles["h3"])) + story.append(Paragraph(_("PC/Tablet/Smartphone configuration:"), styles["h3"])) story.append(Spacer(1, 0.2 * cm)) data = [ [_("SMTP server address"), conf["smtp_server_address"]], @@ -112,15 +138,21 @@ your contacts. [_("IMAP connection security"), conf["imap_connection_security"]], ] table = Table(data) - table.setStyle(TableStyle([ - ('GRID', (0, 0), (-1, -1), 1, colors.black), - ('BACKGROUND', (0, 0), (0, -1), colors.lightgrey), - ])) + table.setStyle( + TableStyle( + [ + ("GRID", (0, 0), (-1, -1), 1, colors.black), + ("BACKGROUND", (0, 0), (0, -1), colors.lightgrey), + ] + ) + ) story.append(table) story.append(Spacer(1, 0.5 * cm)) - story.append(Paragraph( - _("Use those settings for your computer, tablet or phone."), - styles["Normal"]) + story.append( + Paragraph( + _("Use those settings for your computer, tablet or phone."), + styles["Normal"], + ) ) if conf["custom_message"]: diff --git a/modoboa/pdfcredentials/handlers.py b/modoboa/pdfcredentials/handlers.py index cf8dfb360..c67ca2ec4 100644 --- a/modoboa/pdfcredentials/handlers.py +++ b/modoboa/pdfcredentials/handlers.py @@ -23,8 +23,7 @@ def password_updated(sender, account, password, created, **kwargs): """Create or update document.""" if not param_tools.get_global_parameter("enabled_pdfcredentials"): return - generate_at_creation = param_tools.get_global_parameter( - "generate_at_creation") + generate_at_creation = param_tools.get_global_parameter("generate_at_creation") if (generate_at_creation and not created) or account.is_superuser: return try: @@ -32,8 +31,11 @@ def password_updated(sender, account, password, created, **kwargs): except InternalError as e: logger = logging.getLogger("modoboa.admin") logger.error( - _("Failed to create PDF_credentials directory. " - "Please check the permissions or the path.")) + _( + "Failed to create PDF_credentials directory. " + "Please check the permissions or the path." + ) + ) credentials(account, password) @@ -51,13 +53,14 @@ def extra_account_actions(sender, account, **kwargs): fname = get_creds_filename(account) if not os.path.exists(fname): return [] - return [{ - "name": "get_credentials", - "url": reverse("pdfcredentials:account_credentials", - args=[account.id]), - "img": "fa fa-download", - "title": _("Retrieve user's credentials as a PDF document") - }] + return [ + { + "name": "get_credentials", + "url": reverse("pdfcredentials:account_credentials", args=[account.id]), + "img": "fa fa-download", + "title": _("Retrieve user's credentials as a PDF document"), + } + ] @receiver(admin_signals.extra_account_identities_actions) @@ -80,5 +83,5 @@ def extra_identities_actions(sender, account, **kwargs): "type": "download", "content_type": "application/pdf", "url": url, - "filename": os.path.basename(fname) + "filename": os.path.basename(fname), } diff --git a/modoboa/pdfcredentials/lib.py b/modoboa/pdfcredentials/lib.py index 895e202ca..72897fac9 100644 --- a/modoboa/pdfcredentials/lib.py +++ b/modoboa/pdfcredentials/lib.py @@ -25,15 +25,14 @@ def init_storage_dir(): return elif not os.access(storage_dir, os.W_OK) and os.path.exists(storage_dir): raise InternalError( - _("Can't write to selected directory to store PDF " - "documents") - ) + _("Can't write to selected directory to store PDF " "documents") + ) try: os.mkdir(storage_dir) except (OSError, IOError) as inst: raise InternalError( - _("Failed to create the directory that will contain " - "PDF documents (%s)") % inst + _("Failed to create the directory that will contain " "PDF documents (%s)") + % inst ) @@ -55,14 +54,10 @@ def _get_cipher(iv): """Return ready-to-user Cipher.""" key = smart_bytes(settings.SECRET_KEY[:32]) backend = default_backend() - return Cipher( - algorithms.AES(force_bytes(key)), - modes.CBC(iv), - backend=backend - ) + return Cipher(algorithms.AES(force_bytes(key)), modes.CBC(iv), backend=backend) -def crypt_and_save_to_file(content, filename, length, chunksize=64*512): +def crypt_and_save_to_file(content, filename, length, chunksize=64 * 512): """Crypt content and save it to a file.""" iv = os.urandom(16) cipher = _get_cipher(iv) @@ -82,11 +77,14 @@ def crypt_and_save_to_file(content, filename, length, chunksize=64*512): except FileNotFoundError as e: logger = logging.getLogger("modoboa.admin") logger.error( - _("Failed to create PDF_credentials file. " - "Please check the permissions or the path.")) + _( + "Failed to create PDF_credentials file. " + "Please check the permissions or the path." + ) + ) -def decrypt_file(filename, chunksize=24*1024): +def decrypt_file(filename, chunksize=24 * 1024): """Decrypt the content of a file and return it.""" buff = BytesIO() with open(filename, "rb") as fp: diff --git a/modoboa/pdfcredentials/tests/test_lib.py b/modoboa/pdfcredentials/tests/test_lib.py index 87366d542..c66aea3e2 100644 --- a/modoboa/pdfcredentials/tests/test_lib.py +++ b/modoboa/pdfcredentials/tests/test_lib.py @@ -34,9 +34,7 @@ class PDFCredentialsLibTestCase(ModoAPITestCase): data = { "username": f"{username}", "role": "SimpleUsers", - "mailbox": { - "use_domain_quota": True - }, + "mailbox": {"use_domain_quota": True}, "password": "Toto12345", "language": "fr", } @@ -62,16 +60,15 @@ class PDFCredentialsLibTestCase(ModoAPITestCase): fname = os.path.join(self.workdir, "{}.pdf".format(username)) self.assertTrue(os.path.exists(fname)) filebuff = lib.decrypt_file(fname) - self.assertIn("application/pdf", - Popen("/usr/bin/file -b --mime -", - shell=True, - stdout=PIPE, - stdin=PIPE) - .communicate(filebuff)[0].strip().decode() - ) + self.assertIn( + "application/pdf", + Popen("/usr/bin/file -b --mime -", shell=True, stdout=PIPE, stdin=PIPE) + .communicate(filebuff)[0] + .strip() + .decode(), + ) with open(fname, "r") as file: with self.assertRaises(UnicodeDecodeError): - Popen("/usr/bin/file -b --mime -", - shell=True, - stdout=PIPE, - stdin=PIPE).communicate(file.read(1024))[0].strip() + Popen( + "/usr/bin/file -b --mime -", shell=True, stdout=PIPE, stdin=PIPE + ).communicate(file.read(1024))[0].strip() diff --git a/modoboa/pdfcredentials/tests/test_views.py b/modoboa/pdfcredentials/tests/test_views.py index 48f2d9508..f4a1bdf57 100644 --- a/modoboa/pdfcredentials/tests/test_views.py +++ b/modoboa/pdfcredentials/tests/test_views.py @@ -36,14 +36,18 @@ class EventsTestCase(ModoTestCase): """Create a test account.""" values = { "username": username, - "first_name": "Tester", "last_name": "Toto", - "role": "SimpleUsers", "quota_act": True, - "is_active": True, "email": username, - "random_password": True, "stepid": 2 + "first_name": "Tester", + "last_name": "Toto", + "role": "SimpleUsers", + "quota_act": True, + "is_active": True, + "email": username, + "random_password": True, + "stepid": 2, } response = self.client.post( - reverse("admin:account_add"), values, - HTTP_X_REQUESTED_WITH="XMLHttpRequest") + reverse("admin:account_add"), values, HTTP_X_REQUESTED_WITH="XMLHttpRequest" + ) self.assertEqual(response.status_code, expected_status) return values @@ -60,8 +64,8 @@ class EventsTestCase(ModoTestCase): # Try to download the file response = self.client.get( - reverse("pdfcredentials:account_credentials", - args=[account.pk])) + reverse("pdfcredentials:account_credentials", args=[account.pk]) + ) self.assertEqual(response.status_code, 200) self.assertEqual(response["Content-Type"], "application/pdf") @@ -70,21 +74,17 @@ class EventsTestCase(ModoTestCase): # Try to download a second time response = self.client.get( - reverse("pdfcredentials:account_credentials", - args=[account.pk])) + reverse("pdfcredentials:account_credentials", args=[account.pk]) + ) self.assertContains(response, "No document available for this user") # Update account values.update({"language": "en"}) - self.ajax_post( - reverse("admin:account_change", args=[account.pk]), values - ) + self.ajax_post(reverse("admin:account_change", args=[account.pk]), values) self.assertFalse(os.path.exists(fname)) self.set_global_parameter("generate_at_creation", False) - self.ajax_post( - reverse("admin:account_change", args=[account.pk]), values - ) + self.ajax_post(reverse("admin:account_change", args=[account.pk]), values) self.assertTrue(os.path.exists(fname)) def test_with_connection_settings(self): @@ -107,9 +107,7 @@ class EventsTestCase(ModoTestCase): fname = os.path.join(self.workdir, "{}.pdf".format(values["username"])) self.assertTrue(os.path.exists(fname)) account = core_models.User.objects.get(username=values["username"]) - self.ajax_post( - reverse("admin:account_delete", args=[account.pk]), {} - ) + self.ajax_post(reverse("admin:account_delete", args=[account.pk]), {}) self.assertFalse(os.path.exists(fname)) @override_settings(MODOBOA_LOGO="modoboa.png") @@ -128,8 +126,8 @@ class EventsTestCase(ModoTestCase): # Try to download the file response = self.client.get( - reverse("pdfcredentials:account_credentials", - args=[account.pk])) + reverse("pdfcredentials:account_credentials", args=[account.pk]) + ) self.assertEqual(response.status_code, 200) self.assertEqual(response["Content-Type"], "application/pdf") @@ -137,18 +135,15 @@ class EventsTestCase(ModoTestCase): self.assertFalse(os.path.exists(fname)) # Delete account - self.ajax_post( - reverse("admin:account_delete", args=[account.pk]), {} - ) + self.ajax_post(reverse("admin:account_delete", args=[account.pk]), {}) def test_storage_dir_creation(self): """Test storage directory creation.""" self.set_global_parameter("storage_dir", "/nonexistentdir") - with self.assertLogs(logger='modoboa.admin', level='ERROR') as log: + with self.assertLogs(logger="modoboa.admin", level="ERROR") as log: resp = self._create_account("leon@test.com") self.assertIn( "ERROR:modoboa.admin:Failed to create PDF_credentials directory. " "Please check the permissions or the path.", - log.output + log.output, ) - diff --git a/modoboa/pdfcredentials/urls.py b/modoboa/pdfcredentials/urls.py index 9a13a5b3c..939ed979d 100644 --- a/modoboa/pdfcredentials/urls.py +++ b/modoboa/pdfcredentials/urls.py @@ -5,6 +5,9 @@ from . import views app_name = "pdfcredentials" urlpatterns = [ - path('credentials//', views.get_account_credentials, - name="account_credentials"), + path( + "credentials//", + views.get_account_credentials, + name="account_credentials", + ), ] diff --git a/modoboa/pdfcredentials/views.py b/modoboa/pdfcredentials/views.py index 9ee197585..4ef0257bb 100644 --- a/modoboa/pdfcredentials/views.py +++ b/modoboa/pdfcredentials/views.py @@ -5,9 +5,7 @@ import os from django.http import HttpResponse from django.utils.translation import gettext as _ -from django.contrib.auth.decorators import ( - login_required, permission_required -) +from django.contrib.auth.decorators import login_required, permission_required from modoboa.core.models import User from modoboa.lib.exceptions import ModoboaException, PermDeniedException diff --git a/modoboa/policyd/core.py b/modoboa/policyd/core.py index ed710293a..96a085bf0 100644 --- a/modoboa/policyd/core.py +++ b/modoboa/policyd/core.py @@ -37,6 +37,7 @@ def close_db_connections(func, *args, **kwargs): To use in threads. """ + def _close_db_connections(*args, **kwargs): ret = None try: @@ -45,6 +46,7 @@ def close_db_connections(func, *args, **kwargs): for conn in connections.all(): conn.close() return ret + return _close_db_connections @@ -77,10 +79,7 @@ def get_local_config(): @close_db_connections def get_notification_recipients(): """Return superadmins with a mailbox.""" - return ( - core_models.User.objects - .filter(is_superuser=True, mailbox__isnull=False) - ) + return core_models.User.objects.filter(is_superuser=True, mailbox__isnull=False) @close_db_connections @@ -94,16 +93,18 @@ def create_alarm(ltype, name): else: localpart, domain = split_mailbox(name) mailbox = admin_models.Mailbox.objects.get( - address=localpart, domain__name=domain) + address=localpart, domain__name=domain + ) mailbox.alarms.create( - domain=mailbox.domain, title=title, internal_name=internal_name) + domain=mailbox.domain, title=title, internal_name=internal_name + ) async def notify_limit_reached(ltype, name): """Send a notification to super admins about item.""" ltype_translations = { "account": gettext_lazy("account"), - "domain": gettext_lazy("domain") + "domain": gettext_lazy("domain"), } # We're going to execute sync code so we need an executor executor = concurrent.futures.ThreadPoolExecutor(max_workers=3) @@ -118,9 +119,9 @@ async def notify_limit_reached(ltype, name): for recipient in recipients: with translation.override(recipient.language): content = render_to_string( - "policyd/notifications/limit_reached.html", { - "ltype": ltype_translations[ltype], "name": name - }) + "policyd/notifications/limit_reached.html", + {"ltype": ltype_translations[ltype], "name": name}, + ) subject = _("[modoboa] Sending limit reached") msg = EmailMessage() msg["From"] = sender @@ -143,7 +144,9 @@ async def apply_policies(attributes): sasl_username = attributes.get("sasl_username") if not sasl_username: return SUCCESS_ACTION - rclient = aioredis.from_url(settings.REDIS_URL, encoding="utf-8", decode_responses=True) + rclient = aioredis.from_url( + settings.REDIS_URL, encoding="utf-8", decode_responses=True + ) decr_domain = False decr_user = False localpart, domain = split_mailbox(sasl_username) @@ -155,8 +158,7 @@ async def apply_policies(attributes): decr_domain = True if await rclient.hexists(constants.REDIS_HASHNAME, sasl_username): counter = await rclient.hget(constants.REDIS_HASHNAME, sasl_username) - logger.info("Account {} current counter: {}".format( - sasl_username, counter)) + logger.info("Account {} current counter: {}".format(sasl_username, counter)) if int(counter) <= 0: return FAILURE_ACTION decr_user = True @@ -212,8 +214,7 @@ async def new_connection(reader, writer): def get_next_execution_dt(): """Return next execution date and time.""" - return (timezone.now() + relativedelta(days=1)).replace( - hour=0, minute=0, second=0) + return (timezone.now() + relativedelta(days=1)).replace(hour=0, minute=0, second=0) @sync_to_async @@ -226,11 +227,10 @@ def get_domains_to_reset(): """ qset = admin_models.Domain.objects.filter(message_limit__isnull=False) admin_models.Alarm.objects.filter( - internal_name="limit_reached", domain__in=qset, - status=admin_constants.ALARM_OPENED - ).update( - status=admin_constants.ALARM_CLOSED, closed=timezone.now() - ) + internal_name="limit_reached", + domain__in=qset, + status=admin_constants.ALARM_OPENED, + ).update(status=admin_constants.ALARM_CLOSED, closed=timezone.now()) return list(qset) @@ -242,29 +242,27 @@ def get_mailboxes_to_reset(): We also close all associated alarms. """ - qset = ( - admin_models.Mailbox.objects.filter(message_limit__isnull=False) - .select_related("domain") - ) + qset = admin_models.Mailbox.objects.filter( + message_limit__isnull=False + ).select_related("domain") admin_models.Alarm.objects.filter( - internal_name="limit_reached", mailbox__in=qset, - status=admin_constants.ALARM_OPENED - ).update( - status=admin_constants.ALARM_CLOSED, closed=timezone.now() - ) + internal_name="limit_reached", + mailbox__in=qset, + status=admin_constants.ALARM_OPENED, + ).update(status=admin_constants.ALARM_CLOSED, closed=timezone.now()) return list(qset) async def reset_counters(): """Reset all counters.""" - rclient = aioredis.from_url(settings.REDIS_URL, encoding="utf-8", decode_responses=True) + rclient = aioredis.from_url( + settings.REDIS_URL, encoding="utf-8", decode_responses=True + ) logger.info("Resetting all counters") for domain in await get_domains_to_reset(): - await rclient.hset( - constants.REDIS_HASHNAME, domain.name, domain.message_limit) + await rclient.hset(constants.REDIS_HASHNAME, domain.name, domain.message_limit) for mb in await get_mailboxes_to_reset(): - await rclient.hset( - constants.REDIS_HASHNAME, mb.full_address, mb.message_limit) + await rclient.hset(constants.REDIS_HASHNAME, mb.full_address, mb.message_limit) await rclient.close() # reschedule asyncio.ensure_future(run_at(get_next_execution_dt(), reset_counters)) @@ -273,5 +271,6 @@ async def reset_counters(): def start_reset_counters_coro(): """Start coroutine.""" first_time = (timezone.now() + relativedelta(days=1)).replace( - hour=0, minute=0, second=0) + hour=0, minute=0, second=0 + ) asyncio.ensure_future(run_at(first_time, reset_counters)) diff --git a/modoboa/policyd/handlers.py b/modoboa/policyd/handlers.py index cbdcc366e..d4e05465f 100644 --- a/modoboa/policyd/handlers.py +++ b/modoboa/policyd/handlers.py @@ -17,9 +17,7 @@ def set_message_limit(instance, key): if old_message_limit == instance.message_limit: return rclient = redis.Redis( - host=settings.REDIS_HOST, - port=settings.REDIS_PORT, - db=settings.REDIS_QUOTA_DB + host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_QUOTA_DB ) if instance.message_limit is None: # delete existing key diff --git a/modoboa/policyd/management/commands/policy_daemon.py b/modoboa/policyd/management/commands/policy_daemon.py index 2808a5086..e1abc2948 100644 --- a/modoboa/policyd/management/commands/policy_daemon.py +++ b/modoboa/policyd/management/commands/policy_daemon.py @@ -27,8 +27,7 @@ class Command(BaseCommand): """Add command line arguments.""" parser.add_argument("--host", type=str, default="localhost") parser.add_argument("--port", type=int, default=9999) - parser.add_argument("--debug", action="store_true", - help="Enable debug mode") + parser.add_argument("--debug", action="store_true", help="Enable debug mode") def handle(self, *args, **options): """Entry point.""" @@ -41,17 +40,16 @@ class Command(BaseCommand): # Schedule reset task core.start_reset_counters_coro() - for signame in {'SIGINT', 'SIGTERM'}: + for signame in {"SIGINT", "SIGTERM"}: loop.add_signal_handler( - getattr(signal, signame), - functools.partial(ask_exit, signame, loop) + getattr(signal, signame), functools.partial(ask_exit, signame, loop) ) logger.info("Serving on {}".format(server.sockets[0].getsockname())) if options["debug"]: loop.set_debug(True) - logging.getLogger('asyncio').setLevel(logging.DEBUG) + logging.getLogger("asyncio").setLevel(logging.DEBUG) loop.run_forever() diff --git a/modoboa/policyd/tests.py b/modoboa/policyd/tests.py index d3bd97000..000e541f3 100644 --- a/modoboa/policyd/tests.py +++ b/modoboa/policyd/tests.py @@ -36,14 +36,13 @@ class RedisTestCaseMixin: self.rclient = redis.Redis( host=settings.REDIS_HOST, port=settings.REDIS_PORT, - db=settings.REDIS_QUOTA_DB + db=settings.REDIS_QUOTA_DB, ) self.rclient.set_response_callback("HGET", int) self.rclient.delete(constants.REDIS_HASHNAME) -class PolicyDaemonTestCase( - RedisTestCaseMixin, ParametersMixin, TransactionTestCase): +class PolicyDaemonTestCase(RedisTestCaseMixin, ParametersMixin, TransactionTestCase): """Test cases for policy daemon. A redis instance is required to run those tests. @@ -71,7 +70,7 @@ class PolicyDaemonTestCase( domain.save() self.assertEqual( self.rclient.hget(constants.REDIS_HASHNAME, domain.name), - domain.message_limit + domain.message_limit, ) return domain @@ -82,8 +81,7 @@ class PolicyDaemonTestCase( mb.message_limit = value mb.save() self.assertEqual( - self.rclient.hget(constants.REDIS_HASHNAME, account.email), - mb.message_limit + self.rclient.hget(constants.REDIS_HASHNAME, account.email), mb.message_limit ) return account @@ -108,25 +106,29 @@ class PolicyDaemonTestCase( s = self.connect_to_daemon() # This one will be accepted - s.send(b"""protocol_state=RCPT + s.send( + b"""protocol_state=RCPT sasl_username=user@test.com -""") +""" + ) res = s.recv(1024) self.assertEqual(res, b"action=dunno\n\n") self.assertEqual( self.rclient.hget(constants.REDIS_HASHNAME, domain.name), - domain.message_limit - 1 + domain.message_limit - 1, ) s.close() # This one will be accepted and will trigger a notification # but I can't check it yet s = self.connect_to_daemon() - s.send(b"""protocol_state=RCPT + s.send( + b"""protocol_state=RCPT sasl_username=user@test.com -""") +""" + ) time.sleep(0.1) res = s.recv(1024) self.assertEqual(res, b"action=dunno\n\n") @@ -134,10 +136,12 @@ sasl_username=user@test.com # This one will be denied s = self.connect_to_daemon() - s.send(b"""protocol_state=RCPT + s.send( + b"""protocol_state=RCPT sasl_username=user@test.com -""") +""" + ) res = s.recv(1024) self.assertEqual( res, b"action=defer_if_permit Daily limit reached, retry later\n\n" @@ -150,25 +154,29 @@ sasl_username=user@test.com s = self.connect_to_daemon() # This one will be accepted - s.send(b"""protocol_state=RCPT + s.send( + b"""protocol_state=RCPT sasl_username=user@test.com -""") +""" + ) res = s.recv(1024) self.assertEqual(res, b"action=dunno\n\n") self.assertEqual( self.rclient.hget(constants.REDIS_HASHNAME, account.email), - account.mailbox.message_limit - 1 + account.mailbox.message_limit - 1, ) s.close() # This one will be accepted and will trigger a notification # but I can't check it yet s = self.connect_to_daemon() - s.send(b"""protocol_state=RCPT + s.send( + b"""protocol_state=RCPT sasl_username=user@test.com -""") +""" + ) time.sleep(0.1) res = s.recv(1024) self.assertEqual(res, b"action=dunno\n\n") @@ -176,10 +184,12 @@ sasl_username=user@test.com # This one will be denied s = self.connect_to_daemon() - s.send(b"""protocol_state=RCPT + s.send( + b"""protocol_state=RCPT sasl_username=user@test.com -""") +""" + ) res = s.recv(1024) self.assertEqual( res, b"action=defer_if_permit Daily limit reached, retry later\n\n" @@ -202,10 +212,8 @@ sasl_username=user@test.com event_loop.run_until_complete(run_test()) event_loop.close() - self.assertEqual( - self.rclient.hget(constants.REDIS_HASHNAME, domain.name), 20) - self.assertEqual( - self.rclient.hget(constants.REDIS_HASHNAME, account.email), 10) + self.assertEqual(self.rclient.hget(constants.REDIS_HASHNAME, domain.name), 20) + self.assertEqual(self.rclient.hget(constants.REDIS_HASHNAME, account.email), 10) class ModelsTestCase(RedisTestCaseMixin, ModoTestCase): @@ -241,7 +249,7 @@ class ModelsTestCase(RedisTestCaseMixin, ModoTestCase): domain.save() self.assertEqual( self.rclient.hget(constants.REDIS_HASHNAME, domain.name), - domain.message_limit + domain.message_limit, ) # Force constructor call to fill _loaded_values @@ -250,11 +258,9 @@ class ModelsTestCase(RedisTestCaseMixin, ModoTestCase): domain.save() self.assertEqual( self.rclient.hget(constants.REDIS_HASHNAME, domain.name), - domain.message_limit + domain.message_limit, ) domain.message_limit = None domain.save() - self.assertFalse( - self.rclient.hexists(constants.REDIS_HASHNAME, domain.name) - ) + self.assertFalse(self.rclient.hexists(constants.REDIS_HASHNAME, domain.name)) diff --git a/modoboa/policyd/utils.py b/modoboa/policyd/utils.py index 23872ffe6..ca4b88c17 100644 --- a/modoboa/policyd/utils.py +++ b/modoboa/policyd/utils.py @@ -10,9 +10,7 @@ from . import constants def get_redis_connection(): """Return a client connection to Redis server.""" rclient = redis.Redis( - host=settings.REDIS_HOST, - port=settings.REDIS_PORT, - db=settings.REDIS_QUOTA_DB + host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_QUOTA_DB ) rclient.set_response_callback("HGET", int) return rclient diff --git a/modoboa/relaydomains/api/v1/serializers.py b/modoboa/relaydomains/api/v1/serializers.py index c4eab23a7..4461b45d2 100644 --- a/modoboa/relaydomains/api/v1/serializers.py +++ b/modoboa/relaydomains/api/v1/serializers.py @@ -21,16 +21,17 @@ class TransportSerializer(serializers.ModelSerializer): """Check fields based on backend.""" self.backend = tr_backends.manager.get_backend(data["service"]) if not self.backend: - raise serializers.ValidationError({ - "service": _("Unsupported service") - }) + raise serializers.ValidationError({"service": _("Unsupported service")}) data["_settings"] = json.loads(data["_settings"]) errors = self.backend.clean_fields(data["_settings"]) if errors: - raise serializers.ValidationError({ - "_settings": ",".join( - ["{}: {}".format(error[0], error[1]) for error in errors]) - }) + raise serializers.ValidationError( + { + "_settings": ",".join( + ["{}: {}".format(error[0], error[1]) for error in errors] + ) + } + ) return data @@ -42,10 +43,18 @@ class RelayDomainSerializer(serializers.ModelSerializer): class Meta: model = admin_models.Domain fields = ( - "pk", "name", "enabled", "transport", "enable_dkim", - "dkim_key_selector", "dkim_public_key" + "pk", + "name", + "enabled", + "transport", + "enable_dkim", + "dkim_key_selector", + "dkim_public_key", + ) + read_only_fields = ( + "pk", + "dkim_public_key", ) - read_only_fields = ("pk", "dkim_public_key", ) def create(self, validated_data): """Use backend to serialize data.""" diff --git a/modoboa/relaydomains/api/v1/tests.py b/modoboa/relaydomains/api/v1/tests.py index 55be375a3..7f3a1944b 100644 --- a/modoboa/relaydomains/api/v1/tests.py +++ b/modoboa/relaydomains/api/v1/tests.py @@ -16,23 +16,27 @@ class DataMixin(object): def setUpTestData(cls): # NOQA:N802 super(DataMixin, cls).setUpTestData() transport = tr_factories.TransportFactory( - pattern="test.com", _settings={ + pattern="test.com", + _settings={ "relay_target_host": "external.host.tld", "relay_target_port": 25, - "relay_verify_recipients": False - } + "relay_verify_recipients": False, + }, ) cls.domain1 = admin_factories.DomainFactory( - name="test.com", type="relaydomain", transport=transport) + name="test.com", type="relaydomain", transport=transport + ) transport = tr_factories.TransportFactory( - pattern="domain2.test", _settings={ + pattern="domain2.test", + _settings={ "relay_target_host": "external.host.tld", "relay_target_port": 25, - "relay_verify_recipients": True - } + "relay_verify_recipients": True, + }, ) cls.domain2 = admin_factories.DomainFactory( - name="test2.com", type="relaydomain", transport=transport) + name="test2.com", type="relaydomain", transport=transport + ) class RelayDomainAPITestCase(DataMixin, ModoAPITestCase): @@ -48,21 +52,16 @@ class RelayDomainAPITestCase(DataMixin, ModoAPITestCase): def test_create(self): """Test create service.""" url = reverse("api:relaydomain-list") - settings = { - "relay_target_host": "1.2.3.4" - } + settings = {"relay_target_host": "1.2.3.4"} data = { "name": "test3.com", - "transport": { - "service": "relay", - "_settings": json.dumps(settings) - } + "transport": {"service": "relay", "_settings": json.dumps(settings)}, } response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 400) self.assertEqual( response.data["transport"]["_settings"], - ["relay_target_port: This field is required"] + ["relay_target_port: This field is required"], ) settings.update({"relay_target_port": 25}) @@ -71,8 +70,10 @@ class RelayDomainAPITestCase(DataMixin, ModoAPITestCase): self.assertEqual(response.status_code, 201) domain = admin_models.Domain.objects.get(name="test3.com") self.assertEqual( - domain.transport.next_hop, "[{}]:{}".format( - settings["relay_target_host"], settings["relay_target_port"]) + domain.transport.next_hop, + "[{}]:{}".format( + settings["relay_target_host"], settings["relay_target_port"] + ), ) def test_update(self): @@ -82,10 +83,7 @@ class RelayDomainAPITestCase(DataMixin, ModoAPITestCase): settings.update({"relay_target_port": 1000}) data = { "name": "test3.com", - "transport": { - "service": "relay", - "_settings": json.dumps(settings) - } + "transport": {"service": "relay", "_settings": json.dumps(settings)}, } response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) @@ -93,8 +91,10 @@ class RelayDomainAPITestCase(DataMixin, ModoAPITestCase): self.domain1.transport.refresh_from_db() self.assertEqual(self.domain1.name, data["name"]) self.assertEqual( - self.domain1.transport.next_hop, "[{}]:{}".format( - settings["relay_target_host"], settings["relay_target_port"]) + self.domain1.transport.next_hop, + "[{}]:{}".format( + settings["relay_target_host"], settings["relay_target_port"] + ), ) def test_delete(self): @@ -105,4 +105,5 @@ class RelayDomainAPITestCase(DataMixin, ModoAPITestCase): with self.assertRaises(admin_models.Domain.DoesNotExist): self.domain1.refresh_from_db() self.assertFalse( - tr_models.Transport.objects.filter(pattern="test.com").exists()) + tr_models.Transport.objects.filter(pattern="test.com").exists() + ) diff --git a/modoboa/relaydomains/api/v1/urls.py b/modoboa/relaydomains/api/v1/urls.py index e11e61e64..38b81e00c 100644 --- a/modoboa/relaydomains/api/v1/urls.py +++ b/modoboa/relaydomains/api/v1/urls.py @@ -5,6 +5,5 @@ from rest_framework import routers from . import viewsets router = routers.SimpleRouter() -router.register( - r"relaydomains", viewsets.RelayDomainViewSet, basename="relaydomain") +router.register(r"relaydomains", viewsets.RelayDomainViewSet, basename="relaydomain") urlpatterns = router.urls diff --git a/modoboa/relaydomains/api/v1/viewsets.py b/modoboa/relaydomains/api/v1/viewsets.py index c47a92feb..c37aa7550 100644 --- a/modoboa/relaydomains/api/v1/viewsets.py +++ b/modoboa/relaydomains/api/v1/viewsets.py @@ -9,17 +9,21 @@ from modoboa.lib.viewsets import RevisionModelMixin from . import serializers -class RelayDomainViewSet(GetThrottleViewsetMixin, RevisionModelMixin, viewsets.ModelViewSet): +class RelayDomainViewSet( + GetThrottleViewsetMixin, RevisionModelMixin, viewsets.ModelViewSet +): """RelayDomain viewset.""" - permission_classes = [IsAuthenticated, DjangoModelPermissions, ] + permission_classes = [ + IsAuthenticated, + DjangoModelPermissions, + ] serializer_class = serializers.RelayDomainSerializer def get_queryset(self): """Filter queryset based on current user.""" - return ( - admin_models.Domain.objects.get_for_admin(self.request.user) - .filter(type="relaydomain") + return admin_models.Domain.objects.get_for_admin(self.request.user).filter( + type="relaydomain" ) def perform_destroy(self, instance): diff --git a/modoboa/relaydomains/forms.py b/modoboa/relaydomains/forms.py index 9b52086b4..34f00c1e4 100644 --- a/modoboa/relaydomains/forms.py +++ b/modoboa/relaydomains/forms.py @@ -43,10 +43,7 @@ class RelayDomainFormGeneral(tr_forms.TransportForm): class Meta: model = tr_models.Transport - exclude = [ - "creation", "pattern", "next_hop", "enabled", - "_settings" - ] + exclude = ["creation", "pattern", "next_hop", "enabled", "_settings"] def save(self, *args, **kwargs): """Custom save method.""" diff --git a/modoboa/relaydomains/handlers.py b/modoboa/relaydomains/handlers.py index a901052a4..96e634c32 100644 --- a/modoboa/relaydomains/handlers.py +++ b/modoboa/relaydomains/handlers.py @@ -19,7 +19,8 @@ def check_relaydomain_alias(sender, recipients, **kwargs): if not qset.exists(): return False qset = admin_models.Mailbox.objects.select_related("domain").filter( - domain__name=domain, address=localpart) + domain__name=domain, address=localpart + ) if qset.exists(): return False return True @@ -45,7 +46,7 @@ def register_postfix_maps(sender, **kwargs): return [ postfix_maps.RelayDomainsMap, postfix_maps.SplitedDomainsTransportMap, - postfix_maps.RelayRecipientVerification + postfix_maps.RelayRecipientVerification, ] @@ -57,34 +58,38 @@ def extra_domain_form(sender, user, **kwargs): domain = kwargs.get("domain") if not domain or domain.type != "relaydomain": return [] - return [{ - "id": "relaydomain", "title": _("Transport settings"), - "cls": forms.RelayDomainFormGeneral, - "formtpl": "transport/_transport_form.html" - }] + return [ + { + "id": "relaydomain", + "title": _("Transport settings"), + "cls": forms.RelayDomainFormGeneral, + "formtpl": "transport/_transport_form.html", + } + ] @receiver(admin_signals.get_domain_form_instances) def fill_domain_instances(sender, user, domain, **kwargs): """Fill the relaydomain form with the right instance.""" condition = ( - not user.has_perm("transport.change_transport") or - domain.type != "relaydomain" + not user.has_perm("transport.change_transport") or domain.type != "relaydomain" ) if condition: return {} - return { - "relaydomain": domain.transport - } + return {"relaydomain": domain.transport} @receiver(admin_signals.extra_domain_wizard_steps) def extra_wizard_step(sender, **kwargs): """Return a step to configure the relay settings.""" - return [forms.RelayDomainWizardStep( - "relay", forms.RelayDomainFormGeneral, _("Transport"), - "transport/_transport_form.html" - )] + return [ + forms.RelayDomainWizardStep( + "relay", + forms.RelayDomainFormGeneral, + _("Transport"), + "transport/_transport_form.html", + ) + ] @receiver(admin_signals.import_object) @@ -102,12 +107,10 @@ def update_recipient_access(sender, instance, **kwargs): return if instance._settings.get("relay_verify_recipients", False): models.RecipientAccess.objects.get_or_create( - pattern=instance.pattern, - defaults={"action": "reject_unverified_recipient"} + pattern=instance.pattern, defaults={"action": "reject_unverified_recipient"} ) else: - models.RecipientAccess.objects.filter( - pattern=instance.pattern).delete() + models.RecipientAccess.objects.filter(pattern=instance.pattern).delete() @receiver(signals.post_delete, sender=tr_models.Transport) diff --git a/modoboa/relaydomains/lib.py b/modoboa/relaydomains/lib.py index aa4f816a8..aecb0d284 100644 --- a/modoboa/relaydomains/lib.py +++ b/modoboa/relaydomains/lib.py @@ -12,17 +12,21 @@ def import_relaydomain(user, row, formopts): if len(row) != 7: raise BadRequest(_("Invalid line")) domain = admin_models.Domain( - name=row[1].strip(), type="relaydomain", quota=0, - enabled=(row[5].strip().lower() in ["true", "1", "yes", "y"]) + name=row[1].strip(), + type="relaydomain", + quota=0, + enabled=(row[5].strip().lower() in ["true", "1", "yes", "y"]), ) domain.save(creator=user) settings = { "relay_target_host": row[2].strip(), "relay_target_port": row[3].strip(), "relay_verify_recipients": ( - row[6].strip().lower() in ["true", "1", "yes", "y"]) + row[6].strip().lower() in ["true", "1", "yes", "y"] + ), } transport = tr_models.Transport( - pattern=domain.name, service="relay", _settings=settings) + pattern=domain.name, service="relay", _settings=settings + ) tr_backends.manager.get_backend("relay").serialize(transport) transport.save() diff --git a/modoboa/relaydomains/migrations/0001_initial.py b/modoboa/relaydomains/migrations/0001_initial.py index cd708a483..e24f8f88a 100644 --- a/modoboa/relaydomains/migrations/0001_initial.py +++ b/modoboa/relaydomains/migrations/0001_initial.py @@ -4,40 +4,88 @@ from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ - ('admin', '0002_migrate_from_modoboa_admin'), + ("admin", "0002_migrate_from_modoboa_admin"), ] operations = [ migrations.CreateModel( - name='RelayDomain', + name="RelayDomain", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('target_host', models.CharField(help_text='Remote destination of this domain', max_length=255, verbose_name='target host')), - ('verify_recipients', models.BooleanField(default=False, help_text='Check for valid recipients', verbose_name='verify recipients')), - ('dates', models.ForeignKey(to='admin.ObjectDates', on_delete=models.CASCADE)), - ('domain', models.OneToOneField(null=True, to='admin.Domain', on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ( + "target_host", + models.CharField( + help_text="Remote destination of this domain", + max_length=255, + verbose_name="target host", + ), + ), + ( + "verify_recipients", + models.BooleanField( + default=False, + help_text="Check for valid recipients", + verbose_name="verify recipients", + ), + ), + ( + "dates", + models.ForeignKey(to="admin.ObjectDates", on_delete=models.CASCADE), + ), + ( + "domain", + models.OneToOneField( + null=True, to="admin.Domain", on_delete=models.CASCADE + ), + ), ], options={ - 'ordering': ['domain__name'], - 'db_table': 'postfix_relay_domains_relaydomain', + "ordering": ["domain__name"], + "db_table": "postfix_relay_domains_relaydomain", }, bases=(models.Model,), ), migrations.CreateModel( - name='Service', + name="Service", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(help_text='The service name', unique=True, max_length=100, verbose_name='name')), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ( + "name", + models.CharField( + help_text="The service name", + unique=True, + max_length=100, + verbose_name="name", + ), + ), ], options={ - 'db_table': 'postfix_relay_domains_service', + "db_table": "postfix_relay_domains_service", }, bases=(models.Model,), ), migrations.AddField( - model_name='relaydomain', - name='service', - field=models.ForeignKey(to='relaydomains.Service', on_delete=models.CASCADE), + model_name="relaydomain", + name="service", + field=models.ForeignKey( + to="relaydomains.Service", on_delete=models.CASCADE + ), preserve_default=True, ), ] diff --git a/modoboa/relaydomains/migrations/0002_migrate_from_modoboa_admin_relaydomains.py b/modoboa/relaydomains/migrations/0002_migrate_from_modoboa_admin_relaydomains.py index 5fd89c6a3..8b28b733d 100644 --- a/modoboa/relaydomains/migrations/0002_migrate_from_modoboa_admin_relaydomains.py +++ b/modoboa/relaydomains/migrations/0002_migrate_from_modoboa_admin_relaydomains.py @@ -4,8 +4,7 @@ from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ - ('relaydomains', '0001_initial'), + ("relaydomains", "0001_initial"), ] - operations = [ - ] + operations = [] diff --git a/modoboa/relaydomains/migrations/0003_auto_20170116_1508.py b/modoboa/relaydomains/migrations/0003_auto_20170116_1508.py index bec153bd8..a49c7330b 100644 --- a/modoboa/relaydomains/migrations/0003_auto_20170116_1508.py +++ b/modoboa/relaydomains/migrations/0003_auto_20170116_1508.py @@ -5,18 +5,26 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('relaydomains', '0002_migrate_from_modoboa_admin_relaydomains'), + ("relaydomains", "0002_migrate_from_modoboa_admin_relaydomains"), ] operations = [ migrations.AddField( - model_name='relaydomain', - name='target_port', - field=models.IntegerField(default=25, help_text='Remote port of this domain', verbose_name='target host port'), + model_name="relaydomain", + name="target_port", + field=models.IntegerField( + default=25, + help_text="Remote port of this domain", + verbose_name="target host port", + ), ), migrations.AlterField( - model_name='relaydomain', - name='target_host', - field=models.CharField(help_text='Remote address (hostname or IP) of this domain', max_length=255, verbose_name='target host address'), + model_name="relaydomain", + name="target_host", + field=models.CharField( + help_text="Remote address (hostname or IP) of this domain", + max_length=255, + verbose_name="target host address", + ), ), ] diff --git a/modoboa/relaydomains/migrations/0004_auto_20161105_1424.py b/modoboa/relaydomains/migrations/0004_auto_20161105_1424.py index e426a035d..38ac8f5db 100644 --- a/modoboa/relaydomains/migrations/0004_auto_20161105_1424.py +++ b/modoboa/relaydomains/migrations/0004_auto_20161105_1424.py @@ -16,18 +16,18 @@ def move_dates(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('relaydomains', '0003_auto_20170116_1508'), + ("relaydomains", "0003_auto_20170116_1508"), ] operations = [ migrations.AddField( - model_name='relaydomain', - name='creation', + model_name="relaydomain", + name="creation", field=models.DateTimeField(default=django.utils.timezone.now), ), migrations.AddField( - model_name='relaydomain', - name='last_modification', + model_name="relaydomain", + name="last_modification", field=models.DateTimeField(null=True), ), migrations.RunPython(move_dates), diff --git a/modoboa/relaydomains/migrations/0005_auto_20161105_1426.py b/modoboa/relaydomains/migrations/0005_auto_20161105_1426.py index e51a96764..431cd49c6 100644 --- a/modoboa/relaydomains/migrations/0005_auto_20161105_1426.py +++ b/modoboa/relaydomains/migrations/0005_auto_20161105_1426.py @@ -5,12 +5,12 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('relaydomains', '0004_auto_20161105_1424'), + ("relaydomains", "0004_auto_20161105_1424"), ] operations = [ migrations.RemoveField( - model_name='relaydomain', - name='dates', + model_name="relaydomain", + name="dates", ), ] diff --git a/modoboa/relaydomains/migrations/0006_auto_20170215_0948.py b/modoboa/relaydomains/migrations/0006_auto_20170215_0948.py index 5f7ffd1ca..cdedfdba4 100644 --- a/modoboa/relaydomains/migrations/0006_auto_20170215_0948.py +++ b/modoboa/relaydomains/migrations/0006_auto_20170215_0948.py @@ -6,14 +6,16 @@ import django.utils.timezone class Migration(migrations.Migration): dependencies = [ - ('relaydomains', '0005_auto_20161105_1426'), + ("relaydomains", "0005_auto_20161105_1426"), ] operations = [ migrations.AlterField( - model_name='relaydomain', - name='last_modification', - field=models.DateTimeField(auto_now=True, default=django.utils.timezone.now), + model_name="relaydomain", + name="last_modification", + field=models.DateTimeField( + auto_now=True, default=django.utils.timezone.now + ), preserve_default=False, ), ] diff --git a/modoboa/relaydomains/migrations/0007_recipientaccess.py b/modoboa/relaydomains/migrations/0007_recipientaccess.py index aa2f81198..a14e02c34 100644 --- a/modoboa/relaydomains/migrations/0007_recipientaccess.py +++ b/modoboa/relaydomains/migrations/0007_recipientaccess.py @@ -5,16 +5,24 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('relaydomains', '0006_auto_20170215_0948'), + ("relaydomains", "0006_auto_20170215_0948"), ] operations = [ migrations.CreateModel( - name='RecipientAccess', + name="RecipientAccess", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('pattern', models.CharField(max_length=254, unique=True)), - ('action', models.CharField(max_length=40)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("pattern", models.CharField(max_length=254, unique=True)), + ("action", models.CharField(max_length=40)), ], ), ] diff --git a/modoboa/relaydomains/migrations/0008_auto_20171123_1653.py b/modoboa/relaydomains/migrations/0008_auto_20171123_1653.py index 1bc2fdda2..864f02723 100644 --- a/modoboa/relaydomains/migrations/0008_auto_20171123_1653.py +++ b/modoboa/relaydomains/migrations/0008_auto_20171123_1653.py @@ -17,8 +17,8 @@ def move_relaydomain_to_transport(apps, schema_editor): _settings={ "relay_target_host": rd.target_host, "relay_target_port": rd.target_port, - "relay_verify_recipients": rd.verify_recipients - } + "relay_verify_recipients": rd.verify_recipients, + }, ) rd.domain.transport = tr rd.domain.save(update_fields=["transport"]) @@ -26,7 +26,9 @@ def move_relaydomain_to_transport(apps, schema_editor): continue ra_to_create.append( RecipientAccess( - pattern=rd.domain.name, action="reject_unverified_recipient")) + pattern=rd.domain.name, action="reject_unverified_recipient" + ) + ) RecipientAccess.objects.bulk_create(ra_to_create) @@ -38,11 +40,9 @@ def forward(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('relaydomains', '0007_recipientaccess'), - ('transport', '0001_initial'), - ('admin', '0011_domain_transport'), + ("relaydomains", "0007_recipientaccess"), + ("transport", "0001_initial"), + ("admin", "0011_domain_transport"), ] - operations = [ - migrations.RunPython(move_relaydomain_to_transport, forward) - ] + operations = [migrations.RunPython(move_relaydomain_to_transport, forward)] diff --git a/modoboa/relaydomains/migrations/0009_auto_20171124_1508.py b/modoboa/relaydomains/migrations/0009_auto_20171124_1508.py index 11e03c988..579012af8 100644 --- a/modoboa/relaydomains/migrations/0009_auto_20171124_1508.py +++ b/modoboa/relaydomains/migrations/0009_auto_20171124_1508.py @@ -5,22 +5,22 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('relaydomains', '0008_auto_20171123_1653'), + ("relaydomains", "0008_auto_20171123_1653"), ] operations = [ migrations.RemoveField( - model_name='relaydomain', - name='domain', + model_name="relaydomain", + name="domain", ), migrations.RemoveField( - model_name='relaydomain', - name='service', + model_name="relaydomain", + name="service", ), migrations.DeleteModel( - name='RelayDomain', + name="RelayDomain", ), migrations.DeleteModel( - name='Service', + name="Service", ), ] diff --git a/modoboa/relaydomains/postfix_maps.py b/modoboa/relaydomains/postfix_maps.py index 074ba9e97..00b4e49c3 100644 --- a/modoboa/relaydomains/postfix_maps.py +++ b/modoboa/relaydomains/postfix_maps.py @@ -1,7 +1,7 @@ """Map file definitions for postfix.""" -class RelayDomainsMap(object): +class RelayDomainsMap(object): """Map file to list all relay domains.""" filename = "sql-relaydomains.cf" @@ -20,7 +20,6 @@ class RelayDomainsMap(object): class SplitedDomainsTransportMap(object): - """A transport map for splited domains. (ie. ones with both local and remote mailboxes) @@ -57,16 +56,9 @@ class SplitedDomainsTransportMap(object): class RelayRecipientVerification(object): - """A map file to enable recipient verification.""" filename = "sql-relay-recipient-verification.cf" - mysql = ( - "SELECT action FROM relaydomains_recipientaccess WHERE pattern='%d'" - ) - postgres = ( - "SELECT action FROM relaydomains_recipientaccess WHERE pattern='%d'" - ) - sqlite = ( - "SELECT action FROM relaydomains_recipientaccess WHERE pattern='%d'" - ) + mysql = "SELECT action FROM relaydomains_recipientaccess WHERE pattern='%d'" + postgres = "SELECT action FROM relaydomains_recipientaccess WHERE pattern='%d'" + sqlite = "SELECT action FROM relaydomains_recipientaccess WHERE pattern='%d'" diff --git a/modoboa/relaydomains/tests.py b/modoboa/relaydomains/tests.py index dd00901d4..3e2688c54 100644 --- a/modoboa/relaydomains/tests.py +++ b/modoboa/relaydomains/tests.py @@ -26,13 +26,10 @@ class Operations(object): "enabled": True, "stepid": "step3", "quota": 0, - "default_mailbox_quota": 0 + "default_mailbox_quota": 0, } values.update(kwargs) - return self.ajax_post( - reverse("admin:domain_add"), - values, status - ) + return self.ajax_post(reverse("admin:domain_add"), values, status) def _relay_domain_alias_operation(self, optype, domain, name, status=200): transport = tr_models.Transport.objects.get(pattern=domain.name) @@ -43,7 +40,7 @@ class Operations(object): "relay_target_port": transport._settings["relay_target_port"], "type": "relaydomain", "quota": domain.quota, - "default_mailbox_quota": domain.default_mailbox_quota + "default_mailbox_quota": domain.default_mailbox_quota, } aliases = [alias.name for alias in domain.domainalias_set.all()] if optype == "add": @@ -54,9 +51,7 @@ class Operations(object): fname = "aliases" if not cpt else "aliases_%d" % cpt values[fname] = alias return self.ajax_post( - reverse("admin:domain_change", - args=[domain.id]), - values, status + reverse("admin:domain_change", args=[domain.id]), values, status ) def _check_limit(self, name, curvalue, maxvalue): @@ -73,22 +68,23 @@ class RelayDomainsTestCase(ModoTestCase, Operations): super(RelayDomainsTestCase, cls).setUpTestData() admin_factories.populate_database() cls.transport = tr_factories.TransportFactory( - pattern="relaydomain.tld", service="relay", + pattern="relaydomain.tld", + service="relay", _settings={ "relay_target_host": "external.host.tld", "relay_target_port": "25", - "relay_verify_recipients": False - } + "relay_verify_recipients": False, + }, ) cls.dom = admin_factories.DomainFactory( - name="relaydomain.tld", type="relaydomain", - transport=cls.transport) - admin_factories.DomainAliasFactory( - name="relaydomainalias.tld", target=cls.dom) + name="relaydomain.tld", type="relaydomain", transport=cls.transport + ) + admin_factories.DomainAliasFactory(name="relaydomainalias.tld", target=cls.dom) admin_factories.MailboxFactory( - domain=cls.dom, address="local", + domain=cls.dom, + address="local", user__username="local@relaydomain.tld", - user__groups=("SimpleUsers", ) + user__groups=("SimpleUsers",), ) def test_domain_list_view(self): @@ -110,18 +106,17 @@ class RelayDomainsTestCase(ModoTestCase, Operations): """ self._create_relay_domain("relaydomain1.tld") transport = tr_models.Transport.objects.get(pattern="relaydomain1.tld") - self.assertEqual( - transport._settings["relay_target_host"], "external.host.tld") - self.assertEqual( - transport._settings["relay_verify_recipients"], False) + self.assertEqual(transport._settings["relay_target_host"], "external.host.tld") + self.assertEqual(transport._settings["relay_verify_recipients"], False) resp = self._create_relay_domain("test.com", 400) - self.assertEqual(resp["form_errors"]["name"][0], - "Domain with this Name already exists.") + self.assertEqual( + resp["form_errors"]["name"][0], "Domain with this Name already exists." + ) resp = self._create_relay_domain("relaydomainalias.tld", 400) self.assertEqual( resp["form_errors"]["name"][0], - "A domain alias with this name already exists" + "A domain alias with this name already exists", ) def test_create_relaydomainalias(self): @@ -132,22 +127,16 @@ class RelayDomainsTestCase(ModoTestCase, Operations): FIXME: add a check for domain alias. """ - self._relay_domain_alias_operation( - "add", self.dom, "relaydomainalias1.tld" - ) - resp = self._relay_domain_alias_operation( - "add", self.dom, "test.com", 400 - ) + self._relay_domain_alias_operation("add", self.dom, "relaydomainalias1.tld") + resp = self._relay_domain_alias_operation("add", self.dom, "test.com", 400) self.assertEqual( resp["form_errors"]["aliases_2"][0], - "A domain with this name already exists" - ) - resp = self._relay_domain_alias_operation( - "add", self.dom, self.dom.name, 400 + "A domain with this name already exists", ) + resp = self._relay_domain_alias_operation("add", self.dom, self.dom.name, 400) self.assertEqual( resp["form_errors"]["aliases_2"][0], - "A domain with this name already exists" + "A domain with this name already exists", ) def test_edit_relaydomain(self): @@ -163,26 +152,20 @@ class RelayDomainsTestCase(ModoTestCase, Operations): "relay_verify_recipients": True, "type": "relaydomain", "enabled": True, - "quota": 0, "default_mailbox_quota": 0 + "quota": 0, + "default_mailbox_quota": 0, } - self.ajax_post( - reverse("admin:domain_change", args=[self.dom.id]), - values - ) + self.ajax_post(reverse("admin:domain_change", args=[self.dom.id]), values) self.transport.refresh_from_db() - self.assertEqual( - self.transport._settings["relay_target_port"], 4040) + self.assertEqual(self.transport._settings["relay_target_port"], 4040) self.assertTrue( - models.RecipientAccess.objects.filter( - pattern=values["name"]).exists()) - values["relay_verify_recipients"] = False - self.ajax_post( - reverse("admin:domain_change", args=[self.dom.id]), - values + models.RecipientAccess.objects.filter(pattern=values["name"]).exists() ) + values["relay_verify_recipients"] = False + self.ajax_post(reverse("admin:domain_change", args=[self.dom.id]), values) self.assertFalse( - models.RecipientAccess.objects.filter( - pattern=values["name"]).exists()) + models.RecipientAccess.objects.filter(pattern=values["name"]).exists() + ) def test_relaydomain_domain_switch(self): """Check domain <-> relaydomain transitions.""" @@ -195,10 +178,9 @@ class RelayDomainsTestCase(ModoTestCase, Operations): "enabled": True, "service": "relay", "relay_target_host": self.transport._settings["relay_target_host"], - "relay_target_port": self.transport._settings["relay_target_port"] + "relay_target_port": self.transport._settings["relay_target_port"], } - self.ajax_post( - reverse("admin:domain_change", args=[domain_pk]), values) + self.ajax_post(reverse("admin:domain_change", args=[domain_pk]), values) with self.assertRaises(tr_models.Transport.DoesNotExist): self.transport.refresh_from_db() self.dom.refresh_from_db() @@ -208,13 +190,12 @@ class RelayDomainsTestCase(ModoTestCase, Operations): "type": "relaydomain", "enabled": True, "quota": 0, - "default_mailbox_quota": 0 + "default_mailbox_quota": 0, } - self.ajax_post( - reverse("admin:domain_change", args=[domain_pk]), values) + self.ajax_post(reverse("admin:domain_change", args=[domain_pk]), values) self.assertEqual( - admin_models.Domain.objects.get(name="relaydomain.tld").type, - "relaydomain") + admin_models.Domain.objects.get(name="relaydomain.tld").type, "relaydomain" + ) def test_edit_relaydomainalias(self): """Test the modification of a relay domain alias. @@ -228,22 +209,17 @@ class RelayDomainsTestCase(ModoTestCase, Operations): "relay_target_port": self.transport._settings["relay_target_port"], "type": "relaydomain", "aliases": "relaydomainalias.net", - "quota": 0, "default_mailbox_quota": 0 + "quota": 0, + "default_mailbox_quota": 0, } - self.ajax_post( - reverse("admin:domain_change", args=[self.dom.id]), - values - ) + self.ajax_post(reverse("admin:domain_change", args=[self.dom.id]), values) admin_models.DomainAlias.objects.get(name="relaydomainalias.net") with self.assertRaises(admin_models.DomainAlias.DoesNotExist): admin_models.DomainAlias.objects.get(name="relaydomainalias.tld") def test_delete_relaydomain(self): """Test the removal of a relay domain.""" - self.ajax_post( - reverse("admin:domain_delete", args=[self.dom.id]), - {} - ) + self.ajax_post(reverse("admin:domain_delete", args=[self.dom.id]), {}) with self.assertRaises(tr_models.Transport.DoesNotExist): self.transport.refresh_from_db() @@ -251,34 +227,33 @@ class RelayDomainsTestCase(ModoTestCase, Operations): """Test the removal of a recipient access.""" self.transport._settings["relay_verify_recipients"] = True self.transport.save() - self.ajax_post( - reverse("admin:domain_delete", args=[self.dom.id]), - {} - ) + self.ajax_post(reverse("admin:domain_delete", args=[self.dom.id]), {}) self.assertFalse( models.RecipientAccess.objects.filter( - pattern=self.transport.pattern).exists()) + pattern=self.transport.pattern + ).exists() + ) def test_alias_on_relaydomain(self): """Create an alias on a relay domain.""" values = { "address": "alias@relaydomain.tld", "recipients": "recipient@relaydomain.tld", - "enabled": True + "enabled": True, } self.ajax_post(reverse("admin:alias_add"), values) self.assertTrue( - admin_models.Alias.objects.filter( - address="alias@relaydomain.tld").exists()) + admin_models.Alias.objects.filter(address="alias@relaydomain.tld").exists() + ) values = { "address": "alias2@relaydomain.tld", "recipients": "local@relaydomain.tld", - "enabled": True + "enabled": True, } self.ajax_post(reverse("admin:alias_add"), values) self.assertTrue( - admin_models.Alias.objects.filter( - address="alias2@relaydomain.tld").exists()) + admin_models.Alias.objects.filter(address="alias2@relaydomain.tld").exists() + ) class ImportTestCase(ModoTestCase): @@ -286,16 +261,15 @@ class ImportTestCase(ModoTestCase): def test_webui_import(self): """Check if import from webui works.""" - f = ContentFile("relaydomain;relay.com;127.0.0.1;25;relay;True;True", - name="domains.csv") - self.client.post( - reverse("admin:domain_import"), { - "sourcefile": f - } + f = ContentFile( + "relaydomain;relay.com;127.0.0.1;25;relay;True;True", name="domains.csv" ) + self.client.post(reverse("admin:domain_import"), {"sourcefile": f}) self.assertTrue( admin_models.Domain.objects.filter( - name="relay.com", type="relaydomain").exists()) + name="relay.com", type="relaydomain" + ).exists() + ) class LimitsTestCase(ModoTestCase, Operations): @@ -306,11 +280,10 @@ class LimitsTestCase(ModoTestCase, Operations): super(LimitsTestCase, cls).setUpTestData() for name, _definition in limits_utils.get_user_limit_templates(): cls.localconfig.parameters.set_value( - "deflt_user_{0}_limit".format(name), 2, app="limits") + "deflt_user_{0}_limit".format(name), 2, app="limits" + ) cls.localconfig.save() - cls.user = UserFactory.create( - username="reseller", groups=("Resellers",) - ) + cls.user = UserFactory.create(username="reseller", groups=("Resellers",)) def setUp(self): """Initialize test.""" @@ -318,46 +291,32 @@ class LimitsTestCase(ModoTestCase, Operations): self.client.force_login(self.user) def test_relay_domains_limit(self): - self._create_relay_domain( - "relaydomain1.tld", quota=1, default_mailbox_quota=1) + self._create_relay_domain("relaydomain1.tld", quota=1, default_mailbox_quota=1) self._check_limit("domains", 1, 2) - self._create_relay_domain( - "relaydomain2.tld", quota=1, default_mailbox_quota=1) + self._create_relay_domain("relaydomain2.tld", quota=1, default_mailbox_quota=1) self._check_limit("domains", 2, 2) self._create_relay_domain("relaydomain3.tld", 403) self._check_limit("domains", 2, 2) domid = admin_models.Domain.objects.get(name="relaydomain2.tld").id - self.ajax_post( - reverse("admin:domain_delete", args=[domid]), {}) + self.ajax_post(reverse("admin:domain_delete", args=[domid]), {}) self._check_limit("domains", 1, 2) def test_relay_domain_aliases_limit(self): - self._create_relay_domain( - "relaydomain1.tld", quota=1, default_mailbox_quota=1) + self._create_relay_domain("relaydomain1.tld", quota=1, default_mailbox_quota=1) domain = admin_models.Domain.objects.get(name="relaydomain1.tld") - self._relay_domain_alias_operation( - "add", domain, "relay-domain-alias1.tld" - ) + self._relay_domain_alias_operation("add", domain, "relay-domain-alias1.tld") self._check_limit("domain_aliases", 1, 2) - self._relay_domain_alias_operation( - "add", domain, "relay-domain-alias2.tld" - ) + self._relay_domain_alias_operation("add", domain, "relay-domain-alias2.tld") self._check_limit("domain_aliases", 2, 2) self._relay_domain_alias_operation( "add", domain, "relay-domain-alias3.tld", 403 ) self._check_limit("domain_aliases", 2, 2) - self._relay_domain_alias_operation( - "delete", domain, "relay-domain-alias2.tld" - ) + self._relay_domain_alias_operation("delete", domain, "relay-domain-alias2.tld") self._check_limit("domain_aliases", 1, 2) class MapFilesTestCase(MapFilesTestCaseMixin, TestCase): - """Test case for relaydomains.""" - MAP_FILES = [ - "sql-relaydomains.cf", - "sql-relay-recipient-verification.cf" - ] + MAP_FILES = ["sql-relaydomains.cf", "sql-relay-recipient-verification.cf"] diff --git a/modoboa/relaydomains/transport.py b/modoboa/relaydomains/transport.py index a357f2b52..628be60bd 100644 --- a/modoboa/relaydomains/transport.py +++ b/modoboa/relaydomains/transport.py @@ -11,19 +11,32 @@ class RelayTransportBackend(backends.TransportBackend): name = "relay" settings = ( - {"name": "target_host", "label": _("target host address"), - "validator": "host_address"}, - {"name": "target_port", "label": _("target host port"), - "type": "int", "default": 25}, - {"name": "verify_recipients", "label": _("verify recipients"), - "type": "boolean", "required": False, "default": False}, + { + "name": "target_host", + "label": _("target host address"), + "validator": "host_address", + }, + { + "name": "target_port", + "label": _("target host port"), + "type": "int", + "default": 25, + }, + { + "name": "verify_recipients", + "label": _("verify recipients"), + "type": "boolean", + "required": False, + "default": False, + }, ) def serialize(self, transport): """Make sure next_hop is set.""" transport.next_hop = "[{}]:{}".format( transport._settings["relay_target_host"], - transport._settings["relay_target_port"]) + transport._settings["relay_target_port"], + ) backends.manager.register_backend(RelayTransportBackend) diff --git a/modoboa/test_settings.py b/modoboa/test_settings.py index 669959437..1e7457356 100644 --- a/modoboa/test_settings.py +++ b/modoboa/test_settings.py @@ -54,10 +54,7 @@ else: "HOST": "localhost", "PORT": os.environ.get("POSTGRES_PORT", "5432"), "ATOMIC_REQUESTS": True, - "OPTIONS": { - "client_encoding": "UTF8", - "sslmode": "disable" - }, + "OPTIONS": {"client_encoding": "UTF8", "sslmode": "disable"}, "TEST": { "CHARSET": "UTF8", }, diff --git a/modoboa/transport/api/v2/urls.py b/modoboa/transport/api/v2/urls.py index 816410035..3fe4372df 100644 --- a/modoboa/transport/api/v2/urls.py +++ b/modoboa/transport/api/v2/urls.py @@ -6,7 +6,6 @@ from . import viewsets router = routers.SimpleRouter() -router.register( - r"transports", viewsets.TransportViewSet, basename="transport") +router.register(r"transports", viewsets.TransportViewSet, basename="transport") urlpatterns = router.urls diff --git a/modoboa/transport/api/v2/viewsets.py b/modoboa/transport/api/v2/viewsets.py index c8f4b82f0..c8faebe60 100644 --- a/modoboa/transport/api/v2/viewsets.py +++ b/modoboa/transport/api/v2/viewsets.py @@ -12,11 +12,9 @@ from ... import backends class TransportViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): """Viewset for Transport.""" - permissions = (permissions.IsAuthenticated, ) + permissions = (permissions.IsAuthenticated,) - @extend_schema( - responses={200: serializers.TransportBackendSerializer} - ) + @extend_schema(responses={200: serializers.TransportBackendSerializer}) def list(self, request, *args, **kwargs): """Return the list of all defined transport backends.""" all_settings = backends.manager.get_all_backend_settings() diff --git a/modoboa/transport/backends.py b/modoboa/transport/backends.py index ab18bfaeb..85d5fe8bb 100644 --- a/modoboa/transport/backends.py +++ b/modoboa/transport/backends.py @@ -17,7 +17,7 @@ class TransportBackend(object): """Validate an host address syntax.""" validator_list = [ lib_validators.validate_hostname, - validators.validate_ipv46_address + validators.validate_ipv46_address, ] for validator in validator_list: try: @@ -77,11 +77,7 @@ class TransportBackendManager(object): def get_backend_list(self): """Return known backend list.""" return sorted( - ( - (key, key) - for key, backend in self.backends.items() - ), - key=lambda i: i[1] + ((key, key) for key, backend in self.backends.items()), key=lambda i: i[1] ) def get_backend_settings(self, name): diff --git a/modoboa/transport/constants.py b/modoboa/transport/constants.py index 80c50d66b..601e5755b 100644 --- a/modoboa/transport/constants.py +++ b/modoboa/transport/constants.py @@ -1,5 +1,3 @@ """Transport constants.""" -PERMISSIONS = { - -} +PERMISSIONS = {} diff --git a/modoboa/transport/factories.py b/modoboa/transport/factories.py index 332bd400a..37ecc8ffe 100644 --- a/modoboa/transport/factories.py +++ b/modoboa/transport/factories.py @@ -10,7 +10,7 @@ class TransportFactory(factory.django.DjangoModelFactory): class Meta: model = models.Transport - django_get_or_create = ("pattern", ) + django_get_or_create = ("pattern",) pattern = factory.Sequence(lambda n: "transport{}".format(n)) service = "relay" diff --git a/modoboa/transport/forms.py b/modoboa/transport/forms.py index 9d7ec1787..cfe61ba28 100644 --- a/modoboa/transport/forms.py +++ b/modoboa/transport/forms.py @@ -7,7 +7,7 @@ from . import backends, models TYPE_TO_FIELD_MAP = { "int": forms.IntegerField, "boolean": forms.BooleanField, - "string": forms.CharField + "string": forms.CharField, } @@ -32,7 +32,8 @@ class BackendSettingsMixin(object): if "widget" in setting: options["widget"] = setting["widget"] self.fields[fullname] = TYPE_TO_FIELD_MAP[ftype]( - label=setting["label"], required=False, **options) + label=setting["label"], required=False, **options + ) self.setting_field_names.append(fullname) def clean_backend_fields(self, name): @@ -45,8 +46,7 @@ class BackendSettingsMixin(object): """Set settings to JSON field.""" transport = super(BackendSettingsMixin, self).save(commit=False) transport._settings = { - name: self.cleaned_data[name] - for name in self.setting_field_names + name: self.cleaned_data[name] for name in self.setting_field_names } if commit: transport.save() diff --git a/modoboa/transport/migrations/0001_initial.py b/modoboa/transport/migrations/0001_initial.py index 450dc0d69..001c8b0da 100644 --- a/modoboa/transport/migrations/0001_initial.py +++ b/modoboa/transport/migrations/0001_initial.py @@ -6,21 +6,38 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='Transport', + name="Transport", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('pattern', models.CharField(max_length=254, unique=True, verbose_name='pattern')), - ('service', models.CharField(max_length=30, verbose_name='service')), - ('next_hop', models.CharField(blank=True, max_length=100, verbose_name='next hop')), - ('_settings', models.JSONField(default=dict)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "pattern", + models.CharField( + max_length=254, unique=True, verbose_name="pattern" + ), + ), + ("service", models.CharField(max_length=30, verbose_name="service")), + ( + "next_hop", + models.CharField( + blank=True, max_length=100, verbose_name="next hop" + ), + ), + ("_settings", models.JSONField(default=dict)), ], options={ - 'ordering': ['pattern'], + "ordering": ["pattern"], }, ), ] diff --git a/modoboa/transport/migrations/0002_auto_20180928_1520.py b/modoboa/transport/migrations/0002_auto_20180928_1520.py index c44052197..4fe35cb61 100644 --- a/modoboa/transport/migrations/0002_auto_20180928_1520.py +++ b/modoboa/transport/migrations/0002_auto_20180928_1520.py @@ -5,13 +5,15 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('transport', '0001_initial'), + ("transport", "0001_initial"), ] operations = [ migrations.AlterField( - model_name='transport', - name='pattern', - field=models.CharField(db_index=True, max_length=253, unique=True, verbose_name='pattern'), + model_name="transport", + name="pattern", + field=models.CharField( + db_index=True, max_length=253, unique=True, verbose_name="pattern" + ), ), ] diff --git a/modoboa/transport/migrations/0003_alter_transport__settings.py b/modoboa/transport/migrations/0003_alter_transport__settings.py index 79982d0d7..e1c715858 100644 --- a/modoboa/transport/migrations/0003_alter_transport__settings.py +++ b/modoboa/transport/migrations/0003_alter_transport__settings.py @@ -7,18 +7,20 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('transport', '0002_auto_20180928_1520'), + ("transport", "0002_auto_20180928_1520"), ] operations = [ migrations.AlterField( - model_name='transport', - name='_settings', + model_name="transport", + name="_settings", field=models.JSONField(default=dict), ), migrations.AlterField( - model_name='transport', - name='_settings', - field=models.JSONField(default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder), + model_name="transport", + name="_settings", + field=models.JSONField( + default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder + ), ), ] diff --git a/modoboa/transport/models.py b/modoboa/transport/models.py index edd96fb58..67f79da61 100644 --- a/modoboa/transport/models.py +++ b/modoboa/transport/models.py @@ -12,8 +12,7 @@ from . import backends class Transport(models.Model): """Transport table.""" - pattern = models.CharField( - _("pattern"), unique=True, max_length=253, db_index=True) + pattern = models.CharField(_("pattern"), unique=True, max_length=253, db_index=True) service = models.CharField(_("service"), max_length=30) next_hop = models.CharField(_("next hop"), max_length=100, blank=True) diff --git a/modoboa/transport/postfix_maps.py b/modoboa/transport/postfix_maps.py index 0be6fdcc2..35cb3caa8 100644 --- a/modoboa/transport/postfix_maps.py +++ b/modoboa/transport/postfix_maps.py @@ -1,5 +1,6 @@ """Map file definitions for postfix.""" + class TransportMap(object): """A transport map.""" diff --git a/modoboa/urls.py b/modoboa/urls.py index 9eaee8196..9f240ee04 100644 --- a/modoboa/urls.py +++ b/modoboa/urls.py @@ -9,7 +9,9 @@ from django.urls import include, path from django.views.i18n import JavaScriptCatalog from drf_spectacular.views import ( - SpectacularJSONAPIView, SpectacularSwaggerView, SpectacularRedocView + SpectacularJSONAPIView, + SpectacularSwaggerView, + SpectacularRedocView, ) from modoboa.admin.views import user as user_views @@ -17,39 +19,47 @@ from modoboa.core import signals as core_signals, views as core_views from modoboa.core.extensions import exts_pool urlpatterns = [ - path('jsi18n/', JavaScriptCatalog.as_view(), name="javascript-catalog"), - - path('ckeditor/upload/', login_required(cku_views.upload), - name="ckeditor_upload"), - path('ckeditor/browse/', login_required(cku_views.browse), - name="ckeditor_browse"), - - path('', include("modoboa.core.urls")), - path('admin/', include("modoboa.admin.urls")), - path('dnstools/', include("modoboa.dnstools.urls")), - path('pdfcredentials', include("modoboa.pdfcredentials.urls")), - path('stats/', include("modoboa.maillog.urls")), - path('dmarc/', include("modoboa.dmarc.urls")), - path('imap_migration/', include("modoboa.imap_migration.urls")), - - path('user/forward/', user_views.forward, name="user_forward"), - - path('accounts/password_reset/', core_views.PasswordResetView.as_view(), - name="password_reset"), - path('accounts/password_reset/done/', - auth_views.PasswordResetDoneView.as_view(), - name="password_reset_done"), - path('reset/confirm_code/', - core_views.VerifySMSCodeView.as_view(), - name="password_reset_confirm_code"), - path('reset/resend_code/', - core_views.ResendSMSCodeView.as_view(), - name="password_reset_resend_code"), - path('reset///', - auth_views.PasswordResetConfirmView.as_view(), - name="password_reset_confirm"), - path('reset/done/', auth_views.PasswordResetCompleteView.as_view(), - name="password_reset_complete"), + path("jsi18n/", JavaScriptCatalog.as_view(), name="javascript-catalog"), + path("ckeditor/upload/", login_required(cku_views.upload), name="ckeditor_upload"), + path("ckeditor/browse/", login_required(cku_views.browse), name="ckeditor_browse"), + path("", include("modoboa.core.urls")), + path("admin/", include("modoboa.admin.urls")), + path("dnstools/", include("modoboa.dnstools.urls")), + path("pdfcredentials", include("modoboa.pdfcredentials.urls")), + path("stats/", include("modoboa.maillog.urls")), + path("dmarc/", include("modoboa.dmarc.urls")), + path("imap_migration/", include("modoboa.imap_migration.urls")), + path("user/forward/", user_views.forward, name="user_forward"), + path( + "accounts/password_reset/", + core_views.PasswordResetView.as_view(), + name="password_reset", + ), + path( + "accounts/password_reset/done/", + auth_views.PasswordResetDoneView.as_view(), + name="password_reset_done", + ), + path( + "reset/confirm_code/", + core_views.VerifySMSCodeView.as_view(), + name="password_reset_confirm_code", + ), + path( + "reset/resend_code/", + core_views.ResendSMSCodeView.as_view(), + name="password_reset_resend_code", + ), + path( + "reset///", + auth_views.PasswordResetConfirmView.as_view(), + name="password_reset_confirm", + ), + path( + "reset/done/", + auth_views.PasswordResetCompleteView.as_view(), + name="password_reset_complete", + ), ] exts_pool.load_all() @@ -57,39 +67,46 @@ urlpatterns += exts_pool.get_urls() extra_routes = core_signals.extra_uprefs_routes.send(sender="urls") if extra_routes: - extra_routes = reduce( - lambda a, b: a + b, [route[1] for route in extra_routes]) + extra_routes = reduce(lambda a, b: a + b, [route[1] for route in extra_routes]) urlpatterns += extra_routes # API urls urlpatterns += [ # FIXME: legacy, to remove ASAP - path('docs/openapi.json', - SpectacularJSONAPIView.as_view(api_version="v1"), name='schema-v1-legacy'), - - path('api/schema-v1/', - SpectacularJSONAPIView.as_view(api_version="v1"), name='schema-v1'), - path('api/schema-v1/swagger/', - SpectacularSwaggerView.as_view(url_name='schema-v1'), - name='docs-index-v1'), - path('api/schema-v1/redoc/', - SpectacularRedocView.as_view(url_name='schema-v1')), - - path('api/schema-v2/', - SpectacularJSONAPIView.as_view(api_version="v2"), name='schema-v2'), - path('api/schema-v2/swagger/', - SpectacularSwaggerView.as_view(url_name='schema-v2'), - name='docs-index-v2'), - path('api/schema-v2/redoc/', - SpectacularRedocView.as_view(url_name='schema-v2')), - path('api/v1/', include("modoboa.urls_api_v1", namespace="v1")), - path('api/v2/', include("modoboa.urls_api_v2", namespace="v2")), + path( + "docs/openapi.json", + SpectacularJSONAPIView.as_view(api_version="v1"), + name="schema-v1-legacy", + ), + path( + "api/schema-v1/", + SpectacularJSONAPIView.as_view(api_version="v1"), + name="schema-v1", + ), + path( + "api/schema-v1/swagger/", + SpectacularSwaggerView.as_view(url_name="schema-v1"), + name="docs-index-v1", + ), + path("api/schema-v1/redoc/", SpectacularRedocView.as_view(url_name="schema-v1")), + path( + "api/schema-v2/", + SpectacularJSONAPIView.as_view(api_version="v2"), + name="schema-v2", + ), + path( + "api/schema-v2/swagger/", + SpectacularSwaggerView.as_view(url_name="schema-v2"), + name="docs-index-v2", + ), + path("api/schema-v2/redoc/", SpectacularRedocView.as_view(url_name="schema-v2")), + path("api/v1/", include("modoboa.urls_api_v1", namespace="v1")), + path("api/v2/", include("modoboa.urls_api_v2", namespace="v2")), ] if settings.DEBUG: from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.conf.urls.static import static + urlpatterns += staticfiles_urlpatterns() - urlpatterns += static( - settings.MEDIA_URL, document_root=settings.MEDIA_ROOT - ) + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/modoboa/urls_api_v1.py b/modoboa/urls_api_v1.py index 7697ba96b..36863abd2 100644 --- a/modoboa/urls_api_v1.py +++ b/modoboa/urls_api_v1.py @@ -7,10 +7,10 @@ from modoboa.core.extensions import exts_pool app_name = "api" urlpatterns = [ - path('', include("modoboa.core.api.v1.urls")), - path('', include("modoboa.admin.api.v1.urls")), - path('', include("modoboa.limits.api.v1.urls")), - path('', include("modoboa.relaydomains.api.v1.urls")) + path("", include("modoboa.core.api.v1.urls")), + path("", include("modoboa.admin.api.v1.urls")), + path("", include("modoboa.limits.api.v1.urls")), + path("", include("modoboa.relaydomains.api.v1.urls")), ] urlpatterns += exts_pool.get_urls(category="api") diff --git a/modoboa/urls_api_v2.py b/modoboa/urls_api_v2.py index 91ab85b39..9da57ae1a 100644 --- a/modoboa/urls_api_v2.py +++ b/modoboa/urls_api_v2.py @@ -7,17 +7,17 @@ from modoboa.core.extensions import exts_pool app_name = "api" urlpatterns = [ - path('', include("modoboa.core.api.v2.urls")), - path('', include("modoboa.admin.api.v2.urls")), - path('', include("modoboa.parameters.api.v2.urls")), - path('', include("modoboa.imap_migration.api.v2.urls")), - path('', include("modoboa.limits.api.v1.urls")), - path('', include("modoboa.relaydomains.api.v1.urls")), - path('', include("modoboa.dmarc.api.v2.urls")), - path('', include("modoboa.dnstools.api.v2.urls")), - path('', include("modoboa.maillog.api.v2.urls")), - path('', include("modoboa.transport.api.v2.urls")), - path('', include("modoboa.pdfcredentials.api.v2.urls")) + path("", include("modoboa.core.api.v2.urls")), + path("", include("modoboa.admin.api.v2.urls")), + path("", include("modoboa.parameters.api.v2.urls")), + path("", include("modoboa.imap_migration.api.v2.urls")), + path("", include("modoboa.limits.api.v1.urls")), + path("", include("modoboa.relaydomains.api.v1.urls")), + path("", include("modoboa.dmarc.api.v2.urls")), + path("", include("modoboa.dnstools.api.v2.urls")), + path("", include("modoboa.maillog.api.v2.urls")), + path("", include("modoboa.transport.api.v2.urls")), + path("", include("modoboa.pdfcredentials.api.v2.urls")), ] urlpatterns += exts_pool.get_urls(category="api") diff --git a/modoboa/version.py b/modoboa/version.py index 09e8459f7..bbb35225e 100644 --- a/modoboa/version.py +++ b/modoboa/version.py @@ -7,10 +7,10 @@ def local_scheme(version): def get_version(): from setuptools_scm import get_version as default_version - github_version = os.environ.get('GITHUB_REF_NAME', None) - github_type = os.environ.get('GITHUB_REF_TYPE', None) + + github_version = os.environ.get("GITHUB_REF_NAME", None) + github_type = os.environ.get("GITHUB_REF_TYPE", None) if github_version is not None and github_type == "tag": print(f"GITHUB_REF_NAME found, using version: {github_version}") return github_version return default_version(local_scheme=local_scheme) - diff --git a/pylintrc b/pylintrc index 7191ca562..2f7565b28 100644 --- a/pylintrc +++ b/pylintrc @@ -1,301 +1,271 @@ -[MASTER] +[MAIN] -# Specify a configuration file. -#rcfile= +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Clear in-memory caches upon conclusion of linting. Useful if running pylint +# in a server-like mode. +clear-cache-post-run=no + +# Load and enable all available extensions. Use --list-extensions to see a list +# all available extensions. +#enable-all-extensions= + +# In error mode, messages with a category besides ERROR or FATAL are +# suppressed, and no reports are done by default. Error mode is compatible with +# disabling specific errors. +#errors-only= + +# Always return a 0 (non-error) status code, even if lint errors are found. +# This is primarily useful in continuous integration scripts. +#exit-zero= + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-allow-list= + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. (This is an alternative name to extension-pkg-allow-list +# for backward compatibility.) +extension-pkg-whitelist= + +# Return non-zero exit code if any of these messages/categories are detected, +# even if score is above --fail-under value. Syntax same as enable. Messages +# specified are enabled, while categories only check already-enabled messages. +fail-on= + +# Specify a score threshold under which the program will exit with error. +fail-under=10 + +# Interpret the stdin as a python script, whose filename needs to be passed as +# the module_or_package argument. +#from-stdin= + +# Files or directories to be skipped. They should be base names, not paths. +ignore=CVS,migrations + +# Add files or directories matching the regular expressions patterns to the +# ignore-list. The regex matches against paths and can be in Posix or Windows +# format. Because '\\' represents the directory delimiter on Windows systems, +# it can't be used as an escape character. +ignore-paths= + +# Files or directories matching the regular expression patterns are skipped. +# The regex matches against base names, not paths. The default value ignores +# Emacs file locks +ignore-patterns=^\.# + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis). It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). #init-hook= -# Profiled execution. -profile=no +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use, and will cap the count on Windows to +# avoid hangs. +jobs=1 -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS,migrations +# Control the amount of potential inferred values when inferring a single +# object. This can help the performance when dealing with large functions or +# complex, nested conditions. +limit-inference-results=100 + +# List of plugins (as comma separated values of python module names) to load, +# usually to register additional checkers. +load-plugins= # Pickle collected data for later comparisons. persistent=yes -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= +# Minimum Python version to use for version dependent checks. Will default to +# the version used to run pylint. +py-version=3.11 -[MESSAGES CONTROL] +# Discover python modules and packages in the file system subtree. +recursive=no -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time. See also the "--disable" option for examples. -#enable= +# Add paths to the list of the source roots. Supports globbing patterns. The +# source root is an absolute path or a path relative to the current working +# directory used to determine a package namespace for modules located under the +# source root. +source-roots= -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once).You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use"--disable=all --enable=classes -# --disable=W" -disable=no-init,no-member,locally-disabled,too-few-public-methods,too-many-public-methods,too-many-ancestors +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no -[REPORTS] - -# Set the output format. Available formats are text, parseable, colorized, msvs -# (visual studio) and html. You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". -files-output=no - -# Tells whether to display a full report or only the messages -reports=yes - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Add a comment according to your evaluation note. This is used by the global -# evaluation report (RP0004). -comment=no - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= - - -[LOGGING] - -# Logging modules to check that the string format arguments are in logging -# function parameter format -logging-modules=logging - - -[FORMAT] - -# Maximum number of characters on a single line. -max-line-length=80 - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - -# List of optional constructs for which whitespace checking is disabled -no-space-check=trailing-comma,dict-separator - -# Maximum number of lines in a module -max-module-lines=1000 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - - -[SIMILARITIES] - -# Minimum lines number of a similarity. -min-similarity-lines=4 - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME,XXX,TODO +# In verbose mode, extra non-checker-related info will be displayed. +#verbose= [BASIC] -# Required attributes for module, separated by a comma -required-attributes= +# Naming style matching correct argument names. +argument-naming-style=snake_case -# List of builtins function names that should not be used, separated by a comma -bad-functions=map,filter,apply,input,file +# Regular expression matching correct argument names. Overrides argument- +# naming-style. If left empty, argument names will be checked with the set +# naming style. +#argument-rgx= -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_,tz,logger,pk,qs +# Naming style matching correct attribute names. +attr-naming-style=snake_case -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. If left empty, attribute names will be checked with the set naming +# style. +#attr-rgx= -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= +# Bad variable names which should always be refused, separated by a comma. +bad-names=foo, + bar, + baz, + toto, + tutu, + tata -# Include a hint for the correct naming format with invalid-name -include-naming-hint=no +# Bad variable names regexes, separated by a comma. If names match any regex, +# they will always be refused +bad-names-rgxs= -# Regular expression matching correct function names -function-rgx=[a-z_][a-z0-9_]{2,30}$ +# Naming style matching correct class attribute names. +class-attribute-naming-style=any -# Naming hint for function names -function-name-hint=[a-z_][a-z0-9_]{2,30}$ +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. If left empty, class attribute names will be checked +# with the set naming style. +#class-attribute-rgx= -# Regular expression matching correct variable names -variable-rgx=[a-z_][a-z0-9_]{2,30}$ +# Naming style matching correct class constant names. +class-const-naming-style=UPPER_CASE -# Naming hint for variable names -variable-name-hint=[a-z_][a-z0-9_]{2,30}$ +# Regular expression matching correct class constant names. Overrides class- +# const-naming-style. If left empty, class constant names will be checked with +# the set naming style. +#class-const-rgx= -# Regular expression matching correct constant names -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ +# Naming style matching correct class names. +class-naming-style=PascalCase -# Naming hint for constant names -const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ +# Regular expression matching correct class names. Overrides class-naming- +# style. If left empty, class names will be checked with the set naming style. +#class-rgx= -# Regular expression matching correct attribute names -attr-rgx=[a-z_][a-z0-9_]{2,30}$ +# Naming style matching correct constant names. +const-naming-style=UPPER_CASE -# Naming hint for attribute names -attr-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct argument names -argument-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for argument names -argument-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct class attribute names -class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Naming hint for class attribute names -class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Regular expression matching correct inline iteration names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Naming hint for inline iteration names -inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ - -# Regular expression matching correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Naming hint for class names -class-name-hint=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression matching correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Naming hint for module names -module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression matching correct method names -method-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for method names -method-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=__.*__ +# Regular expression matching correct constant names. Overrides const-naming- +# style. If left empty, constant names will be checked with the set naming +# style. +#const-rgx= # Minimum line length for functions/classes that require docstrings, shorter # ones are exempt. docstring-min-length=-1 +# Naming style matching correct function names. +function-naming-style=snake_case -[TYPECHECK] +# Regular expression matching correct function names. Overrides function- +# naming-style. If left empty, function names will be checked with the set +# naming style. +#function-rgx= -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes +# Good variable names which should always be accepted, separated by a comma. +good-names=i, + j, + k, + ex, + Run, + _ -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis -ignored-modules= +# Good variable names regexes, separated by a comma. If names match any regex, +# they will always be accepted +good-names-rgxs= -# List of classes names for which member attributes should not be checked -# (useful for classes with attributes dynamically set). -ignored-classes=SQLObject +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=no -# When zope mode is activated, add a predefined set of Zope acquired attributes -# to generated-members. -zope=no +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E0201 when accessed. Python regular -# expressions are accepted. -generated-members=REQUEST,acl_users,aq_parent +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. If left empty, inline iteration names will be checked +# with the set naming style. +#inlinevar-rgx= +# Naming style matching correct method names. +method-naming-style=snake_case -[VARIABLES] +# Regular expression matching correct method names. Overrides method-naming- +# style. If left empty, method names will be checked with the set naming style. +#method-rgx= -# Tells whether we should check for unused import in __init__ files. -init-import=no +# Naming style matching correct module names. +module-naming-style=snake_case -# A regular expression matching the name of dummy variables (i.e. expectedly -# not used). -dummy-variables-rgx=_$|dummy +# Regular expression matching correct module names. Overrides module-naming- +# style. If left empty, module names will be checked with the set naming style. +#module-rgx= -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ -[DESIGN] +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty -# Maximum number of arguments for function / method -max-args=5 +# Regular expression matching correct type alias names. If left empty, type +# alias names will be checked with the set naming style. +#typealias-rgx= -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.* +# Regular expression matching correct type variable names. If left empty, type +# variable names will be checked with the set naming style. +#typevar-rgx= -# Maximum number of locals for function / method body -max-locals=15 +# Naming style matching correct variable names. +variable-naming-style=snake_case -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of statements in function / method body -max-statements=50 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 +# Regular expression matching correct variable names. Overrides variable- +# naming-style. If left empty, variable names will be checked with the set +# naming style. +#variable-rgx= [CLASSES] -# List of interface methods to ignore, separated by a comma. This is used for -# instance to not check methods defines in Zope's Interface base class. -ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by +# Warn about protected attribute access inside special methods +check-protected-access-in-special-methods=no # List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp +defining-attr-methods=__init__, + __new__, + setUp, + asyncSetUp, + __post_init__ + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict,_fields,_replace,_source,_make,os._exit # List of valid names for the first argument in a class method. valid-classmethod-first-arg=cls @@ -304,26 +274,364 @@ valid-classmethod-first-arg=cls valid-metaclass-classmethod-first-arg=mcs -[IMPORTS] +[DESIGN] -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub,TERMIOS,Bastion,rexec +# List of regular expressions of class ancestor names to ignore when counting +# public methods (see R0903) +exclude-too-few-public-methods= -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= +# List of qualified class names to ignore when counting class parents (see +# R0901) +ignored-parents= -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= +# Maximum number of arguments for function / method. +max-args=5 -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement (see R0916). +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=12 + +# Maximum number of locals for function / method body. +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 [EXCEPTIONS] -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=Exception +# Exceptions that will emit a warning when caught. +overgeneral-exceptions=builtins.BaseException,builtins.Exception + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module. +max-module-lines=1000 + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[IMPORTS] + +# List of modules that can be imported at any level, not just the top level +# one. +allow-any-import-level= + +# Allow explicit reexports by alias from a package __init__. +allow-reexport-from-package=no + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules= + +# Output a graph (.gv or any supported image format) of external dependencies +# to the given file (report RP0402 must not be disabled). +ext-import-graph= + +# Output a graph (.gv or any supported image format) of all (i.e. internal and +# external) dependencies to the given file (report RP0402 must not be +# disabled). +import-graph= + +# Output a graph (.gv or any supported image format) of internal dependencies +# to the given file (report RP0402 must not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + +# Couples of modules and preferred modules, separated by a comma. +preferred-modules= + + +[LOGGING] + +# The type of string formatting that logging methods do. `old` means using % +# formatting, `new` is for `{}` formatting. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, +# UNDEFINED. +confidence=HIGH, + CONTROL_FLOW, + INFERENCE, + INFERENCE_FAILURE, + UNDEFINED + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then re-enable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=raw-checker-failed, + bad-inline-option, + locally-disabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + use-symbolic-message-instead, + no-member, + locally-disabled, + too-few-public-methods, + too-many-public-methods, + too-many-ancestors, + line-too-long + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[METHOD_ARGS] + +# List of qualified names (i.e., library.method) which require a timeout +# parameter e.g. 'requests.api.get,requests.api.post' +timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + +# Regular expression of note tags to take in consideration. +notes-rgx= + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit,argparse.parse_error + + +[REPORTS] + +# Python expression which should return a score less than or equal to 10. You +# have access to the variables 'fatal', 'error', 'warning', 'refactor', +# 'convention', and 'info' which contain the number of messages in each +# category, as well as 'statement' which is the total number of statements +# analyzed. This score is used by the global evaluation report (RP0004). +evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +#output-format= + +# Tells whether to display a full report or only the messages. +reports=no + +# Activate the evaluation score. +score=yes + + +[SIMILARITIES] + +# Comments are removed from the similarity computation +ignore-comments=yes + +# Docstrings are removed from the similarity computation +ignore-docstrings=yes + +# Imports are removed from the similarity computation +ignore-imports=yes + +# Signatures are removed from the similarity computation +ignore-signatures=yes + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 + +# Spelling dictionary name. No available dictionaries : You need to install +# both the python package and the system dependency for enchant to work.. +spelling-dict= + +# List of comma separated words that should be considered directives if they +# appear at the beginning of a comment and should not be checked. +spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains the private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to the private dictionary (see the +# --spelling-private-dict-file option) instead of raising a message. +spelling-store-unknown-words=no + + +[STRING] + +# This flag controls whether inconsistent-quotes generates a warning when the +# character used as a quote delimiter is used inconsistently within a module. +check-quote-consistency=no + +# This flag controls whether the implicit-str-concat should generate a warning +# on implicit string concatenation in sequences defined over several lines. +check-str-concat-over-line-jumps=no + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of symbolic message names to ignore for Mixin members. +ignored-checks-for-mixins=no-member, + not-async-context-manager, + not-context-manager, + attribute-defined-outside-init + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + +# Regex pattern to define which classes are considered mixins. +mixin-class-rgx=.*[Mm]ixin + +# List of decorators that change the signature of a decorated function. +signature-mutators= + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of names allowed to shadow builtins +allowed-redefined-builtins= + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io diff --git a/setup.py b/setup.py index 76446487b..c5c91f3eb 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,8 @@ if __name__ == "__main__": INSTALL_REQUIRES = get_requirements(path.join(HERE, "requirements.txt")) MYSQL_REQUIRES = get_requirements(path.join(HERE, "mysql-requirements.txt")) POSTGRESQL_REQUIRES = get_requirements( - path.join(HERE, "postgresql-requirements.txt")) + path.join(HERE, "postgresql-requirements.txt") + ) LDAP_REQUIRES = get_requirements(path.join(HERE, "ldap-requirements.txt")) with open(path.join(HERE, "README.rst")) as readme: @@ -47,7 +48,7 @@ if __name__ == "__main__": def local_scheme(version): """Skip the local version (eg. +xyz of 0.6.1.dev4+gdf99fe2) - to be able to upload to Test PyPI""" + to be able to upload to Test PyPI""" return "" setup( @@ -74,14 +75,13 @@ if __name__ == "__main__": ], keywords="email", packages=find_packages( - exclude=["doc", "test_data", "test_project", "frontend"]), + exclude=["doc", "test_data", "test_project", "frontend"] + ), include_package_data=True, zip_safe=False, scripts=["bin/modoboa-admin.py"], install_requires=INSTALL_REQUIRES, - use_scm_version={ - "local_scheme": local_scheme - }, + use_scm_version={"local_scheme": local_scheme}, python_requires=">=3.7", setup_requires=["setuptools_scm>6.4"], extras_require={ diff --git a/test_project/test_project/settings.py b/test_project/test_project/settings.py index 8a7299947..10b10b2a9 100644 --- a/test_project/test_project/settings.py +++ b/test_project/test_project/settings.py @@ -22,31 +22,31 @@ BASE_DIR = os.path.realpath(os.path.dirname(os.path.dirname(__file__))) # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '!8o(-dbbl3e+*bh7nx-^xysdt)1gso*%@4ze4-9_9o+i&t--u_' +SECRET_KEY = "!8o(-dbbl3e+*bh7nx-^xysdt)1gso*%@4ze4-9_9o+i&t--u_" # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = 'DEBUG' in os.environ +DEBUG = "DEBUG" in os.environ ALLOWED_HOSTS = [ - 'api', - '127.0.0.1', - 'localhost', + "api", + "127.0.0.1", + "localhost", ] -INTERNAL_IPS = ['127.0.0.1'] +INTERNAL_IPS = ["127.0.0.1"] SITE_ID = 1 -DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' +DEFAULT_AUTO_FIELD = "django.db.models.AutoField" # A list of all the people who get code error notifications. When DEBUG=False # and a view raises an exception, Django will email these people with the full # exception information. # See https://docs.djangoproject.com/en/dev/ref/settings/#admins -#ADMINS = [('Administrator', 'admin@example.net')] +# ADMINS = [('Administrator', 'admin@example.net')] # The email address that error messages come from, such as those sent to ADMINS -#SERVER_EMAIL = 'webmaster@example.net' +# SERVER_EMAIL = 'webmaster@example.net' # Security settings @@ -57,43 +57,43 @@ SESSION_COOKIE_SECURE = False # Application definition INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.sites', - 'django.contrib.staticfiles', - 'reversion', - 'ckeditor', - 'ckeditor_uploader', - 'rest_framework', - 'rest_framework.authtoken', - 'drf_spectacular', - 'django_otp', - 'django_otp.plugins.otp_totp', - 'django_otp.plugins.otp_static', - 'django_rename_app', - 'django_rq', + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.sites", + "django.contrib.staticfiles", + "reversion", + "ckeditor", + "ckeditor_uploader", + "rest_framework", + "rest_framework.authtoken", + "drf_spectacular", + "django_otp", + "django_otp.plugins.otp_totp", + "django_otp.plugins.otp_static", + "django_rename_app", + "django_rq", ) # A dedicated place to register Modoboa applications # Do not delete it. # Do not change the order. MODOBOA_APPS = ( - 'modoboa', - 'modoboa.core', - 'modoboa.lib', - 'modoboa.admin', - 'modoboa.transport', - 'modoboa.relaydomains', - 'modoboa.limits', - 'modoboa.parameters', - 'modoboa.dnstools', - 'modoboa.policyd', - 'modoboa.maillog', - 'modoboa.pdfcredentials', - 'modoboa.dmarc', - 'modoboa.imap_migration', + "modoboa", + "modoboa.core", + "modoboa.lib", + "modoboa.admin", + "modoboa.transport", + "modoboa.relaydomains", + "modoboa.limits", + "modoboa.parameters", + "modoboa.dnstools", + "modoboa.policyd", + "modoboa.maillog", + "modoboa.pdfcredentials", + "modoboa.dmarc", + "modoboa.imap_migration", # Modoboa extensions here. ) @@ -106,30 +106,30 @@ else: INSTALLED_APPS += MODOBOA_APPS -AUTH_USER_MODEL = 'core.User' +AUTH_USER_MODEL = "core.User" MIDDLEWARE = ( - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.locale.LocaleMiddleware', - 'x_forwarded_for.middleware.XForwardedForMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django_otp.middleware.OTPMiddleware', - 'modoboa.core.middleware.TwoFAMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'modoboa.core.middleware.LocalConfigMiddleware', - 'modoboa.lib.middleware.AjaxLoginRedirect', - 'modoboa.lib.middleware.CommonExceptionCatcher', - 'modoboa.lib.middleware.RequestCatcherMiddleware', + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.locale.LocaleMiddleware", + "x_forwarded_for.middleware.XForwardedForMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django_otp.middleware.OTPMiddleware", + "modoboa.core.middleware.TwoFAMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "modoboa.core.middleware.LocalConfigMiddleware", + "modoboa.lib.middleware.AjaxLoginRedirect", + "modoboa.lib.middleware.CommonExceptionCatcher", + "modoboa.lib.middleware.RequestCatcherMiddleware", ) AUTHENTICATION_BACKENDS = ( # 'modoboa.lib.authbackends.LDAPBackend', # 'modoboa.lib.authbackends.SMTPBackend', - 'django.contrib.auth.backends.ModelBackend', - 'modoboa.imap_migration.auth_backends.IMAPBackend', + "django.contrib.auth.backends.ModelBackend", + "modoboa.imap_migration.auth_backends.IMAPBackend", ) # SMTP authentication @@ -140,37 +140,37 @@ AUTHENTICATION_BACKENDS = ( TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.template.context_processors.i18n', - 'django.template.context_processors.media', - 'django.template.context_processors.static', - 'django.template.context_processors.tz', - 'django.contrib.messages.context_processors.messages', - 'modoboa.core.context_processors.top_notifications', - 'modoboa.core.context_processors.new_admin_url' + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.template.context_processors.i18n", + "django.template.context_processors.media", + "django.template.context_processors.static", + "django.template.context_processors.tz", + "django.contrib.messages.context_processors.messages", + "modoboa.core.context_processors.top_notifications", + "modoboa.core.context_processors.new_admin_url", ], - 'debug': DEBUG, + "debug": DEBUG, }, }, ] -ROOT_URLCONF = 'test_project.urls' +ROOT_URLCONF = "test_project.urls" -WSGI_APPLICATION = 'test_project.wsgi.application' +WSGI_APPLICATION = "test_project.wsgi.application" # Internationalization # https://docs.djangoproject.com/en/2.2/topics/i18n/ -LANGUAGE_CODE = 'en' +LANGUAGE_CODE = "en" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -181,72 +181,70 @@ USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.2/howto/static-files/ -STATIC_URL = '/sitestatic/' -STATIC_ROOT = os.path.join(BASE_DIR, 'sitestatic') -STATICFILES_DIRS = ( - os.path.join(BASE_DIR, '..', 'modoboa', 'bower_components'), -) +STATIC_URL = "/sitestatic/" +STATIC_ROOT = os.path.join(BASE_DIR, "sitestatic") +STATICFILES_DIRS = (os.path.join(BASE_DIR, "..", "modoboa", "bower_components"),) -MEDIA_URL = '/media/' -MEDIA_ROOT = os.path.join(BASE_DIR, 'media') +MEDIA_URL = "/media/" +MEDIA_ROOT = os.path.join(BASE_DIR, "media") # Rest framework settings REST_FRAMEWORK = { - 'DEFAULT_THROTTLE_RATES': { - 'user': '200/minute', - 'ddos': '10/second', - 'ddos_lesser': '200/minute', - 'login': '10/minute', - 'password_recovery_request': '11/hour', - 'password_recovery_totp_check': '25/hour', - 'password_recovery_apply': '25/hour' + "DEFAULT_THROTTLE_RATES": { + "user": "200/minute", + "ddos": "10/second", + "ddos_lesser": "200/minute", + "login": "10/minute", + "password_recovery_request": "11/hour", + "password_recovery_totp_check": "25/hour", + "password_recovery_apply": "25/hour", }, - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'modoboa.core.drf_authentication.JWTAuthenticationWith2FA', - 'rest_framework.authentication.TokenAuthentication', - 'rest_framework.authentication.SessionAuthentication', + "DEFAULT_AUTHENTICATION_CLASSES": ( + "modoboa.core.drf_authentication.JWTAuthenticationWith2FA", + "rest_framework.authentication.TokenAuthentication", + "rest_framework.authentication.SessionAuthentication", ), - 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', - 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning', + "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", + "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.NamespaceVersioning", } # Uncomment if you need a custom sub url for new_admin interface # NEW_ADMIN_URL = 'new-admin' SPECTACULAR_SETTINGS = { - 'SCHEMA_PATH_PREFIX': r'/api/v[0-9]', - 'TITLE': 'Modoboa API', - 'VERSION': None, - 'SERVE_PERMISSIONS': ['rest_framework.permissions.IsAuthenticated'], + "SCHEMA_PATH_PREFIX": r"/api/v[0-9]", + "TITLE": "Modoboa API", + "VERSION": None, + "SERVE_PERMISSIONS": ["rest_framework.permissions.IsAuthenticated"], } # Modoboa settings # MODOBOA_CUSTOM_LOGO = os.path.join(MEDIA_URL, "custom_logo.png") # DOVECOT_LOOKUP_PATH = ('/path/to/dovecot', ) -DOVECOT_USER="root" +DOVECOT_USER = "root" -MODOBOA_API_URL = 'https://api.modoboa.org/1/' +MODOBOA_API_URL = "https://api.modoboa.org/1/" -PID_FILE_STORAGE_PATH = '/tmp' +PID_FILE_STORAGE_PATH = "/tmp" # REDIS -REDIS_HOST = os.environ.get('REDIS_HOST', '127.0.0.1') -REDIS_PORT = os.environ.get('REDIS_PORT', 6379) +REDIS_HOST = os.environ.get("REDIS_HOST", "127.0.0.1") +REDIS_PORT = os.environ.get("REDIS_PORT", 6379) REDIS_QUOTA_DB = 0 -REDIS_URL = 'redis://{}:{}/{}'.format(REDIS_HOST, REDIS_PORT, REDIS_QUOTA_DB) +REDIS_URL = "redis://{}:{}/{}".format(REDIS_HOST, REDIS_PORT, REDIS_QUOTA_DB) # RQ RQ_QUEUES = { - 'dkim': { - 'URL': REDIS_URL, + "dkim": { + "URL": REDIS_URL, }, - 'modoboa': { - 'URL': REDIS_URL, + "modoboa": { + "URL": REDIS_URL, }, } @@ -254,8 +252,8 @@ RQ_QUEUES = { CACHES = { "default": { - "BACKEND": 'django.core.cache.backends.redis.RedisCache', - "LOCATION": f"redis://{REDIS_HOST}:{REDIS_PORT}" + "BACKEND": "django.core.cache.backends.redis.RedisCache", + "LOCATION": f"redis://{REDIS_HOST}:{REDIS_PORT}", } } @@ -264,25 +262,20 @@ CACHES = { AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, { - 'NAME': 'modoboa.core.password_validation.ComplexityValidator', - 'OPTIONS': { - 'upper': 1, - 'lower': 1, - 'digits': 1, - 'specials': 0 - } + "NAME": "modoboa.core.password_validation.ComplexityValidator", + "OPTIONS": {"upper": 1, "lower": 1, "digits": 1, "specials": 0}, }, ] @@ -299,21 +292,23 @@ CKEDITOR_BROWSE_SHOW_DIRS = True CKEDITOR_ALLOW_NONIMAGE_FILES = False CKEDITOR_CONFIGS = { - 'default': { - 'allowedContent': True, - 'toolbar': 'Modoboa', - 'width': None, - 'toolbar_Modoboa': [ - ['Bold', 'Italic', 'Underline'], - ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'], - ['BidiLtr', 'BidiRtl', 'Language'], - ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent'], - ['Undo', 'Redo'], - ['Link', 'Unlink', 'Anchor', '-', 'Smiley'], - ['TextColor', 'BGColor', '-', 'Source'], - ['Font', 'FontSize'], - ['Image', ], - ['SpellChecker'] + "default": { + "allowedContent": True, + "toolbar": "Modoboa", + "width": None, + "toolbar_Modoboa": [ + ["Bold", "Italic", "Underline"], + ["JustifyLeft", "JustifyCenter", "JustifyRight", "JustifyBlock"], + ["BidiLtr", "BidiRtl", "Language"], + ["NumberedList", "BulletedList", "-", "Outdent", "Indent"], + ["Undo", "Redo"], + ["Link", "Unlink", "Anchor", "-", "Smiley"], + ["TextColor", "BGColor", "-", "Source"], + ["Font", "FontSize"], + [ + "Image", + ], + ["SpellChecker"], ], }, } @@ -321,65 +316,53 @@ CKEDITOR_CONFIGS = { # Logging configuration LOGGING = { - 'version': 1, - 'formatters': { - 'syslog': { - 'format': '%(name)s: %(levelname)s %(message)s' - }, - 'django.server': { - '()': 'django.utils.log.ServerFormatter', - 'format': '[%(server_time)s] %(message)s', - } - }, - 'handlers': { - 'mail-admins': { - 'level': 'ERROR', - 'class': 'django.utils.log.AdminEmailHandler', - 'include_html': True - }, - 'syslog-auth': { - 'class': 'logging.handlers.SysLogHandler', - 'facility': SysLogHandler.LOG_AUTH, - 'formatter': 'syslog' - }, - 'modoboa': { - 'class': 'modoboa.core.loggers.SQLHandler', - }, - 'console': { - 'class': 'logging.StreamHandler' - }, - 'django.server': { - 'level': 'INFO', - 'class': 'logging.StreamHandler', - 'formatter': 'django.server', + "version": 1, + "formatters": { + "syslog": {"format": "%(name)s: %(levelname)s %(message)s"}, + "django.server": { + "()": "django.utils.log.ServerFormatter", + "format": "[%(server_time)s] %(message)s", }, }, - 'loggers': { - 'django': { - 'handlers': ['mail-admins'], - 'level': 'ERROR', - 'propagate': False + "handlers": { + "mail-admins": { + "level": "ERROR", + "class": "django.utils.log.AdminEmailHandler", + "include_html": True, }, - 'modoboa.auth': { - 'handlers': ['syslog-auth', 'modoboa'], - 'level': 'INFO', - 'propagate': False + "syslog-auth": { + "class": "logging.handlers.SysLogHandler", + "facility": SysLogHandler.LOG_AUTH, + "formatter": "syslog", }, - 'modoboa.admin': { - 'handlers': ['modoboa'], - 'level': 'INFO', - 'propagate': False + "modoboa": { + "class": "modoboa.core.loggers.SQLHandler", }, - 'django.server': { - 'handlers': ['django.server'], - 'level': 'INFO', - 'propagate': False, + "console": {"class": "logging.StreamHandler"}, + "django.server": { + "level": "INFO", + "class": "logging.StreamHandler", + "formatter": "django.server", + }, + }, + "loggers": { + "django": {"handlers": ["mail-admins"], "level": "ERROR", "propagate": False}, + "modoboa.auth": { + "handlers": ["syslog-auth", "modoboa"], + "level": "INFO", + "propagate": False, + }, + "modoboa.admin": {"handlers": ["modoboa"], "level": "INFO", "propagate": False}, + "django.server": { + "handlers": ["django.server"], + "level": "INFO", + "propagate": False, }, # 'django_auth_ldap': { # 'level': 'DEBUG', # 'handlers': ['console'] # }, - } + }, } SILENCED_SYSTEM_CHECKS = [ @@ -390,4 +373,4 @@ DISABLE_DASHBOARD_EXTERNAL_QUERIES = False # Load settings from extensions -LDAP_SERVER_PORT = os.environ.get('LDAP_SERVER_PORT', 3389) +LDAP_SERVER_PORT = os.environ.get("LDAP_SERVER_PORT", 3389) diff --git a/tests.py b/tests.py index df463c12e..db2cf2fe7 100644 --- a/tests.py +++ b/tests.py @@ -25,9 +25,14 @@ class DeployTest(unittest.TestCase): self.workdir = tempfile.mkdtemp() def test_silent(self): - dburl = "default:%s://%s:%s@%s:%s/%s" \ - % (self.dbtype, self.dbuser, self.dbpassword, - self.dbhost, self.dbport, self.projname) + dburl = "default:%s://%s:%s@%s:%s/%s" % ( + self.dbtype, + self.dbuser, + self.dbpassword, + self.dbhost, + self.dbport, + self.projname, + ) cmd = ( "modoboa-admin.py deploy --collectstatic " "--dburl %s --domain %s --admin-username admin %s"