commit
6d8c978d17
2
.github/workflows/pr_to_nightly.yml
vendored
2
.github/workflows/pr_to_nightly.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Run the Action
|
- name: Run the Action
|
||||||
uses: devops-infra/action-pull-request@v0.5.1
|
uses: devops-infra/action-pull-request@v0.5.3
|
||||||
with:
|
with:
|
||||||
github_token: ${{ secrets.PRTONIGHTLY_ACTION_PAT }}
|
github_token: ${{ secrets.PRTONIGHTLY_ACTION_PAT }}
|
||||||
title: Automatic PR to nightly from ${{ github.event.repository.updated_at}}
|
title: Automatic PR to nightly from ${{ github.event.repository.updated_at}}
|
||||||
|
34
.github/workflows/rebuild_backup_image.yml
vendored
Normal file
34
.github/workflows/rebuild_backup_image.yml
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
name: Build mailcow backup image
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# At 00:00 on Sunday
|
||||||
|
- cron: "0 0 * * 0"
|
||||||
|
workflow_dispatch: # Allow to run workflow manually
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker_image_build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.BACKUPIMAGEBUILD_ACTION_DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.BACKUPIMAGEBUILD_ACTION_DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: data/Dockerfiles/backup/Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: mailcow/backup:latest
|
@ -1,12 +1,12 @@
|
|||||||
FROM php:8.0-fpm-alpine3.16
|
FROM php:8.1-fpm-alpine3.16
|
||||||
LABEL maintainer "Andre Peters <andre.peters@servercow.de>"
|
LABEL maintainer "Andre Peters <andre.peters@servercow.de>"
|
||||||
|
|
||||||
ENV APCU_PECL 5.1.21
|
ENV APCU_PECL 5.1.22
|
||||||
ENV IMAGICK_PECL 3.7.0
|
ENV IMAGICK_PECL 3.7.0
|
||||||
# Mailparse is pulled from master branch
|
ENV MAILPARSE_PECL 3.1.4
|
||||||
#ENV MAILPARSE_PECL 3.0.2
|
|
||||||
ENV MEMCACHED_PECL 3.2.0
|
ENV MEMCACHED_PECL 3.2.0
|
||||||
ENV REDIS_PECL 5.3.7
|
ENV REDIS_PECL 5.3.7
|
||||||
|
ENV COMPOSER 2.4.4
|
||||||
|
|
||||||
RUN apk add -U --no-cache autoconf \
|
RUN apk add -U --no-cache autoconf \
|
||||||
aspell-dev \
|
aspell-dev \
|
||||||
@ -18,6 +18,7 @@ RUN apk add -U --no-cache autoconf \
|
|||||||
freetype-dev \
|
freetype-dev \
|
||||||
g++ \
|
g++ \
|
||||||
git \
|
git \
|
||||||
|
gettext \
|
||||||
gettext-dev \
|
gettext-dev \
|
||||||
gmp-dev \
|
gmp-dev \
|
||||||
gnupg \
|
gnupg \
|
||||||
@ -27,8 +28,11 @@ RUN apk add -U --no-cache autoconf \
|
|||||||
imagemagick-dev \
|
imagemagick-dev \
|
||||||
imap-dev \
|
imap-dev \
|
||||||
jq \
|
jq \
|
||||||
|
libavif \
|
||||||
|
libavif-dev \
|
||||||
libjpeg-turbo \
|
libjpeg-turbo \
|
||||||
libjpeg-turbo-dev \
|
libjpeg-turbo-dev \
|
||||||
|
libmemcached \
|
||||||
libmemcached-dev \
|
libmemcached-dev \
|
||||||
libpng \
|
libpng \
|
||||||
libpng-dev \
|
libpng-dev \
|
||||||
@ -38,7 +42,9 @@ RUN apk add -U --no-cache autoconf \
|
|||||||
libtool \
|
libtool \
|
||||||
libwebp-dev \
|
libwebp-dev \
|
||||||
libxml2-dev \
|
libxml2-dev \
|
||||||
|
libxpm \
|
||||||
libxpm-dev \
|
libxpm-dev \
|
||||||
|
libzip \
|
||||||
libzip-dev \
|
libzip-dev \
|
||||||
make \
|
make \
|
||||||
mysql-client \
|
mysql-client \
|
||||||
@ -49,22 +55,24 @@ RUN apk add -U --no-cache autoconf \
|
|||||||
samba-client \
|
samba-client \
|
||||||
zlib-dev \
|
zlib-dev \
|
||||||
tzdata \
|
tzdata \
|
||||||
&& git clone https://github.com/php/pecl-mail-mailparse \
|
&& pecl install mailparse-${MAILPARSE_PECL} \
|
||||||
&& cd pecl-mail-mailparse \
|
&& pecl install redis-${REDIS_PECL} \
|
||||||
&& pecl install package.xml \
|
&& pecl install memcached-${MEMCACHED_PECL} \
|
||||||
&& cd .. \
|
&& pecl install APCu-${APCU_PECL} \
|
||||||
&& rm -r pecl-mail-mailparse \
|
&& pecl install imagick-${IMAGICK_PECL} \
|
||||||
&& pecl install redis-${REDIS_PECL} memcached-${MEMCACHED_PECL} APCu-${APCU_PECL} imagick-${IMAGICK_PECL} \
|
|
||||||
&& docker-php-ext-enable apcu imagick memcached mailparse redis \
|
&& docker-php-ext-enable apcu imagick memcached mailparse redis \
|
||||||
&& pecl clear-cache \
|
&& pecl clear-cache \
|
||||||
&& docker-php-ext-configure intl \
|
&& docker-php-ext-configure intl \
|
||||||
&& docker-php-ext-configure exif \
|
&& docker-php-ext-configure exif \
|
||||||
&& docker-php-ext-configure gd --with-freetype=/usr/include/ \
|
&& docker-php-ext-configure gd --with-freetype=/usr/include/ \
|
||||||
--with-jpeg=/usr/include/ \
|
--with-jpeg=/usr/include/ \
|
||||||
|
--with-webp \
|
||||||
|
--with-xpm \
|
||||||
|
--with-avif \
|
||||||
&& docker-php-ext-install -j 4 exif gd gettext intl ldap opcache pcntl pdo pdo_mysql pspell soap sockets zip bcmath gmp \
|
&& docker-php-ext-install -j 4 exif gd gettext intl ldap opcache pcntl pdo pdo_mysql pspell soap sockets zip bcmath gmp \
|
||||||
&& docker-php-ext-configure imap --with-imap --with-imap-ssl \
|
&& docker-php-ext-configure imap --with-imap --with-imap-ssl \
|
||||||
&& docker-php-ext-install -j 4 imap \
|
&& docker-php-ext-install -j 4 imap \
|
||||||
&& curl --silent --show-error https://getcomposer.org/installer | php \
|
&& curl --silent --show-error https://getcomposer.org/installer | php -- --version=${COMPOSER} \
|
||||||
&& mv composer.phar /usr/local/bin/composer \
|
&& mv composer.phar /usr/local/bin/composer \
|
||||||
&& chmod +x /usr/local/bin/composer \
|
&& chmod +x /usr/local/bin/composer \
|
||||||
&& apk del --purge autoconf \
|
&& apk del --purge autoconf \
|
||||||
@ -72,15 +80,21 @@ RUN apk add -U --no-cache autoconf \
|
|||||||
cyrus-sasl-dev \
|
cyrus-sasl-dev \
|
||||||
freetype-dev \
|
freetype-dev \
|
||||||
g++ \
|
g++ \
|
||||||
|
gettext-dev \
|
||||||
icu-dev \
|
icu-dev \
|
||||||
imagemagick-dev \
|
imagemagick-dev \
|
||||||
imap-dev \
|
imap-dev \
|
||||||
|
libavif-dev \
|
||||||
libjpeg-turbo-dev \
|
libjpeg-turbo-dev \
|
||||||
|
libmemcached-dev \
|
||||||
libpng-dev \
|
libpng-dev \
|
||||||
libressl-dev \
|
libressl-dev \
|
||||||
libwebp-dev \
|
libwebp-dev \
|
||||||
libxml2-dev \
|
libxml2-dev \
|
||||||
|
libxpm-dev \
|
||||||
|
libzip-dev \
|
||||||
make \
|
make \
|
||||||
|
openldap-dev \
|
||||||
pcre-dev \
|
pcre-dev \
|
||||||
zlib-dev
|
zlib-dev
|
||||||
|
|
||||||
|
@ -16,8 +16,7 @@ rules {
|
|||||||
backend = "http";
|
backend = "http";
|
||||||
url = "http://nginx:9081/pushover.php";
|
url = "http://nginx:9081/pushover.php";
|
||||||
selector = "mailcow_rcpt";
|
selector = "mailcow_rcpt";
|
||||||
# Only return msgid, do not parse the full message
|
formatter = "json";
|
||||||
formatter = "msgid";
|
|
||||||
meta_headers = true;
|
meta_headers = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ if (!function_exists('getallheaders')) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$headers = getallheaders();
|
$headers = getallheaders();
|
||||||
|
$json_body = json_decode(file_get_contents('php://input'));
|
||||||
|
|
||||||
$qid = $headers['X-Rspamd-Qid'];
|
$qid = $headers['X-Rspamd-Qid'];
|
||||||
$rcpts = $headers['X-Rspamd-Rcpt'];
|
$rcpts = $headers['X-Rspamd-Rcpt'];
|
||||||
@ -65,6 +66,20 @@ if (is_array($symbols_array)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$sender_address = $json_body->header_from[0];
|
||||||
|
$sender_name = '-';
|
||||||
|
if (preg_match('/(?<name>.*?)<(?<address>.*?)>/i', $sender_address, $matches)) {
|
||||||
|
$sender_address = $matches['address'];
|
||||||
|
$sender_name = trim($matches['name'], '"\' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
$to_address = $json_body->header_to[0];
|
||||||
|
$to_name = '-';
|
||||||
|
if (preg_match('/(?<name>.*?)<(?<address>.*?)>/i', $to_address, $matches)) {
|
||||||
|
$to_address = $matches['address'];
|
||||||
|
$to_name = trim($matches['name'], '"\' ');
|
||||||
|
}
|
||||||
|
|
||||||
$rcpt_final_mailboxes = array();
|
$rcpt_final_mailboxes = array();
|
||||||
|
|
||||||
// Loop through all rcpts
|
// Loop through all rcpts
|
||||||
@ -229,9 +244,16 @@ foreach ($rcpt_final_mailboxes as $rcpt_final) {
|
|||||||
$post_fields = array(
|
$post_fields = array(
|
||||||
"token" => $api_data['token'],
|
"token" => $api_data['token'],
|
||||||
"user" => $api_data['key'],
|
"user" => $api_data['key'],
|
||||||
"title" => sprintf("%s", str_replace(array('{SUBJECT}', '{SENDER}'), array($subject, $sender), $title)),
|
"title" => sprintf("%s", str_replace(
|
||||||
|
array('{SUBJECT}', '{SENDER}', '{SENDER_NAME}', '{SENDER_ADDRESS}', '{TO_NAME}', '{TO_ADDRESS}'),
|
||||||
|
array($subject, $sender, $sender_name, $sender_address, $to_name, $to_address), $title)
|
||||||
|
),
|
||||||
"priority" => $priority,
|
"priority" => $priority,
|
||||||
"message" => sprintf("%s", str_replace(array('{SUBJECT}', '{SENDER}'), array($subject, $sender), $text))
|
"message" => sprintf("%s", str_replace(
|
||||||
|
array('{SUBJECT}', '{SENDER}', '{SENDER_NAME}', '{SENDER_ADDRESS}', '{TO_NAME}', '{TO_ADDRESS}', '\n'),
|
||||||
|
array($subject, $sender, $sender_name, $sender_address, $to_name, $to_address, PHP_EOL), $text)
|
||||||
|
),
|
||||||
|
"sound" => $attributes['sound'] ?? "pushover"
|
||||||
);
|
);
|
||||||
if ($attributes['evaluate_x_prio'] == "1" && $priority == 1) {
|
if ($attributes['evaluate_x_prio'] == "1" && $priority == 1) {
|
||||||
$post_fields['expire'] = 600;
|
$post_fields['expire'] = 600;
|
||||||
|
@ -3349,6 +3349,7 @@ paths:
|
|||||||
evaluate_x_prio: "0"
|
evaluate_x_prio: "0"
|
||||||
key: 21e8918e1jksdjcpis712
|
key: 21e8918e1jksdjcpis712
|
||||||
only_x_prio: "0"
|
only_x_prio: "0"
|
||||||
|
sound: "pushover"
|
||||||
senders: ""
|
senders: ""
|
||||||
senders_regex: ""
|
senders_regex: ""
|
||||||
text: ""
|
text: ""
|
||||||
@ -3392,6 +3393,7 @@ paths:
|
|||||||
evaluate_x_prio: "0"
|
evaluate_x_prio: "0"
|
||||||
key: 21e8918e1jksdjcpis712
|
key: 21e8918e1jksdjcpis712
|
||||||
only_x_prio: "0"
|
only_x_prio: "0"
|
||||||
|
sound: "pushover"
|
||||||
senders: ""
|
senders: ""
|
||||||
senders_regex: ""
|
senders_regex: ""
|
||||||
text: ""
|
text: ""
|
||||||
@ -3413,6 +3415,9 @@ paths:
|
|||||||
only_x_prio:
|
only_x_prio:
|
||||||
description: Only send push for prio mails
|
description: Only send push for prio mails
|
||||||
type: number
|
type: number
|
||||||
|
sound:
|
||||||
|
description: Set notification sound
|
||||||
|
type: string
|
||||||
senders:
|
senders:
|
||||||
description: Only send push for emails from these senders
|
description: Only send push for emails from these senders
|
||||||
type: string
|
type: string
|
||||||
@ -5501,6 +5506,60 @@ paths:
|
|||||||
attr:
|
attr:
|
||||||
spam_score: "8,15"
|
spam_score: "8,15"
|
||||||
summary: Edit mailbox spam filter score
|
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:
|
tags:
|
||||||
- name: Domains
|
- name: Domains
|
||||||
|
@ -51,6 +51,7 @@ function pushover($_action, $_data = null) {
|
|||||||
$active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active'];
|
$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'];
|
$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'];
|
$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 {
|
else {
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
@ -101,7 +102,8 @@ function pushover($_action, $_data = null) {
|
|||||||
$po_attributes = json_encode(
|
$po_attributes = json_encode(
|
||||||
array(
|
array(
|
||||||
'evaluate_x_prio' => strval(intval($evaluate_x_prio)),
|
'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`)
|
$stmt = $pdo->prepare("REPLACE INTO `pushover` (`username`, `key`, `attributes`, `senders_regex`, `senders`, `token`, `title`, `text`, `active`)
|
||||||
|
@ -3,7 +3,7 @@ function init_db_schema() {
|
|||||||
try {
|
try {
|
||||||
global $pdo;
|
global $pdo;
|
||||||
|
|
||||||
$db_version = "25072022_2300";
|
$db_version = "17112022_2115";
|
||||||
|
|
||||||
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
@ -1264,6 +1264,7 @@ function init_db_schema() {
|
|||||||
$pdo->query("UPDATE `pushover` SET `attributes` = '{}' WHERE `attributes` = '' OR `attributes` IS NULL;");
|
$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`, '$.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`, '$.only_x_prio', \"0\") WHERE JSON_VALUE(`attributes`, '$.only_x_prio') IS NULL;");
|
||||||
|
$pdo->query("UPDATE `pushover` SET `attributes` = JSON_SET(`attributes`, '$.sound', \"pushover\") WHERE JSON_VALUE(`attributes`, '$.sound') IS NULL;");
|
||||||
// mailbox
|
// mailbox
|
||||||
$pdo->query("UPDATE `mailbox` SET `attributes` = '{}' WHERE `attributes` = '' OR `attributes` IS NULL;");
|
$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`, '$.passwd_update', \"0\") WHERE JSON_VALUE(`attributes`, '$.passwd_update') IS NULL;");
|
||||||
|
@ -574,6 +574,7 @@
|
|||||||
"pushover_sender_regex": "Consider the following sender regex",
|
"pushover_sender_regex": "Consider the following sender regex",
|
||||||
"pushover_text": "Notification text",
|
"pushover_text": "Notification text",
|
||||||
"pushover_title": "Notification title",
|
"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_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",
|
"pushover_verify": "Verify credentials",
|
||||||
"quota_mb": "Quota (MiB)",
|
"quota_mb": "Quota (MiB)",
|
||||||
@ -1097,6 +1098,7 @@
|
|||||||
"pushover_sender_regex": "Match senders by the following regex",
|
"pushover_sender_regex": "Match senders by the following regex",
|
||||||
"pushover_text": "Notification text",
|
"pushover_text": "Notification text",
|
||||||
"pushover_title": "Notification title",
|
"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_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",
|
"pushover_verify": "Verify credentials",
|
||||||
"q_add_header": "Junk folder",
|
"q_add_header": "Junk folder",
|
||||||
|
@ -536,6 +536,7 @@
|
|||||||
"pushover_sender_regex": "Uitsluitend een afzender met de volgende regex",
|
"pushover_sender_regex": "Uitsluitend een afzender met de volgende regex",
|
||||||
"pushover_text": "Meldingstekst ({SUBJECT} zal worden vervangen door het onderwerp)",
|
"pushover_text": "Meldingstekst ({SUBJECT} zal worden vervangen door het onderwerp)",
|
||||||
"pushover_title": "Meldingstitel",
|
"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_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",
|
"pushover_verify": "Verifieer aanmeldingsgegevens",
|
||||||
"quota_mb": "Quota (MiB)",
|
"quota_mb": "Quota (MiB)",
|
||||||
@ -1002,6 +1003,7 @@
|
|||||||
"pushover_sender_regex": "Uitsluitend een afzender met de volgende regex",
|
"pushover_sender_regex": "Uitsluitend een afzender met de volgende regex",
|
||||||
"pushover_text": "Meldingstekst ({SUBJECT} zal worden vervangen door het onderwerp)",
|
"pushover_text": "Meldingstekst ({SUBJECT} zal worden vervangen door het onderwerp)",
|
||||||
"pushover_title": "Meldingstitel",
|
"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_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",
|
"pushover_verify": "Verifieer aanmeldingsgegevens",
|
||||||
"q_add_header": "Spamfolder",
|
"q_add_header": "Spamfolder",
|
||||||
|
@ -106,7 +106,7 @@
|
|||||||
"username": "Používateľské meno",
|
"username": "Používateľské meno",
|
||||||
"validate": "Overiť",
|
"validate": "Overiť",
|
||||||
"validation_success": "Úspešne overené",
|
"validation_success": "Úspešne overené",
|
||||||
"app_passwd_protocols": "Povolené protokoly"
|
"app_passwd_protocols": "Povolené protokoly k heslu aplikácie"
|
||||||
},
|
},
|
||||||
"admin": {
|
"admin": {
|
||||||
"access": "Prístup",
|
"access": "Prístup",
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -275,7 +275,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<p class="help-block">{{ lang.user.pushover_info|format(mailbox)|raw }}</p>
|
<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></p>
|
<p class="help-block">{{ lang.edit.pushover_vars|raw }}: <code>{SUBJECT}</code>, <code>{SENDER}</code>, <code>{SENDER_ADDRESS}</code>, <code>{SENDER_NAME}</code>, <code>{TO_NAME}</code>, <code>{TO_ADDRESS}</code></p>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
@ -308,6 +308,36 @@
|
|||||||
<input type="text" class="form-control" name="senders" value="{{ pushover_data.senders }}" placeholder="sender1@example.com, sender2@example.com">
|
<input type="text" class="form-control" name="senders" value="{{ pushover_data.senders }}" placeholder="sender1@example.com, sender2@example.com">
|
||||||
</div>
|
</div>
|
||||||
</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="col-sm-12">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label><input type="checkbox" value="1" name="active"{% if pushover_data.active == '1' %} checked{% endif %}> {{ lang.edit.active }}</label>
|
<label><input type="checkbox" value="1" name="active"{% if pushover_data.active == '1' %} checked{% endif %}> {{ lang.edit.active }}</label>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-10">
|
<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_info|format(mailcow_cc_username)|raw }}</p>
|
||||||
<p class="help-block">{{ lang.user.pushover_vars|raw }}: <code>{SUBJECT}</code>, <code>{SENDER}</code></p>
|
<p class="help-block">{{ lang.edit.pushover_vars|raw }}: <code>{SUBJECT}</code>, <code>{SENDER}</code>, <code>{SENDER_ADDRESS}</code>, <code>{SENDER_NAME}</code>, <code>{TO_NAME}</code>, <code>{TO_ADDRESS}</code></p>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
@ -42,6 +42,36 @@
|
|||||||
<input type="text" class="form-control" name="senders" value="{{ pushover_data.senders }}" placeholder="sender1@example.com, sender2@example.com">
|
<input type="text" class="form-control" name="senders" value="{{ pushover_data.senders }}" placeholder="sender1@example.com, sender2@example.com">
|
||||||
</div>
|
</div>
|
||||||
</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="col-sm-12">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label><input type="checkbox" value="1" name="active"{% if pushover_data.active == '1' %} checked{% endif %}> {{ lang.user.active }}</label>
|
<label><input type="checkbox" value="1" name="active"{% if pushover_data.active == '1' %} checked{% endif %}> {{ lang.user.active }}</label>
|
||||||
|
@ -76,7 +76,7 @@ services:
|
|||||||
- clamd
|
- clamd
|
||||||
|
|
||||||
rspamd-mailcow:
|
rspamd-mailcow:
|
||||||
image: mailcow/rspamd:1.90
|
image: mailcow/rspamd:1.91
|
||||||
stop_grace_period: 30s
|
stop_grace_period: 30s
|
||||||
depends_on:
|
depends_on:
|
||||||
- dovecot-mailcow
|
- dovecot-mailcow
|
||||||
@ -106,7 +106,7 @@ services:
|
|||||||
- rspamd
|
- rspamd
|
||||||
|
|
||||||
php-fpm-mailcow:
|
php-fpm-mailcow:
|
||||||
image: mailcow/phpfpm:1.79
|
image: mailcow/phpfpm:1.80
|
||||||
command: "php-fpm -d date.timezone=${TZ} -d expose_php=0"
|
command: "php-fpm -d date.timezone=${TZ} -d expose_php=0"
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis-mailcow
|
- redis-mailcow
|
||||||
@ -168,7 +168,7 @@ services:
|
|||||||
- phpfpm
|
- phpfpm
|
||||||
|
|
||||||
sogo-mailcow:
|
sogo-mailcow:
|
||||||
image: mailcow/sogo:1.111
|
image: mailcow/sogo:1.112
|
||||||
environment:
|
environment:
|
||||||
- DBNAME=${DBNAME}
|
- DBNAME=${DBNAME}
|
||||||
- DBUSER=${DBUSER}
|
- DBUSER=${DBUSER}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
DEBIAN_DOCKER_IMAGE="mailcow/backup:1.0"
|
DEBIAN_DOCKER_IMAGE="mailcow/backup:latest"
|
||||||
|
|
||||||
if [[ ! -z ${MAILCOW_BACKUP_LOCATION} ]]; then
|
if [[ ! -z ${MAILCOW_BACKUP_LOCATION} ]]; then
|
||||||
BACKUP_LOCATION="${MAILCOW_BACKUP_LOCATION}"
|
BACKUP_LOCATION="${MAILCOW_BACKUP_LOCATION}"
|
||||||
@ -58,7 +58,7 @@ if ! [[ "${THREADS}" =~ ^[1-9]+$ ]] ; then
|
|||||||
echo "Thread input is not a number!"
|
echo "Thread input is not a number!"
|
||||||
exit 1
|
exit 1
|
||||||
elif [[ "${THREADS}" =~ ^[1-9]+$ ]] ; then
|
elif [[ "${THREADS}" =~ ^[1-9]+$ ]] ; then
|
||||||
echo "Using ${THREADS} Thread(s) for this run."
|
echo "Using ${THREADS} Thread(s) for this run."
|
||||||
echo "Notice: You can set the Thread count with the THREADS Variable before you run this script."
|
echo "Notice: You can set the Thread count with the THREADS Variable before you run this script."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ function restore() {
|
|||||||
|
|
||||||
elif [ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]; then
|
elif [ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]; then
|
||||||
COMPOSE_COMMAND="docker-compose"
|
COMPOSE_COMMAND="docker-compose"
|
||||||
|
|
||||||
else
|
else
|
||||||
echo -e "\e[31mCan not read DOCKER_COMPOSE_VERSION variable from mailcow.conf! Is your mailcow up to date? Exiting...\e[0m"
|
echo -e "\e[31mCan not read DOCKER_COMPOSE_VERSION variable from mailcow.conf! Is your mailcow up to date? Exiting...\e[0m"
|
||||||
exit 1
|
exit 1
|
||||||
@ -380,4 +380,4 @@ elif [[ ${1} == "restore" ]]; then
|
|||||||
done
|
done
|
||||||
echo "Restoring ${FILE_SELECTION[${input_sel}]} from ${RESTORE_POINT}..."
|
echo "Restoring ${FILE_SELECTION[${input_sel}]} from ${RESTORE_POINT}..."
|
||||||
restore "${RESTORE_POINT}" ${FILE_SELECTION[${input_sel}]}
|
restore "${RESTORE_POINT}" ${FILE_SELECTION[${input_sel}]}
|
||||||
fi
|
fi
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
##
|
##
|
||||||
## Set haproxy_trusted_networks in Dovecots extra.conf!
|
## Set haproxy_trusted_networks in Dovecots extra.conf!
|
||||||
#ä
|
##
|
||||||
|
|
||||||
version: '2.1'
|
version: '2.1'
|
||||||
services:
|
services:
|
||||||
|
@ -50,7 +50,7 @@ echo -e "\e[32mTrying to determine GLIBC version...\e[0m"
|
|||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo -e "\e[33mWARNING: $COMPOSE_PATH is not writable, but new version $LATEST_COMPOSE is available (installed: $COMPOSE_VERSION)\e[0m"
|
echo -e "\e[33mWARNING: $COMPOSE_PATH is not writable, but new version $LATEST_COMPOSE is available (installed: $COMPOSE_VERSION)\e[0m"
|
||||||
return 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
############## Begin Function Section ##############
|
############## Begin Function Section ##############
|
||||||
|
|
||||||
check_online_status() {
|
check_online_status() {
|
||||||
CHECK_ONLINE_IPS=(1.1.1.1 9.9.9.9 8.8.8.8)
|
CHECK_ONLINE_DOMAINS=('https://github.com' 'https://hub.docker.com')
|
||||||
for ip in "${CHECK_ONLINE_IPS[@]}"; do
|
for domain in "${CHECK_ONLINE_DOMAINS[@]}"; do
|
||||||
if timeout 3 ping -c 1 ${ip} > /dev/null; then
|
if timeout 3 curl --head --silent --output /dev/null ${domain}; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
Loading…
Reference in New Issue
Block a user