Compare commits
59 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ecefbf2166 | ||
|
a763dda068 | ||
|
698b2bf988 | ||
|
802d304579 | ||
|
8614d63ace | ||
|
6d8c978d17 | ||
|
ff4f2ae0b6 | ||
|
0b00f15811 | ||
|
bed5218550 | ||
|
86b67a9a7b | ||
|
73370de1f9 | ||
|
524aba0964 | ||
|
64528d8e0e | ||
|
31b5faa729 | ||
|
17977a2fff | ||
|
3e007eeaae | ||
|
05b897f43e | ||
|
738dcac60d | ||
|
b3bbeee5e2 | ||
|
782eae4d4c | ||
|
f2f5e212f5 | ||
|
ff7102468e | ||
|
118cb1017a | ||
|
360bb6f306 | ||
|
d8e314db1a | ||
|
fd14c51f85 | ||
|
57a5a9baeb | ||
|
65c74c75c7 | ||
|
e82f3b3975 | ||
|
fbc33da734 | ||
|
210815d4cf | ||
|
1e672ae349 | ||
|
046e658984 | ||
|
a46db9e0df | ||
|
17f3cc3ad8 | ||
|
3236a10cf5 | ||
|
a4eb6d5f1b | ||
|
05181f1888 | ||
|
6875baf64c | ||
|
c46a1c1e2f | ||
|
b79a1530fb | ||
|
a6a7ab45f8 | ||
|
bc937ed2db | ||
|
df17e6b75e | ||
|
f880e1834d | ||
|
4dd1b97e38 | ||
|
aeb433cc39 | ||
|
eb9d360c0a | ||
|
abfad4e025 | ||
|
e9091cbb8c | ||
|
cb340d78e1 | ||
|
548d7b9833 | ||
|
96dbbf4db6 | ||
|
4f14462af7 | ||
|
1e08b4ece6 | ||
|
6fd9efc30a | ||
|
6f212a41d8 | ||
|
52314d1a35 | ||
|
623397d20a |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1 +1 @@
|
|||||||
custom: https://mailcow.github.io/mailcow-dockerized-docs/#help-mailcow
|
custom: ["https://www.servercow.de/mailcow?lang=en#sal"]
|
||||||
|
162
.github/ISSUE_TEMPLATE/Bug_report.yml
vendored
162
.github/ISSUE_TEMPLATE/Bug_report.yml
vendored
@@ -26,70 +26,132 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Description
|
label: Description
|
||||||
description: Please provide a brief description of the bug in 1-2 sentences. If applicable, add screenshots to help explain your problem. Very useful for bugs in mailcow UI.
|
description: Please provide a brief description of the bug in 1-2 sentences. If applicable, add screenshots to help explain your problem. Very useful for bugs in mailcow UI.
|
||||||
|
render: text
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Logs
|
label: "Logs:"
|
||||||
description: Please take a look at the [official documentation](https://mailcow.github.io/mailcow-dockerized-docs/debug-logs/) and post the last few lines of logs, when the error occurs. For example, docker container logs of affected containers. This will be automatically formatted into code, so no need for backticks.
|
description: "Please take a look at the [official documentation](https://docs.mailcow.email/troubleshooting/debug-logs/) and post the last few lines of logs, when the error occurs. For example, docker container logs of affected containers. This will be automatically formatted into code, so no need for backticks."
|
||||||
render: bash
|
render: text
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Steps to reproduce
|
label: "Steps to reproduce:"
|
||||||
description: Please describe the steps to reproduce the bug. Screenshots can be added, if helpful.
|
description: "Please describe the steps to reproduce the bug. Screenshots can be added, if helpful."
|
||||||
|
render: text
|
||||||
placeholder: |-
|
placeholder: |-
|
||||||
1. ...
|
1. ...
|
||||||
2. ...
|
2. ...
|
||||||
3. ...
|
3. ...
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
label: System information
|
value: |
|
||||||
description: In this stage we would kindly ask you to attach general system information about your setup.
|
## System information
|
||||||
value: |-
|
### In this stage we would kindly ask you to attach general system information about your setup.
|
||||||
| Question | Answer |
|
- type: dropdown
|
||||||
| --- | --- |
|
attributes:
|
||||||
| My operating system | I_DO_REPLY_HERE |
|
label: "Which branch are you using?"
|
||||||
| Is Apparmor, SELinux or similar active? | I_DO_REPLY_HERE |
|
description: "#### `git rev-parse --abbrev-ref HEAD`"
|
||||||
| Virtualization technology (KVM, VMware, Xen, etc - **LXC and OpenVZ are not supported** | I_DO_REPLY_HERE |
|
multiple: false
|
||||||
| Server/VM specifications (Memory, CPU Cores) | I_DO_REPLY_HERE |
|
options:
|
||||||
| Docker version (`docker version`) | I_DO_REPLY_HERE |
|
- master
|
||||||
| docker-compose version (`docker-compose version`) | I_DO_REPLY_HERE |
|
- nightly
|
||||||
| mailcow version (```git describe --tags `git rev-list --tags --max-count=1` ```) | I_DO_REPLY_HERE |
|
validations:
|
||||||
| Reverse proxy (custom solution) | I_DO_REPLY_HERE |
|
required: true
|
||||||
|
- type: input
|
||||||
Output of `git diff origin/master`, any other changes to the code? If so, **please post them**:
|
attributes:
|
||||||
```
|
label: "Operating System:"
|
||||||
YOUR OUTPUT GOES HERE
|
placeholder: "e.g. Ubuntu 22.04 LTS"
|
||||||
```
|
validations:
|
||||||
|
required: true
|
||||||
All third-party firewalls and custom iptables rules are unsupported. **Please check the Docker docs about how to use Docker with your own ruleset**. Nevertheless, iptabels output can help us to help you:
|
- type: input
|
||||||
iptables -L -vn:
|
attributes:
|
||||||
```
|
label: "Server/VM specifications:"
|
||||||
YOUR OUTPUT GOES HERE
|
placeholder: "Memory, CPU Cores"
|
||||||
```
|
validations:
|
||||||
|
required: true
|
||||||
ip6tables -L -vn:
|
- type: input
|
||||||
```
|
attributes:
|
||||||
YOUR OUTPUT GOES HERE
|
label: "Is Apparmor, SELinux or similar active?"
|
||||||
```
|
placeholder: "yes/no"
|
||||||
|
validations:
|
||||||
iptables -L -vn -t nat:
|
required: true
|
||||||
```
|
- type: input
|
||||||
YOUR OUTPUT GOES HERE
|
attributes:
|
||||||
```
|
label: "Virtualization technology:"
|
||||||
|
placeholder: "KVM, VMware, Xen, etc - **LXC and OpenVZ are not supported**"
|
||||||
ip6tables -L -vn -t nat:
|
validations:
|
||||||
```
|
required: true
|
||||||
YOUR OUTPUT GOES HERE
|
- type: input
|
||||||
```
|
attributes:
|
||||||
|
label: "Docker version:"
|
||||||
DNS problems? Please run `docker exec -it $(docker ps -qf name=acme-mailcow) dig +short stackoverflow.com @172.22.1.254` (set the IP accordingly, if you changed the internal mailcow network) and post the output:
|
description: "#### `docker version`"
|
||||||
```
|
placeholder: "20.10.21"
|
||||||
YOUR OUTPUT GOES HERE
|
validations:
|
||||||
```
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: "docker-compose version or docker compose version:"
|
||||||
|
description: "#### `docker-compose version` or `docker compose version`"
|
||||||
|
placeholder: "v2.12.2"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: "mailcow version:"
|
||||||
|
description: "#### ```git describe --tags `git rev-list --tags --max-count=1` ```"
|
||||||
|
placeholder: "2022-08"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: "Reverse proxy:"
|
||||||
|
placeholder: "e.g. Nginx/Traefik"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: "Logs of git diff:"
|
||||||
|
description: "#### Output of `git diff origin/master`, any other changes to the code? If so, **please post them**:"
|
||||||
|
render: text
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: "Logs of iptables -L -vn:"
|
||||||
|
description: "#### Output of `iptables -L -vn`"
|
||||||
|
render: text
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: "Logs of ip6tables -L -vn:"
|
||||||
|
description: "#### Output of `ip6tables -L -vn`"
|
||||||
|
render: text
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: "Logs of iptables -L -vn -t nat:"
|
||||||
|
description: "#### Output of `iptables -L -vn -t nat`"
|
||||||
|
render: text
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: "Logs of ip6tables -L -vn -t nat:"
|
||||||
|
description: "#### Output of `ip6tables -L -vn -t nat`"
|
||||||
|
render: text
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: "DNS check:"
|
||||||
|
description: "#### Output of `docker exec -it $(docker ps -qf name=acme-mailcow) dig +short stackoverflow.com @172.22.1.254` (set the IP accordingly, if you changed the internal mailcow network)"
|
||||||
|
render: text
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
BIN
.github/workflows/assets/check_prs_if_on_staging.png
vendored
Normal file
BIN
.github/workflows/assets/check_prs_if_on_staging.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
33
.github/workflows/check_prs_if_on_staging.yml
vendored
Normal file
33
.github/workflows/check_prs_if_on_staging.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
name: Check PRs if on staging
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [opened, edited]
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
is_not_staging:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event.pull_request.base.ref != 'staging' #check if the target branch is not staging
|
||||||
|
steps:
|
||||||
|
- name: Send message
|
||||||
|
uses: thollander/actions-comment-pull-request@main
|
||||||
|
with:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.CHECKIFPRISSTAGING_ACTION_PAT }}
|
||||||
|
message: |
|
||||||
|
Thanks for contributing!
|
||||||
|
|
||||||
|
I noticed that you didn't select `staging` as your base branch. Please change the base branch to `staging`.
|
||||||
|
See the attached picture on how to change the base branch to `staging`:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- name: Fail #we want to see failed checks in the PR
|
||||||
|
if: ${{ success() }} #set exit code to 1 even if commenting somehow failed
|
||||||
|
run: exit 1
|
||||||
|
|
||||||
|
is_staging:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event.pull_request.base.ref == 'staging' #check if the target branch is staging
|
||||||
|
steps:
|
||||||
|
- name: Success
|
||||||
|
run: exit 0
|
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
|
@@ -4,9 +4,12 @@ on:
|
|||||||
types: [published]
|
types: [published]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
tweet:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- name: "Get Release Tag"
|
||||||
|
run: |
|
||||||
|
RELEASE_TAG=$(curl https://api.github.com/repos/mailcow/mailcow-dockerized/releases/latest | jq -r '.tag_name')
|
||||||
- name: Tweet-trigger-publish-release
|
- name: Tweet-trigger-publish-release
|
||||||
uses: mugi111/tweet-trigger-release@v1.1
|
uses: mugi111/tweet-trigger-release@v1.1
|
||||||
with:
|
with:
|
||||||
@@ -14,4 +17,4 @@ jobs:
|
|||||||
consumer_secret: ${{ secrets.CONSUMER_SECRET }}
|
consumer_secret: ${{ secrets.CONSUMER_SECRET }}
|
||||||
access_token_key: ${{ secrets.ACCESS_TOKEN_KEY }}
|
access_token_key: ${{ secrets.ACCESS_TOKEN_KEY }}
|
||||||
access_token_secret: ${{ secrets.ACCESS_TOKEN_SECRET }}
|
access_token_secret: ${{ secrets.ACCESS_TOKEN_SECRET }}
|
||||||
tweet_body: 'A new mailcow-dockerized Release has been Released on GitHub! Checkout our GitHub Page for the latest Release: github.com/mailcow/mailcow-dockerized/releases/latest'
|
tweet_body: 'A new mailcow update has just been released! Checkout the GitHub Page for changelog and more informations: github.com/mailcow/mailcow-dockerized/releases/tag/latest'
|
||||||
|
@@ -166,17 +166,11 @@ while ($row = $sth->fetchrow_arrayref()) {
|
|||||||
$success = 1;
|
$success = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$keep_job_active = 1;
|
$update = $dbh->prepare("UPDATE imapsync SET returned_text = ?, success = ?, exit_status = ? WHERE id = ?");
|
||||||
if (defined $exit_status && $exit_status eq "EXIT_AUTHENTICATION_FAILURE_USER1") {
|
|
||||||
$keep_job_active = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$update = $dbh->prepare("UPDATE imapsync SET returned_text = ?, success = ?, exit_status = ?, active = ? WHERE id = ?");
|
|
||||||
$update->bind_param( 1, ${stdout} );
|
$update->bind_param( 1, ${stdout} );
|
||||||
$update->bind_param( 2, ${success} );
|
$update->bind_param( 2, ${success} );
|
||||||
$update->bind_param( 3, ${exit_status} );
|
$update->bind_param( 3, ${exit_status} );
|
||||||
$update->bind_param( 4, ${keep_job_active} );
|
$update->bind_param( 4, ${id} );
|
||||||
$update->bind_param( 5, ${id} );
|
|
||||||
$update->execute();
|
$update->execute();
|
||||||
} catch {
|
} catch {
|
||||||
$update = $dbh->prepare("UPDATE imapsync SET returned_text = 'Could not start or finish imapsync', success = 0 WHERE id = ?");
|
$update = $dbh->prepare("UPDATE imapsync SET returned_text = 'Could not start or finish imapsync', success = 0 WHERE id = ?");
|
||||||
|
@@ -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
|
||||||
|
@@ -127,6 +127,7 @@ elseif (!empty($_GET['id']) && ctype_alnum($_GET['id'])) {
|
|||||||
$data['fuzzy_hashes'] = json_decode($mailc['fuzzy_hashes']);
|
$data['fuzzy_hashes'] = json_decode($mailc['fuzzy_hashes']);
|
||||||
// Get text/plain content
|
// Get text/plain content
|
||||||
$data['text_plain'] = $mail_parser->getMessageBody('text');
|
$data['text_plain'] = $mail_parser->getMessageBody('text');
|
||||||
|
if (!json_encode($data['text_plain'])) $data['text_plain'] = '';
|
||||||
// Get html content and convert to text
|
// Get html content and convert to text
|
||||||
$data['text_html'] = $html2text->convert($mail_parser->getMessageBody('html'));
|
$data['text_html'] = $html2text->convert($mail_parser->getMessageBody('html'));
|
||||||
if (empty($data['text_plain']) && empty($data['text_html'])) {
|
if (empty($data['text_plain']) && empty($data['text_html'])) {
|
||||||
|
@@ -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;");
|
||||||
|
@@ -265,8 +265,8 @@
|
|||||||
"quota_notification_html": "Benachrichtigungs-E-Mail Inhalt:<br><small>Leer lassen, um Standard-Template wiederherzustellen.</small>",
|
"quota_notification_html": "Benachrichtigungs-E-Mail Inhalt:<br><small>Leer lassen, um Standard-Template wiederherzustellen.</small>",
|
||||||
"quota_notification_sender": "Benachrichtigungs-E-Mail Absender",
|
"quota_notification_sender": "Benachrichtigungs-E-Mail Absender",
|
||||||
"quota_notification_subject": "Benachrichtigungs-E-Mail Betreff",
|
"quota_notification_subject": "Benachrichtigungs-E-Mail Betreff",
|
||||||
"quota_notifications": "Quota Benachrichtigungen",
|
"quota_notifications": "Quota-Benachrichtigungen",
|
||||||
"quota_notifications_info": "Quota Benachrichtigungen werden an Mailboxen versendet, die 80 respektive 95 Prozent der zur Verfügung stehenden Quota überschreiten.",
|
"quota_notifications_info": "Quota-Benachrichtigungen werden an Mailboxen versendet, die 80 respektive 95 Prozent der zur Verfügung stehenden Quota überschreiten.",
|
||||||
"quota_notifications_vars": "{{percent}} entspricht der aktuellen Quota in Prozent<br>{{username}} entspricht dem Mailbox-Namen",
|
"quota_notifications_vars": "{{percent}} entspricht der aktuellen Quota in Prozent<br>{{username}} entspricht dem Mailbox-Namen",
|
||||||
"r_active": "Aktive Restriktionen",
|
"r_active": "Aktive Restriktionen",
|
||||||
"r_inactive": "Inaktive Restriktionen",
|
"r_inactive": "Inaktive Restriktionen",
|
||||||
|
@@ -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
@@ -172,7 +172,7 @@ function recursiveBase64StrToArrayBuffer(obj) {
|
|||||||
// TFA, CSRF, Alerts in footer.inc.php
|
// TFA, CSRF, Alerts in footer.inc.php
|
||||||
// Other general functions in mailcow.js
|
// Other general functions in mailcow.js
|
||||||
{% for alert_type, alert_msg in alerts %}
|
{% for alert_type, alert_msg in alerts %}
|
||||||
mailcow_alert_box('{{ alert_msg|raw }}', '{{ alert_type }}');
|
mailcow_alert_box('{{ alert_msg|raw|e("js") }}', '{{ alert_type }}');
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
// Confirm TFA modal
|
// Confirm TFA modal
|
||||||
|
@@ -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>
|
||||||
|
@@ -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}
|
||||||
@@ -215,7 +215,7 @@ services:
|
|||||||
- sogo
|
- sogo
|
||||||
|
|
||||||
dovecot-mailcow:
|
dovecot-mailcow:
|
||||||
image: mailcow/dovecot:1.20
|
image: mailcow/dovecot:1.21
|
||||||
depends_on:
|
depends_on:
|
||||||
- mysql-mailcow
|
- mysql-mailcow
|
||||||
dns:
|
dns:
|
||||||
@@ -424,7 +424,7 @@ services:
|
|||||||
- acme
|
- acme
|
||||||
|
|
||||||
netfilter-mailcow:
|
netfilter-mailcow:
|
||||||
image: mailcow/netfilter:1.48
|
image: mailcow/netfilter:1.49
|
||||||
stop_grace_period: 30s
|
stop_grace_period: 30s
|
||||||
depends_on:
|
depends_on:
|
||||||
- dovecot-mailcow
|
- dovecot-mailcow
|
||||||
|
@@ -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}"
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user