Merge pull request #4882 from mailcow/staging

2022-11 Update
This commit is contained in:
Niklas Meyer 2022-12-01 21:22:41 +01:00 committed by GitHub
commit 6d8c978d17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 796 additions and 455 deletions

View File

@ -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}}

View 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

View File

@ -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

View File

@ -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;
} }
} }

View File

@ -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;

View File

@ -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

View File

@ -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`)

View File

@ -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;");

View File

@ -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",

View File

@ -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",

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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}

View File

@ -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}"

View File

@ -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:

View File

@ -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

View File

@ -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