Page MenuHomeWMGMC Issues

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/data/conf/rspamd/meta_exporter/pushover.php b/data/conf/rspamd/meta_exporter/pushover.php
index 974a282d..8db4d3d8 100644
--- a/data/conf/rspamd/meta_exporter/pushover.php
+++ b/data/conf/rspamd/meta_exporter/pushover.php
@@ -1,259 +1,262 @@
<?php
// File size is limited by Nginx site to 10M
// To speed things up, we do not include prerequisites
header('Content-Type: text/plain');
require_once "vars.inc.php";
// Do not show errors, we log to using error_log
ini_set('error_reporting', 0);
// Init database
//$dsn = $database_type . ':host=' . $database_host . ';dbname=' . $database_name;
$dsn = $database_type . ":unix_socket=" . $database_sock . ";dbname=" . $database_name;
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
}
catch (PDOException $e) {
error_log("NOTIFY: " . $e . PHP_EOL);
http_response_code(501);
exit;
}
// Init Redis
$redis = new Redis();
$redis->connect('redis-mailcow', 6379);
// Functions
function parse_email($email) {
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) return false;
$a = strrpos($email, '@');
return array('local' => substr($email, 0, $a), 'domain' => substr(substr($email, $a), 1));
}
if (!function_exists('getallheaders')) {
function getallheaders() {
if (!is_array($_SERVER)) {
return array();
}
$headers = array();
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') {
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
}
}
return $headers;
}
}
$headers = getallheaders();
$qid = $headers['X-Rspamd-Qid'];
$rcpts = $headers['X-Rspamd-Rcpt'];
$sender = $headers['X-Rspamd-From'];
$ip = $headers['X-Rspamd-Ip'];
$subject = $headers['X-Rspamd-Subject'];
$priority = 0;
$symbols_array = json_decode($headers['X-Rspamd-Symbols'], true);
if (is_array($symbols_array)) {
foreach ($symbols_array as $symbol) {
if ($symbol['name'] == 'HAS_X_PRIO_ONE') {
$priority = 1;
break;
}
}
}
$json = json_decode(file_get_contents('php://input'));
-$sender_address = $json->header_from ;
-if (preg_match('/[a-zA-Z0-9.!#$%&’*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)/i', $sender, $matches))
+$sender_address = $json->header_from[0];
+$sender_name = '-';
+if (preg_match('/[a-zA-Z0-9.!#$%&’*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)/i', $sender_address, $matches)) {
$sender_address = $matches[0];
-$sender_name = trim(str_replace('<' . $email . '>', '', $from));
+ $sender_name = trim(str_replace('<' . $sender_address . '>', '', $json->header_from[0]));
+}
$rcpt_final_mailboxes = array();
// Loop through all rcpts
foreach (json_decode($rcpts, true) as $rcpt) {
// Remove tag
$rcpt = preg_replace('/^(.*?)\+.*(@.*)$/', '$1$2', $rcpt);
// Break rcpt into local part and domain part
$parsed_rcpt = parse_email($rcpt);
// Skip if not a mailcow handled domain
try {
if (!$redis->hGet('DOMAIN_MAP', $parsed_rcpt['domain'])) {
continue;
}
}
catch (RedisException $e) {
error_log("NOTIFY: " . $e . PHP_EOL);
http_response_code(504);
exit;
}
// Always assume rcpt is not a final mailbox but an alias for a mailbox or further aliases
//
// rcpt
// |
// mailbox <-- goto ---> alias1, alias2, mailbox2
// | |
// mailbox3 |
// |
// alias3 ---> mailbox4
//
try {
$stmt = $pdo->prepare("SELECT `goto` FROM `alias` WHERE `address` = :rcpt AND `active` = '1'");
$stmt->execute(array(
':rcpt' => $rcpt
));
$gotos = $stmt->fetch(PDO::FETCH_ASSOC)['goto'];
if (empty($gotos)) {
$stmt = $pdo->prepare("SELECT `goto` FROM `alias` WHERE `address` = :rcpt AND `active` = '1'");
$stmt->execute(array(
':rcpt' => '@' . $parsed_rcpt['domain']
));
$gotos = $stmt->fetch(PDO::FETCH_ASSOC)['goto'];
}
if (empty($gotos)) {
$stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :rcpt AND `active` = '1'");
$stmt->execute(array(':rcpt' => $parsed_rcpt['domain']));
$goto_branch = $stmt->fetch(PDO::FETCH_ASSOC)['target_domain'];
if ($goto_branch) {
$gotos = $parsed_rcpt['local'] . '@' . $goto_branch;
}
}
$gotos_array = explode(',', $gotos);
$loop_c = 0;
while (count($gotos_array) != 0 && $loop_c <= 20) {
// Loop through all found gotos
foreach ($gotos_array as $index => &$goto) {
error_log("RCPT RESOVLER: http pipe: query " . $goto . " as username from mailbox" . PHP_EOL);
$stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `username` = :goto AND (`active`= '1' OR `active`= '2');");
$stmt->execute(array(':goto' => $goto));
$username = $stmt->fetch(PDO::FETCH_ASSOC)['username'];
if (!empty($username)) {
error_log("RCPT RESOVLER: http pipe: mailbox found: " . $username . PHP_EOL);
// Current goto is a mailbox, save to rcpt_final_mailboxes if not a duplicate
if (!in_array($username, $rcpt_final_mailboxes)) {
$rcpt_final_mailboxes[] = $username;
}
}
else {
$parsed_goto = parse_email($goto);
if (!$redis->hGet('DOMAIN_MAP', $parsed_goto['domain'])) {
error_log("RCPT RESOVLER:" . $goto . " is not a mailcow handled mailbox or alias address" . PHP_EOL);
}
else {
$stmt = $pdo->prepare("SELECT `goto` FROM `alias` WHERE `address` = :goto AND `active` = '1'");
$stmt->execute(array(':goto' => $goto));
$goto_branch = $stmt->fetch(PDO::FETCH_ASSOC)['goto'];
if ($goto_branch) {
error_log("RCPT RESOVLER: http pipe: goto address " . $goto . " is an alias branch for " . $goto_branch . PHP_EOL);
$goto_branch_array = explode(',', $goto_branch);
} else {
$stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain` = :domain AND `active` AND '1'");
$stmt->execute(array(':domain' => $parsed_goto['domain']));
$goto_branch = $stmt->fetch(PDO::FETCH_ASSOC)['target_domain'];
if ($goto_branch) {
error_log("RCPT RESOVLER: http pipe: goto domain " . $parsed_goto['domain'] . " is a domain alias branch for " . $goto_branch . PHP_EOL);
$goto_branch_array = array($parsed_goto['local'] . '@' . $goto_branch);
}
}
}
}
// goto item was processed, unset
unset($gotos_array[$index]);
}
// Merge goto branch array derived from previous loop (if any), filter duplicates and unset goto branch array
if (!empty($goto_branch_array)) {
$gotos_array = array_unique(array_merge($gotos_array, $goto_branch_array));
unset($goto_branch_array);
}
// Reindex array
$gotos_array = array_values($gotos_array);
// Force exit if loop cannot be solved
// Postfix does not allow for alias loops, so this should never happen.
$loop_c++;
error_log("RCPT RESOVLER: http pipe: goto array count on loop #". $loop_c . " is " . count($gotos_array) . PHP_EOL);
}
}
catch (PDOException $e) {
error_log("RCPT RESOVLER: " . $e->getMessage() . PHP_EOL);
http_response_code(502);
exit;
}
}
foreach ($rcpt_final_mailboxes as $rcpt_final) {
error_log("NOTIFY: pushover pipe: processing pushover message for rcpt " . $rcpt_final . PHP_EOL);
$stmt = $pdo->prepare("SELECT * FROM `pushover`
WHERE `username` = :username AND `active` = '1'");
$stmt->execute(array(
':username' => $rcpt_final
));
$api_data = $stmt->fetch(PDO::FETCH_ASSOC);
if (isset($api_data['key']) && isset($api_data['token'])) {
$title = (!empty($api_data['title'])) ? $api_data['title'] : 'Mail';
$text = (!empty($api_data['text'])) ? $api_data['text'] : 'You\'ve got mail 📧';
$attributes = json_decode($api_data['attributes'], true);
$senders = explode(',', $api_data['senders']);
$senders = array_filter($senders);
$senders_regex = $api_data['senders_regex'];
$sender_validated = false;
if (empty($senders) && empty($senders_regex)) {
$sender_validated = true;
}
else {
if (!empty($senders)) {
if (in_array($sender, $senders)) {
$sender_validated = true;
}
}
if (!empty($senders_regex) && $sender_validated !== true) {
if (preg_match($senders_regex, $sender)) {
$sender_validated = true;
}
}
}
if ($sender_validated === false) {
error_log("NOTIFY: pushover pipe: skipping unwanted sender " . $sender);
continue;
}
if ($attributes['only_x_prio'] == "1" && $priority == 0) {
error_log("NOTIFY: pushover pipe: mail has no X-Priority: 1 header, skipping");
continue;
}
$post_fields = array(
"token" => $api_data['token'],
"user" => $api_data['key'],
"title" => sprintf("%s", str_replace(array('{SUBJECT}', '{SENDER}', '{SENDER_NAME}', '{SENDER_ADDRESS}'), array($subject, $sender, $sender_name, $sender_address), $title)),
"priority" => $priority,
- "message" => sprintf("%s", str_replace(array('{SUBJECT}', '{SENDER}', '{SENDER_NAME}', '{SENDER_ADDRESS}'), array($subject, $sender, $sender_name, $sender_address), $text))
+ "message" => sprintf("%s", str_replace(array('{SUBJECT}', '{SENDER}', '{SENDER_NAME}', '{SENDER_ADDRESS}'), array($subject, $sender, $sender_name, $sender_address), $text)),
+ "sound" => $attributes['sound'] ?? "pushover"
);
if ($attributes['evaluate_x_prio'] == "1" && $priority == 1) {
$post_fields['expire'] = 600;
$post_fields['retry'] = 120;
$post_fields['priority'] = 2;
}
curl_setopt_array($ch = curl_init(), array(
CURLOPT_URL => "https://api.pushover.net/1/messages.json",
CURLOPT_POSTFIELDS => $post_fields,
CURLOPT_SAFE_UPLOAD => true,
CURLOPT_RETURNTRANSFER => true,
));
$result = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
error_log("NOTIFY: result: " . $httpcode . PHP_EOL);
}
}
diff --git a/data/web/api/openapi.yaml b/data/web/api/openapi.yaml
index c23380f1..6310aa58 100644
--- a/data/web/api/openapi.yaml
+++ b/data/web/api/openapi.yaml
@@ -1,5599 +1,5604 @@
openapi: 3.0.0
info:
description: >-
mailcow is complete e-mailing solution with advanced antispam, antivirus,
nice UI and API.
In order to use this API you have to create a API key and add your IP
address to the whitelist of allowed IPs this can be done by logging into the
Mailcow UI using your admin account, then go to Configuration > Access >
Edit administrator details > API. There you will find a collapsed API menu.
There are two types of API keys
- The read only key can only be used for all get endpoints
- The read write key can be used for all endpoints
title: mailcow API
version: "1.0.0"
servers:
- url: /
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
responses:
Unauthorized:
description: Unauthorized
content:
application/json:
schema:
type: object
properties:
type:
type: string
example: error
msg:
type: string
example: authentication failed
required:
- type
- msg
security:
- ApiKeyAuth: []
paths:
/api/v1/add/alias:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- add
- alias
- active: "1"
address: alias@domain.tld
goto: destination@domain.tld
- null
msg:
- alias_added
- alias@domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Aliases
description: >-
You may create your own mailbox alias using this action. It takes a JSON
object containing a domain informations.
Only one `goto*` option can be used, for ex. if you want learn as spam,
then send just `goto_spam = 1` in request body.
operationId: Create alias
requestBody:
content:
application/json:
schema:
example:
active: "1"
address: alias@domain.tld
goto: destination@domain.tld
properties:
active:
description: is alias active or not
type: boolean
address:
description: 'alias address, for catchall use "@domain.tld"'
type: string
goto:
description: "destination address, comma separated"
type: string
goto_ham:
description: learn as ham
type: boolean
goto_null:
description: silently ignore
type: boolean
goto_spam:
description: learn as spam
type: boolean
sogo_visible:
description: toggle visibility as selectable sender in SOGo
type: boolean
type: object
summary: Create alias
/api/v1/add/time_limited_alias:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- add
- time_limited_alias
- address: info@domain.tld
domain: domain.tld
- null
msg:
- mailbox_modified
- info@domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Aliases
description: >-
You may create a time limited alias using this action. It takes a JSON
object containing a domain and mailbox informations.
Mailcow will generate a random alias.
operationId: Create time limited alias
requestBody:
content:
application/json:
schema:
example:
username: info@domain.tld
domain: domain.tld
properties:
username:
description: 'the mailbox an alias should be created for'
type: string
domain:
description: "the domain"
type: string
type: object
summary: Create time limited alias
/api/v1/add/app-passwd:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- app_passwd
- add
- active: "1"
username: info@domain.tld
app_name: wordpress
app_passwd: keyleudecticidechothistishownsan31
app_passwd2: keyleudecticidechothistishownsan31
protocols:
- imap_access
- dav_access
- smtp_access
- eas_access
- pop3_access
- sieve_access
msg: app_passwd_added
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- App Passwords
description: >-
Using this endpoint you can create a new app password for a specific
mailbox.
operationId: Create App Password
requestBody:
content:
application/json:
schema:
example:
active: "1"
username: info@domain.tld
app_name: wordpress
app_passwd: keyleudecticidechothistishownsan31
app_passwd2: keyleudecticidechothistishownsan31
protocols:
- imap_access
- dav_access
- smtp_access
- eas_access
- pop3_access
- sieve_access
properties:
active:
description: is alias active or not
type: boolean
username:
description: mailbox for which the app password should be created
type: string
app_name:
description: name of your app password
type: string
app_passwd:
description: your app password
type: string
app_passwd2:
description: your app password
type: string
type: object
summary: Create App Password
/api/v1/add/bcc:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- bcc
- add
- active: "1"
bcc_dest: bcc@awesomecow.tld
local_dest: mailcow.tld
type: sender
- null
msg: bcc_saved
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Address Rewriting
description: >-
Using this endpoint you can create a BCC map to forward all mails via a
bcc for a given domain.
operationId: Create BCC Map
requestBody:
content:
application/json:
schema:
example:
active: "1"
bcc_dest: bcc@awesomecow.tld
local_dest: mailcow.tld
type: sender
properties:
active:
description: 1 for a active user account 0 for a disabled user account
type: number
bcc_dest:
description: the email address where all mails should be send to
type: string
local_dest:
description: the domain which emails should be forwarded
type: string
type:
description: the type of bcc map can be `sender` or `recipient`
type: string
type: object
summary: Create BCC Map
/api/v1/add/dkim:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- dkim
- add
- dkim_selector: dkim
domains: hanspeterlol.de
key_size: "2048"
msg:
- dkim_added
- hanspeterlol.de
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- DKIM
description: Using this endpoint you can generate new DKIM keys.
operationId: Generate DKIM Key
requestBody:
content:
application/json:
schema:
example:
dkim_selector: dkim
domains: mailcow.tld
key_size: "2048"
properties:
dkim_selector:
description: the DKIM selector default dkim
type: string
domains:
description: a list of domains for which a dkim key should be generated
type: string
key_size:
description: the key size (1024 or 2048)
type: number
type: object
summary: Generate DKIM Key
/api/v1/add/dkim_duplicate:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- dkim
- duplicate
- from_domain: mailcow.tld
to_domain: awesomecow.tld
msg:
- dkim_duplicated
- mailcow.tld
- awesomecow.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- DKIM
description: Using this endpoint you can duplicate the DKIM Key of one domain.
operationId: Duplicate DKIM Key
requestBody:
content:
application/json:
schema:
example:
from_domain: mailcow.tld
to_domain: awesomecow.tld
properties:
fron_domain:
description: the domain where the dkim key should be copied from
type: string
to_domain:
description: the domain where the dkim key should be copied to
type: string
type: object
summary: Duplicate DKIM Key
/api/v1/add/domain:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- ratelimit
- edit
- domain
- object: domain.tld
rl_frame: s
rl_value: "10"
msg:
- rl_saved
- domain.tld
type: success
- log:
- mailbox
- add
- domain
- active: "1"
aliases: "400"
restart_sogo: "1"
backupmx: "0"
defquota: "3072"
description: some decsription
domain: domain.tld
mailboxes: "10"
maxquota: "10240"
quota: "10240"
relay_all_recipients: "0"
rl_frame: s
rl_value: "10"
tags: ["tag1", "tag2"]
- null
msg:
- domain_added
- domain.tld
type: success
schema:
type: array
items:
type: object
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
description: OK
headers: {}
tags:
- Domains
description: >-
You may create your own domain using this action. It takes a JSON object
containing a domain informations.
operationId: Create domain
requestBody:
content:
application/json:
schema:
example:
active: "1"
aliases: "400"
backupmx: "0"
defquota: "3072"
description: some decsription
domain: domain.tld
mailboxes: "10"
maxquota: "10240"
quota: "10240"
relay_all_recipients: "0"
rl_frame: s
rl_value: "10"
restart_sogo: "10"
tags: ["tag1", "tag2"]
properties:
active:
description: is domain active or not
type: boolean
aliases:
description: limit count of aliases associated with this domain
type: number
backupmx:
description: relay domain or not
type: boolean
defquota:
description: predefined mailbox quota in `add mailbox` form
type: number
description:
description: Description of domain
type: string
domain:
description: Fully qualified domain name
type: string
gal:
description: >-
is domain global address list active or not, it enables
shared contacts accross domain in SOGo webmail
type: boolean
mailboxes:
description: limit count of mailboxes associated with this domain
type: number
maxquota:
description: maximum quota per mailbox
type: number
quota:
description: maximum quota for this domain (for all mailboxes in sum)
type: number
restart_sogo:
description: restart SOGo to activate the domain in SOGo
type: number
relay_all_recipients:
description: >-
if not, them you have to create "dummy" mailbox for each
address to relay
type: boolean
relay_unknown_only:
description: Relay non-existing mailboxes only. Existing mailboxes will be delivered locally.
type: boolean
rl_frame:
enum:
- s
- m
- h
- d
type: string
rl_value:
description: rate limit value
type: number
tags:
description: tags for this Domain
type: array
items:
type: string
type: object
summary: Create domain
/api/v1/add/domain-admin:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- domain_admin
- add
- active: "1"
domains: mailcow.tld
password: "*"
password2: "*"
username: testadmin
msg:
- domain_admin_added
- testadmin
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Domain admin
description: >-
Using this endpoint you can create a new Domain Admin user. This user
has full control over a domain, and can create new mailboxes and
aliases.
operationId: Create Domain Admin user
requestBody:
content:
application/json:
schema:
example:
active: "1"
domains: mailcow.tld
password: supersecurepw
password2: supersecurepw
username: testadmin
properties:
active:
description: 1 for a active user account 0 for a disabled user account
type: number
domains:
description: the domains the user should be a admin of
type: string
password:
description: domain admin user password
type: string
password2:
description: domain admin user password
type: string
username:
description: the username for the admin user
type: string
type: object
summary: Create Domain Admin user
/api/v1/edit/da-acl:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- type: success
log:
- acl
- edit
- testadmin
- username:
- testadmin
da_acl:
- syncjobs
- quarantine
- login_as
- sogo_access
- app_passwds
- bcc_maps
- pushover
- filters
- ratelimit
- spam_policy
- extend_sender_acl
- unlimited_quota
- protocol_access
- smtp_ip_access
- alias_domains
- domain_desc
msg:
- acl_saved
- testadmin
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Domain admin
description: >-
Using this endpoint you can edit the ACLs of a Domain Admin user. This user
has full control over a domain, and can create new mailboxes and
aliases.
operationId: Edit Domain Admin ACL
requestBody:
content:
application/json:
schema:
example:
items:
- testadmin
attr:
da_acl:
- syncjobs
- quarantine
- login_as
- sogo_access
- app_passwds
- bcc_maps
- pushover
- filters
- ratelimit
- spam_policy
- extend_sender_acl
- unlimited_quota
- protocol_access
- smtp_ip_access
- alias_domains
- domain_desc
properties:
items:
description: contains the domain admin username you want to edit
type: object
attr:
properties:
da_acl:
description: contains the list of acl names that are active for this user
type: object
type: object
summary: Edit Domain Admin ACL
/api/v1/edit/domain-admin:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- type: success
log:
- domain_admin
- edit
- username: testadmin
active: ["0","1"]
username_new: testadmin
domains: ["domain.tld"]
password: "*"
password2: "*"
msg:
- domain_admin_modified
- testadmin
schema:
properties:
type:
enum:
- success
- danger
- error
type: string
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type: object
description: OK
headers: {}
tags:
- Domain admin
description: >-
Using this endpoint you can edit a existing Domain Admin user. This user
has full control over a domain, and can create new mailboxes and
aliases.
operationId: Edit Domain Admin user
requestBody:
content:
application/json:
schema:
example:
items:
- testadmin
attr:
active:
- '0'
- '1'
username_new: testadmin
domains: ["domain.tld"]
password: supersecurepassword
password2: supersecurepassword
properties:
attr:
properties:
active:
description: is the domain admin active or not
type: boolean
username_new:
description: the username of the domain admin, change this to change the username
type: string
domains:
description: a list of all domains managed by this domain admin
type: array
items:
type: string
password:
description: the new domain admin user password
type: string
password2:
description: the new domain admin user password for confirmation
type: string
type: object
items:
description: contains the domain admin username you want to edit
type: object
summary: Edit Domain Admin user
/api/v1/add/domain-policy:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- policy
- add
- domain
- domain: domain.tld
object_from: "*@baddomain.tld"
object_list: bl
msg:
- domain_modified
- domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Domain antispam policies
description: >-
You may create your own domain policy using this action. It takes a JSON
object containing a domain informations.
operationId: Create domain policy
requestBody:
content:
application/json:
schema:
example:
domain: domain.tld
object_from: "*@baddomain.tld"
object_list: bl
properties:
domain:
description: domain name to which policy is associated to
type: string
object_from:
description: exact address or use wildcard to match whole domain
type: string
object_list:
enum:
- wl
- bl
type: string
type: object
summary: Create domain policy
/api/v1/add/fwdhost:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- fwdhost
- add
- filter_spam: "0"
hostname: hosted.mailcow.de
msg:
- forwarding_host_added
- "5.1.76.202, 2a00:f820:417::202"
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Fordwarding Hosts
description: >-
Add a new Forwarding host to mailcow. You can chose to enable or disable
spam filtering of incoming emails by specifing `filter_spam` 0 =
inactive, 1 = active.
operationId: Add Forward Host
requestBody:
content:
application/json:
schema:
example:
filter_spam: "0"
hostname: hosted.mailcow.de
properties:
filter_spam:
description: "1 to enable spam filter, 0 to disable spam filter"
type: number
hostname:
description: contains the hostname you want to add
type: string
type: object
summary: Add Forward Host
/api/v1/add/mailbox:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- add
- mailbox
- active: "1"
domain: domain.tld
local_part: info
name: Full name
password: "*"
password2: "*"
quota: "3072"
force_pw_update: "1"
tls_enforce_in: "1"
tls_enforce_out: "1"
tags: ["tag1", "tag2"]
- null
msg:
- mailbox_added
- info@domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Mailboxes
description: >-
You may create your own mailbox using this action. It takes a JSON
object containing a domain informations.
operationId: Create mailbox
requestBody:
content:
application/json:
schema:
example:
active: "1"
domain: domain.tld
local_part: info
name: Full name
password: atedismonsin
password2: atedismonsin
quota: "3072"
force_pw_update: "1"
tls_enforce_in: "1"
tls_enforce_out: "1"
tags: ["tag1", "tag2"]
properties:
active:
description: is mailbox active or not
type: boolean
domain:
description: domain name
type: string
local_part:
description: left part of email address
type: string
name:
description: Full name of the mailbox user
type: string
password2:
description: mailbox password for confirmation
type: string
password:
description: mailbox password
type: string
quota:
description: mailbox quota
type: number
force_pw_update:
description: forces the user to update its password on first login
type: boolean
tls_enforce_in:
description: force inbound email tls encryption
type: boolean
tls_enforce_out:
description: force oubound tmail tls encryption
type: boolean
type: object
summary: Create mailbox
/api/v1/add/oauth2-client:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- oauth2
- add
- client
- redirect_uri: "https://mailcow.tld"
msg: Added client access
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- oAuth Clients
description: Using this endpoint you can create a oAuth clients.
operationId: Create oAuth Client
requestBody:
content:
application/json:
schema:
example:
redirect_uri: "https://mailcow.tld"
properties:
redirect_uri:
description: the uri where you should be redirected after oAuth
type: string
type: object
summary: Create oAuth Client
/api/v1/add/recipient_map:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- recipient_map
- add
- active: "1"
recipient_map_new: target@mailcow.tld
recipient_map_old: recipient@mailcow.tld
- null
msg:
- recipient_map_entry_saved
- recipient@mailcow.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Address Rewriting
description: >-
Using this endpoint you can create a recipient map to forward all mails
from one email address to another.
operationId: Create Recipient Map
requestBody:
content:
application/json:
schema:
example:
active: "1"
recipient_map_new: target@mailcow.tld
recipient_map_old: recipient@mailcow.tld
properties:
active:
description: 1 for a active user account 0 for a disabled user account
type: number
recipient_map_new:
description: the email address that should receive the forwarded emails
type: string
recipient_map_old:
description: the email address which emails should be forwarded
type: string
type: object
summary: Create Recipient Map
/api/v1/add/relayhost:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- relayhost
- add
- hostname: "mailcow.tld:25"
password: supersecurepassword
username: testuser
msg:
- relayhost_added
- ""
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Routing
description: Using this endpoint you can create Sender-Dependent Transports.
operationId: Create Sender-Dependent Transports
requestBody:
content:
application/json:
schema:
example:
hostname: "mailcow.tld:25"
password: supersecurepassword
username: testuser
properties:
hostname:
description: the hostname of the smtp server with port
type: string
password:
description: the password for the smtp user
type: string
username:
description: the username used to authenticate
type: string
type: object
summary: Create Sender-Dependent Transports
/api/v1/add/resource:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- add
- resource
- active: "1"
description: test
domain: mailcow.tld
kind: location
multiple_bookings: "0"
multiple_bookings_custom: ""
multiple_bookings_select: "0"
- null
msg:
- resource_added
- mailcow.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Resources
description: Using this endpoint you can create Resources.
operationId: Create Resources
requestBody:
content:
application/json:
schema:
example:
active: "1"
description: test
domain: mailcow.tld
kind: location
multiple_bookings: "0"
multiple_bookings_custom: ""
multiple_bookings_select: "0"
properties:
active:
description: 1 for a active transport map 0 for a disabled transport map
type: number
description:
description: a description of the resource
type: string
domain:
description: the domain for which the resource should be
type: string
kind:
description: the kind of recouse
enum:
- location
- group
- thing
type: string
multiple_bookings:
enum:
- "-1"
- "1"
- custom
type: string
multiple_bookings_custom:
description: always empty
type: number
multiple_bookings_select:
enum:
- "-1"
- "1"
- custom
type: string
type: object
summary: Create Resources
/api/v1/add/syncjob:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- add
- syncjob
- active: "1"
automap: "1"
custom_params: ""
delete1: "0"
delete2: "0"
delete2duplicates: "1"
enc1: SSL
exclude: (?i)spam|(?i)junk
host1: imap.server.tld
maxage: "0"
maxbytespersecond: "0"
mins_interval: "20"
password1: supersecret
port1: 993
skipcrossduplicates: "0"
subfolder2: External
subscribeall: "1"
timeout1: "600"
timeout2: "600"
user1: username
username: mailbox@domain.tld
- null
msg:
- mailbox_modified
- mailbox@domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Sync jobs
description: >-
You can create new sync job using this action. It takes a JSON object
containing a domain informations.
operationId: Create sync job
summary: Create sync job
requestBody:
content:
application/json:
schema:
example:
username: lisa@mailcow.tld
host1: mail.mailcow.tld
port1: "143"
user1: demo@mailcow.tld
password1: supersecretpw
enc1: TLS
mins_interval: "20"
subfolder2: "/SyncIntoSubfolder"
maxage: "0"
maxbytespersecond: "0"
timeout1: "600"
timeout2: "600"
exclude: "(?i)spam|(?i)junk"
custom_params: "--dry"
delete2duplicates: "1"
delete1: "1"
delete2: "0"
automap: "1"
skipcrossduplicates: "0"
subscribeall: "0"
active: "1"
properties:
parameters:
description: your local mailcow mailbox
type: string
host1:
description: the smtp server where mails should be synced from
type: string
port1:
description: the smtp port of the target mail server
type: string
password:
description: the password of the mailbox
type: string
enc1:
description: the encryption method used to connect to the mailserver
type: string
mins_internal:
description: the interval in which messages should be syned
type: number
subfolder2:
description: sync into subfolder on destination (empty = do not use subfolder)
type: string
maxage:
description: only sync messages up to this age in days
type: number
maxbytespersecond:
description: max speed transfer limit for the sync
type: number
timeout1:
description: timeout for connection to remote host
type: number
timeout2:
description: timeout for connection to local host
type: number
exclude:
description: exclude objects (regex)
type: string
custom_params:
description: custom parameters
type: string
delete2duplicates:
description: delete duplicates on destination (--delete2duplicates)
type: boolean
delete1:
description: delete from source when completed (--delete1)
type: boolean
delete2:
description: delete messages on destination that are not on source (--delete2)
type: boolean
automap:
description: try to automap folders ("Sent items", "Sent" => "Sent" etc.) (--automap)
type: boolean
skipcrossduplicates:
description: skip duplicate messages across folders (first come, first serve) (--skipcrossduplicates)
type: boolean
subscribeall:
description: subscribe all folders (--subscribeall)
type: boolean
active:
description: enables or disables the sync job
type: boolean
type: object
/api/v1/add/tls-policy-map:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- tls_policy_maps
- add
- parameters: ""
active: "1"
dest: mailcow.tld
policy: encrypt
- null
msg:
- tls_policy_map_entry_saved
- mailcow.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Outgoing TLS Policy Map Overrides
description: Using this endpoint you can create a TLS policy map override.
operationId: Create TLS Policy Map
requestBody:
content:
application/json:
schema:
example:
parameters: ""
active: "1"
dest: mailcow.tld
policy: encrypt
properties:
parameters:
description: >-
custom parameters you find out more about them
[here](http://www.postfix.org/postconf.5.html#smtp_tls_policy_maps)
type: string
active:
description: 1 for a active user account 0 for a disabled user account
type: number
dest:
description: the target domain or email address
type: string
policy:
description: the policy
enum:
- none
- may
- encrypt
- dane
- "'dane"
- fingerprint
- verify
- secure
type: string
type: object
summary: Create TLS Policy Map
/api/v1/add/transport:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- transport
- add
- active: "1"
destination: example2.org
nexthop: "host:25"
password: supersecurepw
username: testuser
msg:
- relayhost_added
- ""
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Routing
description: Using this endpoint you can create Sender-Dependent Transports.
operationId: Create Transport Maps
requestBody:
content:
application/json:
schema:
example:
active: "1"
destination: example.org
nexthop: "host:25"
password: supersecurepw
username: testuser
properties:
active:
description: 1 for a active transport map 0 for a disabled transport map
type: number
destination:
type: string
nexthop:
type: string
password:
description: the password for the smtp user
type: string
username:
description: the username used to authenticate
type: string
type: object
summary: Create Transport Maps
/api/v1/delete/alias:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- delete
- alias
- id:
- "6"
- "9"
- null
msg:
- alias_removed
- alias@domain.tld
type: success
- log:
- mailbox
- delete
- alias
- id:
- "6"
- "9"
- null
msg:
- alias_removed
- alias2@domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Aliases
description: You can delete one or more aliases.
operationId: Delete alias
requestBody:
content:
application/json:
schema:
items:
example: "6"
type: string
type: array
summary: Delete alias
/api/v1/delete/app-passwd:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- app_passwd
- delete
- id:
- "2"
msg:
- app_passwd_removed
- "2"
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- App Passwords
description: Using this endpoint you can delete a single app password.
operationId: Delete App Password
requestBody:
content:
application/json:
schema:
example:
- "1"
properties:
items:
description: contains list of app passwords you want to delete
type: object
type: object
summary: Delete App Password
/api/v1/delete/bcc:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- bcc
- delete
- id:
- "4"
- null
msg:
- bcc_deleted
- "4"
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Address Rewriting
description: >-
Using this endpoint you can delete a BCC map, for this you have to know
its ID. You can get the ID using the GET method.
operationId: Delete BCC Map
requestBody:
content:
application/json:
schema:
example:
- "3"
properties:
items:
description: contains list of bcc maps you want to delete
type: object
type: object
summary: Delete BCC Map
/api/v1/delete/dkim:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- dkim
- delete
- domains:
- mailcow.tld
msg:
- dkim_removed
- mailcow.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- DKIM
description: Using this endpoint a existing DKIM Key can be deleted
operationId: Delete DKIM Key
requestBody:
content:
application/json:
schema:
items:
example:
- mailcow.tld
type: string
type: array
summary: Delete DKIM Key
/api/v1/delete/domain:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- delete
- domain
- domain:
- domain.tld
- domain2.tld
- null
msg:
- domain_removed
- domain.tld
type: success
- log:
- mailbox
- delete
- domain
- domain:
- domain.tld
- domain2.tld
- null
msg:
- domain_removed
- domain2.tld
type: success
schema:
type: array
items:
type: object
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
description: OK
headers: {}
tags:
- Domains
description: You can delete one or more domains.
operationId: Delete domain
requestBody:
content:
application/json:
schema:
type: object
example:
- domain.tld
- domain2.tld
properties:
items:
type: array
items:
type: string
summary: Delete domain
/api/v1/delete/domain-admin:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- domain_admin
- delete
- username:
- testadmin
msg:
- domain_admin_removed
- testadmin
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Domain admin
description: Using this endpoint a existing Domain Admin user can be deleted.
operationId: Delete Domain Admin
requestBody:
content:
application/json:
schema:
example:
- testadmin
properties:
items:
description: contains list of usernames of the users you want to delete
type: object
type: object
summary: Delete Domain Admin
/api/v1/delete/domain-policy:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- policy
- delete
- domain
- prefid:
- "1"
- "2"
msg:
- item_deleted
- "1"
type: success
- log:
- policy
- delete
- domain
- prefid:
- "1"
- "2"
msg:
- item_deleted
- "2"
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Domain antispam policies
description: You can delete one o more domain policies.
operationId: Delete domain policy
requestBody:
content:
application/json:
schema:
example:
- "1"
- "2"
properties:
items:
description: contains list of domain policys you want to delete
type: object
type: object
summary: Delete domain policy
/api/v1/delete/fwdhost:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- fwdhost
- delete
- forwardinghost:
- 5.1.76.202
- "2a00:f820:417::202"
msg:
- forwarding_host_removed
- 5.1.76.202
type: success
- log:
- fwdhost
- delete
- forwardinghost:
- 5.1.76.202
- "2a00:f820:417::202"
msg:
- forwarding_host_removed
- "2a00:f820:417::202"
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Fordwarding Hosts
description: >-
Using this endpoint you can delete a forwarding host, in order to do so
you need to know the IP of the host.
operationId: Delete Forward Host
requestBody:
content:
application/json:
schema:
example:
- 5.1.76.202
- "2a00:f820:417::202"
properties:
ip:
description: contains the ip of the fowarding host you want to delete
type: string
type: object
summary: Delete Forward Host
/api/v1/delete/mailbox:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- delete
- mailbox
- username:
- info@domain.tld
- sales@domain.tld
- null
msg:
- mailbox_removed
- info@domain.tld
type: success
- log:
- mailbox
- delete
- mailbox
- username:
- info@domain.tld
- sales@domain.tld
- null
msg:
- mailbox_removed
- sales@domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Mailboxes
description: You can delete one or more mailboxes.
operationId: Delete mailbox
requestBody:
content:
application/json:
schema:
example:
- info@domain.tld
- sales@domain.tld
properties:
items:
description: contains list of mailboxes you want to delete
type: object
type: object
summary: Delete mailbox
/api/v1/delete/mailq:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
msg: Task completed
type: success
description: OK
headers: {}
tags:
- Queue Manager
description: >-
Using this API you can delete the current mail queue. This will delete
all mails in it.
This API uses the command: `postsuper -d`
operationId: Delete Queue
requestBody:
content:
application/json:
schema:
example:
action: super_delete
properties:
action:
description: use super_delete to delete the mail queue
type: string
type: object
summary: Delete Queue
/api/v1/delete/oauth2-client:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- oauth2
- delete
- client
- id:
- "1"
msg:
- items_deleted
- "1"
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- oAuth Clients
description: >-
Using this endpoint you can delete a oAuth client, for this you have to
know its ID. You can get the ID using the GET method.
operationId: Delete oAuth Client
requestBody:
content:
application/json:
schema:
example:
- "3"
properties:
items:
description: contains list of oAuth clients you want to delete
type: object
type: object
summary: Delete oAuth Client
/api/v1/delete/qitem:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- quarantine
- delete
- id:
- "33"
msg:
- item_deleted
- "33"
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Quarantine
description: >-
Using this endpoint you can delete a email from quarantine, for this you
have to know its ID. You can get the ID using the GET method.
operationId: Delete mails in Quarantine
requestBody:
content:
application/json:
schema:
example:
- "33"
properties:
items:
description: contains list of emails you want to delete
type: object
type: object
summary: Delete mails in Quarantine
/api/v1/delete/recipient_map:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- recipient_map
- delete
- id:
- "1"
- null
msg:
- recipient_map_entry_deleted
- "1"
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Address Rewriting
description: >-
Using this endpoint you can delete a recipient map, for this you have to
know its ID. You can get the ID using the GET method.
operationId: Delete Recipient Map
requestBody:
content:
application/json:
schema:
example:
- "1"
properties:
items:
description: contains list of recipient maps you want to delete
type: object
type: object
summary: Delete Recipient Map
/api/v1/delete/relayhost:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- relayhost
- delete
- id:
- "1"
msg:
- relayhost_removed
- "1"
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Routing
description: >-
Using this endpoint you can delete a Sender-Dependent Transport, for
this you have to know its ID. You can get the ID using the GET method.
operationId: Delete Sender-Dependent Transports
requestBody:
content:
application/json:
schema:
example:
- "1"
properties:
items:
description: >-
contains list of Sender-Dependent Transport you want to
delete
type: object
type: object
summary: Delete Sender-Dependent Transports
/api/v1/delete/resource:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- delete
- resource
- name:
- test@mailcow.tld
- null
msg:
- resource_removed
- test@mailcow.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Resources
description: >-
Using this endpoint you can delete a Resources, for this you have to
know its ID. You can get the ID using the GET method.
operationId: Delete Resources
requestBody:
content:
application/json:
schema:
example:
- test@mailcow.tld
properties:
items:
description: contains list of Resources you want to delete
type: object
type: object
summary: Delete Resources
/api/v1/delete/syncjob:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
log:
- entity
- action
- object
msg:
- message
- entity name
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Sync jobs
description: You can delete one or more sync jobs.
operationId: Delete sync job
requestBody:
content:
application/json:
schema:
example:
- "6"
- "9"
properties:
items:
description: contains list of aliases you want to delete
type: object
type: object
summary: Delete sync job
/api/v1/delete/tls-policy-map:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- tls_policy_maps
- delete
- id:
- "1"
- null
msg:
- tls_policy_map_entry_deleted
- "1"
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Outgoing TLS Policy Map Overrides
description: >-
Using this endpoint you can delete a TLS Policy Map, for this you have
to know its ID. You can get the ID using the GET method.
operationId: Delete TLS Policy Map
requestBody:
content:
application/json:
schema:
example:
- "3"
properties:
items:
description: contains list of tls policy maps you want to delete
type: object
type: object
summary: Delete TLS Policy Map
/api/v1/delete/transport:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- transport
- delete
- id:
- "1"
msg:
- relayhost_removed
- "1"
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Routing
description: >-
Using this endpoint you can delete a Transport Maps, for this you have
to know its ID. You can get the ID using the GET method.
operationId: Delete Transport Maps
requestBody:
content:
application/json:
schema:
example:
- "1"
properties:
items:
description: contains list of transport maps you want to delete
type: object
type: object
summary: Delete Transport Maps
"/api/v1/delete/mailbox/tag/{mailbox}":
post:
parameters:
- description: name of mailbox
in: path
name: mailbox
example: info@domain.tld
required: true
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- delete
- tags_mailbox
- tags:
- tag1
- tag2
mailbox: info@domain.tld
- null
msg:
- mailbox_modified
- info@domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Mailboxes
description: You can delete one or more mailbox tags.
operationId: Delete mailbox tags
requestBody:
content:
application/json:
schema:
example:
- tag1
- tag2
properties:
items:
description: contains list of mailboxes you want to delete
type: object
type: object
summary: Delete mailbox tags
"/api/v1/delete/domain/tag/{domain}":
post:
parameters:
- description: name of domain
in: path
name: domain
example: domain.tld
required: true
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- delete
- tags_domain
- tags:
- tag1
- tag2
domain: domain.tld
- null
msg:
- domain_modified
- domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Domains
description: You can delete one or more domain tags.
operationId: Delete domain tags
requestBody:
content:
application/json:
schema:
example:
- tag1
- tag2
properties:
items:
description: contains list of domains you want to delete
type: object
type: object
summary: Delete domain tags
/api/v1/edit/alias:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- edit
- alias
- active: "1"
address: alias@domain.tld
goto: destination@domain.tld
id:
- "6"
private_comment: private comment
public_comment: public comment
- null
msg:
- alias_modified
- alias@domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Aliases
description: >-
You can update one or more aliases per request. You can also send just
attributes you want to change
operationId: Update alias
requestBody:
content:
application/json:
schema:
example:
attr:
active: "1"
address: alias@domain.tld
goto: destination@domain.tld
private_comment: private comment
public_comment: public comment
items: ["6"]
properties:
attr:
properties:
active:
description: is alias active or not
type: boolean
address:
description: 'alias address, for catchall use "@domain.tld"'
type: string
goto:
description: "destination address, comma separated"
type: string
goto_ham:
description: learn as ham
type: boolean
goto_null:
description: silently ignore
type: boolean
goto_spam:
description: learn as spam
type: boolean
private_comment:
type: string
public_comment:
type: string
sogo_visible:
description: toggle visibility as selectable sender in SOGo
type: boolean
type: object
items:
description: contains list of aliases you want update
type: object
type: object
summary: Update alias
/api/v1/edit/domain:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
schema:
type: array
items:
type: object
properties:
log:
type: array
description: contains request object
items: {}
msg:
type: array
items: {}
type:
enum:
- success
- danger
- error
type: string
description: OK
headers: {}
tags:
- Domains
description: >-
You can update one or more domains per request. You can also send just
attributes you want to change.
Example: You can add domain names to items list and in attr object just
include `"active": "0"` to deactivate domains.
operationId: Update domain
requestBody:
content:
application/json:
schema:
example:
attr:
active: "1"
aliases: "400"
backupmx: "1"
defquota: "3072"
description: domain description
gal: "1"
mailboxes: "10"
maxquota: "10240"
quota: "10240"
relay_all_recipients: "0"
relayhost: "2"
tags: ["tag3", "tag4"]
items: domain.tld
properties:
attr:
properties:
active:
description: is domain active or not
type: boolean
aliases:
description: limit count of aliases associated with this domain
type: number
backupmx:
description: relay domain or not
type: boolean
defquota:
description: predefined mailbox quota in `add mailbox` form
type: number
description:
description: Description of domain
type: string
gal:
description: >-
is domain global address list active or not, it enables
shared contacts accross domain in SOGo webmail
type: boolean
mailboxes:
description: limit count of mailboxes associated with this domain
type: number
maxquota:
description: maximum quota per mailbox
type: number
quota:
description: maximum quota for this domain (for all mailboxes in sum)
type: number
relay_all_recipients:
description: >-
if not, them you have to create "dummy" mailbox for each
address to relay
type: boolean
relay_unknown_only:
description: Relay non-existing mailboxes only. Existing mailboxes will be delivered locally.
type: boolean
relayhost:
description: id of relayhost
type: number
rl_frame:
enum:
- s
- m
- h
- d
type: string
rl_value:
description: rate limit value
type: number
tags:
description: tags for this Domain
type: array
items:
type: string
type: object
items:
description: contains list of domain names you want update
type: array
items:
type: string
type: object
summary: Update domain
/api/v1/edit/fail2ban:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
"*/*":
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Fail2Ban
description: >-
Using this endpoint you can edit the Fail2Ban config and black or
whitelist new ips.
operationId: Edit Fail2Ban
requestBody:
content:
application/json:
schema:
example:
attr:
ban_time: "86400"
blacklist: "10.100.6.5/32,10.100.8.4/32"
max_attempts: "5"
netban_ipv4: "24"
netban_ipv6: "64"
retry_window: "600"
whitelist: mailcow.tld
items: none
properties:
attr:
description: array containing the fail2ban settings
properties:
backlist:
description: the backlisted ips or hostnames separated by comma
type: string
ban_time:
description: the time a ip should be banned
type: number
max_attempts:
description: the maximum numbe of wrong logins before a ip is banned
type: number
netban_ipv4:
description: the networks mask to ban for ipv4
type: number
netban_ipv6:
description: the networks mask to ban for ipv6
type: number
retry_window:
description: >-
the maximum time in which a ip as to login with false
credentials to be banned
type: number
whitelist:
description: whitelisted ips or hostnames sepereated by comma
type: string
type: object
items:
description: has to be none
type: object
summary: Edit Fail2Ban
/api/v1/edit/mailbox:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- mailbox
- edit
- mailbox
- active: "1"
force_pw_update: "0"
name: Full name
password: "*"
password2: "*"
quota: "3072"
sender_acl:
- default
- info@domain2.tld
- domain3.tld
- "*"
sogo_access: "1"
username:
- info@domain.tld
tags: ["tag3", "tag4"]
- null
msg:
- mailbox_modified
- info@domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Mailboxes
description: >-
You can update one or more mailboxes per request. You can also send just
attributes you want to change
operationId: Update mailbox
requestBody:
content:
application/json:
schema:
example:
attr:
active: "1"
force_pw_update: "0"
name: Full name
password: ""
password2: ""
quota: "3072"
sender_acl:
- default
- info@domain2.tld
- domain3.tld
- "*"
sogo_access: "1"
tags: ["tag3", "tag4"]
items:
- info@domain.tld
properties:
attr:
properties:
active:
description: is mailbox active or not
type: boolean
force_pw_update:
description: force user to change password on next login
type: boolean
name:
description: Full name of the mailbox user
type: string
password2:
description: new mailbox password for confirmation
type: string
password:
description: new mailbox password
type: string
quota:
description: mailbox quota
type: number
sender_acl:
description: list of allowed send from addresses
type: object
sogo_access:
description: is access to SOGo webmail active or not
type: boolean
type: object
items:
description: contains list of mailboxes you want update
type: object
type: object
summary: Update mailbox
/api/v1/edit/mailq:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
msg: Task completed
type: success
description: OK
headers: {}
tags:
- Queue Manager
description: >-
Using this API you can flush the current mail queue. This will try to
deliver all mails currently in it.
This API uses the command: `postqueue -f`
operationId: Flush Queue
requestBody:
content:
application/json:
schema:
example:
action: flush
properties:
action:
description: use flush to flush the mail queue
type: string
type: object
summary: Flush Queue
/api/v1/edit/pushover:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- pushover
- edit
- active: "0"
evaluate_x_prio: "0"
key: 21e8918e1jksdjcpis712
only_x_prio: "0"
+ sound: "pushover"
senders: ""
senders_regex: ""
text: ""
title: Mail
token: 9023e2ohcwed27d1idu2
username:
- info@domain.tld
msg: pushover_settings_edited
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Mailboxes
description: >-
Using this endpoint it is possible to update the pushover settings for
mailboxes
operationId: Update Pushover settings
requestBody:
content:
application/json:
schema:
example:
attr:
active: "0"
evaluate_x_prio: "0"
key: 21e8918e1jksdjcpis712
only_x_prio: "0"
+ sound: "pushover"
senders: ""
senders_regex: ""
text: ""
title: Mail
token: 9023e2ohcwed27d1idu2
items: info@domain.tld
properties:
attr:
properties:
active:
description: Enables pushover 1 disable pushover 0
type: number
evaluate_x_prio:
description: Send the Push with High priority
type: number
key:
description: Pushover key
type: string
only_x_prio:
description: Only send push for prio mails
type: number
+ sound:
+ description: Set notification sound
+ type: string
senders:
description: Only send push for emails from these senders
type: string
senders_regex:
description: Regex to match senders for which a push will be send
type: string
text:
description: Custom push noficiation text
type: string
title:
description: Push title
type: string
token:
description: Pushover token
type: string
type: object
items:
description: contains list of mailboxes you want to delete
type: object
type: object
summary: Update Pushover settings
/api/v1/edit/quarantine_notification:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
description: OK
headers: {}
tags:
- Mailboxes
description: You can update one or more mailboxes per request.
operationId: Quarantine Notifications
requestBody:
content:
application/json:
schema:
example:
attr:
quarantine_notification: hourly
items:
anyOf:
- mailbox1@domain.tld
- mailbox2@domain.tld
properties:
attr:
properties:
quarantine_notification:
description: recurrence
enum:
- hourly
- daily
- weekly
- never
type: string
type: object
items:
description: >-
contains list of mailboxes you want set qurantine
notifications
type: object
type: object
summary: Quarantine Notifications
/api/v1/edit/syncjob:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
log:
- entity
- action
- object
msg:
- message
- entity name
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Sync jobs
description: >-
You can update one or more sync jobs per request. You can also send just
attributes you want to change.
operationId: Update sync job
requestBody:
content:
application/json:
schema:
example:
attr:
active: "1"
automap: "1"
custom_params: ""
delete1: "0"
delete2: "0"
delete2duplicates: "1"
enc1: SSL
exclude: (?i)spam|(?i)junk
host1: imap.server.tld
maxage: "0"
maxbytespersecond: "0"
mins_interval: "20"
password1: supersecret
port1: "993"
skipcrossduplicates: "0"
subfolder2: External
subscribeall: "1"
timeout1: "600"
timeout2: "600"
user1: username
items: "1"
properties:
attr:
properties:
active:
description: Is sync job active
type: boolean
automap:
description: >-
Try to automap folders ("Sent items", "Sent" => "Sent"
etc.)
type: boolean
custom_params:
description: Custom parameters passed to imapsync command
type: string
delete1:
description: Delete from source when completed
type: boolean
delete2:
description: Delete messages on destination that are not on source
type: boolean
delete2duplicates:
description: Delete duplicates on destination
type: boolean
enc1:
description: Encryption
enum:
- TLS
- SSL
- PLAIN
type: string
exclude:
description: Exclude objects (regex)
type: string
host1:
description: Hostname
type: string
maxage:
description: >-
Maximum age of messages in days that will be polled from
remote (0 = ignore age)
type: number
maxbytespersecond:
description: Max. bytes per second (0 = unlimited)
type: number
mins_interval:
description: Interval (min)
type: number
password1:
description: Password
type: string
port1:
description: Port
type: string
skipcrossduplicates:
description: >-
Skip duplicate messages across folders (first come,
first serve)
type: boolean
subfolder2:
description: >-
Sync into subfolder on destination (empty = do not use
subfolder)
type: string
subscribeall:
description: Subscribe all folders
type: boolean
timeout1:
description: Timeout for connection to remote host
type: number
timeout2:
description: Timeout for connection to local host
type: number
user1:
description: Username
type: string
type: object
items:
description: contains list of aliases you want update
type: object
type: object
summary: Update sync job
/api/v1/edit/user-acl:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- log:
- acl
- edit
- user
- user_acl:
- spam_alias
- tls_policy
- spam_score
- spam_policy
- delimiter_action
- syncjobs
- eas_reset
- quarantine
- sogo_profile_reset
- quarantine_attachments
- quarantine_notification
- app_passwds
- pushover
username:
- info@domain.tld
msg:
- acl_saved
- info@domain.tld
type: success
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Mailboxes
description: Using this endpoints its possible to update the ACL's for mailboxes
operationId: Update mailbox ACL
requestBody:
content:
application/json:
schema:
example:
attr:
user_acl:
- spam_alias
- tls_policy
- spam_score
- spam_policy
- delimiter_action
- syncjobs
- eas_reset
- quarantine
- sogo_profile_reset
- quarantine_attachments
- quarantine_notification
- app_passwds
- pushover
items: info@domain.tld
properties:
attr:
properties:
user_acl:
description: contains a list of active user acls
type: object
type: object
items:
description: contains list of mailboxes you want to delete
type: object
type: object
summary: Update mailbox ACL
"/api/v1/get/alias/{id}":
get:
parameters:
- description: id of entry you want to get
example: all
in: path
name: id
required: true
schema:
enum:
- all
- "1"
- "2"
- "5"
- "10"
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
address: alias@domain.tld
created: "2019-04-04 19:29:49"
domain: domain.tld
goto: destination@domain.tld
id: 6
in_primary_domain: ""
is_catch_all: 0
modified: null
private_comment: null
public_comment: null
- active: "1"
address: "@domain.tld"
created: "2019-04-27 13:42:39"
domain: domain.tld
goto: destination@domain.tld
id: 10
in_primary_domain: ""
is_catch_all: 1
modified: null
private_comment: null
public_comment: null
description: OK
headers: {}
tags:
- Aliases
description: You can list mailbox aliases existing in system.
operationId: Get aliases
summary: Get aliases
"/api/v1/get/time_limited_aliases/{mailbox}":
get:
parameters:
- description: mailbox you want to get aliasses from
example: domain.tld
in: path
schema:
type: string
name: mailbox
required: true
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- address: alias@domain.tld
goto: destination@domain.tld
validity: 1668251246
created: "2021-11-12 12:07:26"
modified: null
description: OK
headers: {}
tags:
- Aliases
description: You can list time limited mailbox aliases existing in system.
operationId: Get time limited aliases
summary: Get time limited aliases
"/api/v1/get/app-passwd/all/{mailbox}":
get:
parameters:
- description: mailbox of entry you want to get
example: hello@mailcow.email
in: path
name: mailbox
required: true
schema:
enum:
- hello@mailcow.email
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
created: "2019-12-21 16:04:55"
domain: mailcow.email
id: 2
mailbox: hello@mailcow.email
modified: null
name: emclient
description: OK
headers: {}
tags:
- App Passwords
description: >-
Using this endpoint you can get all app passwords from a specific
mailbox.
operationId: Get App Password
summary: Get App Password
"/api/v1/get/bcc/{id}":
get:
parameters:
- description: id of entry you want to get
example: all
in: path
name: id
required: true
schema:
enum:
- all
- "1"
- "2"
- "5"
- "10"
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
bcc_dest: bcc@awesomecow.tld
created: "2019-10-02 21:44:34"
domain: mailcow.tld
id: 3
local_dest: "@mailcow.tld"
modified: null
type: sender
description: OK
headers: {}
tags:
- Address Rewriting
description: Using this endpoint you can get all BCC maps.
operationId: Get BCC Map
summary: Get BCC Map
"/api/v1/get/dkim/{domain}":
get:
parameters:
- description: name of domain
in: path
name: domain
required: true
schema:
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
dkim_selector: dkim
dkim_txt: >-
v=DKIM1;k=rsa;t=s;s=email;p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA21tUSjyasQy/hJmVjPnlRGfzx6TPhYj8mXY9DVOzSAE64Gddw/GnE/GcCR6WXNT23u9q4zPnz1IPoNt5kFOps8vg/iNqrcH++494noaZuYyFPPFnebkfryO4EvEyxC/c66qts+gnOUml+M8uv5WObBJld2gG12jLwFM0263J/N6J8LuUsaXOB2uCIfx8Nf4zjuJ6Ieez2uyHNK5dXjDLfKA4mTr+EEK6W6e34M4KN1liWM6r9Oy5S1FlLrD42VpURxxBZtBiEtaJPEKSQuk6GQz8ihu7W20Yr53tyCdaORu8dhxXVUWVf+GjuuMEdAmQCjYkarXdYCrt56Psw703kwIDAQAB
length: "2048"
privkey: ""
pubkey: >-
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA21tUSjyasQy/hJmVjPnlRGfzx6TPhYj8mXY9DVOzSAE64Gddw/GnE/GcCR6WXNT23u9q4zPnz1IPoNt5kFOps8vg/iNqrcH++494noaZuYyFPPFnebkfryO4EvEyxC/c66qts+gnOUml+M8uv5WObBJld2gG12jLwFM0263J/N6J8LuUsaXOB2uCIfx8Nf4zjuJ6Ieez2uyHNK5dXjDLfKA4mTr+EEK6W6e34M4KN1liWM6r9Oy5S1FlLrD42VpURxxBZtBiEtaJPEKSQuk6GQz8ihu7W20Yr53tyCdaORu8dhxXVUWVf+GjuuMEdAmQCjYkarXdYCrt56Psw703kwIDAQAB
description: OK
headers: {}
tags:
- DKIM
description: >-
Using this endpoint you can get the DKIM public key for a specific
domain.
operationId: Get DKIM Key
summary: Get DKIM Key
/api/v1/get/domain-admin/all:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
created: "2019-10-02 10:29:41"
selected_domains:
- mailcow.tld
tfa_active: "0"
unselected_domains:
- awesomemailcow.de
- mailcowisgreat.de
username: testadmin
description: OK
headers: {}
tags:
- Domain admin
description: ""
operationId: Get Domain Admins
summary: Get Domain Admins
"/api/v1/get/domain/{id}":
get:
parameters:
- description: id of entry you want to get
example: all
in: path
name: id
required: true
schema:
enum:
- all
- mailcow.tld
type: string
- description: comma seperated list of tags to filter by
example: "tag1,tag2"
in: query
name: tags
required: false
schema:
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
aliases_in_domain: 0
aliases_left: 400
backupmx: "0"
bytes_total: "5076666944"
def_new_mailbox_quota: 3221225472
def_quota_for_mbox: 3221225472
description: Some description
domain_name: domain.tld
gal: "0"
max_new_mailbox_quota: 10737418240
max_num_aliases_for_domain: 400
max_num_mboxes_for_domain: 10
max_quota_for_domain: 10737418240
max_quota_for_mbox: 10737418240
mboxes_in_domain: 0
mboxes_left: 10
msgs_total: "172440"
quota_used_in_domain: "0"
relay_all_recipients: "0"
relayhost: "0"
rl: false
tags: ["tag1", "tag2"]
- active: "1"
aliases_in_domain: 0
aliases_left: 400
backupmx: "1"
bytes_total: "5076666944"
def_new_mailbox_quota: 3221225472
def_quota_for_mbox: 3221225472
description: domain description
domain_name: domain2.tld
gal: "0"
max_new_mailbox_quota: 10737418240
max_num_aliases_for_domain: 400
max_num_mboxes_for_domain: 10
max_quota_for_domain: 10737418240
max_quota_for_mbox: 10737418240
mboxes_in_domain: 0
mboxes_left: 10
msgs_total: "172440"
quota_used_in_domain: "0"
relay_all_recipients: "0"
relayhost: "0"
rl: false
tags: ["tag3", "tag4"]
description: OK
headers: {}
tags:
- Domains
description: You can list all domains existing in system.
operationId: Get domains
summary: Get domains
/api/v1/get/fail2ban:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
ban_time: 604800
blacklist: |-
45.82.153.37/32
92.118.38.52/32
max_attempts: 1
netban_ipv4: 32
netban_ipv6: 128
perm_bans:
- 45.82.153.37/32
- 92.118.38.52/32
retry_window: 7200
whitelist: 1.1.1.1
description: OK
headers: {}
tags:
- Fail2Ban
description: Gets the current Fail2Ban configuration.
operationId: Get Fail2Ban Config
summary: Get Fail2Ban Config
/api/v1/get/fwdhost/all:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- host: 5.1.76.202
keep_spam: "yes"
source: hosted.mailcow.de
- host: "2a00:f820:417::202"
keep_spam: "yes"
source: hosted.mailcow.de
description: OK
headers: {}
tags:
- Fordwarding Hosts
description: You can list all Forwarding Hosts in your mailcow.
operationId: Get Forwarding Hosts
summary: Get Forwarding Hosts
"/api/v1/get/logs/acme/{count}":
get:
parameters:
- description: Number of logs to return
in: path
name: count
required: true
schema:
type: number
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- message: >-
Certificate validation done, neither changed nor due for
renewal, sleeping for another day.
time: "1569927728"
description: OK
headers: {}
tags:
- Logs
description: >-
This Api endpoint lists all ACME logs from issued Lets Enctypts
certificates.
Tip: You can limit how many logs you want to get by using `/<count>` at
the end of the api url.
operationId: Get ACME logs
summary: Get ACME logs
"/api/v1/get/logs/api/{count}":
get:
parameters:
- description: Number of logs to return
in: path
name: count
required: true
schema:
type: number
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- data: ""
method: GET
remote: 1.1.1.1
time: 1569939001
uri: /api/v1/get/logs/api/2
description: OK
headers: {}
tags:
- Logs
description: >-
This Api endpoint lists all Api logs.
Tip: You can limit how many logs you want to get by using `/<count>` at
the end of the api url.
operationId: Get Api logs
summary: Get Api logs
"/api/v1/get/logs/autodiscover/{count}":
get:
parameters:
- description: Number of logs to return
in: path
name: count
required: true
schema:
type: number
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- service: activesync
time: 1569684212
ua: >-
Microsoft Office/16.0 (Windows NT 6.2; MAPICPL
16.0.11328; Pro)
user: awesome@mailcow.de
description: OK
headers: {}
tags:
- Logs
description: >-
This Api endpoint lists all Autodiscover logs.
Tip: You can limit how many logs you want to get by using `/<count>` at
the end of the api url.
operationId: Get Autodiscover logs
summary: Get Autodiscover logs
"/api/v1/get/logs/dovecot/{count}":
get:
parameters:
- description: Number of logs to return
in: path
name: count
required: true
schema:
type: number
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- message: >-
managesieve-login: Disconnected (no auth attempts in 0
secs): user=<>, rip=172.22.1.3, lip=172.22.1.250
priority: info
program: dovecot
time: "1569938740"
description: OK
headers: {}
tags:
- Logs
description: >-
This Api endpoint lists all Dovecot logs.
Tip: You can limit how many logs you want to get by using `/<count>` at
the end of the api url.
operationId: Get Dovecot logs
summary: Get Dovecot logs
"/api/v1/get/logs/netfilter/{count}":
get:
parameters:
- description: Number of logs to return
in: path
name: count
required: true
schema:
type: number
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- message: "Whitelist was changed, it has 1 entries"
priority: info
time: 1569754911
- message: Add host/network 1.1.1.1/32 to blacklist
priority: crit
time: 1569754911
description: OK
headers: {}
tags:
- Logs
description: >-
This Api endpoint lists all Netfilter logs.
Tip: You can limit how many logs you want to get by using `/<count>` at
the end of the api url.
operationId: Get Netfilter logs
summary: Get Netfilter logs
"/api/v1/get/logs/postfix/{count}":
get:
parameters:
- description: Number of logs to return
in: path
name: count
required: true
schema:
type: number
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- message: "EF1711500458: removed"
priority: info
program: postfix/qmgr
time: "1569937433"
description: OK
headers: {}
tags:
- Logs
description: >-
This Api endpoint lists all Postfix logs.
Tip: You can limit how many logs you want to get by using `/<count>` at
the end of the api url.
operationId: Get Postfix logs
summary: Get Postfix logs
"/api/v1/get/logs/ratelimited/{count}":
get:
parameters:
- description: Number of logs to return
in: path
name: count
required: true
schema:
type: number
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- from: awesome@mailcow.email
header_from: '"Awesome" <awesome@mailcow.email>'
header_subject: Mailcow is amazing
ip: 172.22.1.248
message_id: 6a-5d892500-7-240abd80@90879116
qid: E3CF91500458
rcpt: hello@mailcow.email
rl_hash: RLsdz3tuabozgd4oacbdh8kc78
rl_info: mailcow(RLsdz3tuabozgd4oacbdh8kc78)
rl_name: mailcow
time: 1569269003
user: awesome@mailcow.email
description: OK
headers: {}
tags:
- Logs
description: >-
This Api endpoint lists all Ratelimit logs.
Tip: You can limit how many logs you want to get by using `/<count>` at
the end of the api url.
operationId: Get Ratelimit logs
summary: Get Ratelimit logs
"/api/v1/get/logs/rspamd-history/{count}":
get:
parameters:
- description: Number of logs to return
in: path
name: count
required: true
schema:
type: number
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
description: OK
headers: {}
tags:
- Logs
description: >-
This Api endpoint lists all Rspamd logs.
Tip: You can limit how many logs you want to get by using `/<count>` at
the end of the api url.
operationId: Get Rspamd logs
summary: Get Rspamd logs
"/api/v1/get/logs/sogo/{count}":
get:
parameters:
- description: Number of logs to return
in: path
name: count
required: true
schema:
type: number
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- message: >-
[109]:
mailcowdockerized_watchdog-mailcow_1.mailcowdockerized_mailcow-network
"GET /SOGo.index/ HTTP/1.1" 200 2531/0 0.005 - - 0
priority: notice
program: sogod
time: "1569938874"
description: OK
headers: {}
tags:
- Logs
description: >-
This Api endpoint lists all SOGo logs.
Tip: You can limit how many logs you want to get by using `/<count>` at
the end of the api url.
operationId: Get SOGo logs
summary: Get SOGo logs
"/api/v1/get/logs/watchdog/{count}":
get:
parameters:
- description: Number of logs to return
in: path
name: count
required: true
schema:
type: number
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- hpdiff: "0"
hpnow: "1"
hptotal: "1"
lvl: "100"
service: Fail2ban
time: "1569938958"
- hpdiff: "0"
hpnow: "5"
hptotal: "5"
lvl: "100"
service: Rspamd
time: "1569938956"
description: OK
headers: {}
tags:
- Logs
description: >-
This Api endpoint lists all Watchdog logs.
Tip: You can limit how many logs you want to get by using `/<count>` at
the end of the api url.
operationId: Get Watchdog logs
summary: Get Watchdog logs
"/api/v1/get/mailbox/{id}":
get:
parameters:
- description: id of entry you want to get
example: all
in: path
name: id
required: true
schema:
enum:
- all
- user@domain.tld
type: string
- description: comma seperated list of tags to filter by
example: "tag1,tag2"
in: query
name: tags
required: false
schema:
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
attributes:
force_pw_update: "0"
mailbox_format: "maildir:"
quarantine_notification: never
sogo_access: "1"
tls_enforce_in: "0"
tls_enforce_out: "0"
domain: doman3.tld
is_relayed: 0
local_part: info
max_new_quota: 10737418240
messages: 0
name: Full name
percent_class: success
percent_in_use: 0
quota: 3221225472
quota_used: 0
rl: false
spam_aliases: 0
username: info@doman3.tld
tags: ["tag1", "tag2"]
description: OK
headers: {}
tags:
- Mailboxes
description: You can list all mailboxes existing in system.
operationId: Get mailboxes
summary: Get mailboxes
/api/v1/get/mailq/all:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- arrival_time: 1570091234
message_size: 1848
queue_id: B98C6260CA1
queue_name: incoming
recipients:
- recipient@awesomecow.tld
sender: sender@mailcow.tld
description: OK
headers: {}
tags:
- Queue Manager
description: Get the current mail queue and everything it contains.
operationId: Get Queue
summary: Get Queue
"/api/v1/get/oauth2-client/{id}":
get:
parameters:
- description: id of entry you want to get
example: all
in: path
name: id
required: true
schema:
enum:
- all
- "1"
- "2"
- "5"
- "10"
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- client_id: 17c76aaa88c0
client_secret: 73fc668a88147e32a31ff80c
grant_types: null
id: 1
redirect_uri: "https://mailcow.tld"
scope: profile
user_id: null
description: OK
headers: {}
tags:
- oAuth Clients
description: Using this endpoint you can get all oAuth clients.
operationId: Get oAuth Clients
summary: Get oAuth Clients
"/api/v1/get/policy_bl_domain/{domain}":
get:
parameters:
- description: name of domain
in: path
name: domain
required: true
schema:
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- object: domain.tld
prefid: 2
value: "*@baddomain.tld"
description: OK
headers: {}
tags:
- Domain antispam policies
description: You can list all blacklist policies per domain.
operationId: List blacklist domain policy
summary: List blacklist domain policy
"/api/v1/get/policy_wl_domain/{domain}":
get:
parameters:
- description: name of domain
in: path
name: domain
required: true
schema:
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- object: domain.tld
prefid: 1
value: "*@gooddomain.tld"
description: OK
headers: {}
tags:
- Domain antispam policies
description: You can list all whitelist policies per domain.
operationId: List whitelist domain policy
summary: List whitelist domain policy
/api/v1/get/quarantine/all:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
created: 1572688831
id: 33
notified: 1
qid: 8224615004C1
rcpt: admin@domain.tld
score: 15.48
sender: bounces@send.domain.tld
subject: mailcow is awesome
virus_flag: 0
description: OK
headers: {}
tags:
- Quarantine
description: Get all mails that are currently in Quarantine.
operationId: Get mails in Quarantine
summary: Get mails in Quarantine
"/api/v1/get/recipient_map/{id}":
get:
parameters:
- description: id of entry you want to get
example: all
in: path
name: id
required: true
schema:
enum:
- all
- "1"
- "2"
- "5"
- "10"
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
created: "2019-10-02 22:06:29"
id: 3
modified: null
recipient_map_new: target@mailcow.tld
recipient_map_old: recipient@mailcow.tld
description: OK
headers: {}
tags:
- Address Rewriting
description: Using this endpoint you can get all recipient maps.
operationId: Get Recipient Map
summary: Get Recipient Map
"/api/v1/get/relayhost/{id}":
get:
parameters:
- description: id of entry you want to get
example: all
in: path
name: id
required: true
schema:
enum:
- all
- "1"
- "2"
- "5"
- "10"
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
hostname: "mailcow.tld:25"
id: 1
password: supersecurepassword
password_short: tes...
used_by_domains: ""
username: testuser
description: OK
headers: {}
tags:
- Routing
description: Using this endpoint you can get all Sender-Dependent Transports.
operationId: Get Sender-Dependent Transports
summary: Get Sender-Dependent Transports
/api/v1/get/resource/all:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
description: test
domain: mailcow.tld
kind: location
local_part: test
multiple_bookings: 0
name: test@mailcow.tld
description: OK
headers: {}
tags:
- Resources
description: Using this endpoint you can get all Resources.
operationId: Get Resources
summary: Get Resources
"/api/v1/get/rl-mbox/{mailbox}":
get:
parameters:
- description: name of mailbox or all
in: path
name: mailbox
required: true
schema:
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- frame: s
mailbox: leon@mailcow.tld
value: "5"
- frame: s
mailbox: lisa@mailcow.tld
value: "3"
description: OK
headers: {}
tags:
- Ratelimits
description: >-
Using this endpoint you can get the ratelimits for a certain mailbox.
You can use all for all mailboxes.
operationId: Get mailbox ratelimits
summary: Get mailbox ratelimits
"/api/v1/get/rl-domain/{domain}":
get:
parameters:
- description: name of domain or all
in: path
name: domain
required: true
schema:
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- frame: s
domain: domain.tld
value: "5"
- frame: s
mailbox: domain2.tld
value: "3"
description: OK
headers: {}
tags:
- Ratelimits
description: >-
Using this endpoint you can get the ratelimits for a certain domains.
You can use all for all domain.
operationId: Get domain ratelimits
summary: Get domain ratelimits
/api/v1/edit/rl-mbox/:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- type: success
log:
- ratelimit
- edit
- mailbox
- object:
- info@domain.tld
rl_value: "10"
rl_frame: h
msg:
- rl_saved
- info@domain.tld
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Ratelimits
description: >-
Using this endpoint you can edit the ratelimits for a certain mailbox.
operationId: Edit mailbox ratelimits
requestBody:
content:
application/json:
schema:
example:
attr:
rl_value: "10"
rl_frame: "h"
items:
- info@domain.tld
properties:
attr:
properties:
rl_frame:
description: contains the frame for the ratelimit h,s,m
type: string
rl_value:
description: contains the rate for the ratelimit 10,20,50,1
type: number
type: object
items:
description: contains list of mailboxes you want to edit the ratelimit of
type: object
type: object
summary: Edit mailbox ratelimits
/api/v1/edit/rl-domain/:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- type: success
- log:
- ratelimit
- edit
- domain
- object:
- domain.tld
rl_value: "50"
rl_frame: "h"
msg:
- rl_saved
- domain.tld
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Ratelimits
description: >-
Using this endpoint you can edit the ratelimits for a certain domains.
operationId: Edit domain ratelimits
requestBody:
content:
application/json:
schema:
example:
attr:
rl_value: "10"
rl_frame: "h"
items:
- domain.tld
properties:
attr:
properties:
rl_frame:
description: contains the frame for the ratelimit h,s,m
type: string
rl_value:
description: contains the rate for the ratelimit 10,20,50,1
type: number
type: object
items:
description: contains list of domains you want to edit the ratelimit of
type: object
type: object
summary: Edit domain ratelimits
/api/v1/get/status/containers:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
acme-mailcow:
container: acme-mailcow
image: "mailcow/acme:1.63"
started_at: "2019-12-22T21:00:08.270660275Z"
state: running
type: info
clamd-mailcow:
container: clamd-mailcow
image: "mailcow/clamd:1.35"
started_at: "2019-12-22T21:00:01.622856172Z"
state: running
type: info
dockerapi-mailcow:
container: dockerapi-mailcow
image: "mailcow/dockerapi:1.36"
started_at: "2019-12-22T20:59:59.984797808Z"
state: running
type: info
dovecot-mailcow:
container: dovecot-mailcow
image: "mailcow/dovecot:1.104"
started_at: "2019-12-22T21:00:08.988680259Z"
state: running
type: info
ipv6nat-mailcow:
container: ipv6nat-mailcow
image: robbertkl/ipv6nat
started_at: "2019-12-22T21:06:37.273225445Z"
state: running
type: info
memcached-mailcow:
container: memcached-mailcow
image: "memcached:alpine"
started_at: "2019-12-22T20:59:58.0907785Z"
state: running
type: info
mysql-mailcow:
container: mysql-mailcow
image: "mariadb:10.3"
started_at: "2019-12-22T21:00:02.201937528Z"
state: running
type: info
netfilter-mailcow:
container: netfilter-mailcow
image: "mailcow/netfilter:1.31"
started_at: "2019-12-22T21:00:09.851559297Z"
state: running
type: info
nginx-mailcow:
container: nginx-mailcow
image: "nginx:mainline-alpine"
started_at: "2019-12-22T21:00:12.9843038Z"
state: running
type: info
olefy-mailcow:
container: olefy-mailcow
image: "mailcow/olefy:1.2"
started_at: "2019-12-22T20:59:59.676259274Z"
state: running
type: info
php-fpm-mailcow:
container: php-fpm-mailcow
image: "mailcow/phpfpm:1.55"
started_at: "2019-12-22T21:00:00.955808957Z"
state: running
type: info
postfix-mailcow:
container: postfix-mailcow
image: "mailcow/postfix:1.44"
started_at: "2019-12-22T21:00:07.186717617Z"
state: running
type: info
redis-mailcow:
container: redis-mailcow
image: "redis:5-alpine"
started_at: "2019-12-22T20:59:56.827166834Z"
state: running
type: info
rspamd-mailcow:
container: rspamd-mailcow
image: "mailcow/rspamd:1.56"
started_at: "2019-12-22T21:00:12.456075355Z"
state: running
type: info
sogo-mailcow:
container: sogo-mailcow
image: "mailcow/sogo:1.65"
started_at: "2019-12-22T20:59:58.382274592Z"
state: running
type: info
solr-mailcow:
container: solr-mailcow
image: "mailcow/solr:1.7"
started_at: "2019-12-22T20:59:59.635413798Z"
state: running
type: info
unbound-mailcow:
container: unbound-mailcow
image: "mailcow/unbound:1.10"
started_at: "2019-12-22T20:59:58.760595825Z"
state: running
type: info
watchdog-mailcow:
container: watchdog-mailcow
image: "mailcow/watchdog:1.65"
started_at: "2019-12-22T20:59:56.028660382Z"
state: running
type: info
description: OK
headers: {}
tags:
- Status
description: >-
Using this endpoint you can get the status of all containers and when
hey where started and a few other details.
operationId: Get container status
summary: Get container status
/api/v1/get/status/solr:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
solr_documents: null
solr_enabled: false
solr_size: null
type: info
description: OK
headers: {}
tags:
- Status
description: >-
Using this endpoint you can get the status of all containers and when
hey where started and a few other details.
operationId: Get solr status
summary: Get solr status
/api/v1/get/status/vmail:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
disk: /dev/mapper/mail--vg-root
total: 41G
type: info
used: 11G
used_percent: 28%
description: OK
headers: {}
tags:
- Status
description: >-
Using this endpoint you can get the status of the vmail and the amount
of used storage.
operationId: Get vmail status
summary: Get vmail status
/api/v1/get/status/version:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
version: "2022-04"
description: OK
headers: {}
tags:
- Status
description: >-
Using this endpoint you can get the current running release of this
instance.
operationId: Get version status
summary: Get version status
/api/v1/get/syncjobs/all/no_log:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
authmd51: 0
authmech1: PLAIN
automap: 1
created: "2019-05-22 11:37:25"
custom_params: ""
delete1: 0
delete2: 0
delete2duplicates: 1
domain2: ""
enc1: TLS
exclude: (?i)spam|(?i)junk
host1: imap.server.tld
id: 1
is_running: 0
last_run: "2019-05-22 11:40:02"
log: ""
maxage: 0
maxbytespersecond: "0"
mins_interval: "20"
modified: "2019-05-22 11:40:02"
port1: 993
regextrans2: ""
skipcrossduplicates: 0
subfolder2: External
subscribeall: 1
timeout1: 600
timeout2: 600
user1: username
user2: mailbox@domain.tld
description: OK
headers: {}
tags:
- Sync jobs
description: You can list all syn jobs existing in system.
operationId: Get sync jobs
summary: Get sync jobs
"/api/v1/get/tls-policy-map/{id}":
get:
parameters:
- description: id of entry you want to get
example: all
in: path
name: id
required: true
schema:
enum:
- all
- "1"
- "2"
- "5"
- "10"
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- parameters: ""
active: "1"
created: "2019-10-03 08:42:12"
dest: mailcow.tld
id: 1
modified: null
policy: encrypt
description: OK
headers: {}
tags:
- Outgoing TLS Policy Map Overrides
description: Using this endpoint you can get all TLS policy map override maps.
operationId: Get TLS Policy Map
summary: Get TLS Policy Map
"/api/v1/get/transport/{id}":
get:
parameters:
- description: id of entry you want to get
example: all
in: path
name: id
required: true
schema:
enum:
- all
- "1"
- "2"
- "5"
- "10"
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
destination: example.org
id: 1
lookup_mx: "0"
nexthop: "host:25"
password: supersecurepw
password_short: sup...
username: testuser
description: OK
headers: {}
tags:
- Routing
description: Using this endpoint you can get all Transport Maps.
operationId: Get Transport Maps
summary: Get Transport Maps
/api/v1/edit/spam-score/:
post:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- type: success
log:
- mailbox
- edit
- spam_score
- username:
- info@domain.tld
spam_score: "8,15"
msg:
- mailbox_modified
- info@domain.tld
schema:
properties:
log:
description: contains request object
items: {}
type: array
msg:
items: {}
type: array
type:
enum:
- success
- danger
- error
type: string
type: object
description: OK
headers: {}
tags:
- Mailboxes
description: >-
Using this endpoint you can edit the spam filter score for a certain mailbox.
operationId: Edit mailbox spam filter score
requestBody:
content:
application/json:
schema:
example:
- items:
- info@domain.tld
attr:
spam_score: "8,15"
summary: Edit mailbox spam filter score
"/api/v1/get/mailbox/all/{domain}":
get:
parameters:
- description: name of domain
in: path
name: domain
required: false
schema:
type: string
- description: e.g. api-key-string
example: api-key-string
in: header
name: X-API-Key
required: false
schema:
type: string
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
- active: "1"
attributes:
force_pw_update: "0"
mailbox_format: "maildir:"
quarantine_notification: never
sogo_access: "1"
tls_enforce_in: "0"
tls_enforce_out: "0"
domain: domain3.tld
is_relayed: 0
local_part: info
max_new_quota: 10737418240
messages: 0
name: Full name
percent_class: success
percent_in_use: 0
quota: 3221225472
quota_used: 0
rl: false
spam_aliases: 0
username: info@domain3.tld
tags: ["tag1", "tag2"]
description: OK
headers: {}
tags:
- Mailboxes
description: You can list all mailboxes existing in system for a specific domain.
operationId: Get mailboxes of a domain
summary: Get mailboxes of a domain
tags:
- name: Domains
description: You can create antispam whitelist and blacklist policies
- name: Domain antispam policies
description: You can edit the Domain Antispam policies
- name: Mailboxes
description: You can manage mailboxes
- name: Aliases
description: You can manage aliases
- name: Sync jobs
description: Using Syncjobs you can sync your mails with other email servers
- name: Fordwarding Hosts
description: Forwarding Hosts enable you to send mail using a relay
- name: Logs
description: Get all mailcow system logs
- name: Queue Manager
description: Manage the postfix mail queue
- name: Quarantine
description: Check what emails went to quarantine
- name: Fail2Ban
description: Manage the Netfilter fail2ban options
- name: DKIM
description: Manage DKIM keys
- name: Domain admin
description: Create or udpdate domain admin users
- name: Address Rewriting
description: Create BCC maps or recipient maps
- name: Outgoing TLS Policy Map Overrides
description: Force global TLS policys
- name: oAuth Clients
description: Use mailcow as a oAuth server
- name: Routing
description: Define your own email routes
- name: Resources
description: Manage ressources
- name: App Passwords
description: Create mailbox app passwords
- name: Status
description: Get the status of your cow
- name: Ratelimits
description: Edit domain ratelimits
diff --git a/data/web/inc/functions.pushover.inc.php b/data/web/inc/functions.pushover.inc.php
index 74e8bb1c..5393c0d5 100644
--- a/data/web/inc/functions.pushover.inc.php
+++ b/data/web/inc/functions.pushover.inc.php
@@ -1,221 +1,223 @@
<?php
function pushover($_action, $_data = null) {
global $pdo;
switch ($_action) {
case 'edit':
if (!isset($_SESSION['acl']['pushover']) || $_SESSION['acl']['pushover'] != "1" ) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'access_denied'
);
return false;
}
if (!is_array($_data['username'])) {
$usernames = array();
$usernames[] = $_data['username'];
}
else {
$usernames = $_data['username'];
}
foreach ($usernames as $username) {
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'access_denied'
);
continue;
}
$delete = $_data['delete'];
if ($delete == "true") {
$stmt = $pdo->prepare("DELETE FROM `pushover` WHERE `username` = :username");
$stmt->execute(array(
':username' => $username
));
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'pushover_settings_edited'
);
continue;
}
$is_now = pushover('get', $username);
if (!empty($is_now)) {
$key = (!empty($_data['key'])) ? $_data['key'] : $is_now['key'];
$token = (!empty($_data['token'])) ? $_data['token'] : $is_now['token'];
$senders = (isset($_data['senders'])) ? $_data['senders'] : $is_now['senders'];
$senders_regex = (isset($_data['senders_regex'])) ? $_data['senders_regex'] : $is_now['senders_regex'];
$title = (!empty($_data['title'])) ? $_data['title'] : $is_now['title'];
$text = (!empty($_data['text'])) ? $_data['text'] : $is_now['text'];
$active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active'];
$evaluate_x_prio = (isset($_data['evaluate_x_prio'])) ? intval($_data['evaluate_x_prio']) : $is_now['evaluate_x_prio'];
$only_x_prio = (isset($_data['only_x_prio'])) ? intval($_data['only_x_prio']) : $is_now['only_x_prio'];
+ $sound = (isset($_data['sound'])) ? $_data['sound'] : $is_now['sound'];
}
else {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'access_denied'
);
continue;
}
if (!empty($senders_regex) && !is_valid_regex($senders_regex)) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'Invalid regex'
);
continue;
}
$senders = array_map('trim', preg_split( "/( |,|;|\n)/", $senders));
foreach ($senders as $i => &$sender) {
if (empty($sender)) {
continue;
}
if (!filter_var($sender, FILTER_VALIDATE_EMAIL) === true) {
unset($senders[$i]);
continue;
}
$senders[$i] = preg_replace('/\.(?=.*?@gmail\.com$)/', '$1', $sender);
}
$senders = array_filter($senders);
if (empty($senders)) { $senders = ''; }
$senders = implode(",", (array)$senders);
if (!ctype_alnum($key) || strlen($key) != 30) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data, $_data),
'msg' => 'pushover_key'
);
continue;
}
if (!ctype_alnum($token) || strlen($token) != 30) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data, $_data),
'msg' => 'pushover_token'
);
continue;
}
$po_attributes = json_encode(
array(
'evaluate_x_prio' => strval(intval($evaluate_x_prio)),
- 'only_x_prio' => strval(intval($only_x_prio))
+ 'only_x_prio' => strval(intval($only_x_prio)),
+ 'sound' => strval($sound)
)
);
$stmt = $pdo->prepare("REPLACE INTO `pushover` (`username`, `key`, `attributes`, `senders_regex`, `senders`, `token`, `title`, `text`, `active`)
VALUES (:username, :key, :po_attributes, :senders_regex, :senders, :token, :title, :text, :active)");
$stmt->execute(array(
':username' => $username,
':key' => $key,
':po_attributes' => $po_attributes,
':senders_regex' => $senders_regex,
':senders' => $senders,
':token' => $token,
':title' => $title,
':text' => $text,
':active' => $active
));
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'pushover_settings_edited'
);
}
break;
case 'get':
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'access_denied'
);
return false;
}
$stmt = $pdo->prepare("SELECT * FROM `pushover` WHERE `username` = :username");
$stmt->execute(array(
':username' => $_data
));
$data = $stmt->fetch(PDO::FETCH_ASSOC);
$data['attributes'] = json_decode($data['attributes'], true);
if (empty($data)) {
return false;
}
else {
return $data;
}
break;
case 'test':
if (!isset($_SESSION['acl']['pushover']) || $_SESSION['acl']['pushover'] != "1" ) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'access_denied'
);
return false;
}
if (!is_array($_data['username'])) {
$usernames = array();
$usernames[] = $_data['username'];
}
else {
$usernames = $_data['username'];
}
foreach ($usernames as $username) {
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'access_denied'
);
continue;
}
$stmt = $pdo->prepare("SELECT * FROM `pushover`
WHERE `username` = :username");
$stmt->execute(array(
':username' => $username
));
$api_data = $stmt->fetch(PDO::FETCH_ASSOC);
if (!empty($api_data)) {
$title = (!empty($api_data['title'])) ? $api_data['title'] : 'Mail';
$text = (!empty($api_data['text'])) ? $api_data['text'] : 'You\'ve got mail 📧';
curl_setopt_array($ch = curl_init(), array(
CURLOPT_URL => "https://api.pushover.net/1/users/validate.json",
CURLOPT_POSTFIELDS => array(
"token" => $api_data['token'],
"user" => $api_data['key']
),
CURLOPT_SAFE_UPLOAD => true,
CURLOPT_RETURNTRANSFER => true,
));
$result = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpcode == 200) {
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => sprintf('Pushover API OK (%d): %s', $httpcode, $result)
);
}
else {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => sprintf('Pushover API ERR (%d): %s', $httpcode, $result)
);
}
}
else {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'pushover_credentials_missing'
);
return false;
}
}
break;
}
}
diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php
index b47bd5c2..48db1a62 100644
--- a/data/web/inc/init_db.inc.php
+++ b/data/web/inc/init_db.inc.php
@@ -1,1359 +1,1360 @@
<?php
function init_db_schema() {
try {
global $pdo;
$db_version = "25072022_2300";
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results != 0) {
$stmt = $pdo->query("SELECT `version` FROM `versions` WHERE `application` = 'db_schema'");
if ($stmt->fetch(PDO::FETCH_ASSOC)['version'] == $db_version) {
return true;
}
if (!preg_match('/y|yes/i', getenv('MASTER'))) {
$_SESSION['return'][] = array(
'type' => 'warning',
'log' => array(__FUNCTION__),
'msg' => 'Database not initialized: not running db_init on slave.'
);
return true;
}
}
$views = array(
"grouped_mail_aliases" => "CREATE VIEW grouped_mail_aliases (username, aliases) AS
SELECT goto, IFNULL(GROUP_CONCAT(address ORDER BY address SEPARATOR ' '), '') AS address FROM alias
WHERE address!=goto
AND active = '1'
AND sogo_visible = '1'
AND address NOT LIKE '@%'
GROUP BY goto;",
// START
// Unused at the moment - we cannot allow to show a foreign mailbox as sender address in SOGo, as SOGo does not like this
// We need to create delegation in SOGo AND set a sender_acl in mailcow to allow to send as user X
"grouped_sender_acl" => "CREATE VIEW grouped_sender_acl (username, send_as_acl) AS
SELECT logged_in_as, IFNULL(GROUP_CONCAT(send_as SEPARATOR ' '), '') AS send_as_acl FROM sender_acl
WHERE send_as NOT LIKE '@%'
GROUP BY logged_in_as;",
// END
"grouped_sender_acl_external" => "CREATE VIEW grouped_sender_acl_external (username, send_as_acl) AS
SELECT logged_in_as, IFNULL(GROUP_CONCAT(send_as SEPARATOR ' '), '') AS send_as_acl FROM sender_acl
WHERE send_as NOT LIKE '@%' AND external = '1'
GROUP BY logged_in_as;",
"grouped_domain_alias_address" => "CREATE VIEW grouped_domain_alias_address (username, ad_alias) AS
SELECT username, IFNULL(GROUP_CONCAT(local_part, '@', alias_domain SEPARATOR ' '), '') AS ad_alias FROM mailbox
LEFT OUTER JOIN alias_domain ON target_domain=domain
GROUP BY username;",
"sieve_before" => "CREATE VIEW sieve_before (id, username, script_name, script_data) AS
SELECT md5(script_data), username, script_name, script_data FROM sieve_filters
WHERE filter_type = 'prefilter';",
"sieve_after" => "CREATE VIEW sieve_after (id, username, script_name, script_data) AS
SELECT md5(script_data), username, script_name, script_data FROM sieve_filters
WHERE filter_type = 'postfilter';"
);
$tables = array(
"versions" => array(
"cols" => array(
"application" => "VARCHAR(255) NOT NULL",
"version" => "VARCHAR(100) NOT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
),
"keys" => array(
"primary" => array(
"" => array("application")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"admin" => array(
"cols" => array(
"username" => "VARCHAR(255) NOT NULL",
"password" => "VARCHAR(255) NOT NULL",
"superadmin" => "TINYINT(1) NOT NULL DEFAULT '0'",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE NOW(0)",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("username")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"fido2" => array(
"cols" => array(
"username" => "VARCHAR(255) NOT NULL",
"friendlyName" => "VARCHAR(255)",
"rpId" => "VARCHAR(255) NOT NULL",
"credentialPublicKey" => "TEXT NOT NULL",
"certificateChain" => "TEXT",
// Can be null for format "none"
"certificate" => "TEXT",
"certificateIssuer" => "VARCHAR(255)",
"certificateSubject" => "VARCHAR(255)",
"signatureCounter" => "INT",
"AAGUID" => "BLOB",
"credentialId" => "BLOB NOT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE NOW(0)",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"_sogo_static_view" => array(
"cols" => array(
"c_uid" => "VARCHAR(255) NOT NULL",
"domain" => "VARCHAR(255) NOT NULL",
"c_name" => "VARCHAR(255) NOT NULL",
"c_password" => "VARCHAR(255) NOT NULL DEFAULT ''",
"c_cn" => "VARCHAR(255)",
"mail" => "VARCHAR(255) NOT NULL",
// TODO -> use TEXT and check if SOGo login breaks on empty aliases
"aliases" => "TEXT NOT NULL",
"ad_aliases" => "VARCHAR(6144) NOT NULL DEFAULT ''",
"ext_acl" => "VARCHAR(6144) NOT NULL DEFAULT ''",
"kind" => "VARCHAR(100) NOT NULL DEFAULT ''",
"multiple_bookings" => "INT NOT NULL DEFAULT -1"
),
"keys" => array(
"primary" => array(
"" => array("c_uid")
),
"key" => array(
"domain" => array("domain")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"relayhosts" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"hostname" => "VARCHAR(255) NOT NULL",
"username" => "VARCHAR(255) NOT NULL",
"password" => "VARCHAR(255) NOT NULL",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("id")
),
"key" => array(
"hostname" => array("hostname")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"transports" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"destination" => "VARCHAR(255) NOT NULL",
"nexthop" => "VARCHAR(255) NOT NULL",
"username" => "VARCHAR(255) NOT NULL DEFAULT ''",
"password" => "VARCHAR(255) NOT NULL DEFAULT ''",
"is_mx_based" => "TINYINT(1) NOT NULL DEFAULT '0'",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("id")
),
"key" => array(
"destination" => array("destination"),
"nexthop" => array("nexthop"),
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"alias" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"address" => "VARCHAR(255) NOT NULL",
"goto" => "TEXT NOT NULL",
"domain" => "VARCHAR(255) NOT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"private_comment" => "TEXT",
"public_comment" => "TEXT",
"sogo_visible" => "TINYINT(1) NOT NULL DEFAULT '1'",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("id")
),
"unique" => array(
"address" => array("address")
),
"key" => array(
"domain" => array("domain")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"api" => array(
"cols" => array(
"api_key" => "VARCHAR(255) NOT NULL",
"allow_from" => "VARCHAR(512) NOT NULL",
"skip_ip_check" => "TINYINT(1) NOT NULL DEFAULT '0'",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE NOW(0)",
"access" => "ENUM('ro', 'rw') NOT NULL DEFAULT 'rw'",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("api_key")
),
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sender_acl" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"logged_in_as" => "VARCHAR(255) NOT NULL",
"send_as" => "VARCHAR(255) NOT NULL",
"external" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
"" => array("id")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"domain" => array(
// Todo: Move some attributes to json
"cols" => array(
"domain" => "VARCHAR(255) NOT NULL",
"description" => "VARCHAR(255)",
"aliases" => "INT(10) NOT NULL DEFAULT '0'",
"mailboxes" => "INT(10) NOT NULL DEFAULT '0'",
"defquota" => "BIGINT(20) NOT NULL DEFAULT '3072'",
"maxquota" => "BIGINT(20) NOT NULL DEFAULT '102400'",
"quota" => "BIGINT(20) NOT NULL DEFAULT '102400'",
"relayhost" => "VARCHAR(255) NOT NULL DEFAULT '0'",
"backupmx" => "TINYINT(1) NOT NULL DEFAULT '0'",
"gal" => "TINYINT(1) NOT NULL DEFAULT '1'",
"relay_all_recipients" => "TINYINT(1) NOT NULL DEFAULT '0'",
"relay_unknown_only" => "TINYINT(1) NOT NULL DEFAULT '0'",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("domain")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"tags_domain" => array(
"cols" => array(
"tag_name" => "VARCHAR(255) NOT NULL",
"domain" => "VARCHAR(255) NOT NULL"
),
"keys" => array(
"fkey" => array(
"fk_tags_domain" => array(
"col" => "domain",
"ref" => "domain.domain",
"delete" => "CASCADE",
"update" => "NO ACTION"
)
),
"unique" => array(
"tag_name" => array("tag_name", "domain")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"tls_policy_override" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"dest" => "VARCHAR(255) NOT NULL",
"policy" => "ENUM('none', 'may', 'encrypt', 'dane', 'dane-only', 'fingerprint', 'verify', 'secure') NOT NULL",
"parameters" => "VARCHAR(255) DEFAULT ''",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("id")
),
"unique" => array(
"dest" => array("dest")
),
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"quarantine" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"qid" => "VARCHAR(30) NOT NULL",
"subject" => "VARCHAR(500)",
"score" => "FLOAT(8,2)",
"ip" => "VARCHAR(50)",
"action" => "CHAR(20) NOT NULL DEFAULT 'unknown'",
"symbols" => "JSON",
"fuzzy_hashes" => "JSON",
"sender" => "VARCHAR(255) NOT NULL DEFAULT 'unknown'",
"rcpt" => "VARCHAR(255)",
"msg" => "LONGTEXT",
"domain" => "VARCHAR(255)",
"notified" => "TINYINT(1) NOT NULL DEFAULT '0'",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"user" => "VARCHAR(255) NOT NULL DEFAULT 'unknown'",
),
"keys" => array(
"primary" => array(
"" => array("id")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"mailbox" => array(
"cols" => array(
"username" => "VARCHAR(255) NOT NULL",
"password" => "VARCHAR(255) NOT NULL",
"name" => "VARCHAR(255)",
"description" => "VARCHAR(255)",
// mailbox_path_prefix is followed by domain/local_part/
"mailbox_path_prefix" => "VARCHAR(150) DEFAULT '/var/vmail/'",
"quota" => "BIGINT(20) NOT NULL DEFAULT '102400'",
"local_part" => "VARCHAR(255) NOT NULL",
"domain" => "VARCHAR(255) NOT NULL",
"attributes" => "JSON",
"kind" => "VARCHAR(100) NOT NULL DEFAULT ''",
"multiple_bookings" => "INT NOT NULL DEFAULT -1",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("username")
),
"key" => array(
"domain" => array("domain"),
"kind" => array("kind")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"tags_mailbox" => array(
"cols" => array(
"tag_name" => "VARCHAR(255) NOT NULL",
"username" => "VARCHAR(255) NOT NULL"
),
"keys" => array(
"fkey" => array(
"fk_tags_mailbox" => array(
"col" => "username",
"ref" => "mailbox.username",
"delete" => "CASCADE",
"update" => "NO ACTION"
)
),
"unique" => array(
"tag_name" => array("tag_name", "username")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sieve_filters" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"username" => "VARCHAR(255) NOT NULL",
"script_desc" => "VARCHAR(255) NOT NULL",
"script_name" => "ENUM('active','inactive')",
"script_data" => "TEXT NOT NULL",
"filter_type" => "ENUM('postfilter','prefilter')",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP"
),
"keys" => array(
"primary" => array(
"" => array("id")
),
"key" => array(
"username" => array("username"),
"script_desc" => array("script_desc")
),
"fkey" => array(
"fk_username_sieve_global_before" => array(
"col" => "username",
"ref" => "mailbox.username",
"delete" => "CASCADE",
"update" => "NO ACTION"
)
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"app_passwd" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"name" => "VARCHAR(255) NOT NULL",
"mailbox" => "VARCHAR(255) NOT NULL",
"domain" => "VARCHAR(255) NOT NULL",
"password" => "VARCHAR(255) NOT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"imap_access" => "TINYINT(1) NOT NULL DEFAULT '1'",
"smtp_access" => "TINYINT(1) NOT NULL DEFAULT '1'",
"dav_access" => "TINYINT(1) NOT NULL DEFAULT '1'",
"eas_access" => "TINYINT(1) NOT NULL DEFAULT '1'",
"pop3_access" => "TINYINT(1) NOT NULL DEFAULT '1'",
"sieve_access" => "TINYINT(1) NOT NULL DEFAULT '1'",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("id")
),
"key" => array(
"mailbox" => array("mailbox"),
"password" => array("password"),
"domain" => array("domain"),
),
"fkey" => array(
"fk_username_app_passwd" => array(
"col" => "mailbox",
"ref" => "mailbox.username",
"delete" => "CASCADE",
"update" => "NO ACTION"
)
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"user_acl" => array(
"cols" => array(
"username" => "VARCHAR(255) NOT NULL",
"spam_alias" => "TINYINT(1) NOT NULL DEFAULT '1'",
"tls_policy" => "TINYINT(1) NOT NULL DEFAULT '1'",
"spam_score" => "TINYINT(1) NOT NULL DEFAULT '1'",
"spam_policy" => "TINYINT(1) NOT NULL DEFAULT '1'",
"delimiter_action" => "TINYINT(1) NOT NULL DEFAULT '1'",
"syncjobs" => "TINYINT(1) NOT NULL DEFAULT '0'",
"eas_reset" => "TINYINT(1) NOT NULL DEFAULT '1'",
"sogo_profile_reset" => "TINYINT(1) NOT NULL DEFAULT '0'",
"pushover" => "TINYINT(1) NOT NULL DEFAULT '1'",
// quarantine is for quarantine actions, todo: rename
"quarantine" => "TINYINT(1) NOT NULL DEFAULT '1'",
"quarantine_attachments" => "TINYINT(1) NOT NULL DEFAULT '1'",
"quarantine_notification" => "TINYINT(1) NOT NULL DEFAULT '1'",
"quarantine_category" => "TINYINT(1) NOT NULL DEFAULT '1'",
"app_passwds" => "TINYINT(1) NOT NULL DEFAULT '1'",
),
"keys" => array(
"primary" => array(
"" => array("username")
),
"fkey" => array(
"fk_username" => array(
"col" => "username",
"ref" => "mailbox.username",
"delete" => "CASCADE",
"update" => "NO ACTION"
)
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"alias_domain" => array(
"cols" => array(
"alias_domain" => "VARCHAR(255) NOT NULL",
"target_domain" => "VARCHAR(255) NOT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("alias_domain")
),
"key" => array(
"active" => array("active"),
"target_domain" => array("target_domain")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"spamalias" => array(
"cols" => array(
"address" => "VARCHAR(255) NOT NULL",
"goto" => "TEXT NOT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"validity" => "INT(11)"
),
"keys" => array(
"primary" => array(
"" => array("address")
),
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"filterconf" => array(
"cols" => array(
"object" => "VARCHAR(255) NOT NULL DEFAULT ''",
"option" => "VARCHAR(50) NOT NULL DEFAULT ''",
"value" => "VARCHAR(100) NOT NULL DEFAULT ''",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"prefid" => "INT(11) NOT NULL AUTO_INCREMENT"
),
"keys" => array(
"primary" => array(
"" => array("prefid")
),
"key" => array(
"object" => array("object")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"settingsmap" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"desc" => "VARCHAR(255) NOT NULL",
"content" => "LONGTEXT NOT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"active" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
"" => array("id")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"logs" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"task" => "CHAR(32) NOT NULL DEFAULT '000000'",
"type" => "VARCHAR(32) DEFAULT ''",
"msg" => "TEXT",
"call" => "TEXT",
"user" => "VARCHAR(64) NOT NULL",
"role" => "VARCHAR(32) NOT NULL",
"remote" => "VARCHAR(39) NOT NULL",
"time" => "INT(11) NOT NULL"
),
"keys" => array(
"primary" => array(
"" => array("id")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sasl_log" => array(
"cols" => array(
"service" => "VARCHAR(32) NOT NULL DEFAULT ''",
"app_password" => "INT",
"username" => "VARCHAR(255) NOT NULL",
"real_rip" => "VARCHAR(64) NOT NULL",
"datetime" => "DATETIME(0) NOT NULL DEFAULT NOW(0)"
),
"keys" => array(
"primary" => array(
"" => array("service", "real_rip", "username")
),
"key" => array(
"username" => array("username"),
"service" => array("service"),
"datetime" => array("datetime"),
"real_rip" => array("real_rip")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"quota2" => array(
"cols" => array(
"username" => "VARCHAR(255) NOT NULL",
"bytes" => "BIGINT(20) NOT NULL DEFAULT '0'",
"messages" => "BIGINT(20) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
"" => array("username")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"quota2replica" => array(
"cols" => array(
"username" => "VARCHAR(255) NOT NULL",
"bytes" => "BIGINT(20) NOT NULL DEFAULT '0'",
"messages" => "BIGINT(20) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
"" => array("username")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"domain_admins" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"username" => "VARCHAR(255) NOT NULL",
"domain" => "VARCHAR(255) NOT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("id")
),
"key" => array(
"username" => array("username")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"da_acl" => array(
"cols" => array(
"username" => "VARCHAR(255) NOT NULL",
"syncjobs" => "TINYINT(1) NOT NULL DEFAULT '1'",
"quarantine" => "TINYINT(1) NOT NULL DEFAULT '1'",
"login_as" => "TINYINT(1) NOT NULL DEFAULT '1'",
"sogo_access" => "TINYINT(1) NOT NULL DEFAULT '1'",
"app_passwds" => "TINYINT(1) NOT NULL DEFAULT '1'",
"bcc_maps" => "TINYINT(1) NOT NULL DEFAULT '1'",
"pushover" => "TINYINT(1) NOT NULL DEFAULT '0'",
"filters" => "TINYINT(1) NOT NULL DEFAULT '1'",
"ratelimit" => "TINYINT(1) NOT NULL DEFAULT '1'",
"spam_policy" => "TINYINT(1) NOT NULL DEFAULT '1'",
"extend_sender_acl" => "TINYINT(1) NOT NULL DEFAULT '0'",
"unlimited_quota" => "TINYINT(1) NOT NULL DEFAULT '0'",
"protocol_access" => "TINYINT(1) NOT NULL DEFAULT '1'",
"smtp_ip_access" => "TINYINT(1) NOT NULL DEFAULT '1'",
"alias_domains" => "TINYINT(1) NOT NULL DEFAULT '0'",
"mailbox_relayhost" => "TINYINT(1) NOT NULL DEFAULT '1'",
"domain_relayhost" => "TINYINT(1) NOT NULL DEFAULT '1'",
"domain_desc" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
"" => array("username")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"imapsync" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"user2" => "VARCHAR(255) NOT NULL",
"host1" => "VARCHAR(255) NOT NULL",
"authmech1" => "ENUM('PLAIN','LOGIN','CRAM-MD5') DEFAULT 'PLAIN'",
"regextrans2" => "VARCHAR(255) DEFAULT ''",
"authmd51" => "TINYINT(1) NOT NULL DEFAULT 0",
"domain2" => "VARCHAR(255) NOT NULL DEFAULT ''",
"subfolder2" => "VARCHAR(255) NOT NULL DEFAULT ''",
"user1" => "VARCHAR(255) NOT NULL",
"password1" => "VARCHAR(255) NOT NULL",
"exclude" => "VARCHAR(500) NOT NULL DEFAULT ''",
"maxage" => "SMALLINT NOT NULL DEFAULT '0'",
"mins_interval" => "SMALLINT UNSIGNED NOT NULL DEFAULT '0'",
"maxbytespersecond" => "VARCHAR(50) NOT NULL DEFAULT '0'",
"port1" => "SMALLINT UNSIGNED NOT NULL",
"enc1" => "ENUM('TLS','SSL','PLAIN') DEFAULT 'TLS'",
"delete2duplicates" => "TINYINT(1) NOT NULL DEFAULT '1'",
"delete1" => "TINYINT(1) NOT NULL DEFAULT '0'",
"delete2" => "TINYINT(1) NOT NULL DEFAULT '0'",
"automap" => "TINYINT(1) NOT NULL DEFAULT '0'",
"skipcrossduplicates" => "TINYINT(1) NOT NULL DEFAULT '0'",
"custom_params" => "VARCHAR(512) NOT NULL DEFAULT ''",
"timeout1" => "SMALLINT NOT NULL DEFAULT '600'",
"timeout2" => "SMALLINT NOT NULL DEFAULT '600'",
"subscribeall" => "TINYINT(1) NOT NULL DEFAULT '1'",
"is_running" => "TINYINT(1) NOT NULL DEFAULT '0'",
"returned_text" => "LONGTEXT",
"last_run" => "TIMESTAMP NULL DEFAULT NULL",
"success" => "TINYINT(1) UNSIGNED DEFAULT NULL",
"exit_status" => "VARCHAR(50) DEFAULT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"active" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
"" => array("id")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"bcc_maps" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"local_dest" => "VARCHAR(255) NOT NULL",
"bcc_dest" => "VARCHAR(255) NOT NULL",
"domain" => "VARCHAR(255) NOT NULL",
"type" => "ENUM('sender','rcpt')",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"active" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
"" => array("id")
),
"key" => array(
"local_dest" => array("local_dest"),
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"recipient_maps" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"old_dest" => "VARCHAR(255) NOT NULL",
"new_dest" => "VARCHAR(255) NOT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"active" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
"" => array("id")
),
"key" => array(
"local_dest" => array("old_dest"),
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"tfa" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"key_id" => "VARCHAR(255) NOT NULL",
"username" => "VARCHAR(255) NOT NULL",
"authmech" => "ENUM('yubi_otp', 'u2f', 'hotp', 'totp', 'webauthn')",
"secret" => "VARCHAR(255) DEFAULT NULL",
"keyHandle" => "VARCHAR(1023) DEFAULT NULL",
"publicKey" => "VARCHAR(4096) DEFAULT NULL",
"counter" => "INT NOT NULL DEFAULT '0'",
"certificate" => "TEXT",
"active" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
"" => array("id")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"forwarding_hosts" => array(
"cols" => array(
"host" => "VARCHAR(255) NOT NULL",
"source" => "VARCHAR(255) NOT NULL",
"filter_spam" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
"" => array("host")
),
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sogo_acl" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"c_folder_id" => "INT NOT NULL",
"c_object" => "VARCHAR(255) NOT NULL",
"c_uid" => "VARCHAR(255) NOT NULL",
"c_role" => "VARCHAR(80) NOT NULL"
),
"keys" => array(
"primary" => array(
"" => array("id")
),
"key" => array(
"sogo_acl_c_folder_id_idx" => array("c_folder_id"),
"sogo_acl_c_uid_idx" => array("c_uid")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sogo_alarms_folder" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"c_path" => "VARCHAR(255) NOT NULL",
"c_name" => "VARCHAR(255) NOT NULL",
"c_uid" => "VARCHAR(255) NOT NULL",
"c_recurrence_id" => "INT(11) DEFAULT NULL",
"c_alarm_number" => "INT(11) NOT NULL",
"c_alarm_date" => "INT(11) NOT NULL"
),
"keys" => array(
"primary" => array(
"" => array("id")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sogo_cache_folder" => array(
"cols" => array(
"c_uid" => "VARCHAR(255) NOT NULL",
"c_path" => "VARCHAR(255) NOT NULL",
"c_parent_path" => "VARCHAR(255) DEFAULT NULL",
"c_type" => "TINYINT(3) unsigned NOT NULL",
"c_creationdate" => "INT(11) NOT NULL",
"c_lastmodified" => "INT(11) NOT NULL",
"c_version" => "INT(11) NOT NULL DEFAULT '0'",
"c_deleted" => "TINYINT(4) NOT NULL DEFAULT '0'",
"c_content" => "LONGTEXT"
),
"keys" => array(
"primary" => array(
"" => array("c_uid", "c_path")
),
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sogo_folder_info" => array(
"cols" => array(
"c_folder_id" => "BIGINT(20) unsigned NOT NULL AUTO_INCREMENT",
"c_path" => "VARCHAR(255) NOT NULL",
"c_path1" => "VARCHAR(255) NOT NULL",
"c_path2" => "VARCHAR(255) DEFAULT NULL",
"c_path3" => "VARCHAR(255) DEFAULT NULL",
"c_path4" => "VARCHAR(255) DEFAULT NULL",
"c_foldername" => "VARCHAR(255) NOT NULL",
"c_location" => "VARCHAR(2048) DEFAULT NULL",
"c_quick_location" => "VARCHAR(2048) DEFAULT NULL",
"c_acl_location" => "VARCHAR(2048) DEFAULT NULL",
"c_folder_type" => "VARCHAR(255) NOT NULL"
),
"keys" => array(
"primary" => array(
"" => array("c_path")
),
"unique" => array(
"c_folder_id" => array("c_folder_id")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sogo_quick_appointment" => array(
"cols" => array(
"c_folder_id" => "INT NOT NULL",
"c_name" => "VARCHAR(255) NOT NULL",
"c_uid" => "VARCHAR(1000) NOT NULL",
"c_startdate" => "INT",
"c_enddate" => "INT",
"c_cycleenddate" => "INT",
"c_title" => "VARCHAR(1000) NOT NULL",
"c_participants" => "TEXT",
"c_isallday" => "INT",
"c_iscycle" => "INT",
"c_cycleinfo" => "TEXT",
"c_classification" => "INT NOT NULL",
"c_isopaque" => "INT NOT NULL",
"c_status" => "INT NOT NULL",
"c_priority" => "INT",
"c_location" => "VARCHAR(255)",
"c_orgmail" => "VARCHAR(255)",
"c_partmails" => "TEXT",
"c_partstates" => "TEXT",
"c_category" => "VARCHAR(255)",
"c_sequence" => "INT",
"c_component" => "VARCHAR(10) NOT NULL",
"c_nextalarm" => "INT",
"c_description" => "TEXT"
),
"keys" => array(
"primary" => array(
"" => array("c_folder_id", "c_name")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sogo_quick_contact" => array(
"cols" => array(
"c_folder_id" => "INT NOT NULL",
"c_name" => "VARCHAR(255) NOT NULL",
"c_givenname" => "VARCHAR(255)",
"c_cn" => "VARCHAR(255)",
"c_sn" => "VARCHAR(255)",
"c_screenname" => "VARCHAR(255)",
"c_l" => "VARCHAR(255)",
"c_mail" => "TEXT",
"c_o" => "VARCHAR(500)",
"c_ou" => "VARCHAR(255)",
"c_telephonenumber" => "VARCHAR(255)",
"c_categories" => "VARCHAR(255)",
"c_component" => "VARCHAR(10) NOT NULL",
"c_hascertificate" => "INT4 DEFAULT 0"
),
"keys" => array(
"primary" => array(
"" => array("c_folder_id", "c_name")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sogo_sessions_folder" => array(
"cols" => array(
"c_id" => "VARCHAR(255) NOT NULL",
"c_value" => "VARCHAR(4096) NOT NULL",
"c_creationdate" => "INT(11) NOT NULL",
"c_lastseen" => "INT(11) NOT NULL"
),
"keys" => array(
"primary" => array(
"" => array("c_id")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sogo_store" => array(
"cols" => array(
"c_folder_id" => "INT NOT NULL",
"c_name" => "VARCHAR(255) NOT NULL",
"c_content" => "MEDIUMTEXT NOT NULL",
"c_creationdate" => "INT NOT NULL",
"c_lastmodified" => "INT NOT NULL",
"c_version" => "INT NOT NULL",
"c_deleted" => "INT"
),
"keys" => array(
"primary" => array(
"" => array("c_folder_id", "c_name")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"pushover" => array(
"cols" => array(
"username" => "VARCHAR(255) NOT NULL",
"key" => "VARCHAR(255) NOT NULL",
"token" => "VARCHAR(255) NOT NULL",
"attributes" => "JSON",
"title" => "TEXT",
"text" => "TEXT",
"senders" => "TEXT",
"senders_regex" => "TEXT",
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
),
"keys" => array(
"primary" => array(
"" => array("username")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sogo_user_profile" => array(
"cols" => array(
"c_uid" => "VARCHAR(255) NOT NULL",
"c_defaults" => "LONGTEXT",
"c_settings" => "LONGTEXT"
),
"keys" => array(
"primary" => array(
"" => array("c_uid")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"oauth_clients" => array(
"cols" => array(
"id" => "INT NOT NULL AUTO_INCREMENT",
"client_id" => "VARCHAR(80) NOT NULL",
"client_secret" => "VARCHAR(80)",
"redirect_uri" => "VARCHAR(2000)",
"grant_types" => "VARCHAR(80)",
"scope" => "VARCHAR(4000)",
"user_id" => "VARCHAR(80)"
),
"keys" => array(
"primary" => array(
"" => array("client_id")
),
"unique" => array(
"id" => array("id")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"oauth_access_tokens" => array(
"cols" => array(
"access_token" => "VARCHAR(40) NOT NULL",
"client_id" => "VARCHAR(80) NOT NULL",
"user_id" => "VARCHAR(80)",
"expires" => "TIMESTAMP NOT NULL",
"scope" => "VARCHAR(4000)"
),
"keys" => array(
"primary" => array(
"" => array("access_token")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"oauth_authorization_codes" => array(
"cols" => array(
"authorization_code" => "VARCHAR(40) NOT NULL",
"client_id" => "VARCHAR(80) NOT NULL",
"user_id" => "VARCHAR(80)",
"redirect_uri" => "VARCHAR(2000)",
"expires" => "TIMESTAMP NOT NULL",
"scope" => "VARCHAR(4000)",
"id_token" => "VARCHAR(1000)"
),
"keys" => array(
"primary" => array(
"" => array("authorization_code")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"oauth_refresh_tokens" => array(
"cols" => array(
"refresh_token" => "VARCHAR(40) NOT NULL",
"client_id" => "VARCHAR(80) NOT NULL",
"user_id" => "VARCHAR(80)",
"expires" => "TIMESTAMP NOT NULL",
"scope" => "VARCHAR(4000)"
),
"keys" => array(
"primary" => array(
"" => array("refresh_token")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
)
);
foreach ($tables as $table => $properties) {
// Migrate to quarantine
if ($table == 'quarantine') {
$stmt = $pdo->query("SHOW TABLES LIKE 'quarantaine'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results != 0) {
$stmt = $pdo->query("SHOW TABLES LIKE 'quarantine'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results == 0) {
$pdo->query("RENAME TABLE `quarantaine` TO `quarantine`");
}
}
}
// Migrate tls_enforce_* options
if ($table == 'mailbox') {
$stmt = $pdo->query("SHOW TABLES LIKE 'mailbox'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results != 0) {
$stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE '%tls_enforce%'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results != 0) {
$stmt = $pdo->query("SELECT `username`, `tls_enforce_in`, `tls_enforce_out` FROM `mailbox`");
$tls_options_rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
while ($row = array_shift($tls_options_rows)) {
$tls_options[$row['username']] = array('tls_enforce_in' => $row['tls_enforce_in'], 'tls_enforce_out' => $row['tls_enforce_out']);
}
}
}
}
$stmt = $pdo->query("SHOW TABLES LIKE '" . $table . "'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results != 0) {
$stmt = $pdo->prepare("SELECT CONCAT('ALTER TABLE ', `table_schema`, '.', `table_name`, ' DROP FOREIGN KEY ', `constraint_name`, ';') AS `FKEY_DROP` FROM `information_schema`.`table_constraints`
WHERE `constraint_type` = 'FOREIGN KEY' AND `table_name` = :table;");
$stmt->execute(array(':table' => $table));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
while ($row = array_shift($rows)) {
$pdo->query($row['FKEY_DROP']);
}
foreach($properties['cols'] as $column => $type) {
$stmt = $pdo->query("SHOW COLUMNS FROM `" . $table . "` LIKE '" . $column . "'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results == 0) {
if (strpos($type, 'AUTO_INCREMENT') !== false) {
$type = $type . ' PRIMARY KEY ';
// Adding an AUTO_INCREMENT key, need to drop primary keys first, if exists
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = 'PRIMARY'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results != 0) {
$pdo->query("ALTER TABLE `" . $table . "` DROP PRIMARY KEY");
}
}
$pdo->query("ALTER TABLE `" . $table . "` ADD `" . $column . "` " . $type);
}
else {
$pdo->query("ALTER TABLE `" . $table . "` MODIFY COLUMN `" . $column . "` " . $type);
}
}
foreach($properties['keys'] as $key_type => $key_content) {
if (strtolower($key_type) == 'primary') {
foreach ($key_content as $key_values) {
$fields = "`" . implode("`, `", $key_values) . "`";
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = 'PRIMARY'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
$is_drop = ($num_results != 0) ? "DROP PRIMARY KEY, " : "";
$pdo->query("ALTER TABLE `" . $table . "` " . $is_drop . "ADD PRIMARY KEY (" . $fields . ")");
}
}
if (strtolower($key_type) == 'key') {
foreach ($key_content as $key_name => $key_values) {
$fields = "`" . implode("`, `", $key_values) . "`";
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = '" . $key_name . "'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
$is_drop = ($num_results != 0) ? "DROP INDEX `" . $key_name . "`, " : "";
$pdo->query("ALTER TABLE `" . $table . "` " . $is_drop . "ADD KEY `" . $key_name . "` (" . $fields . ")");
}
}
if (strtolower($key_type) == 'unique') {
foreach ($key_content as $key_name => $key_values) {
$fields = "`" . implode("`, `", $key_values) . "`";
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = '" . $key_name . "'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
$is_drop = ($num_results != 0) ? "DROP INDEX `" . $key_name . "`, " : "";
$pdo->query("ALTER TABLE `" . $table . "` " . $is_drop . "ADD UNIQUE KEY `" . $key_name . "` (" . $fields . ")");
}
}
if (strtolower($key_type) == 'fkey') {
foreach ($key_content as $key_name => $key_values) {
$fields = "`" . implode("`, `", $key_values) . "`";
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = '" . $key_name . "'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results != 0) {
$pdo->query("ALTER TABLE `" . $table . "` DROP INDEX `" . $key_name . "`");
}
@list($table_ref, $field_ref) = explode('.', $key_values['ref']);
$pdo->query("ALTER TABLE `" . $table . "` ADD FOREIGN KEY `" . $key_name . "` (" . $key_values['col'] . ") REFERENCES `" . $table_ref . "` (`" . $field_ref . "`)
ON DELETE " . $key_values['delete'] . " ON UPDATE " . $key_values['update']);
}
}
}
// Drop all vanished columns
$stmt = $pdo->query("SHOW COLUMNS FROM `" . $table . "`");
$cols_in_table = $stmt->fetchAll(PDO::FETCH_ASSOC);
while ($row = array_shift($cols_in_table)) {
if (!array_key_exists($row['Field'], $properties['cols'])) {
$pdo->query("ALTER TABLE `" . $table . "` DROP COLUMN `" . $row['Field'] . "`;");
}
}
// Step 1: Get all non-primary keys, that currently exist and those that should exist
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE `Key_name` != 'PRIMARY'");
$keys_in_table = $stmt->fetchAll(PDO::FETCH_ASSOC);
$keys_to_exist = array();
if (isset($properties['keys']['unique']) && is_array($properties['keys']['unique'])) {
foreach ($properties['keys']['unique'] as $key_name => $key_values) {
$keys_to_exist[] = $key_name;
}
}
if (isset($properties['keys']['key']) && is_array($properties['keys']['key'])) {
foreach ($properties['keys']['key'] as $key_name => $key_values) {
$keys_to_exist[] = $key_name;
}
}
// Index for foreign key must exist
if (isset($properties['keys']['fkey']) && is_array($properties['keys']['fkey'])) {
foreach ($properties['keys']['fkey'] as $key_name => $key_values) {
$keys_to_exist[] = $key_name;
}
}
// Step 2: Drop all vanished indexes
while ($row = array_shift($keys_in_table)) {
if (!in_array($row['Key_name'], $keys_to_exist)) {
$pdo->query("ALTER TABLE `" . $table . "` DROP INDEX `" . $row['Key_name'] . "`");
}
}
// Step 3: Drop all vanished primary keys
if (!isset($properties['keys']['primary'])) {
$stmt = $pdo->query("SHOW KEYS FROM `" . $table . "` WHERE Key_name = 'PRIMARY'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results != 0) {
$pdo->query("ALTER TABLE `" . $table . "` DROP PRIMARY KEY");
}
}
}
else {
// Create table if it is missing
$sql = "CREATE TABLE IF NOT EXISTS `" . $table . "` (";
foreach($properties['cols'] as $column => $type) {
$sql .= "`" . $column . "` " . $type . ",";
}
foreach($properties['keys'] as $key_type => $key_content) {
if (strtolower($key_type) == 'primary') {
foreach ($key_content as $key_values) {
$fields = "`" . implode("`, `", $key_values) . "`";
$sql .= "PRIMARY KEY (" . $fields . ")" . ",";
}
}
elseif (strtolower($key_type) == 'key') {
foreach ($key_content as $key_name => $key_values) {
$fields = "`" . implode("`, `", $key_values) . "`";
$sql .= "KEY `" . $key_name . "` (" . $fields . ")" . ",";
}
}
elseif (strtolower($key_type) == 'unique') {
foreach ($key_content as $key_name => $key_values) {
$fields = "`" . implode("`, `", $key_values) . "`";
$sql .= "UNIQUE KEY `" . $key_name . "` (" . $fields . ")" . ",";
}
}
elseif (strtolower($key_type) == 'fkey') {
foreach ($key_content as $key_name => $key_values) {
@list($table_ref, $field_ref) = explode('.', $key_values['ref']);
$sql .= "FOREIGN KEY `" . $key_name . "` (" . $key_values['col'] . ") REFERENCES `" . $table_ref . "` (`" . $field_ref . "`)
ON DELETE " . $key_values['delete'] . " ON UPDATE " . $key_values['update'] . ",";
}
}
}
$sql = rtrim($sql, ",");
$sql .= ") " . $properties['attr'];
$pdo->query($sql);
}
// Reset table attributes
$pdo->query("ALTER TABLE `" . $table . "` " . $properties['attr'] . ";");
}
// Recreate SQL views
foreach ($views as $view => $create) {
$pdo->query("DROP VIEW IF EXISTS `" . $view . "`;");
$pdo->query($create);
}
// Mitigate imapsync argument injection issue
$pdo->query("UPDATE `imapsync` SET `custom_params` = ''
WHERE `custom_params` LIKE '%pipemess%'
OR custom_params LIKE '%skipmess%'
OR custom_params LIKE '%delete2foldersonly%'
OR custom_params LIKE '%delete2foldersbutnot%'
OR custom_params LIKE '%regexflag%'
OR custom_params LIKE '%pipemess%'
OR custom_params LIKE '%regextrans2%'
OR custom_params LIKE '%maxlinelengthcmd%';");
// Migrate webauthn tfa
$stmt = $pdo->query("ALTER TABLE `tfa` MODIFY COLUMN `authmech` ENUM('yubi_otp', 'u2f', 'hotp', 'totp', 'webauthn')");
// Inject admin if not exists
$stmt = $pdo->query("SELECT NULL FROM `admin`");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results == 0) {
$pdo->query("INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
VALUES ('admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1)");
$pdo->query("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
SELECT `username`, 'ALL', NOW(), 1 FROM `admin`
WHERE superadmin='1' AND `username` NOT IN (SELECT `username` FROM `domain_admins`);");
$pdo->query("DELETE FROM `admin` WHERE `username` NOT IN (SELECT `username` FROM `domain_admins`);");
}
// Insert new DB schema version
$pdo->query("REPLACE INTO `versions` (`application`, `version`) VALUES ('db_schema', '" . $db_version . "');");
// Fix dangling domain admins
$pdo->query("DELETE FROM `admin` WHERE `superadmin` = 0 AND `username` NOT IN (SELECT `username`FROM `domain_admins`);");
$pdo->query("DELETE FROM `da_acl` WHERE `username` NOT IN (SELECT `username`FROM `domain_admins`);");
// Migrate attributes
// pushover
$pdo->query("UPDATE `pushover` SET `attributes` = '{}' WHERE `attributes` = '' OR `attributes` IS NULL;");
$pdo->query("UPDATE `pushover` SET `attributes` = JSON_SET(`attributes`, '$.evaluate_x_prio', \"0\") WHERE JSON_VALUE(`attributes`, '$.evaluate_x_prio') IS NULL;");
$pdo->query("UPDATE `pushover` SET `attributes` = JSON_SET(`attributes`, '$.only_x_prio', \"0\") WHERE JSON_VALUE(`attributes`, '$.only_x_prio') IS NULL;");
+ $pdo->query("UPDATE `pushover` SET `attributes` = JSON_SET(`attributes`, '$.sound', \"0\") WHERE JSON_VALUE(`attributes`, '$.sound') IS NULL;");
// mailbox
$pdo->query("UPDATE `mailbox` SET `attributes` = '{}' WHERE `attributes` = '' OR `attributes` IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.passwd_update', \"0\") WHERE JSON_VALUE(`attributes`, '$.passwd_update') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.relayhost', \"0\") WHERE JSON_VALUE(`attributes`, '$.relayhost') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.force_pw_update', \"0\") WHERE JSON_VALUE(`attributes`, '$.force_pw_update') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.sieve_access', \"1\") WHERE JSON_VALUE(`attributes`, '$.sieve_access') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.sogo_access', \"1\") WHERE JSON_VALUE(`attributes`, '$.sogo_access') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.imap_access', \"1\") WHERE JSON_VALUE(`attributes`, '$.imap_access') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.pop3_access', \"1\") WHERE JSON_VALUE(`attributes`, '$.pop3_access') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.smtp_access', \"1\") WHERE JSON_VALUE(`attributes`, '$.smtp_access') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.mailbox_format', \"maildir:\") WHERE JSON_VALUE(`attributes`, '$.mailbox_format') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.quarantine_notification', \"never\") WHERE JSON_VALUE(`attributes`, '$.quarantine_notification') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.quarantine_category', \"reject\") WHERE JSON_VALUE(`attributes`, '$.quarantine_category') IS NULL;");
foreach($tls_options as $tls_user => $tls_options) {
$stmt = $pdo->prepare("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.tls_enforce_in', :tls_enforce_in),
`attributes` = JSON_SET(`attributes`, '$.tls_enforce_out', :tls_enforce_out)
WHERE `username` = :username");
$stmt->execute(array(':tls_enforce_in' => $tls_options['tls_enforce_in'], ':tls_enforce_out' => $tls_options['tls_enforce_out'], ':username' => $tls_user));
}
// Set tls_enforce_* if still missing (due to deleted attrs for example)
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.tls_enforce_out', \"1\") WHERE JSON_VALUE(`attributes`, '$.tls_enforce_out') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.tls_enforce_in', \"1\") WHERE JSON_VALUE(`attributes`, '$.tls_enforce_in') IS NULL;");
// Fix ACL
$pdo->query("INSERT INTO `user_acl` (`username`) SELECT `username` FROM `mailbox` WHERE `kind` = '' AND NOT EXISTS (SELECT `username` FROM `user_acl`);");
$pdo->query("INSERT INTO `da_acl` (`username`) SELECT DISTINCT `username` FROM `domain_admins` WHERE `username` != 'admin' AND NOT EXISTS (SELECT `username` FROM `da_acl`);");
// Fix domain_admins
$pdo->query("DELETE FROM `domain_admins` WHERE `domain` = 'ALL';");
if (php_sapi_name() == "cli") {
echo "DB initialization completed" . PHP_EOL;
} else {
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__),
'msg' => 'db_init_complete'
);
}
}
catch (PDOException $e) {
if (php_sapi_name() == "cli") {
echo "DB initialization failed: " . print_r($e, true) . PHP_EOL;
} else {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__),
'msg' => array('mysql_error', $e)
);
}
}
}
if (php_sapi_name() == "cli") {
include '/web/inc/vars.inc.php';
include '/web/inc/functions.docker.inc.php';
// $now = new DateTime();
// $mins = $now->getOffset() / 60;
// $sgn = ($mins < 0 ? -1 : 1);
// $mins = abs($mins);
// $hrs = floor($mins / 60);
// $mins -= $hrs * 60;
// $offset = sprintf('%+d:%02d', $hrs*$sgn, $mins);
$dsn = $database_type . ":unix_socket=" . $database_sock . ";dbname=" . $database_name;
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
//PDO::MYSQL_ATTR_INIT_COMMAND => "SET time_zone = '" . $offset . "', group_concat_max_len = 3423543543;",
];
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
$stmt = $pdo->query("SELECT COUNT('OK') AS OK_C FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sogo_view' OR TABLE_NAME = '_sogo_static_view';");
$res = $stmt->fetch(PDO::FETCH_ASSOC);
if (intval($res['OK_C']) === 2) {
// Be more precise when replacing into _sogo_static_view, col orders may change
try {
$stmt = $pdo->query("REPLACE INTO _sogo_static_view (`c_uid`, `domain`, `c_name`, `c_password`, `c_cn`, `mail`, `aliases`, `ad_aliases`, `ext_acl`, `kind`, `multiple_bookings`)
SELECT `c_uid`, `domain`, `c_name`, `c_password`, `c_cn`, `mail`, `aliases`, `ad_aliases`, `ext_acl`, `kind`, `multiple_bookings` from sogo_view");
$stmt = $pdo->query("DELETE FROM _sogo_static_view WHERE `c_uid` NOT IN (SELECT `username` FROM `mailbox` WHERE `active` = '1');");
echo "Fixed _sogo_static_view" . PHP_EOL;
}
catch ( Exception $e ) {
// Dunno
}
}
try {
$m = new Memcached();
$m->addServer('memcached', 11211);
$m->flush();
echo "Cleaned up memcached". PHP_EOL;
}
catch ( Exception $e ) {
// Dunno
}
init_db_schema();
}
diff --git a/data/web/lang/lang.en-gb.json b/data/web/lang/lang.en-gb.json
index 0a384071..260997de 100644
--- a/data/web/lang/lang.en-gb.json
+++ b/data/web/lang/lang.en-gb.json
@@ -1,1187 +1,1189 @@
{
"acl": {
"alias_domains": "Add alias domains",
"app_passwds": "Manage app passwords",
"bcc_maps": "BCC maps",
"delimiter_action": "Delimiter action",
"domain_desc": "Change domain description",
"domain_relayhost": "Change relayhost for a domain",
"eas_reset": "Reset EAS devices",
"extend_sender_acl": "Allow to extend sender ACL by external addresses",
"filters": "Filters",
"login_as": "Login as mailbox user",
"mailbox_relayhost": "Change relayhost for a mailbox",
"prohibited": "Prohibited by ACL",
"protocol_access": "Change protocol access",
"pushover": "Pushover",
"quarantine": "Quarantine actions",
"quarantine_attachments": "Quarantine attachments",
"quarantine_category": "Change quarantine notification category",
"quarantine_notification": "Change quarantine notifications",
"ratelimit": "Rate limit",
"recipient_maps": "Recipient maps",
"smtp_ip_access": "Change allowed hosts for SMTP",
"sogo_access": "Allow management of SOGo access",
"sogo_profile_reset": "Reset SOGo profile",
"spam_alias": "Temporary aliases",
"spam_policy": "Blacklist/Whitelist",
"spam_score": "Spam score",
"syncjobs": "Sync jobs",
"tls_policy": "TLS policy",
"unlimited_quota": "Unlimited quota for mailboxes"
},
"add": {
"activate_filter_warn": "All other filters will be deactivated, when active is checked.",
"active": "Active",
"add": "Add",
"add_domain_only": "Add domain only",
"add_domain_restart": "Add domain and restart SOGo",
"alias_address": "Alias address/es",
"alias_address_info": "<small>Full email address/es or @example.com, to catch all messages for a domain (comma-separated). <b>mailcow domains only</b>.</small>",
"alias_domain": "Alias domain",
"alias_domain_info": "<small>Valid domain names only (comma-separated).</small>",
"app_name": "App name",
"app_password": "Add app password",
"app_passwd_protocols": "Allowed protocols for app password",
"automap": "Try to automap folders (\"Sent items\", \"Sent\" => \"Sent\" etc.)",
"backup_mx_options": "Relay options",
"bcc_dest_format": "BCC destination must be a single valid email address.<br>If you need to send a copy to multiple addresses, create an alias and use it here.",
"comment_info": "A private comment is not visible to the user, while a public comment is shown as tooltip when hovering it in a user's overview",
"custom_params": "Custom parameters",
"custom_params_hint": "Right: --param=xy, wrong: --param xy",
"delete1": "Delete from source when completed",
"delete2": "Delete messages on destination that are not on source",
"delete2duplicates": "Delete duplicates on destination",
"description": "Description",
"destination": "Destination",
"disable_login": "Disallow login (incoming mail is still accepted)",
"domain": "Domain",
"domain_matches_hostname": "Domain %s matches hostname",
"domain_quota_m": "Total domain quota (MiB)",
"enc_method": "Encryption method",
"exclude": "Exclude objects (regex)",
"full_name": "Full name",
"gal": "Global Address List",
"gal_info": "The GAL contains all objects of a domain and cannot be edited by any user. Free/busy information in SOGo is missing, if disabled! <b>Restart SOGo to apply changes.</b>",
"generate": "generate",
"goto_ham": "Learn as <span class=\"text-success\"><b>ham</b></span>",
"goto_null": "Silently discard mail",
"goto_spam": "Learn as <span class=\"text-danger\"><b>spam</b></span>",
"hostname": "Host",
"inactive": "Inactive",
"kind": "Kind",
"mailbox_quota_def": "Default mailbox quota",
"mailbox_quota_m": "Max. quota per mailbox (MiB)",
"mailbox_username": "Username (left part of an email address)",
"max_aliases": "Max. possible aliases",
"max_mailboxes": "Max. possible mailboxes",
"mins_interval": "Polling interval (minutes)",
"multiple_bookings": "Multiple bookings",
"nexthop": "Next hop",
"password": "Password",
"password_repeat": "Confirmation password (repeat)",
"port": "Port",
"post_domain_add": "The SOGo container, \"sogo-mailcow\", needs to be restarted after adding a new domain!<br><br>Additionally the domains DNS configuration should be reviewed. Once the DNS configuration is approved, restart \"acme-mailcow\" to automatically generate certificates for your new domain (autoconfig.&lt;domain&gt;, autodiscover.&lt;domain&gt;).<br>This step is optional and will be retried every 24 hours.",
"private_comment": "Private comment",
"public_comment": "Public comment",
"quota_mb": "Quota (MiB)",
"relay_all": "Relay all recipients",
"relay_all_info": "↪ If you choose <b>not</b> to relay all recipients, you will need to add a (\"blind\") mailbox for every single recipient that should be relayed.",
"relay_domain": "Relay this domain",
"relay_transport_info": "<div class=\"label label-info\">Info</div> You can define transport maps for a custom destination for this domain. If not set, a MX lookup will be made.",
"relay_unknown_only": "Relay non-existing mailboxes only. Existing mailboxes will be delivered locally.",
"relayhost_wrapped_tls_info": "Please do <b>not</b> use TLS-wrapped ports (mostly used on port 465).<br>\r\nUse any non-wrapped port and issue STARTTLS. A TLS policy to enforce TLS can be created in \"TLS policy maps\".",
"select": "Please select...",
"select_domain": "Please select a domain first",
"sieve_desc": "Short description",
"sieve_type": "Filter type",
"skipcrossduplicates": "Skip duplicate messages across folders (first come, first serve)",
"subscribeall": "Subscribe all folders",
"syncjob": "Add sync job",
"syncjob_hint": "Be aware that passwords need to be saved plain-text!",
"tags": "Tags",
"target_address": "Goto addresses",
"target_address_info": "<small>Full email address/es (comma-separated).</small>",
"target_domain": "Target domain",
"timeout1": "Timeout for connection to remote host",
"timeout2": "Timeout for connection to local host",
"username": "Username",
"validate": "Validate",
"validation_success": "Validated successfully"
},
"admin": {
"access": "Access",
"action": "Action",
"activate_api": "Activate API",
"activate_send": "Activate send button",
"active": "Active",
"active_rspamd_settings_map": "Active settings map",
"add": "Add",
"add_admin": "Add administrator",
"add_domain_admin": "Add domain administrator",
"add_forwarding_host": "Add forwarding host",
"add_relayhost": "Add sender-dependent transport",
"add_relayhost_hint": "Please be aware that authentication data, if any, will be stored as plain text.",
"add_row": "Add row",
"add_settings_rule": "Add settings rule",
"add_transport": "Add transport",
"add_transports_hint": "Please be aware that authentication data, if any, will be stored as plain text.",
"additional_rows": " additional rows were added",
"admin": "Administrator",
"admin_details": "Edit administrator details",
"admin_domains": "Domain assignments",
"admins": "Administrators",
"admins_ldap": "LDAP Administrators",
"advanced_settings": "Advanced settings",
"api_allow_from": "Allow API access from these IPs/CIDR network notations",
"api_info": "The API is a work in progress. The documentation can be found at <a href=\"/api\">/api</a>",
"api_key": "API key",
"api_read_only": "Read-Only Access",
"api_read_write": "Read-Write Access",
"api_skip_ip_check": "Skip IP check for API",
"app_links": "App links",
"app_name": "App name",
"apps_name": "\"mailcow Apps\" name",
"arrival_time": "Arrival time (server time)",
"authed_user": "Auth. user",
"ays": "Are you sure you want to proceed?",
"ban_list_info": "See a list of banned IPs below: <b>network (remaining ban time) - [actions]</b>.<br />IPs queued to be unbanned will be removed from the active ban list within a few seconds.<br />Red labels indicate active permanent bans by blacklisting.",
"change_logo": "Change logo",
"configuration": "Configuration",
"convert_html_to_text": "Convert HTML to plain text",
"credentials_transport_warning": "<b>Warning</b>: Adding a new transport map entry will update the credentials for all entries with a matching next hop column.",
"customer_id": "Customer ID",
"customize": "Customize",
"delete_queue": "Delete all",
"destination": "Destination",
"dkim_add_key": "Add ARC/DKIM key",
"dkim_domains_selector": "Selector",
"dkim_domains_wo_keys": "Select domains with missing keys",
"dkim_from": "From",
"dkim_from_title": "Source domain to copy data from",
"dkim_key_length": "DKIM key length (bits)",
"dkim_key_missing": "Key missing",
"dkim_key_unused": "Key unused",
"dkim_key_valid": "Key valid",
"dkim_keys": "ARC/DKIM keys",
"dkim_overwrite_key": "Overwrite existing DKIM key",
"dkim_private_key": "Private key",
"dkim_to": "To",
"dkim_to_title": "Target domain/s - will be overwritten",
"domain": "Domain",
"domain_admin": "Domain administrator",
"domain_admins": "Domain administrators",
"domain_s": "Domain/s",
"duplicate": "Duplicate",
"duplicate_dkim": "Duplicate DKIM record",
"edit": "Edit",
"empty": "No results",
"excludes": "Excludes these recipients",
"f2b_ban_time": "Ban time (s)",
"f2b_blacklist": "Blacklisted networks/hosts",
"f2b_filter": "Regex filters",
"f2b_list_info": "A blacklisted host or network will always outweigh a whitelist entity. <b>List updates will take a few seconds to be applied.</b>",
"f2b_max_attempts": "Max. attempts",
"f2b_netban_ipv4": "IPv4 subnet size to apply ban on (8-32)",
"f2b_netban_ipv6": "IPv6 subnet size to apply ban on (8-128)",
"f2b_parameters": "Fail2ban parameters",
"f2b_regex_info": "Logs taken into consideration: SOGo, Postfix, Dovecot, PHP-FPM.",
"f2b_retry_window": "Retry window (s) for max. attempts",
"f2b_whitelist": "Whitelisted networks/hosts",
"filter_table": "Filter table",
"flush_queue": "Flush queue",
"forwarding_hosts": "Forwarding Hosts",
"forwarding_hosts_add_hint": "You can either specify IPv4/IPv6 addresses, networks in CIDR notation, host names (which will be resolved to IP addresses), or domain names (which will be resolved to IP addresses by querying SPF records or, in their absence, MX records).",
"forwarding_hosts_hint": "Incoming messages are unconditionally accepted from any hosts listed here. These hosts are then not checked against DNSBLs or subjected to greylisting. Spam received from them is never rejected, but optionally it can be filed into the Junk folder. The most common use for this is to specify mail servers on which you have set up a rule that forwards incoming emails to your mailcow server.",
"from": "From",
"generate": "generate",
"guid": "GUID - unique instance ID",
"guid_and_license": "GUID & License",
"hash_remove_info": "Removing a ratelimit hash (if still existing) will reset its counter completely.<br>\r\n Each hash is indicated by an individual color.",
"help_text": "Override help text below login mask (HTML allowed)",
"host": "Host",
"html": "HTML",
"import": "Import",
"import_private_key": "Import private key",
"in_use_by": "In use by",
"inactive": "Inactive",
"include_exclude": "Include/Exclude",
"include_exclude_info": "By default - with no selection - <b>all mailboxes</b> are addressed",
"includes": "Include these recipients",
"is_mx_based": "MX based",
"last_applied": "Last applied",
"license_info": "A license is not required but helps further development.<br><a href=\"https://www.servercow.de/mailcow?lang=en#sal\" target=\"_blank\" alt=\"SAL order\">Register your GUID here</a> or <a href=\"https://www.servercow.de/mailcow?lang=en#support\" target=\"_blank\" alt=\"Support order\">buy support for your mailcow installation.</a>",
"link": "Link",
"loading": "Please wait...",
"login_time": "Login time",
"logo_info": "Your image will be scaled to a height of 40px for the top navigation bar and a max. width of 250px for the start page. A scalable graphic is highly recommended.",
"lookup_mx": "Destination is a regular expression to match against MX name (<code>.*google\\.com</code> to route all mail targeted to a MX ending in google.com over this hop)",
"main_name": "\"mailcow UI\" name",
"merged_vars_hint": "Greyed out rows were merged from <code>vars.(local.)inc.php</code> and cannot be modified.",
"message": "Message",
"message_size": "Message size",
"nexthop": "Next hop",
"no": "&#10005;",
"no_active_bans": "No active bans",
"no_new_rows": "No further rows available",
"no_record": "No record",
"oauth2_apps": "OAuth2 Apps",
"oauth2_add_client": "Add OAuth2 client",
"oauth2_client_id": "Client ID",
"oauth2_client_secret": "Client secret",
"oauth2_info": "The OAuth2 implementation supports the grant type \"Authorization Code\" and issues refresh tokens.<br>\r\nThe server also automatically issues new refresh tokens, after a refresh token has been used.<br><br>\r\n&#8226; The default scope is <i>profile</i>. Only mailbox users can be authenticated against OAuth2. If the scope parameter is omitted, it falls back to <i>profile</i>.<br>\r\n&#8226; The <i>state</i> parameter is required to be sent by the client as part of the authorize request.<br><br>\r\nPaths for requests to the OAuth2 API: <br>\r\n<ul>\r\n <li>Authorization endpoint: <code>/oauth/authorize</code></li>\r\n <li>Token endpoint: <code>/oauth/token</code></li>\r\n <li>Resource page: <code>/oauth/profile</code></li>\r\n</ul>\r\nRegenerating the client secret will not expire existing authorization codes, but they will fail to renew their token.<br><br>\r\nRevoking client tokens will cause immediate termination of all active sessions. All clients need to re-authenticate.",
"oauth2_redirect_uri": "Redirect URI",
"oauth2_renew_secret": "Generate new client secret",
"oauth2_revoke_tokens": "Revoke all client tokens",
"optional": "optional",
"password": "Password",
"password_length": "Password length",
"password_policy": "Password policy",
"password_policy_chars": "Must contain at least one alphabetic character",
"password_policy_length": "Minimum password length is %d",
"password_policy_lowerupper": "Must contain lowercase and uppercase characters",
"password_policy_numbers": "Must contain at least one number",
"password_policy_special_chars": "Must contain special characters",
"password_repeat": "Confirmation password (repeat)",
"priority": "Priority",
"private_key": "Private key",
"quarantine": "Quarantine",
"quarantine_bcc": "Send a copy of all notifications (BCC) to this recipient:<br><small>Leave empty to disable. <b>Unsigned, unchecked mail. Should be delivered internally only.</b></small>",
"quarantine_exclude_domains": "Exclude domains and alias-domains",
"quarantine_max_age": "Maximum age in days<br><small>Value must be equal to or greater than 1 day.</small>",
"quarantine_max_score": "Discard notification if spam score of a mail is higher than this value:<br><small>Defaults to 9999.0</small>",
"quarantine_max_size": "Maximum size in MiB (larger elements are discarded):<br><small>0 does <b>not</b> indicate unlimited.</small>",
"quarantine_notification_html": "Notification email template:<br><small>Leave empty to restore default template.</small>",
"quarantine_notification_sender": "Notification email sender",
"quarantine_notification_subject": "Notification email subject",
"quarantine_redirect": "<b>Redirect all notifications</b> to this recipient:<br><small>Leave empty to disable. <b>Unsigned, unchecked mail. Should be delivered internally only.</b></small>",
"quarantine_release_format": "Format of released items",
"quarantine_release_format_att": "As attachment",
"quarantine_release_format_raw": "Unmodified original",
"quarantine_retention_size": "Retentions per mailbox:<br><small>0 indicates <b>inactive</b>.</small>",
"queue_ays": "Please confirm you want to delete all items from the current queue.",
"queue_deliver_mail": "Deliver",
"queue_hold_mail": "Hold",
"queue_manager": "Queue manager",
"queue_show_message": "Show message",
"queue_unban": "queue unban",
"queue_unhold_mail": "Unhold",
"quota_notification_html": "Notification email template:<br><small>Leave empty to restore default template.</small>",
"quota_notification_sender": "Notification email sender",
"quota_notification_subject": "Notification email subject",
"quota_notifications": "Quota notifications",
"quota_notifications_info": "Quota notifications are sent to users once when crossing 80% and once when crossing 95% usage.",
"quota_notifications_vars": "{{percent}} equals the current quota of the user<br>{{username}} is the mailbox name",
"r_active": "Active restrictions",
"r_inactive": "Inactive restrictions",
"r_info": "Greyed out/disabled elements on the list of active restrictions are not known as valid restrictions to mailcow and cannot be moved. Unknown restrictions will be set in order of appearance anyway. <br>You can add new elements in <code>inc/vars.local.inc.php</code> to be able to toggle them.",
"rate_name": "Rate name",
"recipients": "Recipients",
"refresh": "Refresh",
"regen_api_key": "Regenerate API key",
"regex_maps": "Regex maps",
"relay_from": "\"From:\" address",
"relay_rcpt": "\"To:\" address",
"relay_run": "Run test",
"relayhosts": "Sender-dependent transports",
"relayhosts_hint": "Define sender-dependent transports to be able to select them in a domains configuration dialog.<br>\r\n The transport service is always \"smtp:\" and will therefore try TLS when offered. Wrapped TLS (SMTPS) is not supported. A users individual outbound TLS policy setting is taken into account.<br>\r\n Affects selected domains including alias domains.",
"remove": "Remove",
"remove_row": "Remove row",
"reset_default": "Reset to default",
"reset_limit": "Remove hash",
"routing": "Routing",
"rsetting_add_rule": "Add rule",
"rsetting_content": "Rule content",
"rsetting_desc": "Short description",
"rsetting_no_selection": "Please select a rule",
"rsetting_none": "No rules available",
"rsettings_insert_preset": "Insert example preset \"%s\"",
"rsettings_preset_1": "Disable all but DKIM and rate limit for authenticated users",
"rsettings_preset_2": "Postmasters want spam",
"rsettings_preset_3": "Only allow specific senders for a mailbox (i.e. usage as internal mailbox only)",
"rsettings_preset_4": "Disable Rspamd for a domain",
"rspamd_com_settings": "A setting name will be auto-generated, please see the example presets below. For more details see <a href=\"https://rspamd.com/doc/configuration/settings.html#settings-structure\" target=\"_blank\">Rspamd docs</a>",
"rspamd_global_filters": "Global filter maps",
"rspamd_global_filters_agree": "I will be careful!",
"rspamd_global_filters_info": "Global filter maps contain different kind of global black and whitelists.",
"rspamd_global_filters_regex": "Their names explain their purpose. All content must contain valid regular expression in the format of \"/pattern/options\" (e.g. <code>/.+@domain\\.tld/i</code>).<br>\r\n Although rudimentary checks are being executed on each line of regex, Rspamds functionality can be broken, if it fails to read the syntax correctly.<br>\r\n Rspamd will try to read the map content when changed. If you experience problems, <a href=\"\" data-toggle=\"modal\" data-container=\"rspamd-mailcow\" data-target=\"#RestartContainer\">restart Rspamd</a> to enforce a map reload.<br>Blacklisted elements are excluded from quarantine.",
"rspamd_settings_map": "Rspamd settings map",
"sal_level": "Moo level",
"save": "Save changes",
"search_domain_da": "Search domains",
"send": "Send",
"sender": "Sender",
"service": "Service",
"service_id": "Service ID",
"source": "Source",
"spamfilter": "Spam filter",
"subject": "Subject",
"success": "Success",
"sys_mails": "System mails",
"text": "Text",
"time": "Time",
"title": "Title",
"title_name": "\"mailcow UI\" website title",
"to_top": "Back to top",
"transport_dest_format": "Regex or syntax: example.org, .example.org, *, box@example.org (multiple values can be comma-separated)",
"transport_maps": "Transport Maps",
"transport_test_rcpt_info": "&#8226; Use null@hosted.mailcow.de to test relaying to a foreign destination.",
"transports_hint": "&#8226; A transport map entry <b>overrules</b> a sender-dependent transport map</b>.<br>\r\n&#8226; MX-based transports are preferably used.<br>\r\n&#8226; Outbound TLS policy settings per-user are ignored and can only be enforced by TLS policy map entries.<br>\r\n&#8226; The transport service for defined transports is always \"smtp:\" and will therefore try TLS when offered. Wrapped TLS (SMTPS) is not supported.<br>\r\n&#8226; Addresses matching \"/localhost$/\" will always be transported via \"local:\", therefore a \"*\" destination will not apply to those addresses.<br>\r\n&#8226; To determine credentials for an exemplary next hop \"[host]:25\", Postfix <b>always</b> queries for \"host\" before searching for \"[host]:25\". This behavior makes it impossible to use \"host\" and \"[host]:25\" at the same time.",
"ui_footer": "Footer (HTML allowed)",
"ui_header_announcement": "Announcements",
"ui_header_announcement_active": "Set announcement active",
"ui_header_announcement_content": "Text (HTML allowed)",
"ui_header_announcement_help": "The announcement is visible for all logged in users and on the login screen of the UI.",
"ui_header_announcement_select": "Select announcement type",
"ui_header_announcement_type": "Type",
"ui_header_announcement_type_danger": "Very important",
"ui_header_announcement_type_info": "Info",
"ui_header_announcement_type_warning": "Important",
"ui_texts": "UI labels and texts",
"unban_pending": "unban pending",
"unchanged_if_empty": "If unchanged leave blank",
"upload": "Upload",
"username": "Username",
"validate_license_now": "Validate GUID against license server",
"verify": "Verify",
"yes": "&#10003;"
},
"danger": {
"access_denied": "Access denied or invalid form data",
"alias_domain_invalid": "Alias domain %s is invalid",
"alias_empty": "Alias address must not be empty",
"alias_goto_identical": "Alias and goto address must not be identical",
"alias_invalid": "Alias address %s is invalid",
"aliasd_targetd_identical": "Alias domain must not be equal to target domain: %s",
"aliases_in_use": "Max. aliases must be greater or equal to %d",
"app_name_empty": "App name cannot be empty",
"app_passwd_id_invalid": "App password ID %s invalid",
"bcc_empty": "BCC destination cannot be empty",
"bcc_exists": "A BCC map %s exists for type %s",
"bcc_must_be_email": "BCC destination %s is not a valid email address",
"comment_too_long": "Comment too long, max 160 chars allowed",
"defquota_empty": "Default quota per mailbox must not be 0.",
"description_invalid": "Resource description for %s is invalid",
"dkim_domain_or_sel_exists": "A DKIM key for \"%s\" exists and will not be overwritten",
"dkim_domain_or_sel_invalid": "DKIM domain or selector invalid: %s",
"domain_cannot_match_hostname": "Domain cannot match hostname",
"domain_exists": "Domain %s already exists",
"domain_invalid": "Domain name is empty or invalid",
"domain_not_empty": "Cannot remove non-empty domain %s",
"domain_not_found": "Domain %s not found",
"domain_quota_m_in_use": "Domain quota must be greater or equal to %s MiB",
"extra_acl_invalid": "External sender address \"%s\" is invalid",
"extra_acl_invalid_domain": "External sender \"%s\" uses an invalid domain",
"fido2_verification_failed": "FIDO2 verification failed: %s",
"file_open_error": "File cannot be opened for writing",
"filter_type": "Wrong filter type",
"from_invalid": "Sender must not be empty",
"global_filter_write_error": "Could not write filter file: %s",
"global_map_invalid": "Global map ID %s invalid",
"global_map_write_error": "Could not write global map ID %s: %s",
"goto_empty": "An alias address must contain at least one valid goto address",
"goto_invalid": "Goto address %s is invalid",
"ham_learn_error": "Ham learn error: %s",
"imagick_exception": "Error: Imagick exception while reading image",
"img_invalid": "Cannot validate image file",
"img_tmp_missing": "Cannot validate image file: Temporary file not found",
"invalid_bcc_map_type": "Invalid BCC map type",
"invalid_destination": "Destination format \"%s\" is invalid",
"invalid_filter_type": "Invalid filter type",
"invalid_host": "Invalid host specified: %s",
"invalid_mime_type": "Invalid mime type",
"invalid_nexthop": "Next hop format is invalid",
"invalid_nexthop_authenticated": "Next hop exists with different credentials, please update the existing credentials for this next hop first.",
"invalid_recipient_map_new": "Invalid new recipient specified: %s",
"invalid_recipient_map_old": "Invalid original recipient specified: %s",
"ip_list_empty": "List of allowed IPs cannot be empty",
"is_alias": "%s is already known as an alias address",
"is_alias_or_mailbox": "%s is already known as an alias, a mailbox or an alias address expanded from an alias domain.",
"is_spam_alias": "%s is already known as a temporary alias address (spam alias address)",
"last_key": "Last key cannot be deleted, please deactivate TFA instead.",
"login_failed": "Login failed",
"mailbox_defquota_exceeds_mailbox_maxquota": "Default quota exceeds max quota limit",
"mailbox_invalid": "Mailbox name is invalid",
"mailbox_quota_exceeded": "Quota exceeds the domain limit (max. %d MiB)",
"mailbox_quota_exceeds_domain_quota": "Max. quota exceeds domain quota limit",
"mailbox_quota_left_exceeded": "Not enough space left (space left: %d MiB)",
"mailboxes_in_use": "Max. mailboxes must be greater or equal to %d",
"malformed_username": "Malformed username",
"map_content_empty": "Map content cannot be empty",
"max_alias_exceeded": "Max. aliases exceeded",
"max_mailbox_exceeded": "Max. mailboxes exceeded (%d of %d)",
"max_quota_in_use": "Mailbox quota must be greater or equal to %d MiB",
"maxquota_empty": "Max. quota per mailbox must not be 0.",
"mysql_error": "MySQL error: %s",
"network_host_invalid": "Invalid network or host: %s",
"next_hop_interferes": "%s interferes with nexthop %s",
"next_hop_interferes_any": "An existing next hop interferes with %s",
"nginx_reload_failed": "Nginx reload failed: %s",
"no_user_defined": "No user defined",
"object_exists": "Object %s already exists",
"object_is_not_numeric": "Value %s is not numeric",
"password_complexity": "Password does not meet the policy",
"password_empty": "Password must not be empty",
"password_mismatch": "Confirmation password does not match",
"policy_list_from_exists": "A record with given name exists",
"policy_list_from_invalid": "Record has invalid format",
"private_key_error": "Private key error: %s",
"pushover_credentials_missing": "Pushover token and or key missing",
"pushover_key": "Pushover key has a wrong format",
"pushover_token": "Pushover token has a wrong format",
"quota_not_0_not_numeric": "Quota must be numeric and >= 0",
"recipient_map_entry_exists": "A Recipient map entry \"%s\" exists",
"redis_error": "Redis error: %s",
"relayhost_invalid": "Map entry %s is invalid",
"release_send_failed": "Message could not be released: %s",
"reset_f2b_regex": "Regex filter could not be reset in time, please try again or wait a few more seconds and reload the website.",
"resource_invalid": "Resource name %s is invalid",
"rl_timeframe": "Rate limit time frame is incorrect",
"rspamd_ui_pw_length": "Rspamd UI password should be at least 6 chars long",
"script_empty": "Script cannot be empty",
"sender_acl_invalid": "Sender ACL value %s is invalid",
"set_acl_failed": "Failed to set ACL",
"settings_map_invalid": "Settings map ID %s invalid",
"sieve_error": "Sieve parser error: %s",
"spam_learn_error": "Spam learn error: %s",
"subject_empty": "Subject must not be empty",
"target_domain_invalid": "Target domain %s is invalid",
"targetd_not_found": "Target domain %s not found",
"targetd_relay_domain": "Target domain %s is a relay domain",
"temp_error": "Temporary error",
"text_empty": "Text must not be empty",
"tfa_token_invalid": "TFA token invalid",
"tls_policy_map_dest_invalid": "Policy destination is invalid",
"tls_policy_map_entry_exists": "A TLS policy map entry \"%s\" exists",
"tls_policy_map_parameter_invalid": "Policy parameter is invalid",
"totp_verification_failed": "TOTP verification failed",
"transport_dest_exists": "Transport destination \"%s\" exists",
"webauthn_verification_failed": "WebAuthn verification failed: %s",
"unknown": "An unknown error occurred",
"unknown_tfa_method": "Unknown TFA method",
"unlimited_quota_acl": "Unlimited quota prohibited by ACL",
"username_invalid": "Username %s cannot be used",
"validity_missing": "Please assign a period of validity",
"value_missing": "Please provide all values",
"yotp_verification_failed": "Yubico OTP verification failed: %s"
},
"debug": {
"chart_this_server": "Chart (this server)",
"containers_info": "Container information",
"disk_usage": "Disk usage",
"docs": "Docs",
"external_logs": "External logs",
"history_all_servers": "History (all servers)",
"in_memory_logs": "In-memory logs",
"jvm_memory_solr": "JVM memory usage",
"last_modified": "Last modified",
"log_info": "<p>mailcow <b>in-memory logs</b> are collected in Redis lists and trimmed to LOG_LINES (%d) every minute to reduce hammering.\r\n <br>In-memory logs are not meant to be persistent. All applications that log in-memory, also log to the Docker daemon and therefore to the default logging driver.\r\n <br>The in-memory log type should be used for debugging minor issues with containers.</p>\r\n <p><b>External logs</b> are collected via API of the given application.</p>\r\n <p><b>Static logs</b> are mostly activity logs, that are not logged to the Dockerd but still need to be persistent (except for API logs).</p>",
"login_time": "Time",
"logs": "Logs",
"online_users": "Users online",
"restart_container": "Restart",
"service": "Service",
"size": "Size",
"solr_dead": "Solr is starting, disabled or died.",
"solr_status": "Solr status",
"started_at": "Started at",
"started_on": "Started on",
"static_logs": "Static logs",
"success": "Success",
"system_containers": "System & Containers",
"uptime": "Uptime",
"username": "Username"
},
"diagnostics": {
"cname_from_a": "Value derived from A/AAAA record. This is supported as long as the record points to the correct resource.",
"dns_records": "DNS Records",
"dns_records_24hours": "Please note that changes made to DNS may take up to 24 hours to correctly have their current state reflected on this page. It is intended as a way for you to easily see how to configure your DNS records and to check whether all your records are correctly stored in DNS.",
"dns_records_data": "Correct Data",
"dns_records_docs": "Please also consult <a target=\"_blank\" href=\"https://mailcow.github.io/mailcow-dockerized-docs/prerequisite/prerequisite-dns/\">the documentation</a>.",
"dns_records_name": "Name",
"dns_records_status": "Current State",
"dns_records_type": "Type",
"optional": "This record is optional."
},
"edit": {
"acl": "ACL (Permission)",
"active": "Active",
"admin": "Edit administrator",
"advanced_settings": "Advanced settings",
"alias": "Edit alias",
"allow_from_smtp": "Only allow these IPs to use <b>SMTP</b>",
"allow_from_smtp_info": "Leave empty to allow all senders.<br>IPv4/IPv6 addresses and networks.",
"allowed_protocols": "Allowed protocols",
"app_name": "App name",
"app_passwd": "App password",
"app_passwd_protocols": "Allowed protocols for app password",
"automap": "Try to automap folders (\"Sent items\", \"Sent\" => \"Sent\" etc.)",
"backup_mx_options": "Relay options",
"bcc_dest_format": "BCC destination must be a single valid email address.<br>If you need to send a copy to multiple addresses, create an alias and use it here.",
"client_id": "Client ID",
"client_secret": "Client secret",
"comment_info": "A private comment is not visible to the user, while a public comment is shown as tooltip when hovering it in a user's overview",
"delete1": "Delete from source when completed",
"delete2": "Delete messages on destination that are not on source",
"delete2duplicates": "Delete duplicates on destination",
"delete_ays": "Please confirm the deletion process.",
"description": "Description",
"disable_login": "Disallow login (incoming mail is still accepted)",
"domain": "Edit domain",
"domain_admin": "Edit domain administrator",
"domain_quota": "Domain quota",
"domains": "Domains",
"dont_check_sender_acl": "Disable sender check for domain %s (+ alias domains)",
"edit_alias_domain": "Edit Alias domain",
"encryption": "Encryption",
"exclude": "Exclude objects (regex)",
"extended_sender_acl": "External sender addresses",
"extended_sender_acl_info": "A DKIM domain key should be imported, if available.<br>\r\n Remember to add this server to the corresponding SPF TXT record.<br>\r\n Whenever a domain or alias domain is added to this server, that overlaps with an external address, the external address is removed.<br>\r\n Use @domain.tld to allow to send as *@domain.tld.",
"force_pw_update": "Force password update at next login",
"force_pw_update_info": "This user will only be able to login to %s. App passwords remain useable.",
"full_name": "Full name",
"gal": "Global Address List",
"gal_info": "The GAL contains all objects of a domain and cannot be edited by any user. Free/busy information in SOGo is missing, if disabled! <b>Restart SOGo to apply changes.</b>",
"generate": "generate",
"grant_types": "Grant types",
"hostname": "Hostname",
"inactive": "Inactive",
"kind": "Kind",
"lookup_mx": "Destination is a regular expression to match against MX name (<code>.*google\\.com</code> to route all mail targeted to a MX ending in google.com over this hop)",
"mailbox": "Edit mailbox",
"mailbox_quota_def": "Default mailbox quota",
"mailbox_relayhost_info": "Applied to the mailbox and direct aliases only, does override a domain relayhost.",
"max_aliases": "Max. aliases",
"max_mailboxes": "Max. possible mailboxes",
"max_quota": "Max. quota per mailbox (MiB)",
"maxage": "Maximum age of messages in days that will be polled from remote<br><small>(0 = ignore age)</small>",
"maxbytespersecond": "Max. bytes per second <br><small>(0 = unlimited)</small>",
"mbox_rl_info": "This rate limit is applied on the SASL login name, it matches any \"from\" address used by the logged-in user. A mailbox rate limit overrides a domain-wide rate limit.",
"mins_interval": "Interval (min)",
"multiple_bookings": "Multiple bookings",
"none_inherit": "None / Inherit",
"nexthop": "Next hop",
"password": "Password",
"password_repeat": "Confirmation password (repeat)",
"previous": "Previous page",
"private_comment": "Private comment",
"public_comment": "Public comment",
"pushover": "Pushover",
"pushover_evaluate_x_prio": "Escalate high priority mail [<code>X-Priority: 1</code>]",
"pushover_info": "Push notification settings will apply to all clean (non-spam) mail delivered to <b>%s</b> including aliases (shared, non-shared, tagged).",
"pushover_only_x_prio": "Only consider high priority mail [<code>X-Priority: 1</code>]",
"pushover_sender_array": "Only consider the following sender email addresses <small>(comma-separated)</small>",
"pushover_sender_regex": "Consider the following sender regex",
"pushover_text": "Notification text",
"pushover_title": "Notification title",
+ "pushover_sound": "Sound",
"pushover_vars": "When no sender filter is defined, all mails will be considered.<br>Regex filters as well as exact sender checks can be defined individually and will be considered sequentially. They do not depend on each other.<br>Useable variables for text and title (please take note of data protection policies)",
"pushover_verify": "Verify credentials",
"quota_mb": "Quota (MiB)",
"quota_warning_bcc": "Quota warning BCC",
"quota_warning_bcc_info": "Warnings will be sent as separate copies to the following recipients. The subject will be suffixed by the corresponding username in brackets, for example: <code>Quota warning (user@example.com)</code>.",
"ratelimit": "Rate limit",
"redirect_uri": "Redirect/Callback URL",
"relay_all": "Relay all recipients",
"relay_all_info": "↪ If you choose <b>not</b> to relay all recipients, you will need to add a (\"blind\") mailbox for every single recipient that should be relayed.",
"relay_domain": "Relay this domain",
"relay_transport_info": "<div class=\"label label-info\">Info</div> You can define transport maps for a custom destination for this domain. If not set, a MX lookup will be made.",
"relay_unknown_only": "Relay non-existing mailboxes only. Existing mailboxes will be delivered locally.",
"relayhost": "Sender-dependent transports",
"remove": "Remove",
"resource": "Resource",
"save": "Save changes",
"scope": "Scope",
"sender_acl": "Allow to send as",
"sender_acl_disabled": "<span class=\"label label-danger\">Sender check is disabled</span>",
"sender_acl_info": "If mailbox user A is allowed to send as mailbox user B, the sender address is not automatically displayed as selectable \"from\" field in SOGo.<br>\r\n Mailbox user B needs to create a delegation in SOGo to allow mailbox user A to select their address as sender. To delegate a mailbox in SOGo, use the menu (three dots) to the right of your mailbox name in the upper left while in mail view. This behaviour does not apply to alias addresses.",
"sieve_desc": "Short description",
"sieve_type": "Filter type",
"skipcrossduplicates": "Skip duplicate messages across folders (first come, first serve)",
"sogo_access": "Grant direct login access to SOGo",
"sogo_access_info": "Single-sign-on from within the mail UI remains working. This setting does neither affect access to all other services nor does it delete or change a user's existing SOGo profile.",
"sogo_visible": "Alias is visible in SOGo",
"sogo_visible_info": "This option only affects objects, that can be displayed in SOGo (shared or non-shared alias addresses pointing to at least one local mailbox). If hidden, an alias will not appear as selectable sender in SOGo.",
"spam_alias": "Create or change time limited alias addresses",
"spam_filter": "Spam filter",
"spam_policy": "Add or remove items to white-/blacklist",
"spam_score": "Set a custom spam score",
"subfolder2": "Sync into subfolder on destination<br><small>(empty = do not use subfolder)</small>",
"syncjob": "Edit sync job",
"target_address": "Goto address/es <small>(comma-separated)</small>",
"target_domain": "Target domain",
"timeout1": "Timeout for connection to remote host",
"timeout2": "Timeout for connection to local host",
"title": "Edit object",
"unchanged_if_empty": "If unchanged leave blank",
"username": "Username",
"validate_save": "Validate and save"
},
"fido2": {
"confirm": "Confirm",
"fido2_auth": "Login with FIDO2",
"fido2_success": "Device successfully registered",
"fido2_validation_failed": "Validation failed",
"fn": "Friendly name",
"known_ids": "Known IDs",
"none": "Disabled",
"register_status": "Registration status",
"rename": "Rename",
"set_fido2": "Register FIDO2 device",
"set_fido2_touchid": "Register Touch ID on Apple M1",
"set_fn": "Set friendly name",
"start_fido2_validation": "Start FIDO2 validation"
},
"footer": {
"cancel": "Cancel",
"confirm_delete": "Confirm deletion",
"delete_now": "Delete now",
"delete_these_items": "Please confirm your changes to the following object id",
"hibp_check": "Check against haveibeenpwned.com",
"hibp_nok": "Matched! This is a potentially dangerous password!",
"hibp_ok": "No match found.",
"loading": "Please wait...",
"nothing_selected": "Nothing selected",
"restart_container": "Restart container",
"restart_container_info": "<b>Important:</b> A graceful restart may take a while to complete, please wait for it to finish.",
"restart_now": "Restart now",
"restarting_container": "Restarting container, this may take a while"
},
"header": {
"administration": "Configuration & Details",
"apps": "Apps",
"debug": "System Information",
"mailboxes": "Mail Setup",
"mailcow_settings": "Configuration",
"quarantine": "Quarantine",
"restart_netfilter": "Restart netfilter",
"restart_sogo": "Restart SOGo",
"user_settings": "User Settings"
},
"info": {
"awaiting_tfa_confirmation": "Awaiting TFA confirmation",
"no_action": "No action applicable",
"session_expires": "Your session will expire in about 15 seconds"
},
"login": {
"delayed": "Login was delayed by %s seconds.",
"fido2_webauthn": "FIDO2/WebAuthn",
"login": "Login",
"mobileconfig_info": "Please login as mailbox user to download the requested Apple connection profile.",
"other_logins": "Key login",
"password": "Password",
"username": "Username"
},
"mailbox": {
"action": "Action",
"activate": "Activate",
"active": "Active",
"add": "Add",
"add_alias": "Add alias",
"add_alias_expand": "Expand alias over alias domains",
"add_bcc_entry": "Add BCC map",
"add_domain": "Add domain",
"add_domain_alias": "Add domain alias",
"add_domain_record_first": "Please add a domain first",
"add_filter": "Add filter",
"add_mailbox": "Add mailbox",
"add_recipient_map_entry": "Add recipient map",
"add_resource": "Add resource",
"add_tls_policy_map": "Add TLS policy map",
"address_rewriting": "Address rewriting",
"alias": "Alias",
"alias_domain_alias_hint": "Aliases are <b>not</b> applied on domain aliases automatically. An alias address <code>my-alias@domain</code> <b>does not</b> cover the address <code>my-alias@alias-domain</code> (where \"alias-domain\" is an imaginary alias domain for \"domain\").<br>Please use a sieve filter to redirect mail to an external mailbox (see tab \"Filters\" or use SOGo -> Forwarder). Use \"Expand alias over alias domains\" to automatically add missing aliases.",
"alias_domain_backupmx": "Alias domain inactive for relay domain",
"aliases": "Aliases",
"all_domains": "All Domains",
"allow_from_smtp": "Only allow these IPs to use <b>SMTP</b>",
"allow_from_smtp_info": "Leave empty to allow all senders.<br>IPv4/IPv6 addresses and networks.",
"allowed_protocols": "Allowed protocols for direct user access (does not affect app password protocols)",
"backup_mx": "Relay domain",
"bcc": "BCC",
"bcc_destination": "BCC destination",
"bcc_destinations": "BCC destination",
"bcc_info": "BCC maps are used to silently forward copies of all messages to another address. A recipient map type entry is used, when the local destination acts as recipient of a mail. Sender maps conform to the same principle.<br/>\r\n The local destination will not be informed about a failed delivery.",
"bcc_local_dest": "Local destination",
"bcc_map": "BCC map",
"bcc_map_type": "BCC type",
"bcc_maps": "BCC maps",
"bcc_rcpt_map": "Recipient map",
"bcc_sender_map": "Sender map",
"bcc_to_rcpt": "Switch to recipient map type",
"bcc_to_sender": "Switch to sender map type",
"bcc_type": "BCC type",
"booking_null": "Always show as free",
"booking_0_short": "Always free",
"booking_custom": "Hard-limit to a custom amount of bookings",
"booking_custom_short": "Hard limit",
"booking_ltnull": "Unlimited, but show as busy when booked",
"booking_lt0_short": "Soft limit",
"catch_all": "Catch-All",
"daily": "Daily",
"deactivate": "Deactivate",
"description": "Description",
"disable_login": "Disallow login (incoming mail is still accepted)",
"disable_x": "Disable",
"domain": "Domain",
"domain_admins": "Domain administrators",
"domain_aliases": "Domain aliases",
"domain_quota": "Quota",
"domains": "Domains",
"edit": "Edit",
"empty": "No results",
"enable_x": "Enable",
"excludes": "Excludes",
"filter_table": "Filter table",
"filters": "Filters",
"fname": "Full name",
"goto_ham": "Learn as <b>ham</b>",
"goto_spam": "Learn as <b>spam</b>",
"hourly": "Hourly",
"in_use": "In use (%)",
"inactive": "Inactive",
"insert_preset": "Insert example preset \"%s\"",
"kind": "Kind",
"last_mail_login": "Last mail login",
"last_pw_change": "Last password change",
"last_run": "Last run",
"last_run_reset": "Schedule next",
"mailbox": "Mailbox",
"mailbox_defaults": "Default settings",
"mailbox_defaults_info": "Define default settings for new mailboxes.",
"mailbox_defquota": "Default mailbox size",
"mailbox_quota": "Max. size of a mailbox",
"mailboxes": "Mailboxes",
"mins_interval": "Interval (min)",
"msg_num": "Message #",
"multiple_bookings": "Multiple bookings",
"never": "Never",
"no": "&#10005;",
"no_record": "No record for object %s",
"no_record_single": "No record",
"open_logs": "Open logs",
"owner": "Owner",
"private_comment": "Private comment",
"public_comment": "Public comment",
"q_add_header": "when moved to Junk folder",
"q_all": " when moved to Junk folder and on reject",
"q_reject": "on reject",
"quarantine_category": "Quarantine notification category",
"quarantine_notification": "Quarantine notifications",
"quick_actions": "Actions",
"recipient": "Recipient",
"recipient_map": "Recipient map",
"recipient_map_info": "Recipient maps are used to replace the destination address on a message before it is delivered.",
"recipient_map_new": "New recipient",
"recipient_map_new_info": "Recipient map destination must be a valid email address.",
"recipient_map_old": "Original recipient",
"recipient_map_old_info": "A recipient maps original destination must be valid email addresses or a domain name.",
"recipient_maps": "Recipient maps",
"remove": "Remove",
"resources": "Resources",
"running": "Running",
"sender": "Sender",
"set_postfilter": "Mark as postfilter",
"set_prefilter": "Mark as prefilter",
"sieve_info": "You can store multiple filters per user, but only one prefilter and one postfilter can be active at the same time.<br>\r\nEach filter will be processed in the described order. Neither a failed script nor an issued \"keep;\" will stop processing of further scripts. Changes to global sieve scripts will trigger a restart of Dovecot.<br><br>Global sieve prefilter &#8226; Prefilter &#8226; User scripts &#8226; Postfilter &#8226; Global sieve postfilter",
"sieve_preset_1": "Discard mail with probable dangerous file types",
"sieve_preset_2": "Always mark the e-mail of a specific sender as seen",
"sieve_preset_3": "Discard silently, stop all further sieve processing",
"sieve_preset_4": "File into INBOX, skip further processing by sieve filters",
"sieve_preset_5": "Auto responder (vacation)",
"sieve_preset_6": "Reject mail with reponse",
"sieve_preset_7": "Redirect and keep/drop",
"sieve_preset_8": "Discard message sent to an alias address the sender is part of",
"sieve_preset_header": "Please see the example presets below. For more details see <a href=\"https://en.wikipedia.org/wiki/Sieve_(mail_filtering_language)\" target=\"_blank\">Wikipedia</a>.",
"sogo_visible": "Alias is visible in SOGo",
"sogo_visible_n": "Hide alias in SOGo",
"sogo_visible_y": "Show alias in SOGo",
"spam_aliases": "Temp. alias",
"stats": "Statistics",
"status": "Status",
"sync_jobs": "Sync jobs",
"syncjob_check_log": "Check log",
"syncjob_last_run_result": "Last run result",
"syncjob_EX_OK": "Success",
"syncjob_EXIT_CONNECTION_FAILURE": "Connection problem",
"syncjob_EXIT_TLS_FAILURE": "Problem with encrypted connection",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "Authentication problem",
"syncjob_EXIT_OVERQUOTA": "Target mailbox is over quota",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Can't connect to remote server",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Wrong username or password",
"table_size": "Table size",
"table_size_show_n": "Show %s items",
"target_address": "Goto address",
"target_domain": "Target domain",
"tls_enforce_in": "Enforce TLS incoming",
"tls_enforce_out": "Enforce TLS outgoing",
"tls_map_dest": "Destination",
"tls_map_dest_info": "Examples: example.org, .example.org, [mail.example.org]:25",
"tls_map_parameters": "Parameters",
"tls_map_parameters_info": "Empty or parameters, for example: protocols=!SSLv2 ciphers=medium exclude=3DES",
"tls_map_policy": "Policy",
"tls_policy_maps": "TLS policy maps",
"tls_policy_maps_enforced_tls": "These policies will also override the behaviour for mailbox users that enforce outgoing TLS connections. If no policy exists below, these users will apply the default values specified as <code>smtp_tls_mandatory_protocols</code> and <code>smtp_tls_mandatory_ciphers</code>.",
"tls_policy_maps_info": "This policy map overrides outgoing TLS transport rules independently of a user's TLS policy settings.<br>\r\n Please check <a href=\"http://www.postfix.org/postconf.5.html#smtp_tls_policy_maps\" target=\"_blank\">the \"smtp_tls_policy_maps\" docs</a> for further information.",
"tls_policy_maps_long": "Outgoing TLS policy map overrides",
"toggle_all": "Toggle all",
"username": "Username",
"waiting": "Waiting",
"weekly": "Weekly",
"yes": "&#10003;"
},
"oauth2": {
"access_denied": "Please login as mailbox owner to grant access via OAuth2.",
"authorize_app": "Authorize application",
"deny": "Deny",
"permit": "Authorize application",
"profile": "Profile",
"profile_desc": "View personal information: username, full name, created, modified, active",
"scope_ask_permission": "An application asked for the following permissions"
},
"quarantine": {
"action": "Action",
"atts": "Attachments",
"check_hash": "Search file hash @ VT",
"confirm": "Confirm",
"confirm_delete": "Confirm the deletion of this element.",
"danger": "Danger",
"deliver_inbox": "Deliver to inbox",
"disabled_by_config": "The current system configuration disables the quarantine functionality. Please set \"retentions per mailbox\" and a \"maximum size\" for quarantine elements.",
"download_eml": "Download (.eml)",
"empty": "No results",
"high_danger": "High",
"info": "Information",
"junk_folder": "Junk folder",
"learn_spam_delete": "Learn as spam and delete",
"low_danger": "Low",
"medium_danger": "Medium",
"neutral_danger": "Neutral",
"notified": "Notified",
"qhandler_success": "Request successfully sent to the system. You can now close the window.",
"qid": "Rspamd QID",
"qinfo": "The quarantine system will save rejected mail to the database (the sender will <em>not</em> be given the impression of a delivered mail) as well as mail, that is delivered as copy into the Junk folder of a mailbox.\r\n <br>\"Learn as spam and delete\" will learn a message as spam via Bayesian theorem and also calculate fuzzy hashes to deny similar messages in the future.\r\n <br>Please be aware that learning multiple messages can be - depending on your system - time consuming.<br>Blacklisted elements are excluded from the quarantine.",
"qitem": "Quarantine item",
"quarantine": "Quarantine",
"quick_actions": "Actions",
"quick_delete_link": "Open quick delete link",
"quick_info_link": "Open info link",
"quick_release_link": "Open quick release link",
"rcpt": "Recipient",
"received": "Received",
"recipients": "Recipients",
"refresh": "Refresh",
"rejected": "Rejected",
"release": "Release",
"release_body": "We have attached your message as eml file to this message.",
"release_subject": "Potentially damaging quarantine item %s",
"remove": "Remove",
"rewrite_subject": "Rewrite subject",
"rspamd_result": "Rspamd result",
"sender": "Sender (SMTP)",
"sender_header": "Sender (\"From\" header)",
"settings_info": "Maximum amount of elements to be quarantined: %s<br>Maximum email size: %s MiB",
"show_item": "Show item",
"spam": "Spam",
"spam_score": "Score",
"subj": "Subject",
"table_size": "Table size",
"table_size_show_n": "Show %s items",
"text_from_html_content": "Content (converted html)",
"text_plain_content": "Content (text/plain)",
"toggle_all": "Toggle all",
"type": "Type"
},
"ratelimit": {
"disabled": "Disabled",
"second": "msgs / second",
"minute": "msgs / minute",
"hour": "msgs / hour",
"day": "msgs / day"
},
"start": {
"help": "Show/Hide help panel",
"imap_smtp_server_auth_info": "Please use your full email address and the PLAIN authentication mechanism.<br>\r\nYour login data will be encrypted by the server-side mandatory encryption.",
"mailcow_apps_detail": "Use a mailcow app to access your mails, calendar, contacts and more.",
"mailcow_panel_detail": "<b>Domain administrators</b> create, modify or delete mailboxes and aliases, change domains and read further information about their assigned domains.<br>\r\n<b>Mailbox users</b> are able to create time-limited aliases (spam aliases), change their password and spam filter settings."
},
"success": {
"acl_saved": "ACL for object %s saved",
"admin_added": "Administrator %s has been added",
"admin_api_modified": "Changes to API have been saved",
"admin_modified": "Changes to administrator have been saved",
"admin_removed": "Administrator %s has been removed",
"alias_added": "Alias address %s (%d) has been added",
"alias_domain_removed": "Alias domain %s has been removed",
"alias_modified": "Changes to alias address %s have been saved",
"alias_removed": "Alias %s has been removed",
"aliasd_added": "Added alias domain %s",
"aliasd_modified": "Changes to alias domain %s have been saved",
"app_links": "Saved changes to app links",
"app_passwd_added": "Added new app password",
"app_passwd_removed": "Removed app password ID %s",
"bcc_deleted": "BCC map entries deleted: %s",
"bcc_edited": "BCC map entry %s edited",
"bcc_saved": "BCC map entry saved",
"db_init_complete": "Database initialization completed",
"delete_filter": "Deleted filters ID %s",
"delete_filters": "Deleted filters: %s",
"deleted_syncjob": "Deleted syncjob ID %s",
"deleted_syncjobs": "Deleted syncjobs: %s",
"dkim_added": "DKIM key %s has been saved",
"domain_add_dkim_available": "A DKIM key did already exist",
"dkim_duplicated": "DKIM key for domain %s has been copied to %s",
"dkim_removed": "DKIM key %s has been removed",
"domain_added": "Added domain %s",
"domain_admin_added": "Domain administrator %s has been added",
"domain_admin_modified": "Changes to domain administrator %s have been saved",
"domain_admin_removed": "Domain administrator %s has been removed",
"domain_modified": "Changes to domain %s have been saved",
"domain_removed": "Domain %s has been removed",
"dovecot_restart_success": "Dovecot was restarted successfully",
"eas_reset": "ActiveSync devices for user %s were reset",
"f2b_modified": "Changes to Fail2ban parameters have been saved",
"forwarding_host_added": "Forwarding host %s has been added",
"forwarding_host_removed": "Forwarding host %s has been removed",
"global_filter_written": "Filter was successfully written to file",
"hash_deleted": "Hash deleted",
"item_deleted": "Item %s successfully deleted",
"item_released": "Item %s released",
"items_deleted": "Item %s successfully deleted",
"items_released": "Selected items were released",
"learned_ham": "Successfully learned ID %s as ham",
"license_modified": "Changes to license have been saved",
"logged_in_as": "Logged in as %s",
"mailbox_added": "Mailbox %s has been added",
"mailbox_modified": "Changes to mailbox %s have been saved",
"mailbox_removed": "Mailbox %s has been removed",
"nginx_reloaded": "Nginx was reloaded",
"object_modified": "Changes to object %s have been saved",
"password_policy_saved": "Password policy was saved successfully",
"pushover_settings_edited": "Pushover settings successfully set, please verify credentials.",
"qlearn_spam": "Message ID %s was learned as spam and deleted",
"queue_command_success": "Queue command completed successfully",
"recipient_map_entry_deleted": "Recipient map ID %s has been deleted",
"recipient_map_entry_saved": "Recipient map entry \"%s\" has been saved",
"relayhost_added": "Map entry %s has been added",
"relayhost_removed": "Map entry %s has been removed",
"reset_main_logo": "Reset to default logo",
"resource_added": "Resource %s has been added",
"resource_modified": "Changes to mailbox %s have been saved",
"resource_removed": "Resource %s has been removed",
"rl_saved": "Rate limit for object %s saved",
"rspamd_ui_pw_set": "Rspamd UI password successfully set",
"saved_settings": "Saved settings",
"settings_map_added": "Added settings map entry",
"settings_map_removed": "Removed settings map ID %s",
"sogo_profile_reset": "SOGo profile for user %s was reset",
"tls_policy_map_entry_deleted": "TLS policy map ID %s has been deleted",
"tls_policy_map_entry_saved": "TLS policy map entry \"%s\" has been saved",
"ui_texts": "Saved changes to UI texts",
"upload_success": "File uploaded successfully",
"verified_fido2_login": "Verified FIDO2 login",
"verified_totp_login": "Verified TOTP login",
"verified_webauthn_login": "Verified WebAuthn login",
"verified_yotp_login": "Verified Yubico OTP login"
},
"tfa": {
"api_register": "%s uses the Yubico Cloud API. Please get an API key for your key <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">here</a>",
"confirm": "Confirm",
"confirm_totp_token": "Please confirm your changes by entering the generated token",
"delete_tfa": "Disable TFA",
"disable_tfa": "Disable TFA until next successful login",
"enter_qr_code": "Your TOTP code if your device cannot scan QR codes",
"error_code": "Error code",
"init_webauthn": "Initializing, please wait...",
"key_id": "An identifier for your Device",
"key_id_totp": "An identifier for your key",
"none": "Deactivate",
"reload_retry": "- (reload browser if the error persists)",
"scan_qr_code": "Please scan the following code with your authenticator app or enter the code manually.",
"select": "Please select",
"set_tfa": "Set two-factor authentication method",
"start_webauthn_validation": "Start validation",
"tfa": "Two-factor authentication",
"tfa_token_invalid": "TFA token invalid",
"totp": "Time-based OTP (Google Authenticator, Authy, etc.)",
"u2f_deprecated": "It seems that your Key was registered using the deprecated U2F method. We will deactivate Two-Factor-Authenticaiton for you and delete your Key.",
"u2f_deprecated_important": "Please register your Key in the admin panel with the new WebAuthn method.",
"webauthn": "WebAuthn authentication",
"waiting_usb_auth": "<i>Waiting for USB device...</i><br><br>Please tap the button on your USB device now.",
"waiting_usb_register": "<i>Waiting for USB device...</i><br><br>Please enter your password above and confirm your registration by tapping the button on your USB device.",
"yubi_otp": "Yubico OTP authentication"
},
"user": {
"action": "Action",
"active": "Active",
"active_sieve": "Active filter",
"advanced_settings": "Advanced settings",
"alias": "Alias",
"alias_create_random": "Generate random alias",
"alias_extend_all": "Extend aliases by 1 hour",
"alias_full_date": "d.m.Y, H:i:s T",
"alias_remove_all": "Remove all aliases",
"alias_select_validity": "Period of validity",
"alias_time_left": "Time left",
"alias_valid_until": "Valid until",
"aliases_also_send_as": "Also allowed to send as user",
"aliases_send_as_all": "Do not check sender access for the following domain(s) and its alias domains",
"app_hint": "App passwords are alternative passwords for your IMAP, SMTP, CalDAV, CardDAV and EAS login. The username remains unchanged. SOGo webmail is not available through app passwords.",
"allowed_protocols": "Allowed protocols",
"app_name": "App name",
"app_passwds": "App passwords",
"apple_connection_profile": "Apple connection profile",
"apple_connection_profile_complete": "This connection profile includes IMAP and SMTP parameters as well as CalDAV (calendars) and CardDAV (contacts) paths for an Apple device.",
"apple_connection_profile_mailonly": "This connection profile includes IMAP and SMTP configuration parameters for an Apple device.",
"apple_connection_profile_with_app_password": "A new app password is generated and added to the profile so that no password needs to be entered when setting up your device. Please do not share the file as it grants full access to your mailbox.",
"change_password": "Change password",
"change_password_hint_app_passwords": "Your account has {{number_of_app_passwords}} app passwords that will not be changed. To manage these, go to the App passwords tab.",
"clear_recent_successful_connections": "Clear seen successful connections",
"client_configuration": "Show configuration guides for email clients and smartphones",
"create_app_passwd": "Create app password",
"create_syncjob": "Create new sync job",
"created_on": "Created on",
"daily": "Daily",
"day": "day",
"delete_ays": "Please confirm the deletion process.",
"direct_aliases": "Direct alias addresses",
"direct_aliases_desc": "Direct alias addresses are affected by spam filter and TLS policy settings.",
"direct_protocol_access": "This mailbox user has <b>direct, external access</b> to the following protocols and applications. This setting is controlled by your administrator. App passwords can be created to grant access to individual protocols and applications.<br>The \"Login to webmail\" button provides single-sign-on to SOGo and is always available.",
"eas_reset": "Reset ActiveSync device cache",
"eas_reset_help": "In many cases a device cache reset will help to recover a broken ActiveSync profile.<br><b>Attention:</b> All elements will be redownloaded!",
"eas_reset_now": "Reset now",
"edit": "Edit",
"email": "Email",
"email_and_dav": "Email, calendars and contacts",
"empty": "No results",
"encryption": "Encryption",
"excludes": "Excludes",
"expire_in": "Expire in",
"fido2_webauthn": "FIDO2/WebAuthn",
"force_pw_update": "You <b>must</b> set a new password to be able to access groupware related services.",
"from": "from",
"generate": "generate",
"hour": "hour",
"hourly": "Hourly",
"hours": "hours",
"in_use": "Used",
"interval": "Interval",
"is_catch_all": "Catch-all for domain/s",
"last_mail_login": "Last mail login",
"last_pw_change": "Last password change",
"last_run": "Last run",
"last_ui_login": "Last UI login",
"loading": "Loading...",
"login_history": "Login history",
"mailbox": "Mailbox",
"mailbox_details": "Details",
"mailbox_general": "General",
"mailbox_settings": "Settings",
"messages": "messages",
"month": "month",
"months": "months",
"never": "Never",
"new_password": "New password",
"new_password_repeat": "Confirmation password (repeat)",
"no_active_filter": "No active filter available",
"no_last_login": "No last UI login information",
"no_record": "No record",
"open_logs": "Open logs",
"open_webmail_sso": "Login to webmail",
"password": "Password",
"password_now": "Current password (confirm changes)",
"password_repeat": "Password (repeat)",
"pushover_evaluate_x_prio": "Escalate high priority mail [<code>X-Priority: 1</code>]",
"pushover_info": "Push notification settings will apply to all clean (non-spam) mail delivered to <b>%s</b> including aliases (shared, non-shared, tagged).",
"pushover_only_x_prio": "Only consider high priority mail [<code>X-Priority: 1</code>]",
"pushover_sender_array": "Consider the following sender email addresses <small>(comma-separated)</small>",
"pushover_sender_regex": "Match senders by the following regex",
"pushover_text": "Notification text",
"pushover_title": "Notification title",
+ "pushover_sound": "Sound",
"pushover_vars": "When no sender filter is defined, all mails will be considered.<br>Regex filters as well as exact sender checks can be defined individually and will be considered sequentially. They do not depend on each other.<br>Useable variables for text and title (please take note of data protection policies)",
"pushover_verify": "Verify credentials",
"q_add_header": "Junk folder",
"q_all": "All categories",
"q_reject": "Rejected",
"quarantine_category": "Quarantine notification category",
"quarantine_category_info": "The notification category \"Rejected\" includes mail that was rejected, while \"Junk folder\" will notify a user about mails that were put into the junk folder.",
"quarantine_notification": "Quarantine notifications",
"quarantine_notification_info": "Once a notification has been sent, items will be marked as \"notified\" and no further notifications will be sent for this particular item.",
"recent_successful_connections": "Seen successful connections",
"remove": "Remove",
"running": "Running",
"save": "Save changes",
"save_changes": "Save changes",
"sender_acl_disabled": "<span class=\"label label-danger\">Sender check is disabled</span>",
"shared_aliases": "Shared alias addresses",
"shared_aliases_desc": "Shared aliases are not affected by user specific settings such as the spam filter or encryption policy. Corresponding spam filters can only be made by an administrator as a domain-wide policy.",
"show_sieve_filters": "Show active user sieve filter",
"sogo_profile_reset": "Reset SOGo profile",
"sogo_profile_reset_help": "This will destroy a user's SOGo profile and <b>delete all contact and calendar data irretrievable</b>.",
"sogo_profile_reset_now": "Reset profile now",
"spam_aliases": "Temporary email aliases",
"spam_score_reset": "Reset to server default",
"spamfilter": "Spam filter",
"spamfilter_behavior": "Rating",
"spamfilter_bl": "Blacklist",
"spamfilter_bl_desc": "Blacklisted email addresses to <b>always</b> classify as spam and reject. Rejected mail will <b>not</b> be copied to quarantine. Wildcards may be used. A filter is only applied to direct aliases (aliases with a single target mailbox) excluding catch-all aliases and a mailbox itself.",
"spamfilter_default_score": "Default values",
"spamfilter_green": "Green: this message is not spam",
"spamfilter_hint": "The first value describes the \"low spam score\", the second represents the \"high spam score\".",
"spamfilter_red": "Red: This message is spam and will be rejected by the server",
"spamfilter_table_action": "Action",
"spamfilter_table_add": "Add item",
"spamfilter_table_domain_policy": "n/a (domain policy)",
"spamfilter_table_empty": "No data to display",
"spamfilter_table_remove": "remove",
"spamfilter_table_rule": "Rule",
"spamfilter_wl": "Whitelist",
"spamfilter_wl_desc": "Whitelisted email addresses are programmed to <b>never</b> classify as spam. Wildcards may be used. A filter is only applied to direct aliases (aliases with a single target mailbox) excluding catch-all aliases and a mailbox itself.",
"spamfilter_yellow": "Yellow: this message may be spam, will be tagged as spam and moved to your junk folder",
"status": "Status",
"sync_jobs": "Sync jobs",
"syncjob_check_log": "Check log",
"syncjob_last_run_result": "Last run result",
"syncjob_EX_OK": "Success",
"syncjob_EXIT_CONNECTION_FAILURE": "Connection problem",
"syncjob_EXIT_TLS_FAILURE": "Problem with encrypted connection",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "Authentication problem",
"syncjob_EXIT_OVERQUOTA": "Target mailbox is over quota",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Can't connect to remote server",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Wrong username or password",
"tag_handling": "Set handling for tagged mail",
"tag_help_example": "Example for a tagged email address: me<b>+Facebook</b>@example.org",
"tag_help_explain": "In subfolder: a new subfolder named after the tag will be created below INBOX (\"INBOX/Facebook\").<br>\r\nIn subject: the tags name will be prepended to the mails subject, example: \"[Facebook] My News\".",
"tag_in_none": "Do nothing",
"tag_in_subfolder": "In subfolder",
"tag_in_subject": "In subject",
"text": "Text",
"title": "Title",
"tls_enforce_in": "Enforce TLS incoming",
"tls_enforce_out": "Enforce TLS outgoing",
"tls_policy": "Encryption policy",
"tls_policy_warning": "<strong>Warning:</strong> If you decide to enforce encrypted mail transfer, you may lose emails.<br>Messages to not satisfy the policy will be bounced with a hard fail by the mail system.<br>This option applies to your primary email address (login name), all addresses derived from alias domains as well as alias addresses <b>with only this single mailbox</b> as target.",
"user_settings": "User settings",
"username": "Username",
"verify": "Verify",
"waiting": "Waiting",
"week": "week",
"weekly": "Weekly",
"weeks": "weeks",
"with_app_password": "with app password",
"year": "year",
"years": "years"
},
"warning": {
"cannot_delete_self": "Cannot delete logged in user",
"domain_added_sogo_failed": "Added domain but failed to restart SOGo, please check your server logs.",
"dovecot_restart_failed": "Dovecot failed to restart, please check the logs",
"fuzzy_learn_error": "Fuzzy hash learn error: %s",
"hash_not_found": "Hash not found or already deleted",
"ip_invalid": "Skipped invalid IP: %s",
"is_not_primary_alias": "Skipped non-primary alias %s",
"no_active_admin": "Cannot deactivate last active admin",
"quota_exceeded_scope": "Domain quota exceeded: Only unlimited mailboxes can be created in this domain scope.",
"session_token": "Form token invalid: Token mismatch",
"session_ua": "Form token invalid: User-Agent validation error"
}
}
diff --git a/data/web/lang/lang.nl-nl.json b/data/web/lang/lang.nl-nl.json
index ecfee43d..af8e9834 100644
--- a/data/web/lang/lang.nl-nl.json
+++ b/data/web/lang/lang.nl-nl.json
@@ -1,1078 +1,1080 @@
{
"acl": {
"alias_domains": "Voeg aliasdomeinen toe",
"app_passwds": "Beheer appwachtwoorden",
"bcc_maps": "BCC-maps",
"delimiter_action": "Delimiter-actie",
"eas_reset": "Herstel ActiveSync-apparaatcache",
"extend_sender_acl": "Sta verzenden via externe adressen toe",
"filters": "Filters",
"login_as": "Log in als mailboxgebruiker",
"prohibited": "Toegang geweigerd",
"protocol_access": "Wijzig protocoltoegang",
"pushover": "Pushover",
"quarantine": "Quarantaine-acties",
"quarantine_attachments": "Quarantainebijlagen",
"quarantine_notification": "Quarantainemeldingen",
"quarantine_category": "Wijzig categorie van quarantainemeldingen",
"ratelimit": "Ratelimit",
"recipient_maps": "Ontvanger-maps",
"smtp_ip_access": "Wijzig toegestane hosts voor SMTP",
"sogo_access": "Sta beheer van SOGo-toegang toe",
"sogo_profile_reset": "Verwijder SOGo-profiel",
"spam_alias": "Tijdelijke aliassen",
"spam_policy": "Blacklist/Whitelist",
"spam_score": "Spamscore",
"syncjobs": "Sync jobs",
"tls_policy": "Versleutelingsbeleid",
"unlimited_quota": "Onbeperkte quota voor mailboxen",
"domain_desc": "Wijzig domeinbeschrijving"
},
"add": {
"activate_filter_warn": "Alle andere filters worden gedeactiveerd zolang deze geactiveerd is.",
"active": "Actief",
"add": "Voeg toe",
"add_domain_only": "Voeg enkel domein toe",
"add_domain_restart": "Voeg domein toe en herstart SOGo",
"alias_address": "Aliasadres(sen)",
"alias_address_info": "<small>Volledig(e) mailadres(sen) of @example.com, om een catch-all aan te maken voor een domein (kommagescheiden). <b>Uitsluitend Mailcow-domeinen</b>.</small>",
"alias_domain": "Aliasdomein",
"alias_domain_info": "<small>Uitsluitend geldige domeinnamen (kommagescheiden).</small>",
"app_name": "Naam van app",
"app_password": "Maak appwachtwoord aan",
"automap": "Probeer mappen automatisch te koppelen (\"Verzonden items\", \"Verzonden\" => \"Verzonden\" etc.)",
"backup_mx_options": "Relay-opties",
"comment_info": "Een persoonlijke opmerking is niet zichtbaar voor de gebruiker, terwijl een publieke opmerking wel getoond wordt in het overzicht van de gebruiker.",
"custom_params": "Aangepaste parameters",
"custom_params_hint": "Juist: --param=xy, onjuist: --param xy",
"delete1": "Verwijder van bron wanneer voltooid",
"delete2": "Verwijder berichten die zich niet in de bron bevinden",
"delete2duplicates": "Verwijder duplicaten op de bestemming",
"description": "Beschrijving",
"destination": "Bestemming",
"disable_login": "Weiger aanmelden (inkomende mail blijft binnenkomen)",
"domain": "Domein",
"domain_matches_hostname": "Domein %s komt overeen met hostname",
"domain_quota_m": "Totale domeinquota (MiB)",
"enc_method": "Versleutelingsmethode",
"exclude": "Sluit objecten uit (regex)",
"full_name": "Volledige naam",
"gal": "Globale adreslijst",
"gal_info": "De globale adreslijst bevat alle objecten van een domein. Deze kunnen door geen enkele gebruiker worden bewerkt. <b>Herstart SOGo om wijzigingen door te voeren.</b>",
"generate": "genereer",
"goto_ham": "Train als <span class=\"text-success\"><b>ham</b></span>",
"goto_null": "Verwijder mail onmiddelijk",
"goto_spam": "Train als <span class=\"text-danger\"><b>spam</b></span>",
"hostname": "Hostname",
"inactive": "Inactief",
"kind": "Soort",
"mailbox_quota_def": "Standaard mailboxquota",
"mailbox_quota_m": "Maximale mailboxquota (MiB)",
"mailbox_username": "Gebruikersnaam (linkergedeelte van een mailadres)",
"max_aliases": "Maximaal aantal aliassen",
"max_mailboxes": "Maximaal aantal mailboxen",
"mins_interval": "Interval (min)",
"multiple_bookings": "Meerdere boekingen",
"nexthop": "Nexthop",
"password": "Wachtwoord",
"password_repeat": "Herhaal wachtwoord",
"port": "Poort",
"post_domain_add": "De SOGo-container, \"sogo-mailcow\", dient herstart te worden na het toevoegen van een nieuw domein!<br><br>Daarnaast wordt het aanbevolen om de DNS-configuratie te herzien. Nadat de DNS-configuratie juist is ingesteld, herstart je \"acme-mailcow\" om direct certificaten voor het nieuwe domein te genereren.<br>De laatste stap is optioneel, en zal elke 24 uur automatisch geprobeerd worden.",
"private_comment": "Persoonlijke opmerking",
"public_comment": "Publieke opmerking",
"quota_mb": "Quota (MiB)",
"relay_all": "Forward alle ontvangers",
"relay_all_info": "↪ Wanneer er wordt gekozen om <b>niet</b> alle ontvangers te forwarden, dient er per ontvanger een lege mailbox aangemaakt te worden.",
"relay_domain": "Forward dit domein",
"relay_transport_info": "<div class=\"label label-info\">Info</div> Je kunt transport-maps aanmaken om een aangepaste bestemming in te stellen voor dit domein. Zo niet, zal er een MX-lookup plaatsvinden.",
"relay_unknown_only": "Forward uitsluitend niet-bestaande mailboxen. Bestaande mailboxen zullen lokaal afgeleverd worden.",
"relayhost_wrapped_tls_info": "Gebruik <b>geen</b> in TLS verpakte poorten (meestal poort 465).<br>Gebruik een reguliere poort en initieer STARTTLS. Beleid om verleuteling te forceren kan worden ingesteld bij \"Globaal versleutelingsbeleid\".",
"select": "Selecteer...",
"select_domain": "Selecteer eerst een domein",
"sieve_desc": "Korte beschrijving",
"sieve_type": "Filtertype",
"skipcrossduplicates": "Sla duplicaten verspreid over mappen over (wie het eerst komt, het eerst maalt)",
"subscribeall": "Abonneer op alle mappen",
"syncjob": "Voeg sync job toe",
"syncjob_hint": "Wees ervan bewust dat de authenticatiedata onversleuteld wordt opgeslagen!",
"target_address": "Doeladressen",
"target_address_info": "<small>Volledig(e) mailadres(sen) (kommagescheiden).</small>",
"target_domain": "Doeldomein",
"timeout1": "Time-out voor verbinding met externe hosts",
"timeout2": "Time-out voor verbinding met lokale hosts",
"username": "Gebruikersnaam",
"validate": "Verifieer",
"validation_success": "Succesvol geverifieerd"
},
"admin": {
"access": "Toegang",
"action": "Handeling",
"activate_api": "Activeer API",
"activate_send": "Bevestig bovenstaande gegevens",
"active": "Actief",
"active_rspamd_settings_map": "Huidige instellingen",
"add": "Voeg toe",
"add_admin": "Voeg administrator toe",
"add_domain_admin": "Voeg domeinadministrator toe",
"add_forwarding_host": "Voeg forwarding host toe",
"add_relayhost": "Voeg afzendergebonden transport-map toe",
"add_relayhost_hint": "Wees ervan bewust dat de authenticatiedata onversleuteld wordt opgeslagen!",
"add_row": "Voeg rij toe",
"add_settings_rule": "Voeg regel toe",
"add_transport": "Voeg transport-map toe",
"add_transports_hint": "Wees ervan bewust dat de authenticatiedata onversleuteld wordt opgeslagen!",
"additional_rows": " extra rijen zijn toegevoegd",
"admin": "Administrator",
"admin_details": "Toegangsinstellingen",
"admin_domains": "Domeintoewijzingen",
"advanced_settings": "Geavanceerde instellingen",
"api_allow_from": "Sta API-toegang toe vanaf deze IP-adressen/CIDR-notaties",
"api_info": "De API is nog in ontwikkeling. Documentatie is beschikbaar op <a href=\"/api\">/api</a>",
"api_key": "API-key",
"api_skip_ip_check": "Sla IP-adrescontrole over voor API",
"app_links": "Applicatielinks",
"app_name": "Naam",
"apps_name": "\"Mailcow-apps\"",
"arrival_time": "Aankomsttijd",
"authed_user": "Geauthenticeerde gebruiker",
"ays": "Weet je zeker dat je deze actie wilt uitvoeren?",
"ban_list_info": "Bekijk de lijst met verbannen IP-adressen hieronder: <b>netwerk (resterende tijd) - [acties]</b>.<br />Rode labels geven een permanente verbanning aan.<br />Het kan enkele seconden duren voordat wijzigingen hieronder zichtbaar zijn.",
"change_logo": "Logo",
"configuration": "Instellingen",
"convert_html_to_text": "Converteer HTML naar plaintext",
"credentials_transport_warning": "<b>Waarschuwing</b>: Bij het toevoegen van een nieuwe transport-map zullen de aanmeldingsgegevens voor alle items met een overeenkomende nexthop-kolom worden overgeschreven.",
"customer_id": "Klantnummer",
"customize": "Personalisatie",
"delete_queue": "Verwijder alles",
"destination": "Bestemming",
"dkim_add_key": "Voeg key toe",
"dkim_domains_selector": "Selector",
"dkim_domains_wo_keys": "Selecteer domeinen met ontbrekende keys",
"dkim_from": "Van",
"dkim_from_title": "Kopieer data van domein",
"dkim_key_length": "Grootte van key (bits)",
"dkim_key_missing": "Key ontbreekt",
"dkim_key_unused": "Key ongebruikt",
"dkim_key_valid": "Key geldig",
"dkim_keys": "ARC/DKIM-keys",
"dkim_overwrite_key": "Schrijf bestaande key over",
"dkim_private_key": "Private key",
"dkim_to": "Naar",
"dkim_to_title": "Doeldomein(en) - worden overgeschreven",
"domain": "Domein",
"domain_admin": "Domeinadministrator",
"domain_admins": "Domeinadministrators",
"domain_s": "Domein(en)",
"duplicate": "Dupliceer",
"duplicate_dkim": "Dupliceer key",
"edit": "Wijzig",
"empty": "Geen resultaten",
"excludes": "Exclusief",
"f2b_ban_time": "Verbanningstijd (s)",
"f2b_blacklist": "Netwerken/hosts op de blacklist",
"f2b_filter": "Regex-filters",
"f2b_list_info": "Een host of netwerk op de blacklist staat altijd boven eenzelfde op de whitelist. <b>Het doorvoeren van wijzigingen kan enkele seconden in beslag nemen.</b>",
"f2b_max_attempts": "Maximaal aantal pogingen",
"f2b_netban_ipv4": "Voer de IPv4-subnetgrootte in waar de verbanning van kracht moet zijn (8-32)",
"f2b_netban_ipv6": "Voer de IPv6-subnetgrootte in waar de verbanning van kracht moet zijn (8-128)",
"f2b_parameters": "Fail2ban",
"f2b_regex_info": "De volgende logs worden gebruikt: SOGo, Postfix, Dovecot, PHP-FPM.",
"f2b_retry_window": "Tijdsbestek voor maximale pogingen (s)",
"f2b_whitelist": "Netwerken/hosts op de whitelist",
"filter_table": "Filtertabel",
"flush_queue": "Leeg queue",
"forwarding_hosts": "Forwarding hosts",
"forwarding_hosts_add_hint": "Het is mogelijk om IPv4- of IPv6-adressen, netwerken in CIDR-notatie, hostnames (worden omgezet naar IP-adressen) of domeinnamen (worden tevens omgezet naar IP-adressen of, bij gebrek daaraan, MX-records) op te geven.",
"forwarding_hosts_hint": "Inkomende berichten worden onvoorwaardelijk geaccepteerd vanaf iedere host hieronder vermeld. Deze hosts worden hierdoor niet gecontroleerd op DNSBLs, en zullen de greylisting omzeilen. Spam wordt daarentegen zoals gebruikelijk in de spamfolder geplaatst. Dit wordt vaak gebruikt om mailservers te specificeren die forwarden naar deze Mailcow-server.",
"from": "Afzender",
"generate": "genereer",
"guid": "Identificatienummer - GUID",
"guid_and_license": "Licentie en identificatie",
"hash_remove_info": "Het verwijderen van een ratelimit-hash, indien nog aanwezig, zal zijn teller volledig herstellen.<br>Elke hash wordt aangeduid met een aparte kleur.",
"help_text": "Hulpteksten onder aanmeldvenster (HTML toegestaan)",
"host": "Host",
"html": "HTML",
"import": "Importeer",
"import_private_key": "Importeer private key",
"in_use_by": "In gebruik door",
"inactive": "Inactief",
"include_exclude": "Ontvangers",
"include_exclude_info": "Zonder selectie worden <b>alle mailboxen</b> benaderd!",
"includes": "Inclusief",
"last_applied": "Voor het laatst toegepast",
"license_info": "Een licentie is niet vereist. Je steunt hier echter wel de ontwikkeling van Mailcow mee.<br><a href=\"https://www.servercow.de/mailcow?lang=nl#sal\" target=\"_blank\" alt=\"SAL order\">Registreer je GUID hier</a>, of <a href=\"https://www.servercow.de/mailcow?lang=nl#support\" target=\"_blank\" alt=\"Support order\">schaf ondersteuning aan voor deze installatie.</a>",
"link": "Link",
"loading": "Even geduld aub...",
"logo_info": "De afbeelding zal worden geschaald naar een hoogte van 40px voor de navigatiebar, en naar een breedte van 250px voor de startpagina.",
"lookup_mx": "Match bestemming aan MX (gebruik .outlook.com om alle mail gericht aan MX *.outlook.com over deze hop te laten gaan)",
"main_name": "\"Mailcow\"",
"merged_vars_hint": "Grijze rijen zijn samengevoegd van <code>vars.(local.)inc.php</code> en kunnen niet worden gewijzigd.",
"message": "Bericht",
"message_size": "Berichtgrootte",
"nexthop": "Nexthop",
"no_active_bans": "Geen actieve verbanningen",
"no_new_rows": "Er zijn geen extra rijen beschikbaar",
"no_record": "Geen vermelding",
"oauth2_client_id": "Client-ID",
"oauth2_client_secret": "Client-secret",
"oauth2_info": "De OAuth2-implementatie ondersteunt grant type \"Authorization Code\" en geeft refresh-tokens uit.<br>De server geeft automatisch nieuwe refresh-tokens uit nadat er één is gebruikt.<br><br>→ De standaard scope is <i>profiel</i>. Uitsluitend mailboxgebruikers kunnen OAuth2 gebruiken om zich te authenticeren. Als de scope-parameter wordt weggelaten, zal deze terugvallen op <i>profiel</i>.<br>→ De <i>state</i>-parameter dient verzonden te worden door de client als onderdeel van het authorize-request.<br><br>Paden voor requests naar de OAuth2-API: <br><ul><li>Authorization endpoint: <code>/oauth/authorize</code></li><li>Token endpoint: <code>/oauth/token</code></li><li>Resource page: <code>/oauth/profile</code></li></ul>Het regenereren van de client-secret zal oudere authorization codes niet doen verlopen. Het verversen van de tokens zal echter niet langer werken.<br><br>Het intrekken van client-tokens zal alle actieve sessies per direct beëindigen. Alle clients dienen zich opnieuw te authenticeren.",
"oauth2_redirect_uri": "Redirect URI",
"oauth2_renew_secret": "Genereer een nieuw client-secret",
"oauth2_revoke_tokens": "Trek alle client-tokens in",
"optional": "optioneel",
"password": "Wachtwoord",
"password_repeat": "Herhaal wachtwoord",
"priority": "Prioriteit",
"private_key": "Private key",
"quarantine": "Quarantaine",
"quarantine_bcc": "Forward alle meldingen (bcc) naar dit adres:<br><small>Laat leeg om uit te schakelen. <b>Mails zijn niet gesigneerd of gecontroleerd. Uitsluitend bedoeld voor intern gebruik.</b></small>",
"quarantine_exclude_domains": "Sluit de volgende domeinen en aliasdomeinen uit",
"quarantine_max_age": "Maximale leeftijd in dagen<br><small>Dit kan niet minder zijn dan 1 dag.</small>",
"quarantine_max_size": "Maximale grootte in MiB (mail die de limiet overschrijdt zal worden verwijderd):<br><small>0 betekent <b>niet</b> onbeperkt!</small>",
"quarantine_max_score": "Stuur geen notificatie wanneer de spamscore hoger is dan:<br><small>Standaard: 9999.0</small>",
"quarantine_notification_html": "Meldingssjabloon:<br><small>Laat leeg om de standaardsjabloon te herstellen.</small>",
"quarantine_notification_sender": "Afzender van meldingen",
"quarantine_notification_subject": "Onderwerp van meldingen",
"quarantine_redirect": "<b>Redirect alle meldingen</b> naar dit adres:<br><small>Laat leeg om uit te schakelen. <b>Mails zijn niet gesigneerd of gecontroleerd. Uitsluitend bedoeld voor intern gebruik.</b></small>",
"quarantine_release_format": "Formaat van vrijgegeven items",
"quarantine_release_format_att": "Bijlage",
"quarantine_release_format_raw": "Origineel",
"quarantine_retention_size": "Maximale retenties per mailbox:<br><small>Gebruik 0 om deze functionaliteit <b>uit te schakelen</b>.</small>",
"queue_ays": "Bevestig het verwijderen van alle items uit de queue.",
"queue_deliver_mail": "Lever af",
"queue_hold_mail": "Houd vast",
"queue_manager": "Queue manager",
"queue_unban": "hef verbanning op",
"queue_unhold_mail": "Geef vrij",
"queue_show_message": "Toon item",
"quota_notification_html": "Meldingssjabloon:<br><small>Laat leeg om de standaardsjabloon te herstellen.</small>",
"quota_notification_sender": "Afzender van meldingen",
"quota_notification_subject": "Onderwerp van meldingen",
"quota_notifications": "Quotameldingen",
"quota_notifications_info": "Quotameldingen worden verzonden naar gebruikers wanneer deze 80% of 95% van hun opslagcapaciteit overschreden hebben.",
"quota_notifications_vars": "{{percent}} toont de huidige quota van van de gebruiker<br>{{username}} staat voor de naam van de desbetreffende mailbox",
"r_active": "Actieve beperkingen",
"r_inactive": "Inactieve beperkingen",
"r_info": "Grijze elementen op de lijst van actieve beperkingen zijn niet geldig en kunnen niet worden verplaatst. Onbekende beperkingen zullen hoe dan ook in volgorde van weergave worden ingesteld. <br>Er kunnen nieuwe elementen worden toegevoegd in <code>inc/vars.local.inc.php</code> om ze te kunnen gebruiken.",
"rate_name": "Rate-naam",
"recipients": "Ontvangers",
"refresh": "Ververs",
"regen_api_key": "Vernieuw API-key",
"regex_maps": "Regex-maps",
"relay_from": "\"Van:\" adres",
"relay_run": "Voer test uit",
"relayhosts": "Afzendergebonden transport-maps",
"relayhosts_hint": "Stel afzendergebonden transport-maps in om deze te kunnen gebruiken bij de configuratie van een domein.<br>De transportservice is altijd \"smtp:\" en zal daarom met TLS proberen te verbinden. Wrapped TLS (SMTPS) wordt niet ondersteund. Er wordt rekening gehouden met het uitgaande versleutelingsbeleid van individuele gebruikers.<br>Beïnvloedt geselecteerde domeinen, inclusief bijbehorende aliasdomeinen.",
"remove": "Verwijder",
"remove_row": "Verwijder rij",
"reset_default": "Herstel standaardinstellingen",
"reset_limit": "Verwijder hash",
"routing": "Routing",
"rsetting_add_rule": "Voeg regel toe",
"rsetting_content": "Regelinhoud",
"rsetting_desc": "Korte beschrijving",
"rsetting_no_selection": "Selecteer een regel",
"rsetting_none": "Geen regels beschikbaar",
"rsettings_insert_preset": "Voeg voorbeeld \"%s\" in",
"rsettings_preset_1": "Schakel alles uit voor geauthenticeerde gebruikers, behalve ARC/DKIM en ratelimiting",
"rsettings_preset_2": "Laat postmasters spam ontvangen",
"rsettings_preset_3": "Sta uitsluitend specifieke afzenders toe voor een mailbox (bijvoorbeeld als interne mailbox)",
"rspamd_com_settings": "Een beschrijving voor deze instelling zal automatisch worden gegenereerd, gebruik de onderstaande presets als voorbeeld. Raadpleeg de <a href=\"https://rspamd.com/doc/configuration/settings.html#settings-structure\" target=\"_blank\">Rspamd-documentatie</a> voor meer informatie.",
"rspamd_global_filters": "Globale filters",
"rspamd_global_filters_agree": "Ik ben me ervan bewust dat aanpassingen desastreuze gevolgen kunnen hebben",
"rspamd_global_filters_info": "Ieder globaal filter heeft zijn eigen functie, zie de namen.",
"rspamd_global_filters_regex": "De velden kunnen uitsluitend regular expressions bevatten met het formaat \"/pattern/options\", bijvoorbeeld <code>/.+@domain\\.tld/i</code>.<br>Ondanks dat alle invoer wordt gecontroleerd op fouten, is het toch mogelijk dat Rspamd onbruikbaar wordt als deze de invoer niet kan lezen.<br>Als je problemen ervaart, <a href=\"\" data-toggle=\"modal\" data-container=\"rspamd-mailcow\" data-target=\"#RestartContainer\">herstart Rspamd</a> dan om de filters opnieuw te laten lezen.<br>Elementen op de blacklist zijn uitgesloten van de quarantaine.",
"rspamd_settings_map": "Rspamd",
"sal_level": "Moo-level",
"save": "Sla wijzigingen op",
"search_domain_da": "Zoek domeinen",
"send": "Verzenden",
"sender": "Afzender",
"service_id": "Servicenummer",
"source": "Bron",
"spamfilter": "Spamfilter",
"subject": "Onderwerp",
"sys_mails": "Systeemmails",
"text": "Tekst",
"time": "Tijd",
"title": "Titel",
"title_name": "\"Mailcow\" (websitetitel)",
"to_top": "Naar boven",
"transport_dest_format": "Voorbeeld: example.org, .example.org, *, mailbox@example.org (meerdere waarden zijn kommagescheiden)",
"transport_maps": "Transport-maps",
"transports_hint": "→ Een transport-map wordt boven een afzendergebonden transport-map verkozen.<br>→ Het uitgaande versleutelingsbeleid van individuele gebruikers wordt genegeerd en kan uitsluitend worden gehandhaafd doormiddel van globaal versleutelingsbeleid.<br>→ De transportservice is altijd \"smtp:\" en zal daarom met TLS proberen te verbinden. Wrapped TLS (SMTPS) wordt niet ondersteund.<br>→ Adressen overeenkomend met \"/localhost$/\" zullen altijd via \"local:\" getransporteerd worden, hierdoor zullen \"*\"-bestemmingen niet van toepassing zijn op deze adressen.<br>→ Om de aanmeldingsgegevens van een (voorbeeld) nexthop \"[host]:25\" te bepalen, zoekt Postfix <b>altijd</b> naar \"nexthop\" voodat er wordt gekeken naar \"[nexthop]:25\". Dit maakt het onmogelijk om \"nexthop\" en \"[nexthop]:25\" tegelijkertijd te gebruiken.",
"ui_footer": "Footer (HTML toegestaan)",
"ui_header_announcement": "Aankondigingen",
"ui_header_announcement_active": "Activeer aankondiging",
"ui_header_announcement_content": "Tekst (HTML toegestaan)",
"ui_header_announcement_help": "De aankondiging zal zichtbaar zijn voor zowel alle aangemelde gebruikers als op het aanmeldingsscherm van Mailcow.",
"ui_header_announcement_select": "Selecteer type aankondiging",
"ui_header_announcement_type": "Type",
"ui_header_announcement_type_info": "Info",
"ui_header_announcement_type_warning": "Belangrijk",
"ui_header_announcement_type_danger": "Zeer belangrijk",
"ui_texts": "Labels en teksten",
"unban_pending": "bezig met toestaan",
"unchanged_if_empty": "Laat leeg wanneer ongewijzigd",
"upload": "Upload",
"username": "Gebruikersnaam",
"validate_license_now": "Valideer licentie",
"verify": "Verifieer"
},
"danger": {
"access_denied": "Toegang geweigerd of ongeldige gegevens",
"alias_domain_invalid": "Aliasdomein %s is ongeldig",
"alias_empty": "Aliasadres dient ingevuld te worden",
"alias_goto_identical": "Het alias- en doeladres mogen niet identiek zijn",
"alias_invalid": "Aliasadres %s is ongeldig",
"aliasd_targetd_identical": "Aliasdomein %s dient af te wijken van het doeldomein",
"aliases_in_use": "Maximaal aantal aliassen dient gelijk te zijn aan, of groter te zijn dan %d",
"app_name_empty": "Naam van app dient ingevuld te worden",
"app_passwd_id_invalid": "Appwachtwoord %s is ongeldig",
"bcc_empty": "BCC-bestemming dient ingevuld te worden",
"bcc_exists": "BCC-map %s bestaat voor type %s",
"bcc_must_be_email": "BCC-bestemming %s is geen geldig mailadres",
"comment_too_long": "Opmerkingen mogen niet langer dan 160 karakters zijn",
"defquota_empty": "Standaardquota per mailbox dient geen 0 te zijn.",
"description_invalid": "Beschrijving voor %s is ongeldig",
"dkim_domain_or_sel_exists": "Key voor \"%s\" bestaat reeds en zal niet worden overgeschreven",
"dkim_domain_or_sel_invalid": "ARC/DKIM-domein of selector ongeldig: %s",
"domain_cannot_match_hostname": "Het domein dient af te wijken van de hostname",
"domain_exists": "Domain %s bestaat reeds",
"domain_invalid": "Domeinnaam is ongeldig",
"domain_not_empty": "Domein %s is in gebruik, verwijderen niet mogelijk",
"domain_not_found": "Domein %s niet gevonden",
"domain_quota_m_in_use": "Domeinquota dient gelijk te zijn aan, of groter te zijn dan %s MiB",
"extra_acl_invalid": "Extern verzendadres \"%s\" is ongeldig",
"extra_acl_invalid_domain": "Extern verzendadres \"%s\" gebruikt een ongeldig domein",
"file_open_error": "Er kan niet geschreven worden naar het bestand",
"filter_type": "Verkeerd filtertype",
"from_invalid": "De afzender dient ingevuld te worden",
"global_filter_write_error": "Filter kon niet opgeslagen worden: %s",
"global_map_invalid": "Globaal filter %s is ongeldig",
"global_map_write_error": "Globaal filter %s kon niet opgeslagen worden: %s",
"goto_empty": "Een aliasadres dient ten minste één doeladres te hebben",
"goto_invalid": "Doeladres %s is ongeldig",
"ham_learn_error": "Ham training-error: %s",
"imagick_exception": "Error: Er is een fout opgetreden met Imagick tijdens het lezen van de afbeelding",
"img_invalid": "Kan afbeelding niet valideren",
"img_tmp_missing": "Kan afbeelding niet valideren, tijdelijk bestand niet gevonden",
"invalid_bcc_map_type": "Ongeldig BCC-map type",
"invalid_destination": "Formaat van bestemming \"%s\" is ongeldig",
"invalid_filter_type": "Ongeldig filtertype",
"invalid_host": "Ongeldige host gespecificeerd: %s",
"invalid_mime_type": "Ongeldig mime-type",
"invalid_nexthop": "Formaat van nexthop is ongeldig",
"invalid_nexthop_authenticated": "Er bestaat al een nexthop met andere aanmeldingsgegevens. Pas deze gegevens voor de reeds bestaande nexthop eerst aan.",
"invalid_recipient_map_new": "Ongeldige nieuwe ontvanger ingevoerd: %s",
"invalid_recipient_map_old": "Ongeldige oorspronkelijke ontvanger ingevoerd: %s",
"ip_list_empty": "Lijst met toegestane IP-adressen dient ingevuld te worden",
"is_alias": "Aliasadres %s bestaat reeds",
"is_alias_or_mailbox": "Aliasadres of mailbox %s bestaat reeds",
"is_spam_alias": "Tijdelijk alias (spamalias) %s bestaat reeds",
"last_key": "De laatste key kan niet worden verwijderd. Schakel tweefactorauthenticatie in plaats daarvan uit.",
"login_failed": "Aanmelding mislukt",
"mailbox_defquota_exceeds_mailbox_maxquota": "Standaardquota overschrijdt de quotalimiet",
"mailbox_invalid": "Naam van de mailbox is ongeldig",
"mailbox_quota_exceeded": "Mailboxquota heeft het domeinlimiet overschreden (max. %d MiB)",
"mailbox_quota_exceeds_domain_quota": "Maximale mailboxquota is groter dan domeinquota",
"mailbox_quota_left_exceeded": "Onvoldoende ruimte beschikbaar (%d MiB)",
"mailboxes_in_use": "Maximaal aantal mailboxen dient gelijk te zijn aan, of groter te zijn dan %d",
"malformed_username": "Ongeldige gebruikersnaam",
"map_content_empty": "Inhoud dient ingevuld te zijn",
"max_alias_exceeded": "Maximaal aantal aliassen overschreden",
"max_mailbox_exceeded": "Maximaal aantal mailboxen overschreden (%d van %d)",
"max_quota_in_use": "Mailboxquota dient gelijk te zijn aan, of groter te zijn dan %d MiB",
"maxquota_empty": "Maximale mailboxquota dient groter dan 0 te zijn.",
"mysql_error": "MySQL-error: %s",
"nginx_reload_failed": "Nginx reload mislukt: %s",
"network_host_invalid": "Ongeldig netwerk of host: %s",
"next_hop_interferes": "%s interfereert met nexthop %s",
"next_hop_interferes_any": "Een bestaande nexthop interfereert met %s",
"no_user_defined": "Geen gebruiker gespecificeerd",
"object_exists": "Object %s bestaat reeds",
"object_is_not_numeric": "Waarde %s is niet numeriek",
"password_complexity": "Wachtwoord voldoet niet aan de vereisten (6 tekens lang, letters en nummers)",
"password_empty": "Het wachtwoord dient ingevuld worden",
"password_mismatch": "De ingevoerde wachtwoorden komen niet overeen",
"policy_list_from_exists": "Er bestaat reeds een vermelding met dezelfde naam",
"policy_list_from_invalid": "Invoer is ongeldig",
"private_key_error": "Private key error: %s",
"pushover_credentials_missing": "Pushover-token/key niet ingevuld",
"pushover_key": "Formaat van Pushover-key is ongeldig",
"pushover_token": "Formaat van Pushover-token is ongeldig",
"quota_not_0_not_numeric": "Quota dient numeriek en groter dan 0 te zijn",
"recipient_map_entry_exists": "Ontvanger-map met \"%s\" bestaat reeds",
"redis_error": "Redis-error: %s",
"relayhost_invalid": "Invoer %s is ongeldig",
"release_send_failed": "Het volgende bericht kon niet worden vrijgegeven: %s",
"reset_f2b_regex": "Regex-filters konden niet worden hersteld, probeer het opnieuw of herlaad de pagina over enkele seconden.",
"resource_invalid": "Naam van resource %s is ongeldig",
"rl_timeframe": "Ratelimit-tijdsbestek is ongeldig",
"rspamd_ui_pw_length": "Rspamd-wachtwoord dient minstens 6 tekens lang te zijn",
"script_empty": "Script dient ingevuld te worden",
"sender_acl_invalid": "Toegangscontrole van afzender %s is ongeldig",
"set_acl_failed": "Toegangscontrole kon niet worden ingesteld",
"settings_map_invalid": "Instellingen ongeldig",
"sieve_error": "Sieve-error: %s",
"spam_learn_error": "Spam training-error: %s",
"subject_empty": "Het onderwerp dient ingevuld te worden",
"target_domain_invalid": "Doeladres %s is ongeldig",
"targetd_not_found": "Doeldomein %s niet gevonden",
"targetd_relay_domain": "Doeldomein %s is een geforward domein",
"temp_error": "Tijdelijke fout",
"text_empty": "De tekst dient ingevuld te worden",
"tfa_token_invalid": "Tweefactorauthenticatietoken is ongeldig",
"tls_policy_map_dest_invalid": "Beleidsbestemming is ongeldig",
"tls_policy_map_entry_exists": "Versleutelingsbeleid met \"%s\" bestaat reeds",
"tls_policy_map_parameter_invalid": "Beleidsparameter is ongeldig",
"totp_verification_failed": "TOTP-verificatie mislukt",
"transport_dest_exists": "Transportbestemming \"%s\" bestaat reeds",
"webauthn_verification_failed": "WebAuthn-verificatie mislukt: %s",
"fido2_verification_failed": "FIDO2-verificatie mislukt: %s",
"unknown": "Er is een onbekende fout opgetreden",
"unknown_tfa_method": "Onbekende tweefactorauthenticatiemethode",
"unlimited_quota_acl": "Onbeperkte quota geweigerd door toegangscontrole",
"username_invalid": "Gebruikersnaam %s kan niet worden gebruikt",
"validity_missing": "Wijs een geldigheidstermijn toe",
"value_missing": "Niet alle waarden zijn ingevuld",
"yotp_verification_failed": "Yubico OTP-verificatie mislukt: %s"
},
"debug": {
"chart_this_server": "Grafiek (deze server)",
"containers_info": "Containerinformatie",
"disk_usage": "Schijfgebruik",
"external_logs": "Externe logs",
"history_all_servers": "Geschiedenis (alle servers)",
"in_memory_logs": "Geheugenlogs",
"jvm_memory_solr": "JVM-geheugengebruik",
"log_info": "<p>Mailcows <b>geheugenlogs</b> worden elke minuut afgesneden naar maximaal %d regels (LOG_LINES) om de stabiliteit te garanderen.<br>Geheugenlogs zijn niet bedoeld om bewaard te blijven. Alle applicaties die geheugenlogs schrijven worden ook naar het Docker-proces gelogd.<br>De geheugenlogs kunnen gebruikt worden voor het oplossen van problemen met bepaalde containers.</p><p><b>Externe logs</b> worden verzameld doormiddel van de API van deze applicaties.</p><p><b>Statische logs</b> zijn activiteitenlogs die niet naar het Docker-proces worden gelogd, maar wel bewaard moeten blijven (uitgezonderd API-logs).</p>",
"logs": "Logs",
"restart_container": "Herstart",
"solr_dead": "Solr is uitgeschakeld, uitgevallen of nog bezig met opstarten.",
"docs": "Documenten",
"last_modified": "Voor het laatst bijgewerkt op",
"online_users": "Gebruikers online",
"size": "Grootte",
"started_at": "Opgestart op",
"solr_status": "Solr-status",
"uptime": "Uptime",
"started_on": "Gestart op",
"static_logs": "Statische logs",
"system_containers": "Systeem & containers"
},
"diagnostics": {
"cname_from_a": "Waarde afgeleid van een A- of AAAA-vermelding.",
"dns_records": "DNS-configuratie",
"dns_records_24hours": "Houd er rekening mee dat wijzigingen aan DNS tot wel 24 uur in beslag kunnen nemen voordat ze op deze pagina worden weergegeven. Deze informatie is bedoeld om gemakkelijk te bekijken of de DNS-configuratie aan de eisen voldoet.",
"dns_records_docs": "Raadpleeg ook <a target=\"_blank\" href=\"https://mailcow.github.io/mailcow-dockerized-docs/prerequisite/prerequisite-dns/\">de documentatie</a>.",
"dns_records_data": "Correcte gegevens",
"dns_records_name": "Naam",
"dns_records_status": "Huidige staat",
"dns_records_type": "Type",
"optional": "Deze vermelding is optioneel."
},
"edit": {
"active": "Actief",
"advanced_settings": "Geavanceerde instellingen",
"alias": "Wijzig alias",
"allow_from_smtp": "Sta enkel de volgende IP-adressen toe voor <b>SMTP</b>",
"allow_from_smtp_info": "Laat leeg om alle afzenders toe te staan.<br>IPv4/IPv6-adressen en netwerken.",
"allowed_protocols": "Toegestane protocollen",
"app_name": "Naam van app",
"app_passwd": "Appwachtwoord",
"automap": "Probeer mappen automatisch te koppelen (\"Verzonden items\", \"Verzonden\" => \"Verzonden\" etc.)",
"backup_mx_options": "Relay-opties",
"bcc_dest_format": "Een BCC-bestemming dient één geldig mailadres te zijn.",
"client_id": "Client-ID",
"client_secret": "Client-secret",
"comment_info": "Een persoonlijke opmerking is niet zichtbaar voor de gebruiker, terwijl een publieke opmerking wel getoond wordt in het overzicht van de gebruiker.",
"delete1": "Verwijder van bron wanneer voltooid",
"delete2": "Verwijder berichten die zich niet in de bron bevinden",
"delete2duplicates": "Verwijder duplicaten op de bestemming",
"delete_ays": "Bevestig de verwijdering.",
"description": "Beschrijving",
"disable_login": "Weiger aanmelden (inkomende mail blijft binnenkomen)",
"domain": "Wijzig domein",
"domain_admin": "Wijzig administrator",
"domain_quota": "Domeinquota (MiB)",
"domains": "Domeinen",
"dont_check_sender_acl": "Schakel verzendcontrole uit voor domein %s (inclusief aliasdomeinen)",
"edit_alias_domain": "Wijzig aliasdomein",
"encryption": "Versleuteling",
"exclude": "Sluit objecten uit (regex)",
"extended_sender_acl": "Externe verzendadressen",
"extended_sender_acl_info": "Wanneer mogelijk dient er een ARC/DKIM-key geïmporteerd te worden. Vergeet niet om deze server toe te voegen aan het SPF-record <br>Zodra er een domein of aliasdomein wordt toegevoegd aan deze server, overeenkomend met een extern verzendadres, wordt het externe adres verwijderd.<br>Gebruik @domain.tld om verzenden vanuit *@domain.tld toe te staan.",
"force_pw_update": "Vereis nieuw wachtwoord bij eerstvolgende login",
"force_pw_update_info": "Deze gebruiker kan zich hierdoor uitsluitend aanmelden bij %s, totdat de procedure succesvol doorlopen is.",
"full_name": "Volledige naam",
"gal": "Globale adreslijst",
"gal_info": "De globale adreslijst bevat alle objecten van een domein. Deze kunnen door geen enkele gebruiker worden bewerkt. <b>Herstart SOGo om wijzigingen door te voeren.</b>",
"generate": "genereer",
"grant_types": "Grant types",
"hostname": "Hostname",
"inactive": "Inactief",
"kind": "Soort",
"mailbox": "Wijzig mailbox",
"mailbox_quota_def": "Standaard mailboxquota",
"max_aliases": "Maximaal aantal aliassen",
"max_mailboxes": "Maximaal aantal mailboxen",
"max_quota": "Mailboxquota (MiB)",
"maxage": "Maximale leeftijd van berichten (in dagen) die extern worden opgehaald<br><small>(0 = negeer leeftijd)</small>",
"maxbytespersecond": "Maximale bytes per seconde <br><small>(0 = onbeperkt)</small>",
"mbox_rl_info": "De ratelimit wordt toegepast op de huidige mailboxgebruiker en geldt voor elk verzendadres die door deze wordt gebruikt. Een mailbox-ratelimit staat boven een domein-ratelimit.",
"mins_interval": "Interval (min)",
"multiple_bookings": "Meerdere boekingen",
"nexthop": "Nexthop",
"password": "Wachtwoord",
"password_repeat": "Herhaal wachtwoord",
"previous": "Vorige pagina",
"private_comment": "Persoonlijke opmerking",
"public_comment": "Publieke opmerking",
"pushover_evaluate_x_prio": "Escaleer mail met hoge prioriteit [<code>X-Priority: 1</code>]",
"pushover_info": "Pushmeldingen zijn van toepassing op alle spamvrije mail afgeleverd aan <b>%s</b>, inclusief aliassen (gedeeld, niet gedeeld en getagd).",
"pushover_only_x_prio": "Uitsluitend mail met hoge prioriteit [<code>X-Priority: 1</code>]",
"pushover_sender_array": "Uitsluitend de volgende afzenders <small>(kommagescheiden)</small>",
"pushover_sender_regex": "Uitsluitend een afzender met de volgende regex",
"pushover_text": "Meldingstekst ({SUBJECT} zal worden vervangen door het onderwerp)",
"pushover_title": "Meldingstitel",
+ "pushover_sound": "Geluid",
"pushover_vars": "Wanneer er geen afzenders zijn uitgesloten zullen alle mails doorkomen.<br>Regex-filters en afzendercontroles kunnen individueel worden ingesteld en zullen in volgorde worden verwerkt. Ze zijn niet afhankelijk van elkaar.<br>Bruikbare variabelen voor tekst en titel (neem het gegevensbeschermingsbeleid in acht)",
"pushover_verify": "Verifieer aanmeldingsgegevens",
"quota_mb": "Quota (MiB)",
"ratelimit": "Ratelimit",
"redirect_uri": "Redirect/Callback URL",
"relay_all": "Forward alle ontvangers",
"relay_all_info": "↪ Wanneer er wordt gekozen om <b>niet</b> alle ontvangers te forwarden, dient er per ontvanger een lege mailbox aangemaakt te worden.",
"relay_domain": "Forward dit domein",
"relay_transport_info": "<div class=\"label label-info\">Info</div> Je kunt transport-maps aanmaken om een aangepaste bestemming in te stellen voor dit domein. Zo niet, zal er een MX-lookup plaatsvinden.",
"relay_unknown_only": "Forward uitsluitend niet-bestaande mailboxen. Bestaande mailboxen zullen lokaal afgeleverd worden.",
"relayhost": "Afzendergebonden transport-maps",
"remove": "Verwijder",
"resource": "Resource",
"save": "Wijzigingen opslaan",
"scope": "Scope",
"sender_acl": "Sta toe om te verzenden als",
"sender_acl_disabled": "<span class=\"label label-danger\">Verzendcontrole is uitgeschakeld</span>",
"sender_acl_info": "Wanneer mailboxgebruiker A toegestaan is te verzenden namens mailboxgebruiker B, zal het verzendadres niet automatisch worden weergegeven in het \"van\"-veld in SOGo. Mailboxgebruiker A dient hiervoor een aparte vermelding te maken in SOGo. Om een mailbox te delegeren in SOGo kan het menu (drie punten) aan de rechterkant van de naam van het mailbox linksboven worden gebruikt in de mailweergave. Dit is niet van toepassing op aliasadressen.",
"sieve_desc": "Korte beschrijving",
"sieve_type": "Filtertype",
"skipcrossduplicates": "Sla duplicaten verspreid over mappen over (wie het eerst komt, het eerst maalt)",
"sogo_visible": "Alias tonen in SOGo",
"sogo_visible_info": "Wanneer verborgen zal een alias niet worden weergegeven als een selecteerbaar verzendadres. Deze optie beïnvloedt uitsluitend objecten die kunnen worden weergegeven in SOGo (gedeelde of niet-gedeelde aliasadressen die naar minstens één mailbox verwijzen).",
"spam_alias": "Maak een nieuw tijdelijk alias aan, of pas deze aan",
"spam_filter": "Spamfilter",
"spam_policy": "Voeg items toe of verwijder items van de white- of blacklist",
"spam_score": "Stel een aangepaste spamscore in",
"subfolder2": "Synchroniseer in submap op bestemming<br><small>(leeg = gebruik geen submappen)</small>",
"syncjob": "Wijzig sync job",
"target_address": "Doeladres(sen) <small>(kommagescheiden)</small>",
"target_domain": "Doeldomein",
"timeout1": "Time-out voor verbinding met externe hosts",
"timeout2": "Time-out voor verbinding met lokale hosts",
"title": "Wijzig object",
"unchanged_if_empty": "Laat leeg wanneer ongewijzigd",
"username": "Gebruikersnaam",
"validate_save": "Verifieer en sla op"
},
"footer": {
"cancel": "Annuleren",
"confirm_delete": "Bevestig verwijdering",
"delete_now": "Nu verwijderen",
"delete_these_items": "Bevestig de wijzigingen aan het volgende item",
"hibp_nok": "Dit is een onveilig wachtwoord!",
"hibp_ok": "Dit wachtwoord is niet publiekelijk bekend",
"loading": "Even geduld aub...",
"restart_container": "Herstart container",
"restart_container_info": "<b>Belangrijk:</b> Een herstart kan enige tijd in beslag nemen, wacht aub totdat dit proces voltooid is.<br>Deze pagina zal zichzelf verversen zodra het proces voltooid is.",
"restart_now": "Nu herstarten",
"restarting_container": "Container wordt herstart, even geduld aub..."
},
"header": {
"administration": "Configuratie & details",
"apps": "Apps",
"debug": "Systeeminformatie",
"mailboxes": "Mailconfiguratie",
"mailcow_settings": "Beheer",
"quarantine": "Quarantaine",
"restart_netfilter": "Herstart netfilter",
"restart_sogo": "Herstart SOGo",
"user_settings": "Gebruikersinstellingen"
},
"info": {
"awaiting_tfa_confirmation": "In afwachting van tweefactorauthenticatie...",
"no_action": "Geen handeling van toepassing",
"session_expires": "Je huidige sessie verloopt over ongeveer 15 seconden"
},
"login": {
"delayed": "Aanmelding vertraagd met %s seconden.",
"fido2_webauthn": "FIDO2/WebAuthn",
"login": "Aanmelden",
"mobileconfig_info": "Log in als mailboxgebruiker om het Apple-verbindingsprofiel te downloaden.",
"other_logins": "Meld aan met key",
"password": "Wachtwoord",
"username": "Gebruikersnaam"
},
"mailbox": {
"action": "Handeling",
"activate": "Activeer",
"active": "Actief",
"add": "Voeg toe",
"add_alias": "Voeg alias toe",
"add_bcc_entry": "Voeg BCC-map toe",
"add_domain": "Voeg domein toe",
"add_domain_alias": "Voeg domeinalias toe",
"add_domain_record_first": "Voeg eerst een domein toe",
"add_filter": "Voeg filter toe",
"add_mailbox": "Voeg mailbox toe",
"add_recipient_map_entry": "Voeg ontvanger-map toe",
"add_resource": "Voeg resource toe",
"add_tls_policy_map": "Voeg versleutelingsbeleid toe",
"address_rewriting": "Adresomleidingen",
"alias": "Alias",
"alias_domain_alias_hint": "Aliassen worden <b>niet</b> automatisch toegepast op domeinaliassen. Aliasadres <code>alias@domein</code> dekt het adres <code>alias@alias-domein</code> <b>niet</b> (waarbij \"alias-domein\" een aliasdomein is voor \"domein\").<br>Gebruik een filter om mail te forwarden naar een externe mailbox (zie het tabje \"Filters\" of gebruik SOGo -> Doorsturen).",
"alias_domain_backupmx": "Aliasdomein inactief voor geforward domein",
"aliases": "Aliassen",
"allow_from_smtp": "Sta enkel de volgende IP-adressen toe voor <b>SMTP</b>",
"allow_from_smtp_info": "Laat leeg om alle afzenders toe te staan.<br>IPv4/IPv6-adressen en netwerken.",
"allowed_protocols": "Toegestane protocollen",
"backup_mx": "Relaydomein",
"bcc": "BCC",
"bcc_destination": "BCC-bestemming",
"bcc_destinations": "BCC-bestemmingen",
"bcc_info": "BCC-maps worden gebruikt om kopieën van alle berichten naar een ander adres te forwarden.<br>Wees er van bewust dat er geen melding wordt gedaan van een mislukte aflevering.",
"bcc_local_dest": "Lokale bestemming",
"bcc_map": "BCC-map",
"bcc_map_type": "BCC-type",
"bcc_maps": "BCC-maps",
"bcc_rcpt_map": "Ontvanger-map",
"bcc_sender_map": "Afzender-map",
"bcc_to_rcpt": "Schakel over naar ontvanger-map",
"bcc_to_sender": "Schakel over naar afzender-map",
"bcc_type": "BCC-type",
"booking_null": "Toon altijd als vrij",
"booking_0_short": "Altijd vrij",
"booking_custom": "Zet vast op een specifiek aantal boekingen",
"booking_custom_short": "Hard limit",
"booking_ltnull": "Onbeperkt, maar toon als bezet wanneer geboekt",
"booking_lt0_short": "Soft limit",
"daily": "Dagelijks",
"deactivate": "Deactiveer",
"description": "Beschrijving",
"disable_login": "Weiger aanmelden (inkomende mail blijft binnenkomen)",
"disable_x": "Schakel uit",
"domain": "Domein",
"domain_admins": "Domeinadministrators",
"domain_aliases": "Domeinaliassen",
"domain_quota": "Quota",
"domains": "Domeinen",
"edit": "Wijzig",
"empty": "Geen resultaten",
"enable_x": "Schakel in",
"excludes": "Exclusief",
"filter_table": "Filtertabel",
"filters": "Filters",
"fname": "Volledige naam",
"hourly": "Ieder uur",
"in_use": "In gebruik (%)",
"inactive": "Inactief",
"insert_preset": "Voeg voorbeelden in \"%s\"",
"kind": "Soort",
"last_mail_login": "Laatste mail login",
"last_run": "Laatst uitgevoerd",
"last_run_reset": "Plan volgende",
"mailbox": "Mailbox",
"mailbox_defquota": "Standaard mailboxgrootte",
"mailbox_quota": "Maximale mailboxgrootte",
"mailboxes": "Mailboxen",
"mailbox_defaults": "Standaardinstellingen",
"mailbox_defaults_info": "Stel standaardinstellingen in voor nieuwe mailboxen.",
"mins_interval": "Interval (min)",
"msg_num": "Bericht #",
"multiple_bookings": "Meerdere boekingen",
"never": "Nooit",
"no_record": "Geen vermelding voor object %s",
"no_record_single": "Geen vermelding",
"owner": "Eigenaar",
"private_comment": "Persoonlijke opmerking",
"public_comment": "Publieke opmerking",
"q_add_header": "Spamfolder",
"q_all": "Alle categorieën",
"q_reject": "Geweigerd",
"quarantine_notification": "Quarantainemeldingen",
"quarantine_category": "Categorie van quarantainemelding",
"quick_actions": "Handelingen",
"recipient_map": "Ontvanger-map",
"recipient_map_info": "Ontvanger-maps worden gebruikt om het doeladres van een bericht te vervangen voordat het in een mailbox terecht komt.",
"recipient_map_new": "Nieuwe ontvanger",
"recipient_map_new_info": "De bestemming van een ontvanger-map dient een geldig mailadres te zijn.",
"recipient_map_old": "Oorspronkelijke ontvanger",
"recipient_map_old_info": "De oorspronkelijke bestemming van een ontvanger-map dient een geldig mailadres of domeinnaam te zijn.",
"recipient_maps": "Ontvanger-maps",
"remove": "Verwijder",
"resources": "Resources",
"running": "Wordt uitgevoerd",
"set_postfilter": "Stel in als nafilter",
"set_prefilter": "Stel in als voorfilter",
"sieve_info": "Het is mogelijk om meerdere filters per gebruiker in te stellen, maar er kan slechts één voorfilter en één nafilter tegelijkertijd actief zijn.<br>Elk filter zal in de aangegeven volgorde worden verwerkt. Noch een mislukt script, noch een gespecificeerde \"keep;\" zal de verwerking van volgende scripts stoppen. Bij wijzigingen aan globale filters zal Dovecot herstart worden.<br><br>Globaal voorfilter</a> → Voorfilter → Gebruikersscripts → Nafilter → Globaal nafilter",
"sieve_preset_1": "Weiger mail met mogelijk schadelijke bestandstypes",
"sieve_preset_2": "Markeer de mail van een specifieke afzender altijd als gelezen",
"sieve_preset_3": "Verwijder en stop het filterproces",
"sieve_preset_4": "Behoud en stop het filterproces",
"sieve_preset_5": "Autoreply (vakantie)",
"sieve_preset_6": "Weiger mail met antwoord",
"sieve_preset_7": "Forward en behoud/verwijder",
"sieve_preset_8": "Verwijder mail verstuurd naar een aliasadres van de afzender",
"sieve_preset_header": "Zie de onderstaande voorbeelden. Raadpleeg <a href=\"https://en.wikipedia.org/wiki/Sieve_(mail_filtering_language)\" target=\"_blank\">Wikipedia</a> voor meer informatie.",
"sogo_visible": "Alias tonen in SOGo",
"sogo_visible_n": "Verberg alias in SOGo",
"sogo_visible_y": "Toon alias in SOGo",
"spam_aliases": "Tijdelijk alias",
"stats": "Statistieken",
"status": "Status",
"sync_jobs": "Sync jobs",
"table_size": "Tabelgrootte",
"table_size_show_n": "Toon %s items",
"target_address": "Doeladres",
"target_domain": "Doeldomein",
"tls_enforce_in": "Forceer inkomende versleuteling",
"tls_enforce_out": "Forceer uitgaande versleuteling",
"tls_map_dest": "Bestemming",
"tls_map_dest_info": "Voorbeeld: example.org, .example.org, [mail.example.org]:25",
"tls_map_parameters": "Parameters",
"tls_map_parameters_info": "Voorbeeld: protocols=!SSLv2 ciphers=medium exclude=3DES",
"tls_map_policy": "Beleid",
"tls_policy_maps": "Globaal versleutelingsbeleid",
"tls_policy_maps_info": "Deze opties worden boven het versleutelingsbeleid van een gebruiker verkozen.<br>Bekijk <a href=\"http://www.postfix.org/postconf.5.html#smtp_tls_policy_maps\" target=\"_blank\">de documentatie</a> voor meer informatie.",
"tls_policy_maps_enforced_tls": "Dit is ook van invloed op mailboxgebruikers die uitgaande versleuteling forceren. Wanneer er geen beleid is ingesteld zullen de standaardwaarden, <code>smtp_tls_mandatory_protocols</code> en <code>smtp_tls_mandatory_ciphers</code>, van toepassing zijn.",
"tls_policy_maps_long": "Uitgaand versleutelingsbeleid",
"toggle_all": "Selecteer alles",
"username": "Gebruikersnaam",
"waiting": "Wachten",
"weekly": "Wekelijks"
},
"oauth2": {
"access_denied": "Log in als een mailboxgebruiker om toegang via OAuth te verlenen",
"authorize_app": "Autoriseer applicatie",
"deny": "Weiger",
"permit": "Autoriseer applicatie",
"profile": "Profiel",
"profile_desc": "Persoonlijke informatie: gebruikersnaam, volledige naam, aanmaakdatum, bewerkdatum, activiteit",
"scope_ask_permission": "Een applicatie heeft toegang tot de volgende onderdelen gevraagd"
},
"quarantine": {
"action": "Handeling",
"atts": "Bijlagen",
"check_hash": "Zoek bestandshash op in VT",
"confirm": "Bevestig",
"confirm_delete": "Bevestig de verwijdering van dit item.",
"danger": "Risico",
"deliver_inbox": "Vrijgeven naar inbox",
"disabled_by_config": "De huidige systeemconfiguratie deactiveert de quarantainefunctionaliteit. Het instellen van \"Maximale retenties per mailbox\" en \"Maximale grootte\" is vereist om deze functie te activeren.",
"settings_info": "Maximaal aantal items in quarantaine: %s<br>Maximale mailgrootte: %s MiB",
"download_eml": "Download (.eml)",
"empty": "Geen resultaten",
"high_danger": "Hoog",
"info": "Informatie",
"junk_folder": "Spamfolder",
"learn_spam_delete": "Markeer als spam en verwijder",
"low_danger": "Laag",
"medium_danger": "Gemiddeld",
"neutral_danger": "Neutraal",
"notified": "Verwittigd",
"qhandler_success": "Aanvraag succesvol verzonden naar het systeem. Je kunt nu het venster sluiten.",
"qid": "Rspamd QID",
"qinfo": "Het quarantainesysteem slaat een kopie van zowel geweigerde mail (voor de afzender zal het lijken alsof de mail <em>niet</em> afgeleverd is), als mail die afgeleverd is de spamfolder, op in de database.\r\n <br>\"Markeer als spam en verwijder\" traint het systeem om soortgelijke mails in de toekomst opnieuw als spam te markeren.\r\n <br>Wanneer er meerdere berichten tegelijkertijd worden behandeld kan het mogelijk enige tijd duren.<br>Elementen op de blacklist zijn uitgesloten van de quarantaine.",
"qitem": "Quarantaine-item",
"quarantine": "Quarantaine",
"quick_actions": "Handelingen",
"rcpt": "Ontvanger",
"received": "Ontvangen",
"recipients": "Ontvangers",
"refresh": "Ververs",
"rejected": "Geweigerd",
"release": "Geef vrij",
"release_body": "We hebben het oorspronkelijke bericht als los bestand bijgevoegd. Open dit bestand om het bericht weer te geven.",
"release_subject": "Mogelijk schadelijk quarantaine-item %s",
"remove": "Verwijder",
"rewrite_subject": "Herschrijf onderwerp",
"rspamd_result": "Rspamd-resultaat",
"sender": "Afzender (SMTP)",
"sender_header": "Afzender (\"From\" header)",
"type": "Type",
"quick_release_link": "Open snelkoppeling voor vrijgeven",
"quick_delete_link": "Open snelkoppeling voor verwijderen",
"quick_info_link": "Open snelkoppeling met informatie",
"show_item": "Toon item",
"spam": "Spam",
"spam_score": "Score",
"subj": "Onderwerp",
"table_size": "Tabelgrootte",
"table_size_show_n": "Toon %s items",
"text_from_html_content": "Inhoud (geconverteerde html)",
"text_plain_content": "Inhoud (tekst)",
"toggle_all": "Selecteer alles"
},
"start": {
"help": "Toon/verberg hulppaneel",
"imap_smtp_server_auth_info": "Gebruik je volledige mailadres en het bijbehorende (onversleutelde) verificatiemechanisme.<br>De aanmeldgegevens worden versleuteld verzonden.",
"mailcow_apps_detail": "Gebruik een Mailcow-app om je mails, agenda, contacten en meer te bekijken.",
"mailcow_panel_detail": "<b>Domeinadministrators</b> kunnen mailboxen en aliassen aanmaken, wijzigen en verwijderen. Ook kunnen ze domeinen weergeven en aanpassen.<br><b>Gebruikers</b> kunnen tijdelijke aliassen aanmaken, hun wachtwoord aanpassen en de spamfilterinstellingen wijzigen."
},
"success": {
"acl_saved": "Toegangscontrole voor object %s is opgeslagen",
"admin_added": "Administrator %s is toegevoegd",
"admin_api_modified": "Wijzigingen aan de API zijn opgeslagen",
"admin_modified": "Wijzigingen aan administrator zijn opgeslagen",
"admin_removed": "Administrator %s is verwijderd",
"alias_added": "Aliasadres %s (%d) is toegevoegd",
"alias_domain_removed": "Aliasdomein %s is verwijderd",
"alias_modified": "Wijzigingen aan alias %s zijn opgeslagen",
"alias_removed": "Alias %s is verwijderd",
"aliasd_added": "Aliasdomein %s is toegevoegd",
"aliasd_modified": "Wijzigingen aan aliasadres %s zijn opgeslagen",
"app_links": "Wijzigingen aan app links zijn opgeslagen",
"app_passwd_added": "Appwachtwoord toegevoegd",
"app_passwd_removed": "Appwachtwoord verwijderd: %s",
"bcc_deleted": "BCC-maps %s zijn verwijderd",
"bcc_edited": "BCC-map %s is gewijzigd",
"bcc_saved": "BCC-map is opgeslagen",
"db_init_complete": "Database-initialisatie voltooid",
"delete_filter": "Filter %s is verwijderd",
"delete_filters": "Filters %s zijn verwijderd",
"deleted_syncjob": "Sync job %s is verwijderd",
"deleted_syncjobs": "Sync jobs %s zijn verwijderd",
"dkim_added": "ARC/DKIM-key %s is opgeslagen",
"dkim_duplicated": "ARC/DKIM-key voor domein %s is gekopieerd naar %s",
"dkim_removed": "ARC/DKIM-key %s is verwijderd",
"domain_added": "Domein %s is toegevoegd",
"domain_admin_added": "Domeinadministrator %s is toegevoegd",
"domain_admin_modified": "Wijzigingen aan domeinadministrator %s zijn opgeslagen",
"domain_admin_removed": "Domeinadministrator %s is verwijderd",
"domain_modified": "Wijzigingen aan domein %s zijn opgeslagen",
"domain_removed": "Domein %s is verwijderd",
"dovecot_restart_success": "Dovecot is succesvol herstart",
"eas_reset": "De ActiveSync-apparaatcache van gebruiker %s is hersteld",
"f2b_modified": "Wijzigingen aan Fail2ban zijn opgeslagen",
"forwarding_host_added": "Forwarding host %s is toegevoegd",
"forwarding_host_removed": "Forwarding host %s is verwijderd",
"global_filter_written": "Filter is opgeslagen",
"hash_deleted": "Hash verwijderd",
"item_deleted": "Item %s is verwijderd",
"item_released": "Item %s is vrijgegeven",
"items_deleted": "Items %s zijn verwijderd",
"items_released": "Geselecteerde items zijn vrijgegeven",
"learned_ham": "Bericht %s is als ham gemarkeerd",
"license_modified": "Wijzigingen aan de licentie zijn opgeslagen",
"logged_in_as": "Succesvol aangemeld als %s",
"mailbox_added": "Mailbox %s is toegevoegd",
"mailbox_modified": "Wijzigingen aan mailbox %s zijn opgeslagen",
"mailbox_removed": "Mailbox %s is verwijderd",
"nginx_reloaded": "Nginx is herladen",
"object_modified": "Wijzigingen aan object %s zijn opgeslagen",
"pushover_settings_edited": "Pushover-instellingen zijn opgeslagen, verifieer nu de aanmeldingsgegevens.",
"qlearn_spam": "Bericht %s is als spam gemarkeerd en verwijderd",
"queue_command_success": "Opdracht succesvol voltooid",
"recipient_map_entry_deleted": "Ontvanger-map %s is verwijderd",
"recipient_map_entry_saved": "Ontvanger-map %s is opgeslagen",
"relayhost_added": "Invoer %s is toegevoegd",
"relayhost_removed": "Invoer %s is verwijderd",
"reset_main_logo": "Het standaardlogo is hersteld",
"resource_added": "Resource %s is toegevoegd",
"resource_modified": "Wijzigingen aan mailbox %s zijn opgeslagen",
"resource_removed": "Resource %s is verwijderd",
"rl_saved": "Ratelimit voor object %s is opgeslagen",
"rspamd_ui_pw_set": "Rspamd-wachtwoord succesvol ingesteld",
"saved_settings": "Instellingen opgeslagen",
"settings_map_added": "Instellingen toegevoegd",
"settings_map_removed": "Instellingen verwijderd: %s",
"sogo_profile_reset": "Het SOGo-profiel van gebruiker %s is verwijderd",
"tls_policy_map_entry_deleted": "Versleutelingsbeleid %s is verwijderd",
"tls_policy_map_entry_saved": "Versleutelingsbeleid \"%s\" is opgeslagen",
"ui_texts": "Wijzigingen aan labels en teksten zijn opgeslagen",
"upload_success": "Bestand succesvol geupload",
"verified_totp_login": "TOTP succesvol geverifieerd",
"verified_webauthn_login": "WebAuthn succesvol geverifieerd",
"verified_fido2_login": "FIDO2 succesvol geverifieerd",
"verified_yotp_login": "Yubico OTP succesvol geverifieerd"
},
"tfa": {
"api_register": "%s maakt gebruik van de Yubico Cloud API. Om dit te benutten is er een API-key van Yubico vereist, deze kan <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">hier</a> opgevraagd worden",
"confirm": "Bevestig",
"confirm_totp_token": "Bevestig de wijzigingen door de, door je authenticatie-app gegenereerde code, in te voeren.",
"delete_tfa": "Schakel tweefactorauthenticatie uit",
"disable_tfa": "Pauzeer tweefactorauthenticatie tot de eerstvolgende succesvolle login",
"enter_qr_code": "Voer deze code in als je apparaat geen QR-codes kan scannen:",
"error_code": "Errorcode",
"init_webauthn": "Even geduld aub...",
"key_id": "Geef deze YubiKey een naam",
"key_id_totp": "Geef deze key een naam",
"none": "Deactiveer",
"reload_retry": "- (herlaad de pagina als het probleem aanhoudt)",
"scan_qr_code": "Scan de volgende QR-code met je authenticatie-app:",
"select": "Selecteer...",
"set_tfa": "Kies methode voor tweefactorauthenticatie",
"start_webauthn_validation": "Start validatie",
"tfa": "Tweefactorauthenticatie",
"tfa_token_invalid": "Tweefactorauthenticatietoken is ongeldig",
"totp": "TOTP (Step Two, Authy, etc.)",
"webauthn": "WebAuthn",
"waiting_usb_auth": "<i>In afwachting van USB-apparaat...</i><br><br>Druk nu op de knop van je WebAuthn-apparaat.",
"waiting_usb_register": "<i>In afwachting van USB-apparaat...</i><br><br>Voer je wachtwoord hierboven in en bevestig de registratie van het WebAuthn-apparaat door op de knop van het apparaat te drukken.",
"yubi_otp": "Yubico OTP"
},
"fido2": {
"set_fn": "Stel naam in",
"fn": "Naam",
"rename": "Hernoem",
"confirm": "Bevestig",
"register_status": "Registratiestatus",
"known_ids": "Bekende IDs",
"none": "Uitgeschakeld",
"set_fido2": "Registreer FIDO2-apparaat",
"start_fido2_validation": "Start FIDO2-validatie",
"fido2_auth": "Aanmelden met FIDO2",
"fido2_success": "Apparaat succesvol geregistreerd",
"fido2_validation_failed": "Validatie mislukt"
},
"user": {
"action": "Handeling",
"active": "Actief",
"active_sieve": "Actieve filters",
"advanced_settings": "Geavanceerde instellingen",
"alias": "Alias",
"alias_create_random": "Genereer tijdelijk alias",
"alias_extend_all": "Verleng alias met 1 uur",
"alias_full_date": "d.m.Y, H:i:s T",
"alias_remove_all": "Verwijder alle aliassen",
"alias_select_validity": "Geldigheid",
"alias_time_left": "Resterende tijd",
"alias_valid_until": "Geldig tot",
"aliases_also_send_as": "Toegestaan om te verzenden als",
"aliases_send_as_all": "Controleer verzendtoegang voor de volgende domeinen, inclusief aliassen, niet",
"app_hint": "Appwachtwoorden zijn alternatieve wachtwoorden voor IMAP, SMTP, CalDAV, CardDAV en EAS. De gebruikersnaam blijft ongewijzigd.<br>SOGo is niet toegankelijk met een appwachtwoord.",
"app_name": "Naam van app",
"app_passwds": "Appwachtwoorden",
"apple_connection_profile": "Apple-verbindingsprofiel",
"apple_connection_profile_complete": "Dit verbindingsprofiel bevat de configuratie voor mail, contacten en agenda's op een Apple-apparaat.",
"apple_connection_profile_mailonly": "Dit verbindingsprofiel bevat de configuratie voor mail op een Apple-apparaat.",
"change_password": "Wijzig wachtwoord",
"client_configuration": "Toon configuratiegidsen voor mailprogramma's",
"create_app_passwd": "Maak appwachtwoord aan",
"create_syncjob": "Voeg sync job toe",
"daily": "Dagelijks",
"day": "dag",
"delete_ays": "Bevestig de verwijdering.",
"direct_aliases": "Directe aliasadressen",
"direct_aliases_desc": "Directe aliasadressen worden beïnvloed door spamfilters en het versleutelingsbeleid.",
"eas_reset": "Herstel ActiveSync-apparaatcache",
"eas_reset_help": "In de meeste gevallen verhelpt dit problemen met ActiveSync op je apparaten<br><b>Let wel:</b> alle mails, contacten en agenda's zullen opnieuw gedownload worden!",
"eas_reset_now": "Herstel nu",
"edit": "Wijzig",
"email": "Mail",
"email_and_dav": "Mail, contacten en agenda's",
"encryption": "Versleuteling",
"excludes": "Exclusief",
"expire_in": "Verloopt over",
"force_pw_update": "Er <b>dient</b> een nieuw wachtwoord ingesteld te worden, voordat er gebruik kan worden gemaakt van deze dienst.",
"generate": "genereer",
"hour": "uur",
"hourly": "Ieder uur",
"hours": "uren",
"in_use": "Gebruikt",
"interval": "Interval",
"is_catch_all": "Catch-all voor domeinen",
"last_mail_login": "Laatste mail login",
"last_run": "Laatst uitgevoerd",
"loading": "Bezig met laden...",
"mailbox_details": "Mailboxdetails",
"messages": "berichten",
"never": "Nooit",
"new_password": "Nieuw wachtwoord",
"new_password_repeat": "Herhaal wachtwoord",
"no_active_filter": "Geen actieve filters gevonden",
"no_last_login": "Geen informatie over laatste login",
"no_record": "Geen vermelding",
"password": "Wachtwoord",
"password_now": "Huidig wachtwoord",
"password_repeat": "Herhaal wachtwoord",
"pushover_evaluate_x_prio": "Escaleer mail met hoge prioriteit [<code>X-Priority: 1</code>]",
"pushover_info": "Pushmeldingen zijn van toepassing op alle schone mail (geen spam) afgeleverd aan <b>%s</b>, inclusief aliassen (gedeeld, niet gedeeld en getagd).",
"pushover_only_x_prio": "Uitsluitend mail met hoge prioriteit [<code>X-Priority: 1</code>]",
"pushover_sender_array": "Uitsluitend de volgende afzenders <small>(kommagescheiden)</small>",
"pushover_sender_regex": "Uitsluitend een afzender met de volgende regex",
"pushover_text": "Meldingstekst ({SUBJECT} zal worden vervangen door het onderwerp)",
"pushover_title": "Meldingstitel",
+ "pushover_sound": "Geluid",
"pushover_vars": "Wanneer er geen afzenders zijn uitgesloten zullen alle mails doorkomen.<br>Regex-filters en afzendercontroles kunnen individueel worden ingesteld en zullen in volgorde worden verwerkt. Ze zijn niet afhankelijk van elkaar.<br>Bruikbare variabelen voor tekst en titel (let op het gegevensbeschermingsbeleid)",
"pushover_verify": "Verifieer aanmeldingsgegevens",
"q_add_header": "Spamfolder",
"q_all": "Alle categorieën",
"q_reject": "Geweigerd",
"quarantine_notification": "Quarantainemeldingen",
"quarantine_category": "Categorie van quarantainemelding",
"quarantine_notification_info": "Zodra een melding is verzonden worden de items als gelezen gemarkeerd. Er zal niet nogmaals melding van diezelfde items worden gemaakt.",
"quarantine_category_info": "De meldingscategorie \"Geweigerd\" bevat mail die geweigerd is, terwijl \"Spamfolder\" mail bevat die afgeleverd is in de spamfolder van een gebruiker.",
"remove": "Verwijder",
"running": "Wordt uitgevoerd",
"save": "Sla wijzigingen op",
"save_changes": "Wijzigingen opslaan",
"sender_acl_disabled": "<span class=\"label label-danger\">Verzendcontrole is uitgeschakeld</span>",
"shared_aliases": "Gedeelde aliasadressen",
"shared_aliases_desc": "Een gedeeld aliasadres wordt niet beïnvloed door gebruikersspecifieke instellingen. Een aangepast spamfilter kan eventueel worden ingesteld door een administrator.",
"show_sieve_filters": "Toon actieve filters",
"sogo_profile_reset": "Verwijder SOGo-profiel",
"sogo_profile_reset_help": "Bij het verwijderen van een SOGo-profiel worden <b>alle gegevens, inclusief contacten en agenda's,</b> permanent verwijderd.",
"sogo_profile_reset_now": "Verwijder nu",
"spam_aliases": "Tijdelijke aliassen",
"spam_score_reset": "Herstel naar standaardwaarde",
"spamfilter": "Spamfilter",
"spamfilter_behavior": "Beoordeling",
"spamfilter_bl": "Blacklist",
"spamfilter_bl_desc": "Zet mailadressen op de blacklist om ze <b>altijd</b> als spam te markeren. Geweigerde mail zal <b>niet</b> gekopieerd worden naar de quarantaine. Deze lijst wordt niet toegepast op een gedeeld aliasadres. Wildcards (*) zijn toegestaan.",
"spamfilter_default_score": "Standaardwaarden",
"spamfilter_green": "Groen: dit bericht is geen spam.",
"spamfilter_hint": "De eerste waarde omschrijft een lage spamscore, de tweede een hoge spamscore.",
"spamfilter_red": "Rood: dit bericht is spam en zal, op basis van de instellingen, worden geweigerd of in de quarantaine worden geplaatst.",
"spamfilter_table_action": "Handeling",
"spamfilter_table_add": "Voeg toe",
"spamfilter_table_domain_policy": "n.v.t. (domeinbeleid)",
"spamfilter_table_empty": "Geen gegevens om weer te geven",
"spamfilter_table_remove": "verwijder",
"spamfilter_table_rule": "Regel",
"spamfilter_wl": "Whitelist",
"spamfilter_wl_desc": "Zet mailadressen op de whitelist om ze <b>nooit</b> als spam te markeren.<br>Deze lijst wordt niet toegepast op een gedeeld aliasadres.<br>Wildcards (*) zijn toegestaan.",
"spamfilter_yellow": "Geel: dit bericht is mogelijk spam en zal in de spamfolder geplaatst worden.",
"status": "Status",
"sync_jobs": "Sync jobs",
"tag_handling": "Mailtags",
"tag_help_example": "Voorbeeld van een maildres met tag: me<b>+Tesla</b>@example.org",
"tag_help_explain": "In submap: er wordt een nieuwe map aangemaakt, genoemd naar de tag (bijv.: \"INBOX/Tesla\").<br>In onderwerp: de tag wordt vóór het oorspronkelijke onderwerp geplaatst (bijv.: \"[Tesla] Uw serviceafspraak\").",
"tag_in_none": "Niets doen",
"tag_in_subfolder": "In submap",
"tag_in_subject": "In onderwerp",
"text": "Tekst",
"title": "Titel",
"tls_enforce_in": "Vereis inkomend",
"tls_enforce_out": "Vereis uitgaand",
"tls_policy": "Versleutelingsbeleid",
"tls_policy_warning": "<strong>Let wel:</strong> Door versleuteling te forceren, worden mogelijk niet alle mails afgeleverd.<br>Berichten die niet aan het ingestelde beleid voldoen, worden resoluut geweigerd.<br>Dit is van toepassing op het primaire mailadres, inclusief alle <b>directe</b> aliasadressen.",
"user_settings": "Gebruikersinstellingen",
"username": "Gebruikersnaam",
"verify": "Verifieer",
"waiting": "Wachten",
"week": "week",
"weekly": "Wekelijks",
"weeks": "weken"
},
"warning": {
"cannot_delete_self": "Gebruikers kunnen niet worden verwijderd wanneer deze zijn aangemeld",
"domain_added_sogo_failed": "Domein is toegevoegd, maar de hestart van SOGo mislukte. Controleer de logs.",
"dovecot_restart_failed": "Herstart van Dovecot mislukte. Controleer de logs.",
"fuzzy_learn_error": "Fuzzy-hash training-error: %s",
"hash_not_found": "Hash niet gevonden of reeds verwijderd",
"ip_invalid": "Ongeldig IP-adres overgeslagen: %s",
"no_active_admin": "Het is niet mogelijk om de laatste actieve administrator te verwijderen",
"quota_exceeded_scope": "Domeinquota overschreden: Voor dit domein kunnen uitsluitend onbeperkte mailboxen aangemaakt worden.",
"session_token": "Token ongeldig: komt niet overeen",
"session_ua": "Token ongeldig: gebruikersagentvalidatie mislukt"
}
}
diff --git a/data/web/templates/edit/mailbox.twig b/data/web/templates/edit/mailbox.twig
index d4154292..f0154584 100644
--- a/data/web/templates/edit/mailbox.twig
+++ b/data/web/templates/edit/mailbox.twig
@@ -1,395 +1,425 @@
{% extends 'edit.twig' %}
{% block inner_content %}
{% if result %}
<ul class="nav nav-tabs responsive-tabs" role="tablist">
<li class="active"><a data-toggle="tab" href="#medit">{{ lang.edit.mailbox }}</a></li>
<li><a data-toggle="tab" href="#mpushover">{{ lang.edit.pushover }}</a></li>
<li><a data-toggle="tab" href="#macl">{{ lang.edit.acl }}</a></li>
<li><a data-toggle="tab" href="#mrl">{{ lang.edit.ratelimit }}</a></li>
</ul>
<hr>
<div class="tab-content">
<div id="medit" class="tab-pane in active">
<form class="form-horizontal" data-id="editmailbox" role="form" method="post">
<input type="hidden" value="default" name="sender_acl">
<input type="hidden" value="0" name="force_pw_update">
<input type="hidden" value="0" name="sogo_access">
<input type="hidden" value="0" name="protocol_access">
<div class="form-group">
<label class="control-label col-sm-2" for="name">{{ lang.edit.full_name }}</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="name" value="{{ result.name }}">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{ lang.add.tags }}</label>
<div class="col-sm-10">
<div class="form-control tag-box">
{% for tag in mailbox_details.tags %}
<span data-action='delete_selected' data-item="{{ tag }}" data-id="mailbox_tag_{{ tag }}" data-api-url='delete/mailbox/tag/{{ mailbox }}' class="badge badge-primary tag-badge btn-badge">
<i class="bi bi-tag-fill"></i>
{{ tag }}
</span>
{% endfor %}
<input type="text" class="tag-input">
<span class="btn tag-add"><i class="bi bi-plus-lg"></i></span>
<input type="hidden" value="" name="tags" class="tag-values" />
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="quota">{{ lang.edit.quota_mb }}
<br><span id="quotaBadge" class="badge">max. {{ (result.max_new_quota / 1048576) }} MiB</span>
</label>
<div class="col-sm-10">
<input type="number" name="quota" style="width:100%" min="0" max="{{ (result.max_new_quota / 1048576) }}" value="{{ (result.quota / 1048576) }}" class="form-control">
<small class="help-block">0 = ∞</small>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="sender_acl">{{ lang.edit.sender_acl }}</label>
<div class="col-sm-10">
<select data-live-search="true" data-width="100%" style="width:100%" id="editSelectSenderACL" name="sender_acl" size="10" multiple>
{% for domain in sender_acl_handles.sender_acl_domains.ro %}
<option data-subtext="Admin" value="{{ domain }}" disabled selected>
{{ lang.edit.dont_check_sender_acl|format(domain) }}
</option>
{% endfor %}
{% for alias in sender_acl_handles.sender_acl_addresses.ro %}
<option data-subtext="Admin" disabled selected>
{{ alias }}
</option>
{% endfor %}
{% for alias in sender_acl_handles.fixed_sender_aliases %}
<option data-subtext="Alias" disabled selected>{{ alias }}</option>
{% endfor %}
{% for domain in sender_acl_handles.sender_acl_domains.rw %}
<option value="{{ domain }}" selected>
{{ lang.edit.dont_check_sender_acl|format(domain) }}
</option>
{% endfor %}
{% for domain in sender_acl_handles.sender_acl_domains.selectable %}
<option value="{{ domain }}">
{{ lang.edit.dont_check_sender_acl|format(domain) }}
</option>
{% endfor %}
{% for address in sender_acl_handles.sender_acl_addresses.rw %}
<option selected>{{ address }}</option>
{% endfor %}
{% for address in sender_acl_handles.sender_acl_addresses.selectable %}
<option>{{ address }}</option>
{% endfor %}
</select>
<div id="sender_acl_disabled"><i class="bi bi-shield-exclamation"></i> {{ lang.edit.sender_acl_disabled|raw }}</div>
<small class="help-block">{{ lang.edit.sender_acl_info|raw }}</small>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="relayhost">{{ lang.edit.relayhost }}</label>
<div class="col-sm-10">
<select data-acl="{{ acl.mailbox_relayhost }}" data-live-search="true" id="relayhost" name="relayhost" class="form-control space20">
{% for rlyhost in rlyhosts %}
<option
style="{% if rlyhost.active != '1' %}background: #ff4136; color: #fff{% endif %}"
{% if result.attributes.relayhost == rlyhost.id %} selected{% endif %}
value="{{ rlyhost.id }}">
ID {{ rlyhost.id }}: {{ rlyhost.hostname }} ({{ rlyhost.username }})
</option>
{% endfor %}
<option value=""{% if not result.attributes.relayhost %} selected{% endif %}>
{{ lang.edit.none_inherit }}
</option>
</select>
<p class="visible-xs" style="margin: 0;padding: 0">&nbsp;</p>
<small class="help-block">{{ lang.edit.mailbox_relayhost_info }}</small>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{ lang.user.quarantine_notification }}</label>
<div class="col-sm-10">
<div class="btn-group" data-acl="{{ acl.quarantine_notification }}">
<button type="button" class="btn btn-sm btn-xs-quart visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default{% if quarantine_notification == 'never' %} active{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_notification"
data-api-url='edit/quarantine_notification'
data-api-attr='{"quarantine_notification":"never"}'>{{ lang.user.never }}</button>
<button type="button" class="btn btn-sm btn-xs-quart visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default{% if quarantine_notification == 'hourly' %} active{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_notification"
data-api-url='edit/quarantine_notification'
data-api-attr='{"quarantine_notification":"hourly"}'>{{ lang.user.hourly }}</button>
<button type="button" class="btn btn-sm btn-xs-quart visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default{% if quarantine_notification == 'daily' %} active{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_notification"
data-api-url='edit/quarantine_notification'
data-api-attr='{"quarantine_notification":"daily"}'>{{ lang.user.daily }}</button>
<button type="button" class="btn btn-sm btn-xs-quart visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default{% if quarantine_notification == 'weekly' %} active{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_notification"
data-api-url='edit/quarantine_notification'
data-api-attr='{"quarantine_notification":"weekly"}'>{{ lang.user.weekly }}</button>
<div class="clearfix visible-xs"></div>
</div>
<p class="help-block"><small>{{ lang.user.quarantine_notification_info }}</small></p>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">{{ lang.user.quarantine_category }}</label>
<div class="col-sm-10">
<div class="btn-group" data-acl="{{ acl.quarantine_category }}">
<button type="button" class="btn btn-sm btn-xs-third visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default{% if quarantine_category == 'reject' %} active{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_category"
data-api-url='edit/quarantine_category'
data-api-attr='{"quarantine_category":"reject"}'>{{ lang.user.q_reject }}</button>
<button type="button" class="btn btn-sm btn-xs-third visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default{% if quarantine_category == 'add_header' %} active{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_category"
data-api-url='edit/quarantine_category'
data-api-attr='{"quarantine_category":"add_header"}'>{{ lang.user.q_add_header }}</button>
<button type="button" class="btn btn-sm btn-xs-third visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default{% if quarantine_category == 'all' %} active{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_category"
data-api-url='edit/quarantine_category'
data-api-attr='{"quarantine_category":"all"}'>{{ lang.user.q_all }}</button>
<div class="clearfix visible-xs"></div>
</div>
<p class="help-block"><small>{{ lang.user.quarantine_category_info }}</small></p>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="sender_acl">{{ lang.user.tls_policy }}</label>
<div class="col-sm-10">
<div class="btn-group" data-acl="{{ acl.tls_policy }}">
<button type="button" class="btn btn-sm btn-xs-half visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default{% if get_tls_policy.tls_enforce_in == '1' %} active"{% endif %}"
role="switch"
aria-checked="{% if get_tls_policy.tls_enforce_in == '1' %}true{% else %}false{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="tls_policy"
data-api-url='edit/tls_policy'
data-api-attr='{"tls_enforce_in": {% if get_tls_policy.tls_enforce_in == '1' %}0{% else %}1{% endif %} }'>{{ lang.user.tls_enforce_in }}</button>
<button type="button" class="btn btn-sm btn-xs-half visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default{% if get_tls_policy.tls_enforce_out == '1' %} active"{% endif %}"
role="switch"
aria-checked="{% if get_tls_policy.tls_enforce_out == '1' %}true{% else %}false{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="tls_policy"
data-api-url='edit/tls_policy'
data-api-attr='{"tls_enforce_out": {% if get_tls_policy.tls_enforce_out == '1' %}0{% else %}1{% endif %} }'>{{ lang.user.tls_enforce_out }}</button>
<div class="clearfix visible-xs"></div>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="password">{{ lang.edit.password }} (<a href="#" class="generate_password">{{ lang.edit.generate }}</a>)</label>
<div class="col-sm-10">
<input type="password" data-pwgen-field="true" data-hibp="true" class="form-control" name="password" placeholder="{{ lang.edit.unchanged_if_empty }}" autocomplete="new-password">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="password2">{{ lang.edit.password_repeat }}</label>
<div class="col-sm-10">
<input type="password" data-pwgen-field="true" class="form-control" name="password2" autocomplete="new-password">
</div>
</div>
<div data-acl="{{ acl.extend_sender_acl }}" class="form-group">
<label class="control-label col-sm-2" for="extended_sender_acl">{{ lang.edit.extended_sender_acl }}</label>
<div class="col-sm-10">
{% if sender_acl_handles.external_sender_aliases %}
{% set ext_sender_acl = sender_acl_handles.external_sender_aliases|join(', ') %}
{% endif %}
<input type="text" class="form-control" name="extended_sender_acl" value="{{ ext_sender_acl }}" placeholder="user1@example.com, user2@example.org, @example.com, ...">
<small class="help-block">{{ lang.edit.extended_sender_acl_info|raw }}</small>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="protocol_access">{{ lang.edit.allowed_protocols }}</label>
<div class="col-sm-10">
<select data-acl="{{ acl.protocol_access }}" name="protocol_access" multiple class="form-control">
<option value="imap"{% if result.attributes.imap_access == '1' %} selected{% endif %}>IMAP</option>
<option value="pop3"{% if result.attributes.pop3_access == '1' %} selected{% endif %}>POP3</option>
<option value="smtp"{% if result.attributes.smtp_access == '1' %} selected{% endif %}>SMTP</option>
<option value="sieve"{% if result.attributes.sieve_access == '1' %} selected{% endif %}>Sieve</option>
</select>
</div>
</div>
<div hidden data-acl="{{ acl.smtp_ip_access }}" class="form-group">
<label class="control-label col-sm-2" for="allow_from_smtp">{{ lang.edit.allow_from_smtp }}</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="allow_from_smtp" value="{{ allow_from_smtp }}" placeholder="1.1.1.1, 10.2.0.0/24, ...">
<small class="help-block">{{ lang.edit.allow_from_smtp_info }}</small>
</div>
</div>
<hr>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<select name="active" class="form-control">
<option value="1"{% if result.active == '1' %} selected{% endif %}>{{ lang.edit.active }}</option>
<option value="2"{% if result.active == '2' %} selected{% endif %}>{{ lang.edit.disable_login }}</option>
<option value="0"{% if result.active == '0' %} selected{% endif %}>{{ lang.edit.inactive }}</option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" value="1" name="force_pw_update"{% if result.attributes.force_pw_update == '1' %} checked{% endif %}> {{ lang.edit.force_pw_update }}</label>
<small class="help-block">{{ lang.edit.force_pw_update_info|format(ui_texts.main_name) }}</small>
</div>
</div>
</div>
{% if not skip_sogo %}
<div data-acl="{{ acl.sogo_access }}" class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" value="1" name="sogo_access"{% if result.attributes.sogo_access == '1' %} checked{% endif %}> {{ lang.edit.sogo_access }}</label>
<small class="help-block">{{ lang.edit.sogo_access_info }}</small>
</div>
</div>
</div>
{% endif %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button class="btn btn-xs-lg visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-success" data-action="edit_selected" data-id="editmailbox" data-item="{{ result.username }}" data-api-url='edit/mailbox' data-api-attr='{}' href="#">{{ lang.edit.save }}</button>
</div>
</div>
</form>
</div>
<div id="mpushover" class="tab-pane">
<form data-id="pushover" class="form well" method="post">
<input type="hidden" value="0" name="evaluate_x_prio">
<input type="hidden" value="0" name="only_x_prio">
<input type="hidden" value="0" name="active">
<div class="row">
<div class="col-sm-1">
<p class="help-block"><a href="https://pushover.net" target="_blank"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAACglBMVEUAAAAAAAEAAAAilecFGigAAAAAAAAAAAAAAAANj+c3n+Ypm+oeYI4KWI4MieAtkdQbleoJcLcjmeswmN4Rit4KgdMKUYQJKUAQSnILL0kMNlMSTngimOoNPF0hlOQBBgkNOlkRS3MHIjUhk+IPf8wKLUYsjM0AAAASTngAAAAAAAAPfckbdLIbdrYUWIgegsgce70knfEAAAAknfENOVkGHi8YaaIjnvEdgMUhkuAQSG8aca0hleQUh9YLjOM4nOEMgtMcbaYWa6YemO02ltkKhNktgLodYZEPXJEyi8kKesktfLUzj84cWYMiluckZ5YJXJYeW4Y0k9YKfs4yjs0pc6YHZaUviskLfMkqmugak+cqkNcViNcqeK4Iaq4XRmYGPmYMKDsFJTstgr0LdL0ti84CCQ4BCQ4Qgc8rlt8XjN8shcQsi8wZSGgEP2cRMEUDKkUAAAD///8dmvEamfExo/EXmPEWl/ERlvElnvEsofEjnfETl/Enn/Ezo/E4pvEvovEfm/E1pPEzpPEvofEOlfEpoPEamPEQlfEYmfE6p/EgnPEVlvEroPE3pfE2pfENk/Ern/E3pPEcmfEfmvEnnvBlufT6/P0soPAknPDd7/zs9vzo9PxBqfItofAqoPD9/f3B4/q43/mx2/l/xfZ6w/Vxv/VtvfVgt/RXtPNTsfNEq/L3+/31+v3a7fvR6vvH5fqs2vmc0/jx+P3v9/3h8fzW7PvV7PvL5/q13fmo1/mh1PiY0fiNy/aHyfZ2wfVou/Vdt/RPsPM3oeoQkuowmeAgjdgcgMQbeLrw9/3k8vy74Pm63/mX0PdYtfNNr/Ikm+4wnOchkuAVjOAfdrMVcrOdoJikAAAAcnRSTlMAIQ8IzzweFwf+/fvw8P79+/Xt7e3p6eji4d7U08y8qZyTiIWDgn53bWxqaWBKQ0JBOjUwMCkoJCEfHBkT/vz8/Pv7+vr69/b29PTy7ezm5ubm5N7e29vQ0M/Pv7+4uLW1pqaWloWDg3x7e21mUVFFRUXdPracAAAEbElEQVRIx4WUZbvaQBCFF+ru7u7u7u7u7t4mvVwSoBC0JIUCLRQolLq7u7vr/+nMLkmQyvlwyfPcd86e3ZldUqwyQ/p329J+XfutPQYOLUP+q55rFtQJRvY79+xxlZTUWbKpz7/xrrMr2+3BoNPpdLn2lJQ4HEeqLOr1d7z7XNkesQed4A848G63Oy4Gmg/6Mz542QvZbqe8C/Ig73CLYiYTrtLmT3zfqbIcAR7y4wIqH/B6M9Fo0+Ldb6sM9ph/v4ozPuz12mxRofaAAr7jCNkuoz/jNf9AGHibkBCm51fsGKvxsAGWx4H+jBcEi6V2birDpCL/9Klrd1KHbiSvPWP8V0tTnTfO03iXi57P6WNHOVUf44IFdFDRz6pV5fw8Zy5z3JVH5+R48OwxqDiGvKJIY9R+9JsCuJ5HPg74OVEMpz+nbdEPUHEWeEk6IDUnTC1l5r+f8uffc0cfxc8fS17kLso24SwUPFDA/6DE82xKDOPliJ7n/GGOOyWK9zD9CdjvOfg9Dv6AH+AX04LW9gj2i8W/APx1UbxwCAu+wPmcpgUKL/EHdvtq4uwaZwCuznPJVY5LHhED15G/isd5Hz4eKui/e/du02YoKFeD5mHzHIN/nxEDe25gQQwKorAid04CfyzwL4XutXvl1Pt1guMOwwKPkU8mYIFT8JHK+vv8prpDScUVL+j8s3lOctw1GIhbWHAS+HgKPk7xPM/4UtNAYmzizJkf6NgTb/gM8jePQLsewMdthS3g95tMpT1IhVm6v1s8fYmLeb13Odwp8Fh5KY048y/d14WUrwrb1e/X/rNp73nkD8kWS+wi/MZ4XuetG4mhKubJm3/WNEvi8SHwB56nPKjUam0LBdp9ARwupFemTYudvgN/L1+A/Ko/LGBuS8pPy+YR1fuCTWNKnUyoeUyYx2o2dyEVGmr5xTD42xzvkD16+Pb9WIIH6fmt1r3mbsTY7Bvw+n23naT8BUWh86bz6G/e259UXPUK3gfAxQDlo7Rpx3Geqb2e3wp83SGEdKpB7zvwYbzvT2n65xLwbH6YP+M9C8vA8E1wxLU8gkCbdhXGUyrMgwVrcbzLHonr78lzDvWM3q/C/HtDlXoSUIe3YkblhRPIX4E8Oo/9siLv8dRjV7SBlkdgTXvKS7nzsA/9AfeEuhKq9T8zWIDv1Sd6ETAP4D6/H/1V+1BojvruNa4SZXz4JhY84dV5MOF5agUvu5OsOo+KRpG30KalEnoeDccFlutPZYs38D5n3zcpr1/0fBhfb3DOY1z2tSAgLxWezz6zuoHhfUmOejf6blHQH/sFuJYfcMZX307ytKvRa3ifoV/586P5j+tICtS77BuJxzxYAPZsntX8k3eSIhlajK4p8b7iefCEKs03kD/I2LnxL9ovH+43y4fAv1YrI/mzDBsavAX/UppfzVOrZT/ydxk6lJ047MfLfVbcb6hS9ZEzWxekKQ5WrtPqZg3rV6tWrX6Tle3KQZj/q6KxQnmDoXwFY0VSrN9e8FRXBCTAvwAAAABJRU5ErkJggg==" class="img img-fluid"></a></p>
</div>
<div class="col-sm-10">
<p class="help-block">{{ lang.user.pushover_info|format(mailbox)|raw }}</p>
<p class="help-block">{{ lang.edit.pushover_vars|raw }}: <code>{SUBJECT}</code>, <code>{SENDER}</code>, <code>{SENDER_ADDRESS}</code>, <code>{SENDER_NAME}</code></p>
<div class="form-group">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="token">API Token/Key (Application)</label>
<input type="text" class="form-control" name="token" maxlength="30" value="{{ pushover_data.token }}" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="key">User/Group Key</label>
<input type="text" class="form-control" name="key" maxlength="30" value="{{ pushover_data.key }}" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="title">{{ lang.edit.pushover_title }}</label>
<input type="text" class="form-control" name="title" value="{{ pushover_data.title }}" placeholder="Mail">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="text">{{ lang.edit.pushover_text }}</label>
<input type="text" class="form-control" name="text" value="{{ pushover_data.text }}" placeholder="You've got mail 📧">
</div>
</div>
<div class="col-sm-12">
<div class="form-group">
<label for="text">{{ lang.edit.pushover_sender_array|raw }}</label>
<input type="text" class="form-control" name="senders" value="{{ pushover_data.senders }}" placeholder="sender1@example.com, sender2@example.com">
</div>
</div>
+ <div class="col-sm-12">
+ <div class="form-group">
+ <label for="sound">{{ lang.edit.pushover_sound }}</label><br>
+ <select name="sound" class="form-control">
+ <option value="pushover"{% if pushover_data.attributes.sound == 'pushover' %} selected{% endif %}>Pushover (default)</option>
+ <option value="bike"{% if pushover_data.attributes.sound == 'bike' %} selected{% endif %}>Bike</option>
+ <option value="bugle"{% if pushover_data.attributes.sound == 'bugle' %} selected{% endif %}>Bugle</option>
+ <option value="cashregister"{% if pushover_data.attributes.sound == 'cashregister' %} selected{% endif %}>Cash Register</option>
+ <option value="classical"{% if pushover_data.attributes.sound == 'classical' %} selected{% endif %}>Classical</option>
+ <option value="cosmic"{% if pushover_data.attributes.sound == 'cosmic' %} selected{% endif %}>Cosmic</option>
+ <option value="falling"{% if pushover_data.attributes.sound == 'falling' %} selected{% endif %}>Falling</option>
+ <option value="gamelan"{% if pushover_data.attributes.sound == 'gamelan' %} selected{% endif %}>Gamelan</option>
+ <option value="incoming"{% if pushover_data.attributes.sound == 'incoming' %} selected{% endif %}>Incoming</option>
+ <option value="intermission"{% if pushover_data.attributes.sound == 'intermission' %} selected{% endif %}>Intermission</option>
+ <option value="magic"{% if pushover_data.attributes.sound == 'magic' %} selected{% endif %}>Magic</option>
+ <option value="mechanical"{% if pushover_data.attributes.sound == 'mechanical' %} selected{% endif %}>Mechanical</option>
+ <option value="pianobar"{% if pushover_data.attributes.sound == 'pianobar' %} selected{% endif %}>Piano Bar</option>
+ <option value="siren"{% if pushover_data.attributes.sound == 'siren' %} selected{% endif %}>Siren</option>
+ <option value="spacealarm"{% if pushover_data.attributes.sound == 'spacealarm' %} selected{% endif %}>Space Alarm</option>
+ <option value="tugboat"{% if pushover_data.attributes.sound == 'tugboat' %} selected{% endif %}>Tug Boat</option>
+ <option value="alien"{% if pushover_data.attributes.sound == 'alien' %} selected{% endif %}>Alien Alarm (long)</option>
+ <option value="climb"{% if pushover_data.attributes.sound == 'climb' %} selected{% endif %}>Climb (long)</option>
+ <option value="persistent"{% if pushover_data.attributes.sound == 'persistent' %} selected{% endif %}>Persistent (long)</option>
+ <option value="echo"{% if pushover_data.attributes.sound == 'echo' %} selected{% endif %}>Pushover Echo (long)</option>
+ <option value="updown"{% if pushover_data.attributes.sound == 'updown' %} selected{% endif %}>Up Down (long)</option>
+ <option value="vibrate"{% if pushover_data.attributes.sound == 'vibrate' %} selected{% endif %}>Vibrate Only</option>
+ <option value="none"{% if pushover_data.attributes.sound == 'none' %} selected{% endif %}> None (silent) </option>
+ </select>
+ </div>
+ </div>
<div class="col-sm-12">
<div class="checkbox">
<label><input type="checkbox" value="1" name="active"{% if pushover_data.active == '1' %} checked{% endif %}> {{ lang.edit.active }}</label>
</div>
</div>
<div class="col-sm-12">
<legend style="cursor:pointer;margin-top:10px" data-target="#po_advanced" unselectable="on" data-toggle="collapse">
<i class="bi bi-plus"></i> {{ lang.edit.advanced_settings }}
</legend>
</div>
<div class="col-sm-12">
<div id="po_advanced" class="collapse">
<div class="form-group">
<label for="text">{{ lang.edit.pushover_sender_regex }}</label>
<input type="text" class="form-control" name="senders_regex" value="{{ pushover_data.senders_regex }}" placeholder="/(.*@example\.org$|^foo@example\.com$)/i" regex="true">
<div class="checkbox">
<label><input type="checkbox" value="1" name="evaluate_x_prio"{% if pushover_data.attributes.evaluate_x_prio == '1' %} checked{% endif %}> {{ lang.edit.pushover_evaluate_x_prio|raw }}</label>
</div>
<div class="checkbox">
<label><input type="checkbox" value="1" name="only_x_prio"{% if pushover_data.attributes.only_x_prio == '1' %} checked{% endif %}> {{ lang.edit.pushover_only_x_prio|raw }}</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="btn-group" data-acl="{{ acl.pushover }}">
<a class="btn btn-sm btn-xs-half visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-success" data-action="edit_selected" data-id="pushover" data-item="{{ mailbox }}" data-api-url='edit/pushover' data-api-attr='{}' href="#">{{ lang.edit.save }}</a>
<a class="btn btn-sm btn-xs-half visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default" data-action="edit_selected" data-id="pushover-test" data-item="{{ mailbox }}" data-api-url='edit/pushover-test' data-api-attr='{}' href="#"><i class="bi bi-check-lg"></i> {{ lang.edit.pushover_verify }}</a>
<div class="clearfix visible-xs"></div>
<a id="pushover_delete" class="btn btn-sm visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-danger" data-action="edit_selected" data-id="pushover-delete" data-item="{{ mailbox }}" data-api-url='edit/pushover' data-api-attr='{"delete":"true"}' href="#"><i class="bi bi-trash"></i> {{ lang.edit.remove }}</a>
</div>
</div>
</div>
</form>
</div>
<div id="macl" class="tab-pane">
<form data-id="useracl" class="form-inline well" method="post">
<div class="row">
<div class="col-sm-1">
<p class="help-block">ACL</p>
</div>
<div class="col-sm-10">
<div class="form-group">
<select id="user_acl" name="user_acl" size="10" multiple>
{% for acl, val in user_acls %}
<option value="{{ acl }}"{% if val == 1 %} selected{% endif %}>{{ lang.acl[acl] }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<button class="btn btn-xs-lg visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default" data-action="edit_selected" data-id="useracl" data-item="{{ mailbox }}" data-api-url='edit/user-acl' data-api-attr='{}' href="#">{{ lang.edit.save }}</button>
</div>
</div>
</div>
</form>
</div>
<div id="mrl" class="tab-pane">
<form data-id="mboxratelimit" class="form-inline well" method="post">
<div class="row">
<div class="col-sm-1">
<p class="help-block">{{ lang.acl.ratelimit }}</p>
</div>
<div class="col-sm-10">
<div class="form-group">
<input name="rl_value" type="number" autocomplete="off" value="{{ rl.value }}" class="form-control" placeholder="{{ lang.ratelimit.disabled }}">
</div>
<div class="form-group">
<select name="rl_frame" class="form-control">
{% include 'mailbox/rl-frame.twig' %}
</select>
</div>
<div class="form-group">
<button class="btn btn-xs-lg visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default" data-action="edit_selected" data-id="mboxratelimit" data-item="{{ mailbox }}" data-api-url='edit/rl-mbox' data-api-attr='{}' href="#">{{ lang.edit.save }}</button>
</div>
<p class="help-block">{{ lang.edit.mbox_rl_info }}</p>
</div>
</div>
</form>
</div>
</div>
{% else %}
{{ parent() }}
{% endif %}
{% endblock %}
diff --git a/data/web/templates/user/Pushover.twig b/data/web/templates/user/Pushover.twig
index 8a6755a8..a1867a8b 100644
--- a/data/web/templates/user/Pushover.twig
+++ b/data/web/templates/user/Pushover.twig
@@ -1,80 +1,110 @@
<div role="tabpanel" class="tab-pane" id="Pushover">
<form data-id="pushover" class="form well" method="post">
<input type="hidden" value="0" name="evaluate_x_prio">
<input type="hidden" value="0" name="only_x_prio">
<input type="hidden" value="0" name="active">
<div class="row">
<div class="col-sm-1">
<p class="help-block"><a href="https://pushover.net" target="_blank"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAACglBMVEUAAAAAAAEAAAAilecFGigAAAAAAAAAAAAAAAANj+c3n+Ypm+oeYI4KWI4MieAtkdQbleoJcLcjmeswmN4Rit4KgdMKUYQJKUAQSnILL0kMNlMSTngimOoNPF0hlOQBBgkNOlkRS3MHIjUhk+IPf8wKLUYsjM0AAAASTngAAAAAAAAPfckbdLIbdrYUWIgegsgce70knfEAAAAknfENOVkGHi8YaaIjnvEdgMUhkuAQSG8aca0hleQUh9YLjOM4nOEMgtMcbaYWa6YemO02ltkKhNktgLodYZEPXJEyi8kKesktfLUzj84cWYMiluckZ5YJXJYeW4Y0k9YKfs4yjs0pc6YHZaUviskLfMkqmugak+cqkNcViNcqeK4Iaq4XRmYGPmYMKDsFJTstgr0LdL0ti84CCQ4BCQ4Qgc8rlt8XjN8shcQsi8wZSGgEP2cRMEUDKkUAAAD///8dmvEamfExo/EXmPEWl/ERlvElnvEsofEjnfETl/Enn/Ezo/E4pvEvovEfm/E1pPEzpPEvofEOlfEpoPEamPEQlfEYmfE6p/EgnPEVlvEroPE3pfE2pfENk/Ern/E3pPEcmfEfmvEnnvBlufT6/P0soPAknPDd7/zs9vzo9PxBqfItofAqoPD9/f3B4/q43/mx2/l/xfZ6w/Vxv/VtvfVgt/RXtPNTsfNEq/L3+/31+v3a7fvR6vvH5fqs2vmc0/jx+P3v9/3h8fzW7PvV7PvL5/q13fmo1/mh1PiY0fiNy/aHyfZ2wfVou/Vdt/RPsPM3oeoQkuowmeAgjdgcgMQbeLrw9/3k8vy74Pm63/mX0PdYtfNNr/Ikm+4wnOchkuAVjOAfdrMVcrOdoJikAAAAcnRSTlMAIQ8IzzweFwf+/fvw8P79+/Xt7e3p6eji4d7U08y8qZyTiIWDgn53bWxqaWBKQ0JBOjUwMCkoJCEfHBkT/vz8/Pv7+vr69/b29PTy7ezm5ubm5N7e29vQ0M/Pv7+4uLW1pqaWloWDg3x7e21mUVFFRUXdPracAAAEbElEQVRIx4WUZbvaQBCFF+ru7u7u7u7u7t4mvVwSoBC0JIUCLRQolLq7u7vr/+nMLkmQyvlwyfPcd86e3ZldUqwyQ/p329J+XfutPQYOLUP+q55rFtQJRvY79+xxlZTUWbKpz7/xrrMr2+3BoNPpdLn2lJQ4HEeqLOr1d7z7XNkesQed4A848G63Oy4Gmg/6Mz542QvZbqe8C/Ig73CLYiYTrtLmT3zfqbIcAR7y4wIqH/B6M9Fo0+Ldb6sM9ph/v4ozPuz12mxRofaAAr7jCNkuoz/jNf9AGHibkBCm51fsGKvxsAGWx4H+jBcEi6V2birDpCL/9Klrd1KHbiSvPWP8V0tTnTfO03iXi57P6WNHOVUf44IFdFDRz6pV5fw8Zy5z3JVH5+R48OwxqDiGvKJIY9R+9JsCuJ5HPg74OVEMpz+nbdEPUHEWeEk6IDUnTC1l5r+f8uffc0cfxc8fS17kLso24SwUPFDA/6DE82xKDOPliJ7n/GGOOyWK9zD9CdjvOfg9Dv6AH+AX04LW9gj2i8W/APx1UbxwCAu+wPmcpgUKL/EHdvtq4uwaZwCuznPJVY5LHhED15G/isd5Hz4eKui/e/du02YoKFeD5mHzHIN/nxEDe25gQQwKorAid04CfyzwL4XutXvl1Pt1guMOwwKPkU8mYIFT8JHK+vv8prpDScUVL+j8s3lOctw1GIhbWHAS+HgKPk7xPM/4UtNAYmzizJkf6NgTb/gM8jePQLsewMdthS3g95tMpT1IhVm6v1s8fYmLeb13Odwp8Fh5KY048y/d14WUrwrb1e/X/rNp73nkD8kWS+wi/MZ4XuetG4mhKubJm3/WNEvi8SHwB56nPKjUam0LBdp9ARwupFemTYudvgN/L1+A/Ko/LGBuS8pPy+YR1fuCTWNKnUyoeUyYx2o2dyEVGmr5xTD42xzvkD16+Pb9WIIH6fmt1r3mbsTY7Bvw+n23naT8BUWh86bz6G/e259UXPUK3gfAxQDlo7Rpx3Geqb2e3wp83SGEdKpB7zvwYbzvT2n65xLwbH6YP+M9C8vA8E1wxLU8gkCbdhXGUyrMgwVrcbzLHonr78lzDvWM3q/C/HtDlXoSUIe3YkblhRPIX4E8Oo/9siLv8dRjV7SBlkdgTXvKS7nzsA/9AfeEuhKq9T8zWIDv1Sd6ETAP4D6/H/1V+1BojvruNa4SZXz4JhY84dV5MOF5agUvu5OsOo+KRpG30KalEnoeDccFlutPZYs38D5n3zcpr1/0fBhfb3DOY1z2tSAgLxWezz6zuoHhfUmOejf6blHQH/sFuJYfcMZX307ytKvRa3ifoV/586P5j+tICtS77BuJxzxYAPZsntX8k3eSIhlajK4p8b7iefCEKs03kD/I2LnxL9ovH+43y4fAv1YrI/mzDBsavAX/UppfzVOrZT/ydxk6lJ047MfLfVbcb6hS9ZEzWxekKQ5WrtPqZg3rV6tWrX6Tle3KQZj/q6KxQnmDoXwFY0VSrN9e8FRXBCTAvwAAAABJRU5ErkJggg==" class="img img-fluid"></a></p>
</div>
<div class="col-sm-10">
<p class="help-block">{{ lang.user.pushover_info|format(mailcow_cc_username)|raw }}</p>
- <p class="help-block">{{ lang.user.pushover_vars|raw }}: <code>{SUBJECT}</code>, <code>{SENDER}</code>, <code>{SENDER_ADDRESS}</code>, <code>{SENDER_NAME}</p>
+ <p class="help-block">{{ lang.user.pushover_vars|raw }}: <code>{SUBJECT}</code>, <code>{SENDER}</code>, <code>{SENDER_ADDRESS}</code>, <code>{SENDER_NAME}</code></p>
<div class="form-group">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="token">API Token/Key (Application)</label>
<input type="text" class="form-control" name="token" maxlength="30" value="{{ pushover_data.token }}" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="key">User/Group Key</label>
<input type="text" class="form-control" name="key" maxlength="30" value="{{ pushover_data.key }}" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="title">{{ lang.user.pushover_title }}</label>
<input type="text" class="form-control" name="title" value="{{ pushover_data.title }}" placeholder="Mail">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="text">{{ lang.user.pushover_text }}</label>
<input type="text" class="form-control" name="text" value="{{ pushover_data.text }}" placeholder="You've got mail 📧">
</div>
</div>
<div class="col-sm-12">
<div class="form-group">
<label for="text">{{ lang.user.pushover_sender_array|raw }}</label>
<input type="text" class="form-control" name="senders" value="{{ pushover_data.senders }}" placeholder="sender1@example.com, sender2@example.com">
</div>
</div>
+ <div class="col-sm-12">
+ <div class="form-group">
+ <label for="sound">{{ lang.edit.pushover_sound }}</label><br>
+ <select name="sound" class="form-control">
+ <option value="pushover"{% if pushover_data.attributes.sound == 'pushover' %} selected{% endif %}>Pushover (default)</option>
+ <option value="bike"{% if pushover_data.attributes.sound == 'bike' %} selected{% endif %}>Bike</option>
+ <option value="bugle"{% if pushover_data.attributes.sound == 'bugle' %} selected{% endif %}>Bugle</option>
+ <option value="cashregister"{% if pushover_data.attributes.sound == 'cashregister' %} selected{% endif %}>Cash Register</option>
+ <option value="classical"{% if pushover_data.attributes.sound == 'classical' %} selected{% endif %}>Classical</option>
+ <option value="cosmic"{% if pushover_data.attributes.sound == 'cosmic' %} selected{% endif %}>Cosmic</option>
+ <option value="falling"{% if pushover_data.attributes.sound == 'falling' %} selected{% endif %}>Falling</option>
+ <option value="gamelan"{% if pushover_data.attributes.sound == 'gamelan' %} selected{% endif %}>Gamelan</option>
+ <option value="incoming"{% if pushover_data.attributes.sound == 'incoming' %} selected{% endif %}>Incoming</option>
+ <option value="intermission"{% if pushover_data.attributes.sound == 'intermission' %} selected{% endif %}>Intermission</option>
+ <option value="magic"{% if pushover_data.attributes.sound == 'magic' %} selected{% endif %}>Magic</option>
+ <option value="mechanical"{% if pushover_data.attributes.sound == 'mechanical' %} selected{% endif %}>Mechanical</option>
+ <option value="pianobar"{% if pushover_data.attributes.sound == 'pianobar' %} selected{% endif %}>Piano Bar</option>
+ <option value="siren"{% if pushover_data.attributes.sound == 'siren' %} selected{% endif %}>Siren</option>
+ <option value="spacealarm"{% if pushover_data.attributes.sound == 'spacealarm' %} selected{% endif %}>Space Alarm</option>
+ <option value="tugboat"{% if pushover_data.attributes.sound == 'tugboat' %} selected{% endif %}>Tug Boat</option>
+ <option value="alien"{% if pushover_data.attributes.sound == 'alien' %} selected{% endif %}>Alien Alarm (long)</option>
+ <option value="climb"{% if pushover_data.attributes.sound == 'climb' %} selected{% endif %}>Climb (long)</option>
+ <option value="persistent"{% if pushover_data.attributes.sound == 'persistent' %} selected{% endif %}>Persistent (long)</option>
+ <option value="echo"{% if pushover_data.attributes.sound == 'echo' %} selected{% endif %}>Pushover Echo (long)</option>
+ <option value="updown"{% if pushover_data.attributes.sound == 'updown' %} selected{% endif %}>Up Down (long)</option>
+ <option value="vibrate"{% if pushover_data.attributes.sound == 'vibrate' %} selected{% endif %}>Vibrate Only</option>
+ <option value="none"{% if pushover_data.attributes.sound == 'none' %} selected{% endif %}> None (silent) </option>
+ </select>
+ </div>
+ </div>
<div class="col-sm-12">
<div class="checkbox">
<label><input type="checkbox" value="1" name="active"{% if pushover_data.active == '1' %} checked{% endif %}> {{ lang.user.active }}</label>
</div>
</div>
<div class="col-sm-12">
<legend style="cursor:pointer;margin-top:10px" data-target="#po_advanced" unselectable="on" data-toggle="collapse">
<i style="font-size:10pt;" class="bi bi-plus-square"></i> {{ lang.user.advanced_settings }}
</legend>
</div>
<div class="col-sm-12">
<div id="po_advanced" class="collapse">
<div class="form-group">
<label for="text">{{ lang.user.pushover_sender_regex }}</label>
<input type="text" class="form-control" name="senders_regex" value="{{ pushover_data.senders_regex }}" placeholder="/(.*@example\.org$|^foo@example\.com$)/i" regex="true">
<div class="checkbox">
<label><input type="checkbox" value="1" name="evaluate_x_prio"{% if pushover_data.attributes.evaluate_x_prio == '1' %} checked{% endif %}> {{ lang.user.pushover_evaluate_x_prio|raw }}</label>
</div>
<div class="checkbox">
<label><input type="checkbox" value="1" name="only_x_prio"{% if pushover_data.attributes.only_x_prio == '1' %} checked{% endif %}> {{ lang.user.pushover_only_x_prio|raw }}</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="btn-group mass-actions-user" data-acl="{{ acl.pushover }}">
<a class="btn btn-sm btn-xs-half visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-success" data-action="edit_selected" data-id="pushover" data-item="{{ mailcow_cc_username }}" data-api-url='edit/pushover' data-api-attr='{}' href="#">{{ lang.user.save }}</a>
<a class="btn btn-sm btn-xs-half visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-default" data-action="edit_selected" data-id="pushover-test" data-item="{{ mailcow_cc_username }}" data-api-url='edit/pushover-test' data-api-attr='{}' href="#"><i class="bi bi-check-all"></i> {{ lang.user.pushover_verify }}</a>
<div class="clearfix visible-xs"></div>
<a id="pushover_delete" class="btn btn-sm visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-danger" data-action="edit_selected" data-id="pushover-delete" data-item="{{ mailcow_cc_username }}" data-api-url='edit/pushover' data-api-attr='{"delete":"true"}' href="#"><i class="bi bi-trash"></i> {{ lang.user.remove }}</a>
</div>
</div>
</div>
</form>
</div>

File Metadata

Mime Type
text/x-diff
Expires
9月 9 Tue, 5:53 AM (11 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5410
默认替代文本
(451 KB)

Event Timeline