Compare commits

679 Commits
1.5 ... master

Author SHA1 Message Date
mergify[bot]
13c4acffa1 Merge pull request #775 from usrpro/workaround-lucene
Option to disable full text search (lucene)
2018-12-25 21:26:39 +00:00
Tim Möhlmann
3a5b763018 Option to disable full text search (lucene)
This is a workaround for the bug in issue #751
2018-12-25 13:52:12 +02:00
mergify[bot]
3fa3fd5f69 Merge pull request #767 from hoellen/fix-localpart-chars
allow all characters for username in dovecot
2018-12-21 14:12:06 +00:00
mergify-bot
983c388150 Merge branch 'master' into 'fix-localpart-chars' 2018-12-21 14:48:36 +01:00
Tim Möhlmann
27f13c1ba3 Merge pull request #768 from Mailu/fix-admin-volumes
Fix admin volumes
2018-12-21 15:27:33 +02:00
mergify-bot
6cfb74e96c Merge branch 'master' into 'fix-localpart-chars' 2018-12-21 14:25:19 +01:00
Tim Möhlmann
9249b4a2d4 Merge pull request #765 from usrpro/feat-setup-update
Added welcome email to setup env
2018-12-20 18:06:10 +02:00
Tim Möhlmann
ad1ca42bde Remove unused docker socket mount for Admin 2018-12-20 17:48:29 +02:00
Tim Möhlmann
af086bbdbe Include DKIM in VOLUME 2018-12-20 17:47:15 +02:00
Tim Möhlmann
d19abc60bc Merge pull request #766 from usrpro/fix-webmail-root
Fix webmail on root
2018-12-20 17:20:20 +02:00
hoellen
c041a9d45c allow all characters for username in dovecot 2018-12-19 16:19:37 +01:00
Tim Möhlmann
24828615cf Webmail on root, fixes #757 2018-12-19 16:20:24 +02:00
Ionut Filip
5e2552bcd5 Removed if block 2018-12-19 12:05:50 +02:00
Tim Möhlmann
be7dc1e6bd Merge pull request #753 from usrpro/deploy-docks
Add deploy settings for server
2018-12-17 00:13:35 +02:00
Tim Möhlmann
533a6f8faa Add deploy settings for server 2018-12-17 00:12:21 +02:00
Tim Möhlmann
c0645eadef Remove healthcheck
Did not work correctly and prevents Traefik from serving the page.
2018-12-17 00:04:55 +02:00
Tim Möhlmann
d96debb2a6 Merge pull request #752 from usrpro/setup-deploy
Setup deploy
2018-12-16 23:29:59 +02:00
Tim Möhlmann
e994fefb2d Remove the test branch 2018-12-16 23:28:15 +02:00
kaiyou
66844fbca8 Merge pull request #750 from usrpro/fix-mailu_version_docs
Use MAILU_VERSION from Travis for Docs build
2018-12-16 22:27:52 +01:00
Tim Möhlmann
1df3b46454 Use ADDRESS instead of HOSTNAME 2018-12-16 23:16:53 +02:00
Tim Möhlmann
8ef0493f53 Define external web network for Traefik connections 2018-12-16 23:16:26 +02:00
Tim Möhlmann
db9a3787b1 Disable healthcheck, doen't work in versioned env 2018-12-16 23:14:36 +02:00
Tim Möhlmann
3655c7c902 Merge remote-tracking branch 'origin/fix-setup-bugs' into setup-deploy 2018-12-16 16:27:11 +02:00
Tim Möhlmann
9c284c4004 Prepare setup for multi-ver deployment on docs server 2018-12-16 16:26:45 +02:00
Tim Möhlmann
a5d6acfb96 Use MAILU_VERSION from Travis for Docs build 2018-12-15 21:40:00 +02:00
Tim Möhlmann
3c4ee1b31e Merge pull request #743 from kaiyou/master
Fixes #738 regarding application context
2018-12-14 11:09:27 +02:00
ofthesun9
97b3a85090 Merge pull request #737 from hoellen/fix-alias-match-behaviour
fix alias match behaviour
2018-12-13 20:34:09 +01:00
mergify-bot
09a50b6cfc Merge branch 'master' into 'master' 2018-12-13 19:14:20 +01:00
mergify[bot]
5795d8be16 Merge pull request #744 from kaiyou/fix-remove-debug
Remove some forgotten debugging, fix #720
2018-12-13 16:40:31 +00:00
kaiyou
4060ac2223 Remove some forgotten debugging 2018-12-13 15:19:34 +01:00
kaiyou
087841d5b7 Fix the way we handle the application context
The init script was pushing an application context, which maked
flask.g global and persisted across requests. This was evaluated
to have a minimal security impact.

This explains/fixes #738: flask_wtf caches the csrf token in the
application context to have a single token per request, and only
sets the session attribute after the first generation.
2018-12-13 14:23:17 +01:00
kaiyou
b5f51b0e2e Update python dependencies 2018-12-13 14:10:43 +01:00
mergify[bot]
0f4ba39141 Merge pull request #741 from usrpro/fix-networks-bug
Fixed networks indentation
2018-12-12 08:45:27 +00:00
Ionut Filip
514d179db1 Fixed networks indentation 2018-12-11 17:40:36 +02:00
Ionut Filip
bb0fd896b3 Fix some bugs in setup for stack flavor
- Unbound and webmail images were hardcoded
- Removed unnecesary environment keyword
2018-12-11 17:31:21 +02:00
hoellen
8fe9e695f3 prefer non-wildcard aliases over wildcard aliases 2018-12-10 08:40:10 +01:00
Tim Möhlmann
c7dcfee882 Merge pull request #713 from pgeorgi/extend-nginx
nginx: Allow extending config with overrides
2018-12-09 21:44:24 +02:00
hoellen
79768c09f6 fix alias matching behaviour 2018-12-09 19:49:23 +01:00
mergify[bot]
74693ee47c Merge pull request #736 from usrpro/clamav-health-start
Increase health start period for clamav's DB download
2018-12-09 18:17:42 +00:00
Tim Möhlmann
c1839b1ec1 Increase health start period for clamav's DB download 2018-12-08 23:47:37 +02:00
Tim Möhlmann
6ca8ed437d Merge pull request #732 from Nebukadneza/add_front_certificate_reload
Add certificate watcher for external certs to reload nginx
2018-12-08 20:11:09 +02:00
Tim Möhlmann
94e42c9b52 Merge pull request #727 from usrpro/feat-subnet2
Move the Mailu Docker network to a fixed subnet.
2018-12-08 12:40:45 +02:00
Tim Möhlmann
33c0a99ffc Merge pull request #678 from hacor/k8s-cni-fix
Added kubernetes CNI support for Mailu
2018-12-08 12:29:25 +02:00
Tim Möhlmann
bb85079d92 Merge pull request #695 from ofthesun9/master-patch1
POD_ADDRESS_RANGE need to be defined for admin service (dovecot authentific…
2018-12-08 12:25:35 +02:00
mergify-bot
491f6b24bb Merge branch 'master' into 'feat-subnet2' 2018-12-08 00:46:17 +01:00
Dario Ernst
1aa97c9914 Add certificate watcher for external certs to reload nginx
In case of TLS_FLAVOR=[mail,cert], the user supplies their own certificates.
However, since nginx is not aware of changes to these files, it cannot
reload itself e.g. when the certs get renewed.

To solve this, let’s add a small daemon in the place of
`letsencrypt.py`, which uses a flexible file-watching framework and
reloads nginx in the case the certificates change ….
2018-12-07 16:20:42 +00:00
Tim Möhlmann
c00910ca4b Merge remote-tracking branch 'upstream/master' into extend-nginx 2018-12-07 16:48:50 +02:00
Tim Möhlmann
97d338e68a Rectify 'endif' placement 2018-12-07 16:44:42 +02:00
Tim Möhlmann
7f46876b0c Merge pull request #731 from usrpro/attachment-size
Dynamic attachment size limit
2018-12-07 16:38:34 +02:00
Tim Möhlmann
425cdd5e77 Fix syntax errors 2018-12-07 16:29:41 +02:00
Tim Möhlmann
20f1faf6d0 Send 404 when nothing server at '/'
Prevents Nginx welcome screen
2018-12-07 16:10:52 +02:00
Tim Möhlmann
c25ba75d68 Include WEBROOT_REDIRECT in setup templates 2018-12-07 15:29:33 +02:00
Tim Möhlmann
9208d7262f Correct variable naming in .env 2018-12-07 15:22:01 +02:00
Tim Möhlmann
2de4995fec Don't redirect when webmail is served on '/' 2018-12-07 15:17:04 +02:00
Tim Möhlmann
28daa22842 Merge pull request #726 from usrpro/update-mergify
review/need2 in mergify
2018-12-07 13:48:15 +02:00
Tim Möhlmann
8e5ccf2754 Don't merge when WIP or Blocked 2018-12-07 13:47:22 +02:00
Tim Möhlmann
626559f99b Mergify dismiss reviews 2018-12-07 13:43:53 +02:00
Ionut Filip
94edb48f08 Dynamic attachment size 2018-12-07 13:37:40 +02:00
Tim Möhlmann
a2a9512afa Enable mergify strict mode
In the past we had strict mode in branch protection. This didn't really work as it broke mergify. Now mergify supports this options and takes care of the merging automatically. Let's see how it goes ;)

Reason is the recent build failures we had on master, during a busy merge day. This could have been prevented if sequential PR's where re-merging with master.

More info: https://doc.mergify.io/strict-workflow.html
2018-12-07 11:53:43 +02:00
Tim Möhlmann
f0906073e3 Merge remote-tracking branch 'upstream/master' into feat-subnet2 2018-12-07 11:08:28 +02:00
mergify[bot]
a634c7b72d Merge pull request #725 from usrpro/fix-outlook2019-smtp
Add login method to smtp_auth under ssl
2018-12-06 16:02:35 +00:00
Tim Möhlmann
38eb266c25 Merge pull request #728 from usrpro/fix-autobuild
Fix autobuild
2018-12-06 17:41:43 +02:00
Tim Möhlmann
c0972face6 Correct subnetting functionality for the tests and setup 2018-12-06 16:44:12 +02:00
Ionut Filip
35be1710a6 Changed user creation command 2018-12-06 12:36:56 +02:00
Ionut Filip
8acf9451fa Changed admin and user creation command 2018-12-06 12:34:56 +02:00
Tim Möhlmann
8172f3eab8 Move the Mailu Docker network to a fixed subnet.
This will make network configuration and host based authentication
more robust, across different deployment platforms.
The options `RELAYNETS` and`POD_ADDRESS_RANGE` are kept for compatibility.
However, their usage have become optional.
2018-12-06 12:08:22 +02:00
kaiyou
3d98124bcd Merge pull request #670 from kaiyou/refactor-config
Refactor the admin architecture and configuration management
2018-12-06 10:56:42 +01:00
Tim Möhlmann
fee52e87ed Don't allow for 1 review when review/need2 label is set 2018-12-06 11:34:28 +02:00
kaiyou
b6aaf57be1 Merge branch 'refactor-config' of github.com:kaiyou/mailu into refactor-config 2018-12-06 10:33:21 +01:00
kaiyou
d0f07984b0 Merge remote-tracking branch 'upstream/master' into refactor-config 2018-12-06 10:23:43 +01:00
kaiyou
07b1e8d765 Merge pull request #722 from usrpro/update-mergify
Update .mergify.yml
2018-12-06 10:19:07 +01:00
Tim Möhlmann
9dd447e23b Add login method to smtp_auth under ssl
Fixes #704
2018-12-06 01:00:16 +02:00
Patrick Georgi
eac4d553a9 nginx: Allow extending config with overrides
To facilitate this, the default redirect at / can be disabled, even if
the default remains at redirecting to the webmailer.

The extensions are within the host scope and are read from
$ROOT/overrides/nginx/*.conf.
2018-12-05 23:54:52 +01:00
mergify[bot]
c25c646909 Merge pull request #702 from dani909/feat-image-prefix
Add docker image prefix
2018-12-05 19:24:07 +00:00
hoellen
02367d1447 Merge branch 'master' into feat-image-prefix 2018-12-05 19:48:51 +01:00
mergify[bot]
2d4bac03ad Merge pull request #723 from usrpro/clean-healthcheck-logs
Admin: Prevent redirects during health checking
2018-12-05 18:09:14 +00:00
mergify[bot]
a382f74680 Merge pull request #705 from usrpro/fix-recaptcha
Fix recaptcha
2018-12-05 18:05:22 +00:00
mergify[bot]
ca86090011 Merge pull request #682 from usrpro/feat-setup
Further improve setup and neccesary re-write of the test suite
2018-12-05 17:57:41 +00:00
mergify[bot]
37027cfce7 Merge pull request #633 from kaiyou/fix-sender-checks
Improve sender checks
2018-12-05 16:03:24 +00:00
Tim Möhlmann
d18cf7cb25 Prevent redirects during health checking 2018-12-05 17:43:42 +02:00
Tim Möhlmann
d84254ccd8 Update user creation to python3 2018-12-05 16:23:16 +02:00
mergify[bot]
161b27a204 Merge pull request #719 from davidrothera/master
Query alternative table for domain matches
2018-12-05 12:37:13 +00:00
Tim Möhlmann
b564b879aa Update .mergify.yml
- New syntax for mergify engine v. 2
- Relax review rules for trusted users
2018-12-05 12:38:06 +02:00
Tim Möhlmann
c9df311a0d Set forward_destination to an empty list
The value of `None` resulted in an error, since a list was expected.
2018-12-04 16:22:18 +02:00
Tim Möhlmann
eff6c34632 Catch asterisk before resolve_domain
Asterisk results in IDNA error and a 500 return code.
2018-12-04 15:40:07 +02:00
David Rothera
88c174fb7a Query alternative table for domain matches
At present postfix checks this view for matches in the domain table and is used to accept/deny messages sent into it however it never checks for matches in the alternative table.

Fixes #718
2018-12-02 11:21:42 +00:00
Tim Möhlmann
2b6f5ea3d0 Update setup's own docker-compose.yml file 2018-12-01 02:37:34 +02:00
Tim Möhlmann
eccadeca16 Merge pull request #8 from usrpro/feat-email-test
Feat email test
2018-11-09 12:58:32 +02:00
Ionut Filip
fed7146873 Captcha check on signup form 2018-11-09 12:30:49 +02:00
Tim Möhlmann
4783e61693 Fix password context
Fixes the following error:
```
admin_1      | [2018-11-09 09:44:10,533] ERROR in app: Exception on /internal/auth/email [GET]
admin_1      | Traceback (most recent call last):
admin_1      |   File "/usr/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
admin_1      |     response = self.full_dispatch_request()
admin_1      |   File "/usr/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
admin_1      |     rv = self.handle_user_exception(e)
admin_1      |   File "/usr/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
admin_1      |     reraise(exc_type, exc_value, tb)
admin_1      |   File "/usr/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
admin_1      |     raise value
admin_1      |   File "/usr/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
admin_1      |     rv = self.dispatch_request()
admin_1      |   File "/usr/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
admin_1      |     return self.view_functions[rule.endpoint](**req.view_args)
admin_1      |   File "/usr/lib/python3.6/site-packages/flask_limiter/extension.py", line 544, in __inner
admin_1      |     return obj(*a, **k)
admin_1      |   File "/app/mailu/internal/views/auth.py", line 18, in nginx_authentication
admin_1      |     headers = nginx.handle_authentication(flask.request.headers)
admin_1      |   File "/app/mailu/internal/nginx.py", line 48, in handle_authentication
admin_1      |     if user.check_password(password):
admin_1      |   File "/app/mailu/models.py", line 333, in check_password
admin_1      |     context = User.pw_context
admin_1      | AttributeError: type object 'User' has no attribute 'pw_context'
```
2018-11-09 11:45:08 +02:00
kaiyou
72e1b444ca Merge alembic migrations 2018-11-08 21:55:39 +01:00
kaiyou
5b769e23da Merge branch 'master' into refactor-config 2018-11-08 21:43:05 +01:00
kaiyou
30716b8bdf Update docs with the new flask command 2018-11-08 21:35:41 +01:00
kaiyou
02995f0a15 Add a mailu command line to flask 2018-11-08 21:29:30 +01:00
kaiyou
f9e30bd87c Update the dockerfile and upgrade dependencies 2018-11-08 21:29:11 +01:00
kaiyou
4a7eb1eb6c Explicitely declare flask migrate 2018-11-08 20:32:23 +01:00
kaiyou
2a8808bdec Add the configuration table migration 2018-11-08 20:32:06 +01:00
kaiyou
f57d4859f3 Provide an in-context wrapper for getting users 2018-11-08 20:30:41 +01:00
kaiyou
f6013aa29f Fix an old migration that was reading configuration before migrating 2018-11-08 20:30:20 +01:00
kaiyou
206cce0b47 Finish the configuration bits 2018-11-08 20:29:52 +01:00
mergify[bot]
5c24390114 Merge pull request #697 from HorayNarea/fix-missing-dkim
allow DKIM-signing if From-Header and Auth-User mismatch - fix #462
2018-11-08 17:24:51 +00:00
Ionut Filip
2a76451a98 Moved scripts to an external js file 2018-11-07 16:41:11 +02:00
Ionut Filip
1bbf3f235d Using a new class when captcha is enabled 2018-11-07 09:58:49 +02:00
mergify[bot]
12689965bd Merge pull request #699 from usrpro/fix-admin-bug
Fixed admin_1 errors in the logs
2018-11-06 18:10:52 +00:00
hoellen
680ad4b67a Catching only ValueError
Co-Authored-By: ionutfilip <ionut.philip@gmail.com>
2018-11-05 19:36:28 +02:00
Ionut Filip
76d9fc3865 Rewrite of email test script and added eicar virus file 2018-11-05 17:28:40 +02:00
Ionut Filip
4032e7128d Calling email test as hook with msg as arg 2018-11-05 12:34:52 +02:00
Ionut Filip
fca3dc4e70 Flushing stream before calling subprocess 2018-11-03 19:34:47 +02:00
Ionut Filip
9a7fc1416a Replaces os.popen with subprocess.check_output 2018-11-03 19:15:05 +02:00
Daniel Huber
b3ac4465f2 Add docker image prefix 2018-11-03 14:54:17 +01:00
mergify[bot]
da96ef183b Merge pull request #700 from usrpro/feat-review-docs
Dev. docs.: Add git workflows for branching, PR and reviewing
2018-11-02 21:01:07 +00:00
mergify[bot]
e08f3e81d0 Merge pull request #680 from usrpro/feat-startup
Standarize images
2018-11-02 17:36:28 +00:00
Ionut Filip
982e586e49 Replaced os.system calls with native python calls 2018-11-02 16:25:55 +02:00
Ionut Filip
0d6a203a9d Use sudo for running sh commands 2018-11-02 15:32:36 +02:00
Ionut Filip
fd8ed3dfa6 Moved certs copy in travis 2018-11-02 15:17:59 +02:00
Tim Möhlmann
2576379df5 Dev. docs.: Add git workflows for branching, PR and reviewing 2018-11-02 15:10:18 +02:00
Ionut Filip
88f5e6e4cf Moved users creation in core 2018-11-02 15:05:16 +02:00
Ionut Filip
c3bc7988c9 Implemented email test for travis 2018-11-02 14:27:46 +02:00
Ionut Filip
6dcc33e390 Fixed admin_1 errors in the logs
Fixed errors when trying to log in with an account without domain.
This closes #585
2018-11-02 12:14:23 +02:00
Ionut Filip
4e9dc0c3c9 Implemented sending/reading email(local tests) 2018-11-01 11:40:54 +02:00
Thomas Sänger
13bc6261e4 allow DKIM-signing if From-Header and Auth-User mismatch 2018-10-31 20:30:16 +01:00
Tim Möhlmann
ca4804653d Merge branch 'master' into feat-setup 2018-10-31 20:11:52 +01:00
mergify[bot]
09abaff9b6 Merge pull request #692 from HorayNarea/feat-rspamd-history
store rspamd history in redis - fix #561
2018-10-31 17:57:01 +00:00
mergify[bot]
7a116c0364 Merge pull request #696 from usrpro/fix-imap-no-webmail
Fix imap login when no webmail selected
2018-10-31 17:56:48 +00:00
Tim Möhlmann
42e2dbe35d Standarize image by using shared / similair layers 2018-10-31 19:17:23 +02:00
Tim Möhlmann
003c36c98a Fix imap login when no webmail selected 2018-10-31 17:48:34 +02:00
Tim Möhlmann
5fa2aac569 Fix imap login when no webmail selected 2018-10-31 17:47:05 +02:00
ofthesun9
5067b5c59a POD_ADDRESS need to be defined for admin service (dovecot authentification) fixes #694
- updated the docs
- corrected a typo
2018-10-31 14:27:37 +00:00
Tim Möhlmann
903bb70c5b Merge remote-tracking branch 'upstream/master' into standarize-images 2018-10-31 16:22:21 +02:00
Thomas Sänger
9ba086fcff store rspamd history in redis 2018-10-30 23:28:25 +01:00
Tim Möhlmann
9004c9b8b5 Merge pull request #677 from usrpro/feat-faq
Implement a FAQ
2018-10-30 21:04:34 +01:00
mergify[bot]
e9217b8389 Merge pull request #681 from usrpro/feat-unbound-dns
Unbound DNS as optional service
2018-10-30 17:32:13 +00:00
mergify[bot]
1a5e106bb8 Merge pull request #691 from Mailu/HorayNarea-patch-1
Update roundcube
2018-10-30 07:47:49 +00:00
Thomas Sänger
7125077dec Update roundcube 2018-10-29 01:41:04 +01:00
mergify[bot]
7408e625f6 Merge pull request #690 from dani909/fix-typo
Fix Typo in Kubernetes Docs
2018-10-28 18:11:32 +00:00
Daniel Huber
2237e641b0 Fix Typo in K8s Docs 2018-10-28 12:26:14 +01:00
Ionut Filip
ffdef18bd6 Rendering admin/webmail path based on checkbox value 2018-10-26 16:50:59 +03:00
Tim Möhlmann
a46d0fe581 Fix path for hooks 2018-10-25 18:45:24 +03:00
Tim Möhlmann
35e0fa1b9d Drop IPv6 for travis 2018-10-25 18:23:42 +03:00
Tim Möhlmann
a1ac7fc19c Upgrade docker-compose inside travis (fix build errors) 2018-10-25 18:12:07 +03:00
mergify[bot]
da81f67254 Merge pull request #688 from hoellen/doc-fix-typo
fix typo in cli doc
2018-10-25 14:53:05 +00:00
mergify[bot]
27cf2c33a6 Merge pull request #684 from romracer/fix-683
Fix typo (duplicate self).  Fixes #683
2018-10-25 14:48:16 +00:00
Tim Möhlmann
1e3392e417 Antispam not an optional service, postfix fails without it 2018-10-25 17:37:22 +03:00
Tim Möhlmann
dde7ccca97 Created test cases from latest setup revision 2018-10-25 17:35:53 +03:00
Tim Möhlmann
72e931f4b4 Modify setup templates to allow for DOCKER_ORG and VERSION override. (Needed for Travis) 2018-10-25 16:35:08 +03:00
Tim Möhlmann
928fbb372d Merge branch 'feat-test-suite' into feat-setup 2018-10-25 15:35:48 +03:00
Ionut Filip
3b1fdc6166 Migrate test script from shell to python
- test.py needs to be called with 2 arguments : test_name and timeout
  - it will cd to test_name dir and use the test_name.yml from there
  - it will sleep for an amount of time equals to timeout in minutes
- it will perform health checks for containers. If healtcheck isn't enabled will check for running state
- it will run hooks inside the test_name dir ( .py and .sh) if there are any
- printing logs in any case
2018-10-25 15:27:09 +03:00
hoellen
fd3a944850 fix typo in doc 2018-10-25 13:04:40 +02:00
Tim Möhlmann
55297424cd Merge remote-tracking branch 'upstream/master' into feat-setup 2018-10-24 14:45:21 +03:00
Tim Möhlmann
b8783b670a Take out DNS entry for webmail 2018-10-24 12:18:03 +03:00
Tim Möhlmann
238d4e7f20 Provide test cases created with the new setup utility 2018-10-24 12:02:28 +03:00
Scott
56fb74c502 Fix typo (duplicate self). Fixes #683 2018-10-23 10:47:31 -05:00
Ionut Filip
e5268de0c7 Revert default value for subnet 2018-10-23 17:55:44 +03:00
Ionut Filip
120c29eff6 Added unbound for stack flavor 2018-10-23 17:46:06 +03:00
Ionut Filip
ae8f928fc0 Added project name on docker commands 2018-10-23 17:07:05 +03:00
Ionut Filip
393bf566da Merge branch 'feat-unbound-dns' of github.com:usrpro/Mailu into feat-unbound-dns 2018-10-23 16:40:36 +03:00
Ionut Filip
6c12e2fffb Fixed subnet variable in unbound 2018-10-23 16:39:22 +03:00
Tim Möhlmann
12d8872a09 Fix unbound build path 2018-10-23 16:09:59 +03:00
Ionut Filip
da37555a3c Fixed naming error 2018-10-23 15:46:53 +03:00
Ionut Filip
7c07efc216 Added unbound to setup
- Added checkbox for unbound resolver
- Added subnet variable
- Added dns variable which is generating the ip address based on subnet
2018-10-23 15:44:30 +03:00
Tim Möhlmann
bcfce27ee2 Standarize unbound, prepare for setup inclusion
- Use jinja template for configuration file (start.py)
- Limit access to the Mailu subnet
- Implement health checks
2018-10-23 15:07:49 +03:00
hoellen
9412c8e1e9 Correct spelling error
Co-Authored-By: muhlemmer <muhlemmer@gmail.com>
2018-10-23 13:52:43 +03:00
Ionut Filip
8a44a44688 Merge branch 'master' into feat-startup 2018-10-23 12:51:32 +03:00
Tim Möhlmann
40d8e65762 Revert docker-compose to latest upstream version 2018-10-23 12:22:36 +03:00
Tim Möhlmann
5b7b29ee3f Merge remote-tracking branch 'upstream/master' into feat-unbound-dns 2018-10-23 12:16:36 +03:00
Ionut Filip
1187cac5e1 Finished up switching from .sh to .py 2018-10-23 11:58:36 +03:00
Tim Möhlmann
ed81c076f2 Take out "models" path, as we are already in it 2018-10-23 11:53:52 +03:00
Tim Möhlmann
aed80a74fa Rectify decleration of domain_name 2018-10-23 11:52:15 +03:00
Hans Cornelis
99540cd90b - Added kubernetes CNI support for Mailu
Signed-off-by: Hans Cornelis <hacornelis@gmail.com>
2018-10-23 10:47:26 +02:00
Tim Möhlmann
2d382f2d67 Merge branch 'master' into fix-sender-checks 2018-10-23 10:58:29 +03:00
Tim Möhlmann
2124df36ec Merge pull request #663 from HorayNarea/feat-healthchecks
implement healthchecks - resolves #631
2018-10-22 21:07:03 +03:00
Thomas Sänger
76e95bd585 Fix typo
Co-Authored-By: muhlemmer <muhlemmer@gmail.com>
2018-10-22 21:05:55 +03:00
Ionut Filip
0e5606d493 Changed start.sh to start.py 2018-10-22 18:01:59 +03:00
Ionut Filip
eb7dfb5771 Cleaning up start.py 2018-10-22 17:02:43 +03:00
Tim Möhlmann
7c1118df7d Extending the FAQ 2018-10-22 16:14:54 +03:00
Tim Möhlmann
3552c59ff3 Insert ref link for FAQ, shortened title for display purposes 2018-10-22 16:11:45 +03:00
Ionut Filip
3c9cae5d06 Added replicas variables for core containers
- Added back restart: always on compose flavor
- Moved Log driver from .env to docker-compose.yml
2018-10-22 15:13:18 +03:00
Ionut Filip
6a9e5c1921 Create/generate file template 2018-10-22 12:53:25 +03:00
Tim Möhlmann
b54a51e3ba Merge branch 'master' into feat-faq 2018-10-22 12:30:23 +03:00
Ionut Filip
9881dd2074 Documentation for adding more steps/flavors 2018-10-22 12:13:22 +03:00
Thomas Sänger
603b6e7390 Merge pull request #2 from usrpro/fix-nginx-healthcheck
Fix nginx healthcheck
2018-10-21 22:44:44 +02:00
Tim Möhlmann
81b24f61e8 Merge branch 'master' into feat-healthchecks 2018-10-21 20:58:59 +03:00
Tim Möhlmann
a2fea36c79 Increase HEALTHCHECK start time for services that need to wait for host resolving during startup.
In Docker Swarm mode the services listed below can get stuck in their start script, while they
are waiting for other services become available. Now, with HEALTHCHECK enabled, docker does not resolve
names of services that not pass HEALTHCHECK yet. Meaning that if one of the depenend services is not yet
available, it will create a chain of failing services.

The services below retry to resolve 100 time, with an average of 3.5 seconds. Hence, the --start-time
flag is now set at 350 seconds.
- dovecot (imap)
- postfix (smtp)
- rspamd (antispam)
2018-10-21 20:49:01 +03:00
Tim Möhlmann
c3e89967fb Fix front health checking
- Specified seperated /health path in order to allow for healthcheck even if webmail and admin are not seletectd. This also allows healthchecking fom external services like DNS load balancers;
- Make curl not to fail on TLS because localhost is not included in the certificates.
2018-10-21 20:45:41 +03:00
mergify[bot]
f2c4e52fee Merge pull request #664 from kaiyou/feat-docs-versions
Implement a multi-version documentation
2018-10-21 14:22:13 +00:00
mergify[bot]
d167c8ca7c Merge pull request #668 from usrpro/feat-setup
Feat setup
2018-10-21 13:04:46 +00:00
mergify[bot]
90b8c3cc1f Merge pull request #665 from kaiyou/feat-reply-startdate
Implement a start date filter for autoreply, fixes #362
2018-10-20 23:18:06 +00:00
mergify[bot]
bce1487338 Merge pull request #576 from hacor/master
Kubernetes fixed for production
2018-10-20 22:30:38 +00:00
mergify[bot]
8112d31ce9 Merge pull request #674 from paulprogrammer/feat-nginx-http2
enable http2, because it's that easy
2018-10-20 09:04:31 +00:00
kaiyou
eaaf0125d1 Merge pull request #1 from usrpro/feat-docs-versions
Documentation update on local docs container
2018-10-20 10:20:20 +02:00
kaiyou
1fcaef7c7e Merge branch 'master' into fix-sender-checks 2018-10-20 10:18:36 +02:00
Paul Williams
78bd5aea1c enable http2, because it's that easy 2018-10-19 22:46:36 -06:00
hoellen
72d4fa2bc9 remove empty line from merge conflict 2018-10-19 22:13:38 +02:00
hoellen
857ad50509 Merge branch 'master' into feat-reply-startdate 2018-10-19 22:06:56 +02:00
mergify[bot]
4a5c0a6d21 Merge pull request #667 from kaiyou/fix-password-performance
Improve password checking performance
2018-10-19 18:56:26 +00:00
mergify[bot]
80658c30da Merge pull request #669 from hoellen/fix-webmail-root
Fix nginx conf if webmail is on root path
2018-10-19 15:18:40 +00:00
Ionut Filip
c5be360a48 Updated setup page for stack flavor 2018-10-19 17:29:35 +03:00
Tim Möhlmann
771e0ee6a2 Remove old crypt settings from .env
As per conversation in PR
2018-10-19 16:29:47 +03:00
Ionut Filip
ebaba8fb41 Moved variables from docker-compose.yml back to env file 2018-10-19 15:27:18 +03:00
Hans Cornelis
f10416e85a Merged with new PRs 2018-10-19 13:40:17 +02:00
Hans Cornelis
6fb0b93240 - Removed RSPAMD Password feature
- Updated roles on the Front DS
- Reverted the Auth limits

Signed-off-by: Hans Cornelis <hacornelis@gmail.com>
2018-10-19 13:39:32 +02:00
Ionut Filip
9c56e4c1b6 Fixed misstyped condition 2018-10-19 14:09:58 +03:00
Tim Möhlmann
4ccefd6d5e Documentation update on local docs container 2018-10-19 13:43:09 +03:00
Ionut Filip
02c802159a Updated env file with the latest version 2018-10-19 12:53:26 +03:00
mergify[bot]
118ea0f3fb Merge pull request #604 from ofthesun9/feature-swarm
Enabling swarm deployment on master branch
2018-10-19 09:18:34 +00:00
Tim Möhlmann
84c6b12d06 Updated labels in config page 2018-10-19 11:57:14 +03:00
Ionut Filip
08987dfa22 Minor changes 2018-10-19 11:45:55 +03:00
mergify[bot]
727970514d Merge pull request #527 from ofthesun9/feat-fuzzyhashes
Trying to enable fuzzy hashes for rspamd
2018-10-18 21:59:08 +00:00
kaiyou
672fca3347 Merge pull request #666 from kaiyou/feat-sieve-edit
Re-enable local dovecot sieve scripts
2018-10-18 23:18:39 +02:00
ofthesun9
7a3922c2e7 Fixes few typos 2018-10-18 19:14:53 +00:00
ofthesun9
5b8deed06b Made the instructions more simple
Updated the volume defintion to the latest master status
Removed the part around .yml variable substitution as we can use a "trick"
2018-10-18 18:59:22 +00:00
ofthesun9
9c639eebd4 Made the instructions more simple (moved the nfs-volume example to another file)
Removed he part around variable substitution as we can use a "trick"
2018-10-18 18:46:59 +00:00
kaiyou
82069ea3f0 Clean most of the refactored code 2018-10-18 17:55:07 +02:00
Ionut Filip
35193f5530 Added functionality for stack flavor 2018-10-18 17:23:25 +03:00
kaiyou
f40fcd7ac0 Use click for the manager command 2018-10-18 16:20:56 +02:00
kaiyou
fc24426291 First batch of refactoring, using the app factory pattern 2018-10-18 15:57:43 +02:00
hoellen
d4f32c3e7d remove rewrite if webmail is on root 2018-10-18 14:27:28 +02:00
Tim Möhlmann
39a1de956f Add docker stack flavor
- Template still untested
- mailu.env and setup.html are symbolic links to compose flavor
2018-10-18 14:35:38 +03:00
Tim Möhlmann
adfadab4cf Load steps after setting flavor 2018-10-18 12:56:16 +03:00
kaiyou
828d96f8f0 Switch the default password scheme to PBKDF2 2018-10-17 21:26:44 +02:00
kaiyou
01fa179767 Update the user password in database when needed 2018-10-17 21:22:22 +02:00
kaiyou
988e09e65e Add a profiler in debug mode for improving performance 2018-10-17 21:22:15 +02:00
kaiyou
dba8f1810d Do not check the password another time in Dovecot 2018-10-17 21:22:09 +02:00
ofthesun9
dbce059ae8 Merge pull request #5 from kaiyou/ofthesun9-feat-fuzzyhashes
Merging from kaiyou:ofthesun9-feat-fuzzyhashes
2018-10-17 20:51:55 +02:00
ofthesun9
86bdce8407 Explicitely specify the fuzzy worker listen address 2018-10-17 18:49:19 +00:00
ofthesun9
cec5c1b16b Merge branch 'master' into feat-fuzzyhashes 2018-10-17 18:31:42 +00:00
kaiyou
d5162328ec Allow dovecot to write the source configuration directory for compiling sieve scripts 2018-10-17 18:48:59 +02:00
kaiyou
ce0bf3366d Learn fuzzy hashes automatically 2018-10-17 18:48:28 +02:00
kaiyou
b9b4a8cd77 Explicitely specify the fuzzy worker listen address 2018-10-17 18:47:55 +02:00
kaiyou
0c40057767 Merge branch 'feat-fuzzyhashes' of https://github.com/ofthesun9/Mailu into ofthesun9-feat-fuzzyhashes 2018-10-17 17:58:48 +02:00
Tim Möhlmann
5679d355aa Avoid binding conflicts on production servers 2018-10-17 18:45:09 +03:00
kaiyou
0a5dbf6230 Re-enable local dovecot sieve scripts 2018-10-17 17:41:21 +02:00
Tim Möhlmann
b2059be966 Merge branch 'feat-setup' of github.com:usrpro/Mailu into feat-setup 2018-10-17 18:38:51 +03:00
Tim Möhlmann
ed53d655d3 Extend documentation in download page. Small cleanup in env. 2018-10-17 18:38:10 +03:00
Ionut Filip
7c0f5b20d6 Bug fixes 2018-10-17 17:54:37 +03:00
Ionut Filip
cb1ed349bf Bug fixes 2018-10-17 16:46:20 +03:00
Ionut Filip
6b6cbcf977 Modified variables in .env file 2018-10-17 15:38:51 +03:00
Ionut Filip
b3c7c45140 Added input form constraints 2018-10-17 15:11:55 +03:00
Hans Cornelis
ef55ca525c Deleted conflicting merge files
Signed-off-by: Hans Cornelis <hacornelis@gmail.com>
2018-10-17 07:48:52 +02:00
Hans Cornelis
e67a0d464b Deleted old folder 2018-10-17 07:44:21 +02:00
Hans Cornelis
3098343360 Merged conflicts 2018-10-17 07:32:56 +02:00
hacor
4ea12deae7 Added kubernetes to Mailu 2018-10-17 07:22:55 +02:00
kaiyou
ed3388ed6e Merge branch 'master' into feat-reply-startdate 2018-10-16 23:53:43 +02:00
kaiyou
7c82be904f Merge branch 'master' of github.com:mailu/mailu 2018-10-16 23:50:07 +02:00
kaiyou
53b9c031c9 Add a warning banner when not reading the stable docs 2018-10-16 23:19:48 +02:00
Thomas Sänger
a412951a30 simpler healthcheck for postfix 2018-10-16 23:12:02 +02:00
Thomas Sänger
0bc901a722 add healthcheck for dovecot 2018-10-16 23:11:20 +02:00
Thomas Sänger
1fc40bf932 add healthcheck for postfix 2018-10-16 22:57:25 +02:00
kaiyou
13e3862ca7 Simplify the docs configuration 2018-10-16 22:55:05 +02:00
kaiyou
8fa80c1589 Support multiple docs versions 2018-10-16 22:52:21 +02:00
Thomas Sänger
f0f5cea5d1 make antivirus-healthcheck more understandable 2018-10-16 22:30:15 +02:00
Thomas Sänger
040c1e529a add healthcheck for antivirus 2018-10-16 22:20:16 +02:00
Thomas Sänger
39272ab05c add healthcheck for http services 2018-10-16 21:38:12 +02:00
kaiyou
e784556330 Fix an edge case with old values containing None for coma separated lists 2018-10-16 20:47:38 +02:00
kaiyou
f647d1a0bc Merge branch 'master' into fix-sender-checks 2018-10-16 20:41:18 +02:00
kaiyou
5ada669f43 Rebase reply startdate on master 2018-10-16 20:38:18 +02:00
mergify[bot]
28a5f8574d Merge pull request #661 from usrpro/feat-sys-log
Option to send front logs to journald or syslog
2018-10-16 18:29:09 +00:00
kaiyou
7de6acad11 Merge pull request #649 from HorayNarea/webmails
reduce webmail image-layers/sizes
2018-10-16 20:21:11 +02:00
mergify[bot]
bee81d1a54 Merge pull request #647 from HorayNarea/bcrypt
support bcrypt and use it as default
2018-10-16 17:50:44 +00:00
Ionut Filip
b9ecc0ccc6 Added minor changes 2018-10-16 18:03:59 +03:00
mergify[bot]
eacf27452e Merge pull request #660 from usrpro/update-dev-docs
Update Dev-docs to use build.yml for building
2018-10-16 13:49:42 +00:00
mergify[bot]
7bccfa69a8 Merge pull request #652 from usrpro/improve-docs
Some documentation flow refactoring and updates
2018-10-16 13:47:30 +00:00
Ionut Filip
e8dee22ecf Added vars and fixed naming use 2018-10-16 16:12:42 +03:00
Tim Möhlmann
f3ebf35c75 Fix autotest 2018-10-16 12:56:12 +03:00
Tim Möhlmann
acbb586e71 Option to send logs to journald or syslog 2018-10-16 12:38:17 +03:00
Ionut Filip
0d164486b4 docker-compose variables and setup 2018-10-16 12:34:55 +03:00
Tim Möhlmann
11a8e49f05 Compose file upgrade and define more variables for setup 2018-10-16 11:09:42 +03:00
mergify[bot]
9fd7851cb6 Merge pull request #648 from HorayNarea/apk-no-cache
remove apk-warning about cache
2018-10-16 06:35:09 +00:00
kaiyou
15eb2806bf Merge branch 'master' into feat-reply-startdate 2018-10-15 22:10:08 +02:00
kaiyou
5035975c41 Remove Postfix debugging 2018-10-15 22:07:38 +02:00
kaiyou
c6846fd8db Merge branch 'master' into feat-reply-startdate 2018-10-15 21:52:06 +02:00
Tim Möhlmann
b38deb18cf Update Dev-docs to use build.yml for building 2018-10-15 19:37:24 +03:00
Tim Möhlmann
3f7e7ca3a6 Use defaults in variables, to allow for local builds 2018-10-15 19:36:37 +03:00
Tim Möhlmann
1394955447 FAQ about TLS issues 2018-10-13 21:13:09 +03:00
Tim Möhlmann
b5693edc63 Include a doc section for external certbot 2018-10-13 20:59:14 +03:00
Tim Möhlmann
f4ef0eed09 Wrote informational section of the FAQ 2018-10-12 20:48:44 +03:00
Tim Möhlmann
70c4e42f74 Fix small typo 2018-10-11 18:33:58 +03:00
Tim Möhlmann
77e3fc0ebc Some documentation flow refactoring and updates:
- Improve advice on IP binding; Follow up on issue #641
 - mailradar is dead. Found mxtoolbox instead
 - Fix some internal linking
2018-10-11 18:14:37 +03:00
mergify[bot]
a91a54b5f1 Merge pull request #651 from usrpro/fix-certbot
Front: move to Alpine:3.8 and fixing #522
2018-10-11 14:15:04 +00:00
mergify[bot]
1a04c13da8 Merge pull request #650 from HorayNarea/pin-alpine
pin alpine-version for 'none'-image
2018-10-11 12:08:26 +00:00
Tim Möhlmann
de43060ef8 Move to Alpine:3.8 and fixing #522 2018-10-11 14:06:26 +03:00
Thomas Sänger
bdfcc5b530 pin alpine-version for 'none'-image 2018-10-11 03:20:19 +02:00
Thomas Sänger
f2259c3302 reduce webmail image-layers/sizes 2018-10-11 03:18:49 +02:00
Thomas Sänger
6aafef88bd remove apk-warning about cache 2018-10-11 02:57:13 +02:00
mergify[bot]
39f58c03ff Merge pull request #644 from usrpro/fix-alpine-38
Move to alpine:3.8. Fixes #625 and #627
2018-10-10 22:08:22 +00:00
mergify[bot]
6c3c64f873 Merge pull request #646 from gitting/patch-2
Add newline for list to display properly
2018-10-10 17:39:44 +00:00
Thomas Sänger
c8b39c5d4a support bcrypt and use it as default 2018-10-10 19:29:23 +02:00
gitting
3541b7cc63 Add newline for list to display properly 2018-10-10 08:09:55 -07:00
mergify[bot]
eb4cbc0f81 Merge pull request #642 from HorayNarea/update-php
use PHP 7.2 for rainloop
2018-10-10 13:48:44 +00:00
mergify[bot]
4641ae6d2b Merge pull request #612 from Mailu/feat-abstract-db
Abstract db access from Postfix and Dovecot
2018-10-10 13:45:15 +00:00
Tim Möhlmann
2c7a5a97e4 Move to alpine:3.8. Fixes #625 and #627 2018-10-10 14:28:26 +03:00
kaiyou
10ec2f999a Another (embarrassing) fix for a merge typo 2018-10-10 11:39:41 +02:00
kaiyou
2e1aa079c1 Fix one (hopefully) last merge typo 2018-10-10 11:24:51 +02:00
kaiyou
4b9dbf00a8 Fix yet another merge-time typo 2018-10-10 09:51:50 +02:00
kaiyou
e8e133b53d Fix a merge typo in postfix build 2018-10-10 08:54:57 +02:00
kaiyou
00b5ae11db Merge branch 'master' into feat-abstract-db 2018-10-10 08:41:56 +02:00
Thomas Sänger
2f7b6e14c0 use PHP 7.2 for rainloop 2018-10-09 23:21:32 +02:00
Tim Möhlmann
cde22be4c9 Some cleanup and changes:
- Don't upgrade the docker-compose file. (Not in the scope of this feature)
- No need to use aliases. Docker already resolves to service names
- Use a fixed IP range, which stays clear of the network ranges used by Docker. (172.xx.0.0/16)
2018-10-09 14:50:09 +03:00
Tim Möhlmann
013d02d726 Add unbound to the build directive 2018-10-09 14:11:59 +03:00
mergify[bot]
5180ce527c Merge pull request #637 from usrpro/fix-rainloop-permissions
Fix rainloop permissions
2018-10-09 09:57:51 +00:00
Tim Möhlmann
ada09f7922 Unbound: Use alpine:3.8 2018-10-09 12:35:08 +03:00
ofthesun9
6bd365e771 Change title layout 2018-10-08 21:00:44 +00:00
ofthesun9
afba7b9c11 Merge branch 'master' into feature-swarm 2018-10-08 20:44:31 +00:00
ofthesun9
bd0a7050f2 Merge branch 'master' into feat-fuzzyhashes 2018-10-08 20:43:16 +00:00
ofthesun9
9d610f56f7 Added some lines around ingress mode 2018-10-08 18:53:44 +00:00
Ionut Filip
29e4ca0768 Changed command placement 2018-10-08 16:47:10 +03:00
Ionut Filip
d59d6b0d0d Added chwon command 2018-10-08 16:35:09 +03:00
Tim Möhlmann
676c408f06 Merge remote-tracking branch 'obi/feature/dns-resolver' into feat-unbound-dns 2018-10-08 12:36:01 +03:00
mergify[bot]
c9ae89e350 Merge pull request #628 from usrpro/feat-test-suite-v2
Feat test suite v2
2018-10-07 18:00:19 +00:00
ofthesun9
1f71d10899 Change POD_ADDRESS_RANGE introduction like it is done on deovecot-sql.conf.ext 2018-10-07 16:46:42 +00:00
ofthesun9
13146be57e Merge branch 'master' into feature-swarm 2018-10-07 16:42:25 +00:00
ofthesun9
6b34b2728e Declare fuzzy_worker port 11335 in EXPOSE section 2018-10-07 16:38:41 +00:00
ofthesun9
fdda813163 Merge branch 'feat-fuzzyhashes' of https://github.com/ofthesun9/Mailu into feat-fuzzyhashes 2018-10-07 16:34:33 +00:00
ofthesun9
0eb963eb21 Merge branch 'master' into feat-fuzzyhashes 2018-10-07 16:31:26 +00:00
mergify[bot]
c1834d3500 Merge pull request #560 from usrpro/fix-swarm-start
Fix start.py for Swarm mode
2018-10-07 16:22:17 +00:00
kaiyou
508e519a34 Refactor the postfix views and implement sender checks 2018-10-07 16:24:48 +02:00
kaiyou
8b189ed145 Separate senderaccess and senderlogin maps 2018-10-07 16:23:53 +02:00
Tim Möhlmann
c316c040c5 Use travis_wait for sleep 2018-10-07 14:08:45 +03:00
ofthesun9
74796201ec Merge branch 'master' into feature-swarm 2018-10-07 08:00:12 +00:00
kaiyou
fc99eb7b34 Re-enable sender access check to prevent source spoofing 2018-10-07 01:52:01 +02:00
kaiyou
f3f0b98755 Fix relay restrictions so email gets delivered correctly 2018-10-07 01:28:22 +02:00
Tim Möhlmann
0817629869 Increase attempts as it failed on fresh Swarm host 2018-10-07 02:10:13 +03:00
Tim Möhlmann
716ed16f34 Fix typo 2018-10-07 01:52:52 +03:00
Tim Möhlmann
16469d7282 Upgrade to newer pip version 2018-10-07 01:40:22 +03:00
Tim Möhlmann
1bae5968ad Import tenacy and fix syntax errors 2018-10-07 01:39:02 +03:00
Tim Möhlmann
c457ccfa60 Use tenacity for resolver retries 2018-10-07 00:32:05 +03:00
Tim Möhlmann
d6c386651d Merge branch 'master' into fix-swarm-start 2018-10-06 23:48:32 +03:00
Tim Möhlmann
1bbb86eab5 Add autobuild for 'setup' 2018-10-06 20:26:39 +03:00
Tim Möhlmann
5716ca933e Fix autodeploy after merge with master 2018-10-06 20:24:54 +03:00
mergify[bot]
011f4e317b Merge pull request #616 from HorayNarea/patch-2
implement support for ARC - fixes #495
2018-10-06 17:12:18 +00:00
Tim Möhlmann
2d886554c8 Merge branch 'master' into feat-test-suite-v2 2018-10-06 20:11:00 +03:00
kaiyou
7a7854bf3f Disable strict checking 2018-10-06 19:09:59 +02:00
kaiyou
afe0c1bf86 Merge branch 'master' into patch-2 2018-10-06 19:07:24 +02:00
mergify[bot]
2b1c94d965 Merge pull request #626 from ofthesun9/feature-smtpd_reject_unlisted_recipient
Add variable to choose whether to bounce or reject email when recipient is unknown. Fixes #583
2018-10-06 17:01:44 +00:00
kaiyou
f430f410f0 Merge branch 'master' into feature-smtpd_reject_unlisted_recipient 2018-10-06 18:56:36 +02:00
Tim Möhlmann
a405d4cc6f Merge branch 'master' into feat-fuzzyhashes 2018-10-06 19:55:40 +03:00
kaiyou
fff802b5bf Merge branch 'master' into feat-test-suite-v2 2018-10-06 18:55:40 +02:00
kaiyou
c135b37b07 Enable mergify 2018-10-06 18:53:49 +02:00
Tim Möhlmann
32224202d6 Merge branch 'master' into feat-test-suite-v2 2018-10-06 18:38:34 +03:00
kaiyou
e8c0f031ac Merge pull request #608 from Mailu/feat-docs-docker
Docs as a Docker image
2018-10-06 17:23:48 +02:00
kaiyou
6a6b3af2d7 Merge branch 'master' into patch-2 2018-10-06 17:21:54 +02:00
kaiyou
9f861a4547 Merge pull request #620 from usrpro/feat-docs-docker
Documentation on running a local docs container
2018-10-06 17:16:13 +02:00
Tim Möhlmann
c09ac713a3 Project name can be ommitted in docker-compose build 2018-10-06 17:36:59 +03:00
Tim Möhlmann
940b88a641 Fix syntax error 2018-10-06 17:31:01 +03:00
Tim Möhlmann
f7d8f20c87 Move DOCKER_ORG default to travis.yml 2018-10-06 17:24:42 +03:00
Tim Möhlmann
a19e11d552 Clean terminal distortion from docker-compose in travis 2018-10-06 17:06:23 +03:00
Tim Möhlmann
7915f2631f DOCKER_UN needs to be non-zero for deploy 2018-10-06 17:04:14 +03:00
Tim Möhlmann
bb6b984610 Exclude fetchmail for the time being. See Mailu/Mailu#412 2018-10-06 16:46:01 +03:00
Tim Möhlmann
bc85dff27e Don't try deploy is DOCKER_UN is not set 2018-10-06 16:43:04 +03:00
Tim Möhlmann
39c159bae9 Make the code a bit more DRY. Put sleep back into main loop 2018-10-06 16:34:57 +03:00
Tim Möhlmann
508796eaab Verbose sleep 2018-10-06 16:25:12 +03:00
Tim Möhlmann
59eb4a5a00 Minor script flow restructure 2018-10-06 16:12:05 +03:00
Tim Möhlmann
42f557ff38 Cleanup containers 2018-10-06 16:03:07 +03:00
Tim Möhlmann
4133bab280 Default to mailu for DOCKER_ORG 2018-10-06 15:52:39 +03:00
Ionut Filip
38db35f1d6 Make docker ps more verbose 2018-10-05 15:04:04 +03:00
Tim Möhlmann
9c266cc8e5 Merge pull request #6 from usrpro/feat-travis-deploy
Tavis-ci to upload images to the Docker hub, after succesfull tests.
2018-10-05 14:42:01 +03:00
Tim Möhlmann
0c73be7c6e Deploy on all branches 2018-10-05 13:02:10 +03:00
Tim Möhlmann
3224a8ecad Further introduction of the DOCKER_ORG variable 2018-10-05 12:52:19 +03:00
Tim Möhlmann
5987703631 Tavis-ci to upload images to the Docker hub, after succesfull tests.
For this to work, the following variables will need to be set at Docker hub:
 - DOCKER_ORG	first part of docker repo name (example: mailu)
 - DOCKER_UN	Docker-hub login username (private)
 - DOCKER_PW	Docker-hub login password (private)
Note that also Docker hub autobuilds will have to be disabled.
2018-10-05 12:18:29 +03:00
Ionut Filip
20f37607bb Added docker ps and logs 2018-10-05 11:55:01 +03:00
ofthesun9
58a83a93e6 Add REJECT_UNLISTED_RECIPIENT variable in .env file 2018-10-04 18:55:56 +00:00
ofthesun9
09d77bc2de Handle the case where the variable REJECT_UNLISTED_RECIPIENT is not set 2018-10-04 18:55:56 +00:00
ofthesun9
cc17962c86 fixes #583 2018-10-04 18:55:56 +00:00
Ionut Filip
71eed72e21 Changed exit condition 2018-10-04 17:58:34 +03:00
Ionut Filip
027b8f36df Added a check for container status 2018-10-04 17:58:34 +03:00
Ionut Filip
bc70be35c2 Added function to check docker containers 2018-10-04 17:58:34 +03:00
Ionut Filip
645a7f3c96 Removed BIND_ADDRESS6 2018-10-04 17:58:34 +03:00
Ionut Filip
28ebcd5007 Fixed paths to files 2018-10-04 17:58:34 +03:00
Ionut Filip
ebe90fc447 Added run script for travis 2018-10-04 17:58:34 +03:00
Ionut Filip
0067d97f26 Copied docs/compose/.env to tests/compose/core.env 2018-10-04 17:58:34 +03:00
Ionut Filip
5cc5b7c40a Copied docs/compose/docker-compose.yml to tests/compose/run.yml
Edit for test environment
2018-10-04 17:58:34 +03:00
kaiyou
23c8dea27b Merge pull request #623 from usrpro/revert-docs-build
Revert docs build
2018-10-02 18:34:01 +02:00
Hypriot Pirate
12882cfacf Merge branch 'master' into feat-fuzzyhashes 2018-10-01 16:31:45 +00:00
Tim Möhlmann
6479f5177b Revert "Add a Dockerfile for buliding the docs"
This reverts commit f97d0d9e43.
2018-10-01 12:07:49 +03:00
Tim Möhlmann
07af9978e2 Revert "Build the docs during tests"
This reverts commit b287a85124.
2018-10-01 12:06:56 +03:00
Tim Möhlmann
6490a43492 Revert "Attempt to fix the docs build context"
This reverts commit 11bcae4c57.
2018-10-01 12:06:18 +03:00
Tim Möhlmann
73add1b428 Documentation on running a local docs container 2018-10-01 01:47:40 +03:00
Thomas Sänger
76923d80d8 implement support for ARC 2018-09-29 13:03:33 +02:00
kaiyou
4d70a8737e Expose the data volume for admin container 2018-09-28 17:42:10 +02:00
kaiyou
2cba045013 Explicitely declare required volumes, fixes #568 2018-09-28 17:28:46 +02:00
Tim Möhlmann
11bcae4c57 Attempt to fix the docs build context 2018-09-28 17:28:46 +02:00
kaiyou
b287a85124 Build the docs during tests 2018-09-28 17:28:46 +02:00
kaiyou
f97d0d9e43 Add a Dockerfile for buliding the docs 2018-09-28 17:28:46 +02:00
kaiyou
339b3c1b24 Build the documentation as a Docker image 2018-09-28 10:41:17 +02:00
kaiyou
fcad52b145 Implement a start date filter for autoreply, fixes #362 2018-09-27 22:45:16 +02:00
Tim Möhlmann
69c19dca55 Attempt to fix the docs build context 2018-09-27 21:45:06 +03:00
kaiyou
82bb8c2fd9 Merge remote-tracking branch 'github/master' into feat-abstract-db 2018-09-27 17:06:21 +02:00
kaiyou
f5668dea51 Handle relays as virtual transports through podop 2018-09-27 16:30:20 +02:00
kaiyou
9890e1fb2a Fix the dovecot configuration path 2018-09-27 16:13:02 +02:00
kaiyou
42c6bdb4df Split the internal blueprint into multiple view files 2018-09-27 16:09:38 +02:00
kaiyou
dc4b0d21ea Clean the dovecot configuration dir 2018-09-27 16:01:21 +02:00
kaiyou
f9c6c98180 Remove fetchmail dependency to the databse 2018-09-27 15:54:08 +02:00
kaiyou
43b6547e1c Lower the loglevel of podop 2018-09-27 14:53:58 +02:00
kaiyou
542793260b Handle wildcard aliases using podop 2018-09-27 14:53:23 +02:00
kaiyou
0d52364eac Fix alias resolution through podop 2018-09-27 14:38:10 +02:00
kaiyou
6d088504bd Adjust podop debug level based on environment 2018-09-27 14:37:47 +02:00
kaiyou
6ba55ee377 Implement the sieve script name resolution pattern 2018-09-27 14:10:53 +02:00
kaiyou
3c725bf634 Only support generating the default sieve script 2018-09-27 08:18:22 +02:00
kaiyou
ca6c0bc8fd Fix the user sieve script generation 2018-09-27 08:18:03 +02:00
kaiyou
4d25083847 Move sieve script generation to the admin container 2018-09-27 08:11:26 +02:00
kaiyou
cfeaa189f9 Use proper 404 return codes for missing objects 2018-09-27 08:00:31 +02:00
kaiyou
d8365bfbcf Use simpler routes for Dovecot 2018-09-27 07:55:54 +02:00
kaiyou
82140baa69 Add a very simple test script for sending mails 2018-09-27 07:52:43 +02:00
kaiyou
697caaab81 Update podop access and mail restrictions 2018-09-26 00:15:24 +02:00
kaiyou
7143fb8c47 Implement some basic views for podop 2018-09-26 00:15:03 +02:00
kaiyou
39cd0d5034 Upgrade to alpine 3.8 for smtp and imap 2018-09-26 00:14:30 +02:00
kaiyou
68aa797720 Merge branch 'master' into feat-abstract-db 2018-09-25 21:46:12 +02:00
kaiyou
72cfadd5e8 Build the docs during tests 2018-09-25 21:08:04 +02:00
kaiyou
5341ee4472 Add a Dockerfile for buliding the docs 2018-09-25 21:04:30 +02:00
ofthesun9
f5f09fad6e Reverting the patch for dovecot.conf, as it is not needed 2018-09-25 18:54:40 +00:00
kaiyou
e9aa85ad01 Merge pull request #606 from HorayNarea/roundcube
upgrade to PHP 7.2 and remove unused dependencies
2018-09-25 20:34:26 +02:00
kaiyou
f3a8f47b0a Merge pull request #607 from HorayNarea/patch-1
bind to any protocol
2018-09-25 18:19:15 +02:00
Thomas Sänger
cbaac01790 remove unused dependencies 2018-09-25 07:38:49 +02:00
Thomas Sänger
0b885548ab bind to any protocol 2018-09-25 06:29:53 +02:00
Thomas Sänger
a684739b9c update to PHP 7.2 and remove mcrypt
removed mcrypt because Rouncube uses openssl exclusively since version 1.2 and mcrypt was removed from PHP 7.2
2018-09-25 05:59:31 +02:00
kaiyou
73ca5fb3d3 Provide a more generic skeletton for postfix virtual lookups 2018-09-24 23:19:06 +02:00
ofthesun9
23e288aadc Enabling swarm deployment on master branch:
-Extends the usage of POD_ADDRESS_RANGE
-Provides documentation
2018-09-24 17:29:31 +00:00
kaiyou
91349d62ee Merge pull request #602 from usrpro/feat-test-suite
Travis-CI automated test build
2018-09-24 08:19:05 +02:00
Tim Möhlmann
f5f8d1d84b Test-building using travis-ci 2018-09-24 02:23:07 +03:00
kaiyou
f9ef126e03 Merge pull request #597 from HorayNarea/patch-1
use safer cipher in roundcube
2018-09-19 09:00:29 +02:00
kaiyou
5dc9ee9516 Merge pull request #510 from hoellen/spam-trash-fix
Dont flag spam as ham if moved to trash
2018-09-19 08:50:52 +02:00
Thomas Sänger
89c55ba8fe use safer cipher in roundcube
"Default is set for backward compatibility to DES-EDE3-CBC,
but you can choose e.g. AES-256-CBC which we consider a better choice."

https://github.com/roundcube/roundcubemail/blob/master/config/defaults.inc.php#L512
2018-09-19 01:36:22 +02:00
kaiyou
d917f60352 Merge pull request #553 from HorayNarea/compress
add optional Maildir-Compression
2018-09-16 20:00:32 +02:00
kaiyou
64269e08c0 Merge pull request #552 from HorayNarea/master
add full-text search support
2018-09-16 19:59:28 +02:00
kaiyou
313b79538e Merge pull request #513 from mprihoda/feature/better-ratelimit-error
Return correct status codes from auth rate limiter failure.
2018-09-16 19:58:34 +02:00
kaiyou
4b60ee5361 Merge pull request #580 from usrpro/fix-setup-binding
Fix binding in setup utility's gunicorn
2018-09-16 19:57:53 +02:00
kaiyou
482ce3bcd6 Merge pull request #551 from ofthesun9/doc-swarm
Documentation to deploy mailu on a docker swarm. Fixes #530
2018-09-16 19:56:53 +02:00
kaiyou
99914c50fd Merge pull request #581 from usrpro/feat-setup-compose
Add a compose file for mailu/setup
2018-09-16 19:48:26 +02:00
Tim Möhlmann
fe7e32dc82 Make gunicorn bind to port 80 of any available protocol 2018-08-26 21:11:48 +03:00
Tim Möhlmann
6fc51d879b Add docker-compose.yml file for Setup utility 2018-08-26 21:08:20 +03:00
Tim Möhlmann
cc8e15748b Retry 10 times when resolving fails in start.py scripts 2018-08-08 17:54:15 +03:00
Tim Möhlmann
ac62f26dfd Merge branch 'master' of https://github.com/mailu/mailu 2018-08-07 19:24:42 +03:00
Thomas Sänger
0bdb2a16bc add optional Maildir-Compression 2018-08-05 19:48:24 +02:00
Thomas Sänger
fb62e6b5a2 add full-text search support 2018-08-05 18:59:57 +02:00
ofthesun9
935cd7f706 Update README.md 2018-08-04 18:13:08 +02:00
ofthesun9
480fc6c437 Update README.md
Typo
2018-08-04 18:12:41 +02:00
ofthesun9
d13725ce33 Update README.md
Typo
2018-08-04 18:09:18 +02:00
ofthesun9
dc8df56976 Update README.md
Typo
2018-08-04 18:08:07 +02:00
ofthesun9
a6412f3f23 Update README.md 2018-08-04 18:03:50 +02:00
ofthesun9
b3131496c6 Update README.md 2018-08-04 18:00:57 +02:00
ofthesun9
27d43384c5 Documentation to deploy mailu on a docker swarm 2018-08-04 15:58:53 +00:00
ofthesun9
91300c1c5c Update README.md
Typo
2018-08-04 17:48:37 +02:00
ofthesun9
820e5c667b Update README.md
Typo
2018-08-04 17:47:10 +02:00
ofthesun9
8a0ff1153e Documentation to deploy mailu on a docker swarm 2018-08-04 15:44:43 +00:00
ofthesun9
a34090502d Documentation to deploy mailu on a docker swarm 2018-08-04 15:38:25 +00:00
ofthesun9
806dfc804a Typo 2018-08-04 15:33:08 +00:00
ofthesun9
bd6026384a Documentation to deploy mailu on a doxker swarm 2018-08-04 15:27:27 +00:00
kaiyou
f506966abc Pin Alpine 3.7 to preserve the Postfix version 2018-08-03 08:24:06 +02:00
Tim Möhlmann
9350bb9b9a Use fixed alpine:3.7 tag to prevent postix upgrade 2018-08-03 00:18:39 +03:00
Pierre Jaury
3dca1a834c Pin alpine 3.7 until we fix the certbot issue, see #522 2018-08-01 21:56:29 +02:00
Pierre Jaury
18fe8cd9f2 Pin alpine:3.7 for Dovecot since extdata was removed from repos, fixes #528 2018-08-01 21:29:18 +02:00
Pierre Jaury
5ad02ae2e5 Use a more uniform 'Save' for most form submits, fixes #523 2018-08-01 21:24:13 +02:00
kaiyou
b6e4b0e557 Merge pull request #544 from hacor/master
Created new manifests for Kubernetes
2018-08-01 21:13:33 +02:00
kaiyou
d52d01924a Merge pull request #540 from d-fens/patch-1
[Security] Update Roundcube to 1.3.7
2018-08-01 21:09:54 +02:00
kaiyou
8bf8a0328e Merge pull request #514 from mprihoda/hotfix/libpng-dep
Fixed libpng12-dev dependency, called libpng-dev now.
2018-08-01 21:09:14 +02:00
kaiyou
b188c5790c Merge pull request #524 from jake-walker/patch-1
Fix typo
2018-08-01 21:08:42 +02:00
kaiyou
9abee93328 Merge pull request #543 from hoellen/update-rainloop
update rainloop to 1.12.1
2018-08-01 21:07:58 +02:00
hacor
151aeb9c06 Updated adaptations for dovecot on shared filesystem and indexing errors
Signed-off-by: hacor <hacornelis@gmail.com>
2018-08-01 15:45:49 +02:00
hacor
699a25939f Updated docs for Travis
Signed-off-by: hacor <hacornelis@gmail.com>
2018-07-31 17:45:11 +02:00
hacor
db3cb2aac1 Updated docs
Signed-off-by: hacor <hacornelis@gmail.com>
2018-07-31 17:17:21 +02:00
hacor
eb9649db4e Added a new release for Kubernetes
Signed-off-by: hacor <hacornelis@gmail.com>
2018-07-31 17:15:25 +02:00
hoellen
9e24064e35 update rainloop to 1.12.1 2018-07-31 00:07:11 +02:00
d-fens
14a6cfb5c6 [Security] Update Roundcube to 1.3.7
https://github.com/roundcube/roundcubemail/releases/tag/1.3.7
2018-07-28 21:46:33 +01:00
Pierre Jaury
0085b6f1e6 Remove the data mount where unused 2018-07-26 21:58:50 +02:00
Pierre Jaury
c04e58498d Remove unused postfix sqlite files 2018-07-26 21:57:48 +02:00
Pierre Jaury
bb73933e1e Switch postfix to Podop 2018-07-26 21:57:21 +02:00
Pierre Jaury
82e738cc53 Remove the old code of postproxy 2018-07-26 21:45:33 +02:00
Pierre Jaury
b5d6b93869 Switch to using Podop in Dovecot 2018-07-26 21:41:11 +02:00
Pierre Jaury
809fe78f82 Add dovecot views to the internal API 2018-07-26 21:40:44 +02:00
Pierre Jaury
28001213d4 Remove the redis-based quota code 2018-07-26 21:39:30 +02:00
Pierre Jaury
76617a3c97 Store the quota status in database 2018-07-26 21:38:21 +02:00
Pierre Jaury
2b2ab864d1 Add support for querying the table in Dovecot proxy 2018-07-15 15:35:35 +02:00
Pierre Jaury
70175f8c28 Add postproxy support for Dovecot dict protocol 2018-07-15 15:30:16 +02:00
Jake Walker
109842502a Fix typo 2018-07-13 15:11:40 +01:00
Pierre Jaury
262e82a367 Add a postfix socketmap to http proxy 2018-07-03 20:13:00 +02:00
Michal Prihoda
147a1359cd Fixed libpng12-dev dependency, called libpng-dev now. 2018-07-02 21:43:25 +02:00
Michal Prihoda
f5e7751835 Return correct status codes from auth rate limiter failure. 2018-07-02 21:41:40 +02:00
hoellen
ca26264d01 Dont flag spam as ham if moved to trash (fix #474) 2018-06-29 13:47:55 +02:00
kaiyou
75a1bf967c Merge pull request #502 from hoellen/webmail-messagesize
Use message_size_limit variable from env for webmail client_max_body_size
2018-06-28 21:29:30 +02:00
hoellen
c51e1b9eef webmail client_max_body_size with message_size_limit and 8M tolerance 2018-06-28 19:23:08 +02:00
kaiyou
77aac02b43 Merge pull request #509 from reallinfo/master
logo added & readme updated.
2018-06-28 16:32:17 +02:00
reallinfo
0b513768fb Update README.md 2018-06-28 17:29:52 +03:00
reallinfo
6478400cba Add files via upload 2018-06-28 17:28:37 +03:00
kaiyou
74b72375cb Merge pull request #493 from MFAshby/user_validation
Made User and UserSignup validation consistent for the local part of
2018-06-28 14:16:01 +02:00
kaiyou
53bf6085dc Merge pull request #501 from hoellen/webmail-root
Add posibilty to run webmail on root '/'
2018-06-28 14:13:40 +02:00
kaiyou
0a6632de4e Merge pull request #505 from hoellen/admin-hide-header
Hide administration header in sidebar for normal users.
2018-06-28 14:12:51 +02:00
kaiyou
8ec31df139 Merge pull request #507 from mildred/parametrize-hosts
roundcube: fix host parametrization
2018-06-28 14:11:22 +02:00
Mildred Ki'Lya
b7ece9f9b8 roundcube: fix host parametrization
Roundcube can be parametrized so it can take a different hostname than
'front' or 'imap' to connect to the mail servers through environment
variables. Unfortunately, this was not correct and in PHP a `||`
operator always returns a boolean. It did not work as expected.

Instead use the ternary operator `:?` that works in all cases.
2018-06-27 16:40:04 +00:00
hoellen
9091e54fda Hide administration header in sidebar for normal users. 2018-06-25 21:35:40 +02:00
hoellen
81a6a7cbf6 Use message_size variable from env for webmail 2018-06-25 15:51:20 +02:00
hoellen
a1fb8442e3 Add posibilty to run webmail on root '/' 2018-06-25 15:45:43 +02:00
mfashby
0284b6a8e9 Made User and UserSignup validation consistent for the local part of the email address 2018-06-10 15:15:36 +00:00
ofthesun9
12294a6e5a Trying to enable fuzzy hashes for rspamd 2018-06-10 06:16:40 +00:00
Pierre Jaury
50f2ea66c8 Switch to Python for rainloop startup script and fix #93 2018-06-04 21:41:18 +02:00
Pierre Jaury
14687d09ba Fix announcements for idna domains 2018-06-02 10:59:57 +02:00
Pierre Jaury
e543477c2e Revert "Only enable milter for incoming emails"
This reverts commit cfd233039e.
2018-06-02 10:38:08 +02:00
Pierre Jaury
cfd233039e Only enable milter for incoming emails 2018-06-02 10:33:58 +02:00
kaiyou
069fe195e0 Merge pull request #484 from ofthesun9/master
Consistency for nginx.pid path
2018-06-02 10:25:05 +02:00
Pierre Jaury
6828231c28 Fix the path of the nginx pid in startup scripts, fixes #483 2018-06-02 10:23:33 +02:00
Pierre Jaury
1b0b3a2b1e Only check login mismatch for authenticated users, fixes #309 2018-06-02 10:22:15 +02:00
ofthesun9
9de58279a5 Update start.py
replace /var/log/nginx.pid with /var/run/nginx.pid to ensure consistency with core/nginx/conf/nginx.conf
2018-06-02 07:04:14 +02:00
ofthesun9
c6095cd72e Update config.py
replace /var/log/nginx.pid with /var/run/nginx.pid to ensure consistency with core/nginx/conf/nginx.conf
2018-06-02 07:03:16 +02:00
Pierre Jaury
52d89b2f5d Fix rspamd behavior, currently failing due to worker-fuzzy 2018-06-01 20:18:36 +02:00
Pierre Jaury
1371ba5f5e Add the keep field to fetch forms, fixes #479 2018-05-30 00:40:50 +02:00
Pierre Jaury
ea658a174d Fix a typo in the base html template 2018-05-30 00:37:34 +02:00
Pierre Jaury
b6c76a5e39 Do not remove openssl when purging build deps, fixes #481 2018-05-30 00:28:44 +02:00
kaiyou
a47ba3474c Merge pull request #448 from romracer/pod-address
Use POD_ADDRESS_RANGE for Dovecot if it exists
2018-05-28 23:19:06 +02:00
kaiyou
3beceb90ec Merge pull request #429 from mildred/parametrize-hosts
Add various environment variables to allow running outside of docker-compose
2018-05-28 23:09:08 +02:00
kaiyou
a9e41960a1 Merge pull request #468 from dtwardow/flex_tls_filenames
TLS using configurable filenames
2018-05-28 23:00:14 +02:00
kaiyou
91e51a24c8 Merge pull request #465 from sanduhrs/feature/463
Remove services status page
2018-05-28 22:57:43 +02:00
kaiyou
ebdfcbd18e Merge pull request #476 from benlemasurier/benlemasurier-patch-1
Fixes typo in README.md
2018-05-28 22:55:28 +02:00
kaiyou
efec26d0af Merge pull request #469 from hoellen/master
update RainLoop to 1.12.0
2018-05-28 22:54:57 +02:00
kaiyou
b25325912a Merge pull request #477 from HorayNarea/master
don't require BootstrapCDN for FontAwesome (GDPR-compliance)
2018-05-28 22:54:21 +02:00
Thomas Sänger
7d661ab80d don't require BootstrapCDN for FontAwesome (GDPR-compliance) 2018-05-22 03:33:27 +02:00
Ben LeMasurier
2d4e769a25 Fixes typo in README.md 2018-05-14 16:00:28 -06:00
Mildred Ki'Lya
6bb4c6e2f0 Parametrize front address from dovecot 2018-05-08 20:42:07 +01:00
Mildred Ki'Lya
ae8c9f5a6b Add various environment variables to allow running outside of docker-compose 2018-05-08 20:41:02 +01:00
Roman Hoellen
f353b2d9ae update RainLoop to 1.12.0 2018-05-01 18:55:42 +02:00
Dennis Twardowsky
8f5036e769 Update documentation for TLS flexible filenames support 2018-05-01 14:58:57 +02:00
Dennis Twardowsky
50f9f379e9 Flexible filenames for TLS via envvars (flavours 'cert' and 'mail' only) 2018-05-01 14:04:18 +02:00
Stefan Auditor
6177571e4d Remove services status localization 2018-04-23 18:59:46 +02:00
Stefan Auditor
b541d4c257 Remove services status sidebar link 2018-04-23 18:56:48 +02:00
Stefan Auditor
e89b32a3f4 Remove services route 2018-04-23 18:55:37 +02:00
Stefan Auditor
ec8e82aaca Remove services status template 2018-04-23 18:55:13 +02:00
kaiyou
d4cc142f64 Rename the config dir to setup 2018-04-22 16:12:13 +02:00
kaiyou
f5538698d3 Rename the config dir to setup 2018-04-22 16:10:25 +02:00
kaiyou
40720fb3ea Rename the mailu setup app 2018-04-22 16:10:11 +02:00
kaiyou
5502297fce Add the most important steps 2018-04-22 16:09:26 +02:00
kaiyou
f70acfe893 Factor some generic bits in the base template 2018-04-22 16:09:07 +02:00
kaiyou
dd8b0dba54 Allow selecting version 2018-04-22 16:08:43 +02:00
kaiyou
987cfde91f Disable gitsplit 2018-04-22 12:20:45 +02:00
kaiyou
f55e5e26cd Update messages.po (POEditor.com) 2018-04-22 12:19:35 +02:00
kaiyou
2b96abbef4 Update messages.po (POEditor.com) 2018-04-22 12:15:40 +02:00
kaiyou
af38d5ab0c Update messages.po (POEditor.com) 2018-04-22 12:15:38 +02:00
kaiyou
fc89b30e8a Update messages.po (POEditor.com) 2018-04-22 12:15:36 +02:00
kaiyou
791fab688a Update messages.po (POEditor.com) 2018-04-22 12:15:33 +02:00
kaiyou
c9b0832899 Update messages.po (POEditor.com) 2018-04-22 12:15:31 +02:00
kaiyou
fa1b0ac32c Update messages.po (POEditor.com) 2018-04-22 12:15:28 +02:00
kaiyou
75f0791965 Update messages.po (POEditor.com) 2018-04-22 12:15:26 +02:00
kaiyou
c91c5c7493 Update messages.po (POEditor.com) 2018-04-22 12:15:24 +02:00
kaiyou
299a654e97 Update messages.po (POEditor.com) 2018-04-22 12:15:22 +02:00
kaiyou
494e52d8f0 Update messages.po (POEditor.com) 2018-04-22 12:15:20 +02:00
kaiyou
3b7014d563 Add dummy spanish and russion languages 2018-04-22 12:13:25 +02:00
kaiyou
be0a0b4ac8 Update translation strings 2018-04-22 12:10:39 +02:00
kaiyou
9ec3d3673e Convert the config uid to a string 2018-04-22 12:06:00 +02:00
kaiyou
002198d3d3 Build a Dockerfile 2018-04-22 12:02:59 +02:00
kaiyou
b18a1d5217 Provide a function to generate secrets 2018-04-22 11:54:10 +02:00
kaiyou
08e95c08ca Add a way to get a dev environment 2018-04-22 11:53:40 +02:00
kaiyou
5a9f01d473 Provide some first configuration items 2018-04-22 11:53:18 +02:00
kaiyou
8efc51bc29 Finish writing the framework for the config manager 2018-04-22 11:04:11 +02:00
kaiyou
8bad30cd59 Move the domain MX status to the detail page 2018-04-22 10:15:09 +02:00
kaiyou
7f0447514c Finish storing the user quota to redis 2018-04-21 17:19:44 +02:00
kaiyou
80893be68b Add a missing import to dnspython 2018-04-21 16:37:30 +02:00
kaiyou
091369915b Display the user quota in the admin interface 2018-04-21 15:48:07 +02:00
kaiyou
e13593f29a Switch to database 2 for rate limiting 2018-04-21 15:07:04 +02:00
kaiyou
d1dbba2d3a Add expose instructions in Dockerfiles, fixes #392 2018-04-21 14:46:01 +02:00
kaiyou
62d1a0c104 Add a status field to the domain list 2018-04-21 13:56:20 +02:00
kaiyou
bb0d7bf6dc Enforce the nocase collation on the email table 2018-04-21 13:25:48 +02:00
kaiyou
186c30d2ac Have the admin listen on ipv6 2018-04-21 12:55:14 +02:00
kaiyou
35276c3101 Merge pull request #458 from Farthen/master
Dovecot: Add SQL iterate_query to config file.
2018-04-21 11:48:22 +02:00
kaiyou
dfaedb76f1 Merge pull request #447 from sanduhrs/feature/446
Add a sqlalchemy custom type for unicode to idna conversion of domain names
2018-04-21 11:46:43 +02:00
kaiyou
5a4b0a18ef Try to fix the Travis build 2018-04-21 11:39:38 +02:00
farthen
f75280e4a3 Dovecot: Add SQL iterate_query to config file.
This allows to use doveadm -A to execute maintenance tasks for all users on the server
2018-04-19 00:44:50 +02:00
kaiyou
a03d884ccc Add the domain registration option in .env 2018-04-18 20:34:21 +02:00
kaiyou
9968d708f1 Update the prod requirements 2018-04-18 20:34:21 +02:00
kaiyou
381e76511d Add self-service domain registration 2018-04-18 20:34:21 +02:00
Stefan Auditor
c688970b32 Respect user enabled flag in admin authentication 2018-04-16 08:57:35 +02:00
Scott
49b17d31be [Security] Update Roundcube to 1.3.6
Fixes a security issue in roundcube.  May also fix the last comment in #391.
2018-04-16 08:57:35 +02:00
Stefan Auditor
d3064579f4 Respect user enabled flag in basic authentication 2018-04-16 08:57:35 +02:00
Stefan Auditor
92f4858323 Respect user.enabled status in internal authentication 2018-04-16 08:57:35 +02:00
Stefan Auditor
d2c6cecca6 Remove is_enabled method and use the enabled attribute instead 2018-04-16 08:57:35 +02:00
Stefan Auditor
5bfdd75738 Respect user enabled flag on user.login 2018-04-16 08:57:35 +02:00
Stefan Auditor
78f4fa7db9 Add field to ui for user enabled flag 2018-04-16 08:57:35 +02:00
Stefan Auditor
20d6fbae48 Add enabled flag to user model 2018-04-16 08:57:35 +02:00
Scott
2c2a1ed042 Remove stale link to old auto-forward settings. Fixes #450
Also update a reference to 'smtp' to use HOST_AUTHSMTP
2018-04-16 08:57:35 +02:00
Vados
1e609acbaf Remove ports option completely
Not needed since `hostNetwork: true`
2018-04-16 08:57:35 +02:00
Vados
3aaecca989 Update NGINX Ingress controller configuration 2018-04-16 08:57:35 +02:00
kaiyou
1c26c9e376 Merge pull request #409 from t3hmrman/patch-1
Update NGINX Ingress controller configuration
2018-04-16 08:23:59 +02:00
kaiyou
a51416a4af Merge pull request #452 from sanduhrs/feature/449
Add enabled flag to user model
2018-04-15 23:15:20 +02:00
Stefan Auditor
e843f7ef1f Respect user enabled flag in admin authentication 2018-04-15 19:53:24 +02:00
kaiyou
d333acabea Merge pull request #453 from romracer/roundcube-1.3.6
[Security] Update Roundcube to 1.3.6
2018-04-15 17:32:58 +02:00
Scott
386a02588b [Security] Update Roundcube to 1.3.6
Fixes a security issue in roundcube.  May also fix the last comment in #391.
2018-04-15 08:04:54 -05:00
Stefan Auditor
c8540ddba7 Respect user enabled flag in basic authentication 2018-04-15 14:02:15 +02:00
Stefan Auditor
6fc22e5432 Respect user.enabled status in internal authentication 2018-04-15 13:43:30 +02:00
Stefan Auditor
733b89bff5 Remove is_enabled method and use the enabled attribute instead 2018-04-15 13:42:19 +02:00
kaiyou
bc17171c02 Merge pull request #451 from romracer/fix-450
Remove stale link to old auto-forward settings. Fixes #450
2018-04-15 13:40:40 +02:00
Stefan Auditor
3b66fcada7 Respect user enabled flag on user.login 2018-04-15 13:00:38 +02:00
Stefan Auditor
7139a27bf1 Add field to ui for user enabled flag 2018-04-15 11:35:37 +02:00
Stefan Auditor
f585197e52 Add enabled flag to user model 2018-04-15 11:23:58 +02:00
Scott
e5c25c395f Remove stale link to old auto-forward settings. Fixes #450
Also update a reference to 'smtp' to use HOST_AUTHSMTP
2018-04-14 16:48:08 -05:00
Stefan Auditor
7f5bd98a2e Add parameters to database field 2018-04-14 13:02:00 +02:00
Stefan Auditor
93d5254b3f Add another type decorator for idna email support 2018-04-14 13:00:29 +02:00
Scott
6018995534 Use POD_ADDRESS_RANGE for Dovecot if it exists
This is required to override allow_nets in a Kubernetes environment where pods are not recreated with the same IP address.
2018-04-13 20:04:49 -05:00
Stefan Auditor
792c720c13 Save user email domain_name as idna representation 2018-04-13 08:13:26 +02:00
Stefan Auditor
c40e255f3b Reset relay columns to string 2018-04-12 22:21:28 +02:00
Stefan Auditor
d9ea64fac7 Import idna library and move code a bit upwards 2018-04-12 21:35:38 +02:00
Stefan Auditor
5a7272ff12 Replace other occurences of domain names with idna 2018-04-12 20:30:19 +02:00
Stefan Auditor
1b666cd25b Add a sqlalchemy custom type for unicode to idna conersion of domain names 2018-04-12 19:07:48 +02:00
kaiyou
db0cd8efb4 Fix the client setup page when not logged in 2018-04-11 22:45:04 +02:00
kaiyou
ea8aced2e6 Merge pull request #434 from steamedhams1/patch-1
Update .env
2018-04-11 21:53:52 +02:00
kaiyou
e92113bd57 Merge pull request #433 from mildred/delivered-to-hdr
Add original Delivered-To header to received messages
2018-04-11 21:53:30 +02:00
kaiyou
b4134b7774 Add a client setup page, fixes #342 2018-04-11 21:45:17 +02:00
kaiyou
fa0bda7b69 Merge the auto-forward and antispam settings 2018-04-11 21:28:36 +02:00
kaiyou
3ef4e1f6b7 Add support for recaptcha upon signup 2018-04-11 21:08:59 +02:00
kaiyou
e02e47c48e Merge pull request #416 from calebj/patch-1
Add support for sending from alternative domains
2018-04-11 20:37:23 +02:00
kaiyou
d23becb910 Disable esld when signing with dkim, fixes #435 2018-04-11 20:35:31 +02:00
kaiyou
8504b78c76 Merge pull request #437 from romracer/fix-436
Use HOST_ADMIN in "Forwarding authentication server".  Fixes #436.
2018-04-10 09:18:17 +02:00
Scott
b9e67635f4 Use HOST_ADMIN in "Forwarding authentication server". Fixes #436. 2018-04-07 12:40:32 -05:00
steamedhams1
46cd86e66a Update .env
Fixed typo
2018-04-04 02:21:37 -07:00
Mildred Ki'Lya
649a4fc9cf Add Delivered-To header to received messages
Postfix, after expanding the alias, is not transmitting the original
envelope recipient email address to dovecot and cannot record it in a
Received: header.

The LMTP DSN extension allows postfix to specify an ORCPT= parameter to
the "RCPT TO:" line (in postfix src/smtp/smtp_proto.c). However, dovecot
does not support the DNS extension on the LMTP endpoint. It has
preliminary support of the ORCPT parameter in latest versions but is is
disabled and not working.

The solution taken was to add a sieve script to parse the Received:
header written by postfix and parse the original RCPT TO address from
it. Then add the header through the "editheader" sieve extension. Later
sieve scripts can take this header to perform further filtering.
2018-04-03 22:19:13 +01:00
kaiyou
52bad80af8 Add a link to MFAshby's fork 2018-03-21 22:49:59 +01:00
kaiyou
d5cfc91fc4 Merge pull request #414 from adi90x/master
Add explicit ssl_protocols in conf
2018-03-21 08:18:54 +01:00
Caleb Johnson
b58dcfb511 Add support for sending from alternative domains
See Mailu/Mailu#415
2018-03-19 17:54:04 -05:00
AdrienM
29a1548532 Add explicit ssl_protocols in conf 2018-03-19 08:36:03 +00:00
kaiyou
bac906ba5b Switch to edge for clamav 2018-03-13 19:32:05 +01:00
Vados
f2c74dd014 Remove ports option completely
Not needed since `hostNetwork: true`
2018-03-13 21:06:53 +09:00
Vados
82ff7c421d Update NGINX Ingress controller configuration 2018-03-13 20:51:36 +09:00
kaiyou
88903bc6f5 Prepare for multi-version setup wizard 2018-03-10 15:25:52 +01:00
kaiyou
90ba755abc Test commit 2018-03-10 15:02:44 +01:00
kaiyou
efaa3058c0 Very first version of the configuration wizard 2018-03-10 14:05:49 +01:00
Patrick Oberdorf
d0f759acca Adding unbound as dns resolver 2018-03-08 15:57:28 +01:00
kaiyou
31b887807a Enable enigma for testing in Roundcube, fixes #391 2018-03-05 21:32:31 +01:00
kaiyou
8903cb1367 Update Roundcube to 1.3.4 2018-03-05 21:25:58 +01:00
Paul Binks
933d3a435d Update setup.rst 2018-03-05 21:22:05 +01:00
kaiyou
a0d7b987ca Remove the reference to stable in the setup docs, fixes #393 2018-03-05 21:19:11 +01:00
Paul Binks
a453df3503 Update cli.rst 2018-03-05 21:17:24 +01:00
Paul Binks
75c103ccc9 Update maintain.rst 2018-03-05 21:17:19 +01:00
Paul Binks
198f145821 Update reverse.rst 2018-03-05 21:17:14 +01:00
Paul Binks
f818936012 Update dns.rst 2018-03-05 21:17:09 +01:00
Paul Binks
dba6bf5ae9 Update index.rst 2018-03-05 21:17:03 +01:00
Paul Binks
3ae2dffb4d Update requirements.rst 2018-03-05 21:16:58 +01:00
kaiyou
eaaef0d0f5 Merge pull request #403 from iBrotNano/master
Added webmail-imap dependency in docker-compose.yml.
2018-03-05 20:47:28 +01:00
kaiyou
df42a2d149 Merge pull request #388 from Sharsie/feat-roundcube-attachments
Fixes the inability to upload attachments from roundcube
2018-03-05 20:41:28 +01:00
Marcel Melzig
e7d838ac2a Added webmail-imap dependency in docker-compose.yml. 2018-03-02 11:23:41 +01:00
Arnie
9dfb2b8f2c Fixes the inability to upload attachments from roundcube #365 2018-02-20 11:37:47 +01:00
kaiyou
dfb5463c94 Relax the frame filtering to allow roundcube to display previews 2018-02-11 22:56:26 +01:00
kaiyou
04278b6cbf Pass the full host to the backend, fixes #372 2018-02-06 18:56:41 +01:00
kaiyou
9e7aa423fd Merge pull request #376 from navossoc/patch-1
Update configuration.rst
2018-02-01 00:40:53 +01:00
Rafael Cossovan
23f392efb2 Update configuration.rst
Fix env variable.
2018-01-31 09:00:53 -02:00
kaiyou
6c56c8e298 Specify the client max body size in the front, related to #371 2018-01-28 10:35:55 +01:00
kaiyou
8cee04dbcc Merge pull request #373 from mildred/master
Add parameters to specify hosts for various containers
2018-01-27 11:26:59 +01:00
Mildred Ki'Lya
f538e33dcf Parametrize hosts
Allows to use mailu without docker-compose when hostnames are not set up
by docker itself but provided via a separate resolver.

Use case: use mailu using nomad scheduler and consul resolver instead of
docker-compose. Other servers are provided by the DNS resolver that
resolves names like admin.service.consul or webmail.service.consul.
These names needs to be configurable.
2018-01-24 22:54:41 +01:00
kaiyou
d8ebfbe020 Display infinite user quotas correctly, fixes #368 2018-01-16 20:03:07 +01:00
kaiyou
7c2b4be954 Merge pull request #358 from SunMar/master
Adding options for when using reverse proxy (real ip header / from and mail-letsencrypt)
2018-01-16 19:49:14 +01:00
SunMar
6ec0fe7036 Adding options for mail-letsencrypt 2018-01-04 16:23:28 +01:00
kaiyou
34d88144b2 Set the temp directory for Roundcube, related to #365 2017-12-19 19:50:38 +01:00
kaiyou
d98f16333a Display an infinite quota when necessary for users, fixes #345 2017-12-17 15:13:47 +01:00
kaiyou
8d224824ea Display a conditional button for generation dkim keys, fixes #346 2017-12-17 15:11:08 +01:00
kaiyou
d0b8de72e4 Do not deny HTTP access upon TLS error when the flavor is mail 2017-12-17 15:09:10 +01:00
kaiyou
bfc898c2d8 Move dhparam to /conf 2017-12-17 14:47:02 +01:00
Greg Fitzgerald
f1ad2cf4d0 Use a predefined dhparam.pem, This fixes issue #322 2017-12-17 14:47:02 +01:00
kaiyou
7a9d2c9725 Merge pull request #353 from ripkens/patch-1
Added adress verification before accepting mails for delivery
2017-12-17 14:41:28 +01:00
kaiyou
bbef3b651e Roundcube is now using php7, update the htaccess, fixes #366 2017-12-17 14:35:14 +01:00
kaiyou
7f92bfd6b6 Install the php zip extension for roundcube, fixes #364 2017-12-17 14:34:45 +01:00
kaiyou
ca2cc4fc24 Add some details about the development environment 2017-12-06 19:51:14 +01:00
kaiyou
36e2e35ea8 Merge pull request #338 from gregf/fix_roundcube_attachment_size
This sets the max attachment size in roundcube
2017-12-05 19:10:44 +01:00
Greg Fitzgerald
7594226c50 Fix copy/paste failure 2017-12-04 18:49:42 -05:00
kaiyou
acb5d7da38 Use relative redirect for / to the webmail 2017-12-04 22:42:12 +01:00
kaiyou
2dfc91ac4d Use a map for passing x-forwarded-proto along 2017-12-04 22:19:17 +01:00
Marcus Ripkens
7375134474 Update main.cf 2017-12-04 22:04:22 +01:00
Marcus Ripkens
175349a224 Added adress verification before accepting mails for delivery
See https://www.endpoint.com/blog/2015/05/28/postfix-address-verification

Block client until address verifiction is completed and mail will not be rejected by relaying MTA or smarthost.
If verification fails, mail is rejected.
If verification takes too long, mail is temporaryly rejected and sending client will retry later.
2017-12-04 22:02:33 +01:00
kaiyou
42314d3d75 Remove a remaining rebug print() statement 2017-12-04 21:55:40 +01:00
kaiyou
a4f46ced49 Properly use x-forwarded-proto with redirects in the webui, related to #347 2017-12-04 21:16:08 +01:00
kaiyou
48d736feef Configure a resolver for the mail server to populate xclient hostnames 2017-12-04 20:28:54 +01:00
kaiyou
2e4a9e21f8 Merge pull request #351 from rageOS/patch-1
Fix for relayed Domains
2017-12-04 20:14:21 +01:00
rageOS
59766d289e Fix for relayed Domains 2017-12-04 19:57:51 +01:00
kaiyou
319965a4af Add a format check for the email localpart when signing up 2017-12-03 19:37:36 +01:00
kaiyou
18ae6a4a0f Fix the signup quota 2017-12-03 17:53:33 +01:00
kaiyou
e85eada522 Fix the login view when no next page is provided 2017-12-03 17:53:12 +01:00
kaiyou
def0a8b89d Fix the signup domain list with non infinite mailbox max count 2017-12-03 17:52:54 +01:00
kaiyou
2662abedef Enable self-service account signup 2017-12-03 12:01:25 +01:00
kaiyou
3b79e5196a Add a default quota setting for new accounts 2017-12-03 12:01:03 +01:00
kaiyou
6d71fa96ad Add a signup field to domains 2017-12-03 12:00:44 +01:00
kaiyou
4761646616 Make sure stale pid files are dealt with, fix #341 2017-12-03 11:28:26 +01:00
Greg Fitzgerald
bbf0a9a61c This sets the max attachment size in roundcube
I used the php.ini from the rainloop folder, so they are both set to
25MB.
2017-11-30 19:16:11 -05:00
kaiyou
743eb81908 Fix the Webdav behavior with Radicale, related to #334 2017-11-30 22:03:42 +01:00
kaiyou
03d3351496 Set the title of web pages in the docs 2017-11-21 22:37:21 +01:00
kaiyou
328001a417 Merge pull request #329 from HorayNarea/patch-1
Disable ssl_session_tickets, see https://wiki.mozilla.org/Security/Server_Side_TLS#TLS_tickets_.28RFC_5077.29
2017-11-21 22:16:25 +01:00
Thomas Sänger
d61ba8e651 disable ssl_session_tickets 2017-11-15 12:34:00 +01:00
247 changed files with 14062 additions and 2468 deletions

View File

@@ -1,30 +0,0 @@
splits:
- prefix: "admin"
target: "https://${GH_TOKEN}@github.com/Mailu/Admin.git"
- prefix: "clamav"
target: "https://${GH_TOKEN}@github.com/Mailu/ClamAV.git"
- prefix: "dovecot"
target: "https://${GH_TOKEN}@github.com/Mailu/Dovecot.git"
- prefix: "fetchmail"
target: "https://${GH_TOKEN}@github.com/Mailu/Fetchmail.git"
- prefix: "nginx-no-https"
target: "https://${GH_TOKEN}@github.com/Mailu/NGINX-no-HTTPS.git"
- prefix: "nginx"
target: "https://${GH_TOKEN}@github.com/Mailu/NGINX.git"
- prefix: "postfix"
target: "https://${GH_TOKEN}@github.com/Mailu/Postfix.git"
- prefix: "radicale"
target: "https://${GH_TOKEN}@github.com/Mailu/Radicale.git"
- prefix: "rainloop"
target: "https://${GH_TOKEN}@github.com/Mailu/RainLoop.git"
- prefix: "rmilter"
target: "https://${GH_TOKEN}@github.com/Mailu/Rmilter.git"
- prefix: "roundcube"
target: "https://${GH_TOKEN}@github.com/Mailu/Roundcube.git"
- prefix: "rspamd"
target: "https://${GH_TOKEN}@github.com/Mailu/Rspamd.git"
origins:
- ^master$
- ^stable$
- ^v\d+\.\d+\.\d+$

25
.mergify.yml Normal file
View File

@@ -0,0 +1,25 @@
pull_request_rules:
- name: Successful travis and 2 approved reviews
conditions:
- status-success=continuous-integration/travis-ci/pr
- label!=["status"/wip","status/blocked"]
- "#approved-reviews-by>=2"
actions:
merge:
method: merge
strict: true
dismiss_reviews:
approved: true
- name: Trusted author, successful travis and 1 approved review
conditions:
- author~=(kaiyou|muhlemmer|mildred|HorayNarea|adi90x|hoellen|ofthesun9)
- status-success=continuous-integration/travis-ci/pr
- label!=["status"/wip","status/blocked","review/need2"]
- "#approved-reviews-by>=1"
actions:
merge:
method: merge
strict: true
dismiss_reviews:
approved: true

View File

@@ -1,8 +1,37 @@
sudo: required
services: docker
addons:
apt:
packages:
- docker-ce
env:
- MAILU_VERSION=$TRAVIS_BRANCH
language: python
python:
- "3.6"
install:
- pip install -r docs/requirements.txt
- pip install -r tests/requirements.txt
- sudo curl -L https://github.com/docker/compose/releases/download/1.23.0-rc3/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
- sudo chmod +x /usr/local/bin/docker-compose
before_script:
- docker-compose -v
- docker-compose -f tests/build.yml build
- sudo -- sh -c 'mkdir -p /mailu && cp -r tests/certs /mailu && chmod 600 /mailu/certs/*'
script:
- sphinx-versioning build -b -B 1.5 -r 1.5 -w '^[0-9.]*$' -w master -W '^$' docs/ build/
- python docs/conf.py build $DEPLOY_HOST $DEPLOY_USERNAME $DEPLOY_PASSWORD $DEPLOY_REMOTEDIR
# test.py, test name and timeout between start and tests.
- python tests/compose/test.py core 1
- python tests/compose/test.py fetchmail 1
- travis_wait python tests/compose/test.py filters 10
- python tests/compose/test.py rainloop 1
- python tests/compose/test.py roundcube 1
- python tests/compose/test.py webdav 1
deploy:
provider: script
script: bash tests/deploy.sh
on:
all_branches: true
condition: -n $DOCKER_UN

View File

@@ -1,4 +1,5 @@
![Logo](docs/assets/logo.png)
<p align="leftr"><img src="docs/assets/logomark.png" alt="Mailu" height="200px"></p>
Mailu is a simple yet full-featured mail server as a set of Docker images.
It is free software (both as in free beer and as in free speech), open to
@@ -18,7 +19,7 @@ Main features include:
- **Standard email server**, IMAP and IMAP+, SMTP and Submission
- **Advanced email features**, aliases, domain aliases, custom routing
- **Web access**, multiple Webmails and adminitration interface
- **Web access**, multiple Webmails and administration interface
- **User features**, aliases, auto-reply, auto-forward, fetched accounts
- **Admin features**, global admins, announcements, per-domain delegation, quotas
- **Security**, enforced TLS, Letsencrypt!, outgoing DKIM, anti-virus scanner

View File

@@ -1,18 +1,28 @@
FROM python:3-alpine
FROM alpine:3.8
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip \
&& pip3 install --upgrade pip
# Image specific layers under this line
RUN mkdir -p /app
WORKDIR /app
COPY requirements-prod.txt requirements.txt
RUN apk --update add --virtual build-dep openssl-dev libffi-dev python-dev build-base \
&& pip install -r requirements.txt \
&& apk del build-dep
RUN apk add --no-cache openssl curl \
&& apk add --no-cache --virtual build-dep openssl-dev libffi-dev python3-dev build-base \
&& pip3 install -r requirements.txt \
&& apk del --no-cache build-dep
COPY mailu ./mailu
COPY migrations ./migrations
COPY manage.py .
COPY start.sh /start.sh
COPY start.py /start.py
RUN pybabel compile -d mailu/translations
CMD ["/start.sh"]
EXPOSE 80/tcp
VOLUME ["/data","/dkim"]
ENV FLASK_APP mailu
CMD /start.py
HEALTHCHECK CMD curl -f -L http://localhost/ui/login?next=ui.index || exit 1

View File

@@ -1,100 +1,42 @@
import flask
import flask_sqlalchemy
import flask_bootstrap
import flask_login
import flask_script
import flask_migrate
import flask_babel
import flask_limiter
import os
import docker
import socket
import uuid
from mailu import utils, debug, models, manage, configuration
# Create application
def create_app_from_config(config):
""" Create a new application based on the given configuration
"""
app = flask.Flask(__name__)
app.cli.add_command(manage.mailu)
default_config = {
# Specific to the admin UI
'SQLALCHEMY_DATABASE_URI': 'sqlite:////data/main.db',
'SQLALCHEMY_TRACK_MODIFICATIONS': False,
'DOCKER_SOCKET': 'unix:///var/run/docker.sock',
'BABEL_DEFAULT_LOCALE': 'en',
'BABEL_DEFAULT_TIMEZONE': 'UTC',
'BOOTSTRAP_SERVE_LOCAL': True,
'RATELIMIT_STORAGE_URL': 'redis://redis',
'DEBUG': False,
# Statistics management
'INSTANCE_ID_PATH': '/data/instance',
'STATS_ENDPOINT': '0.{}.stats.mailu.io',
# Common configuration variables
'SECRET_KEY': 'changeMe',
'DOMAIN': 'mailu.io',
'HOSTNAMES': 'mail.mailu.io,alternative.mailu.io,yetanother.mailu.io',
'POSTMASTER': 'postmaster',
'TLS_FLAVOR': 'cert',
'AUTH_RATELIMIT': '10/minute;1000/hour',
'DISABLE_STATISTICS': 'False',
# Mail settings
'DMARC_RUA': None,
'DMARC_RUF': None,
'WELCOME': 'False',
'WELCOME_SUBJECT': 'Dummy welcome topic',
'WELCOME_BODY': 'Dummy welcome body',
'DKIM_SELECTOR': 'dkim',
'DKIM_PATH': '/dkim/{domain}.{selector}.key',
# Web settings
'SITENAME': 'Mailu',
'WEBSITE': 'https://mailu.io',
'WEB_ADMIN': '/admin',
'WEB_WEBMAIL': '/webmail',
# Advanced settings
'PASSWORD_SCHEME': 'SHA512-CRYPT',
}
# Bootstrap is used for basic JS and CSS loading
# TODO: remove this and use statically generated assets instead
app.bootstrap = flask_bootstrap.Bootstrap(app)
# Load configuration from the environment if available
for key, value in default_config.items():
app.config[key] = os.environ.get(key, value)
# Initialize application extensions
config.init_app(app)
models.db.init_app(app)
utils.limiter.init_app(app)
utils.babel.init_app(app)
utils.login.init_app(app)
utils.login.user_loader(models.User.get)
utils.proxy.init_app(app)
utils.migrate.init_app(app, models.db)
# Base application
flask_bootstrap.Bootstrap(app)
db = flask_sqlalchemy.SQLAlchemy(app)
migrate = flask_migrate.Migrate(app, db)
limiter = flask_limiter.Limiter(app, key_func=lambda: current_user.username)
# Debugging toolbar
# Initialize debugging tools
if app.config.get("DEBUG"):
import flask_debugtoolbar
toolbar = flask_debugtoolbar.DebugToolbarExtension(app)
# Manager commnad
manager = flask_script.Manager(app)
manager.add_command('db', flask_migrate.MigrateCommand)
# Babel configuration
babel = flask_babel.Babel(app)
translations = list(map(str, babel.list_translations()))
@babel.localeselector
def get_locale():
return flask.request.accept_languages.best_match(translations)
# Login configuration
login_manager = flask_login.LoginManager()
login_manager.init_app(app)
login_manager.login_view = "ui.login"
@login_manager.unauthorized_handler
def handle_needs_login():
return flask.redirect(
flask.url_for('ui.login', next=flask.request.endpoint)
)
debug.toolbar.init_app(app)
# TODO: add a specific configuration variable for profiling
# debug.profiler.init_app(app)
# Inject the default variables in the Jinja parser
# TODO: move this to blueprints when needed
@app.context_processor
def inject_defaults():
signup_domains = models.Domain.query.filter_by(signup_enabled=True).all()
return dict(
current_user=flask_login.current_user,
signup_domains=signup_domains,
config=app.config
)
@@ -103,16 +45,12 @@ from mailu import ui, internal
app.register_blueprint(ui.ui, url_prefix='/ui')
app.register_blueprint(internal.internal, url_prefix='/internal')
# Create the prefix middleware
class PrefixMiddleware(object):
return app
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
prefix = environ.get('HTTP_X_FORWARDED_PREFIX', '')
if prefix:
environ['SCRIPT_NAME'] = prefix
return self.app(environ, start_response)
def create_app():
""" Create a new application based on the config module
"""
config = configuration.ConfigManager()
return create_app_from_config(config)
app.wsgi_app = PrefixMiddleware(app.wsgi_app)

View File

@@ -0,0 +1,91 @@
import os
DEFAULT_CONFIG = {
# Specific to the admin UI
'SQLALCHEMY_DATABASE_URI': 'sqlite:////data/main.db',
'SQLALCHEMY_TRACK_MODIFICATIONS': False,
'DOCKER_SOCKET': 'unix:///var/run/docker.sock',
'BABEL_DEFAULT_LOCALE': 'en',
'BABEL_DEFAULT_TIMEZONE': 'UTC',
'BOOTSTRAP_SERVE_LOCAL': True,
'RATELIMIT_STORAGE_URL': 'redis://redis/2',
'QUOTA_STORAGE_URL': 'redis://redis/1',
'DEBUG': False,
'DOMAIN_REGISTRATION': False,
'TEMPLATES_AUTO_RELOAD': True,
# Statistics management
'INSTANCE_ID_PATH': '/data/instance',
'STATS_ENDPOINT': '0.{}.stats.mailu.io',
# Common configuration variables
'SECRET_KEY': 'changeMe',
'DOMAIN': 'mailu.io',
'HOSTNAMES': 'mail.mailu.io,alternative.mailu.io,yetanother.mailu.io',
'POSTMASTER': 'postmaster',
'TLS_FLAVOR': 'cert',
'AUTH_RATELIMIT': '10/minute;1000/hour',
'DISABLE_STATISTICS': 'False',
# Mail settings
'DMARC_RUA': None,
'DMARC_RUF': None,
'WELCOME': 'False',
'WELCOME_SUBJECT': 'Dummy welcome topic',
'WELCOME_BODY': 'Dummy welcome body',
'DKIM_SELECTOR': 'dkim',
'DKIM_PATH': '/dkim/{domain}.{selector}.key',
'DEFAULT_QUOTA': 1000000000,
# Web settings
'SITENAME': 'Mailu',
'WEBSITE': 'https://mailu.io',
'WEB_ADMIN': '/admin',
'WEB_WEBMAIL': '/webmail',
'RECAPTCHA_PUBLIC_KEY': '',
'RECAPTCHA_PRIVATE_KEY': '',
# Advanced settings
'PASSWORD_SCHEME': 'BLF-CRYPT',
# Host settings
'HOST_IMAP': 'imap',
'HOST_POP3': 'imap',
'HOST_SMTP': 'smtp',
'HOST_WEBMAIL': 'webmail',
'HOST_FRONT': 'front',
'HOST_AUTHSMTP': os.environ.get('HOST_SMTP', 'smtp'),
'SUBNET': '192.168.203.0/24',
'POD_ADDRESS_RANGE': None
}
class ConfigManager(dict):
""" Naive configuration manager that uses environment only
"""
def __init__(self):
self.config = dict()
def init_app(self, app):
self.config.update(app.config)
self.config.update({
key: os.environ.get(key, value)
for key, value in DEFAULT_CONFIG.items()
})
app.config = self
def setdefault(self, key, value):
if key not in self.config:
self.config[key] = value
return self.config[key]
def get(self, *args):
return self.config.get(*args)
def keys(self):
return self.config.keys()
def __getitem__(self, key):
return self.config.get(key)
def __setitem__(self, key, value):
self.config[key] = value
def __contains__(self, key):
return key in self.config

17
core/admin/mailu/debug.py Normal file
View File

@@ -0,0 +1,17 @@
import flask_debugtoolbar
from werkzeug.contrib import profiler as werkzeug_profiler
# Debugging toolbar
toolbar = flask_debugtoolbar.DebugToolbarExtension()
# Profiler
class Profiler(object):
def init_app(self, app):
app.wsgi_app = werkzeug_profiler.ProfilerMiddleware(
app.wsgi_app, restrictions=[30]
)
profiler = Profiler()

View File

@@ -1,26 +0,0 @@
from mailu import app
import docker
import signal
# Connect to the Docker socket
cli = docker.Client(base_url=app.config['DOCKER_SOCKET'])
def get(*names):
result = {}
all_containers = cli.containers(all=True)
for brief in all_containers:
if brief['Image'].startswith('mailu/'):
container = cli.inspect_container(brief['Id'])
container['Image'] = cli.inspect_image(container['Image'])
name = container['Config']['Labels']['com.docker.compose.service']
if not names or name in names:
result[name] = container
return result
def reload(*names):
for name, container in get(*names).items():
cli.kill(container["Id"], signal.SIGHUP.value)

View File

@@ -1,13 +1,25 @@
from mailu import limiter
from flask_limiter import RateLimitExceeded
from mailu import utils
import socket
import flask
internal = flask.Blueprint('internal', __name__)
internal = flask.Blueprint('internal', __name__, template_folder='templates')
@limiter.request_filter
@internal.app_errorhandler(RateLimitExceeded)
def rate_limit_handler(e):
response = flask.Response()
response.headers['Auth-Status'] = 'Authentication rate limit from one source exceeded'
response.headers['Auth-Error-Code'] = '451 4.3.2'
if int(flask.request.headers['Auth-Login-Attempt']) < 10:
response.headers['Auth-Wait'] = '3'
return response
@utils.limiter.request_filter
def whitelist_webmail():
try:
return flask.request.headers["Client-Ip"] ==\
@@ -16,4 +28,4 @@ def whitelist_webmail():
return False
from mailu.internal import views
from mailu.internal.views import *

View File

@@ -1,5 +1,7 @@
from mailu import db, models
from mailu import models
from flask import current_app as app
import re
import socket
import urllib
@@ -50,7 +52,7 @@ def handle_authentication(headers):
status = False
elif protocol == "pop3" and not user.enable_pop:
status = False
if status:
if status and user.enabled:
return {
"Auth-Status": "OK",
"Auth-Server": server,
@@ -73,14 +75,19 @@ def get_status(protocol, status):
status, codes = STATUSES[status]
return status, codes[protocol]
def extract_host_port(host_and_port, default_port):
host, _, port = re.match('^(.*)(:([0-9]*))?$', host_and_port).groups()
return host, int(port) if port else default_port
def get_server(protocol, authenticated=False):
if protocol == "imap":
hostname, port = "imap", 143
hostname, port = extract_host_port(app.config['HOST_IMAP'], 143)
elif protocol == "pop3":
hostname, port = "imap", 110
hostname, port = extract_host_port(app.config['HOST_POP3'], 110)
elif protocol == "smtp":
hostname = "smtp"
port = 10025 if authenticated else 25
if authenticated:
hostname, port = extract_host_port(app.config['HOST_AUTHSMTP'], 10025)
else:
hostname, port = extract_host_port(app.config['HOST_SMTP'], 25)
address = socket.gethostbyname(hostname)
return address, port

View File

@@ -0,0 +1,37 @@
require "variables";
require "vacation";
require "fileinto";
require "envelope";
require "mailbox";
require "imap4flags";
require "regex";
require "relational";
require "date";
require "comparator-i;ascii-numeric";
require "spamtestplus";
require "editheader";
require "index";
if header :index 2 :matches "Received" "from * by * for <*>; *"
{
deleteheader "Delivered-To";
addheader "Delivered-To" "<${3}>";
}
{% if user.spam_enabled %}
if spamtest :percent :value "gt" :comparator "i;ascii-numeric" "{{ user.spam_threshold }}"
{
setflag "\\seen";
fileinto :create "Junk";
stop;
}
{% endif %}
if exists "X-Virus" {
discard;
stop;
}
{% if user.reply_active %}
vacation :days 1 :subject "{{ user.reply_subject }}" "{{ user.reply_body }}";
{% endif %}

View File

@@ -0,0 +1,3 @@
__all__ = [
'auth', 'postfix', 'dovecot', 'fetch'
]

View File

@@ -1,15 +1,15 @@
from mailu import db, models, app, limiter
from mailu import models, utils
from mailu.internal import internal, nginx
from flask import current_app as app
import flask
import flask_login
import base64
import urllib
@internal.route("/auth/email")
@limiter.limit(
app.config["AUTH_RATELIMIT"],
@utils.limiter.limit(
lambda: app.config["AUTH_RATELIMIT"],
lambda: flask.request.headers["Client-Ip"]
)
def nginx_authentication():
@@ -27,7 +27,8 @@ def admin_authentication():
""" Fails if the user is not an authenticated admin.
"""
if (not flask_login.current_user.is_anonymous
and flask_login.current_user.global_admin):
and flask_login.current_user.global_admin
and flask_login.current_user.enabled):
return ""
return flask.abort(403)
@@ -41,7 +42,7 @@ def basic_authentication():
encoded = authorization.replace("Basic ", "")
user_email, password = base64.b64decode(encoded).split(b":")
user = models.User.query.get(user_email.decode("utf8"))
if user and user.check_password(password.decode("utf8")):
if user and user.enabled and user.check_password(password.decode("utf8")):
response = flask.Response()
response.headers["X-User"] = user.email
return response

View File

@@ -0,0 +1,48 @@
from mailu import models
from mailu.internal import internal
from flask import current_app as app
import flask
import socket
import os
@internal.route("/dovecot/passdb/<user_email>")
def dovecot_passdb_dict(user_email):
user = models.User.query.get(user_email) or flask.abort(404)
allow_nets = []
allow_nets.append(app.config["SUBNET"])
if app.config["POD_ADDRESS_RANGE"]:
allow_nets.append(app.config["POD_ADDRESS_RANGE"])
return flask.jsonify({
"password": None,
"nopassword": "Y",
"allow_nets": ",".join(allow_nets)
})
@internal.route("/dovecot/userdb/<user_email>")
def dovecot_userdb_dict(user_email):
user = models.User.query.get(user_email) or flask.abort(404)
return flask.jsonify({
"quota_rule": "*:bytes={}".format(user.quota_bytes)
})
@internal.route("/dovecot/quota/<ns>/<user_email>", methods=["POST"])
def dovecot_quota(ns, user_email):
user = models.User.query.get(user_email) or flask.abort(404)
if ns == "storage":
user.quota_bytes_used = flask.request.get_json()
models.db.session.commit()
return flask.jsonify(None)
@internal.route("/dovecot/sieve/name/<script>/<user_email>")
def dovecot_sieve_name(script, user_email):
return flask.jsonify(script)
@internal.route("/dovecot/sieve/data/default/<user_email>")
def dovecot_sieve_data(user_email):
user = models.User.query.get(user_email) or flask.abort(404)
return flask.jsonify(flask.render_template("default.sieve", user=user))

View File

@@ -0,0 +1,32 @@
from mailu import models
from mailu.internal import internal
import flask
import datetime
@internal.route("/fetch")
def fetch_list():
return flask.jsonify([
{
"id": fetch.id,
"tls": fetch.tls,
"keep": fetch.keep,
"user_email": fetch.user_email,
"protocol": fetch.protocol,
"host": fetch.host,
"port": fetch.port,
"username": fetch.username,
"password": fetch.password
} for fetch in models.Fetch.query.all()
])
@internal.route("/fetch/<fetch_id>", methods=["POST"])
def fetch_done(fetch_id):
fetch = models.Fetch.query.get(fetch_id) or flask.abort(404)
fetch.last_check = datetime.datetime.now()
fetch.error_message = str(flask.request.get_json())
models.db.session.add(fetch)
models.db.session.commit()
return ""

View File

@@ -0,0 +1,53 @@
from mailu import models
from mailu.internal import internal
import flask
@internal.route("/postfix/domain/<domain_name>")
def postfix_mailbox_domain(domain_name):
domain = models.Domain.query.get(domain_name) or \
models.Alternative.query.get(domain_name) or \
flask.abort(404)
return flask.jsonify(domain.name)
@internal.route("/postfix/mailbox/<email>")
def postfix_mailbox_map(email):
user = models.User.query.get(email) or flask.abort(404)
return flask.jsonify(user.email)
@internal.route("/postfix/alias/<alias>")
def postfix_alias_map(alias):
localpart, domain_name = models.Email.resolve_domain(alias)
if localpart is None:
return flask.jsonify(domain_name)
destination = models.Email.resolve_destination(localpart, domain_name)
return flask.jsonify(",".join(destination)) if destination else flask.abort(404)
@internal.route("/postfix/transport/<email>")
def postfix_transport(email):
if email == '*':
return flask.abort(404)
localpart, domain_name = models.Email.resolve_domain(email)
relay = models.Relay.query.get(domain_name) or flask.abort(404)
return flask.jsonify("smtp:[{}]".format(relay.smtp))
@internal.route("/postfix/sender/login/<sender>")
def postfix_sender_login(sender):
localpart, domain_name = models.Email.resolve_domain(sender)
if localpart is None:
return flask.abort(404)
destination = models.Email.resolve_destination(localpart, domain_name, True)
return flask.jsonify(",".join(destination)) if destination else flask.abort(404)
@internal.route("/postfix/sender/access/<sender>")
def postfix_sender_access(sender):
""" Simply reject any sender that pretends to be from a local domain
"""
localpart, domain_name = models.Email.resolve_domain(sender)
return flask.jsonify("REJECT") if models.Domain.query.get(domain_name) else flask.abort(404)

View File

@@ -1,11 +1,26 @@
from mailu import app, manager, db, models
from mailu import models
from flask import current_app as app
from flask import cli as flask_cli
import flask
import os
import socket
import uuid
import click
@manager.command
db = models.db
@click.group()
def mailu(cls=flask_cli.FlaskGroup):
""" Mailu command line
"""
@mailu.command()
@flask_cli.with_appcontext
def advertise():
""" Advertise this server against statistic services.
"""
@@ -23,7 +38,11 @@ def advertise():
pass
@manager.command
@mailu.command()
@click.argument('localpart')
@click.argument('domain_name')
@click.argument('password')
@flask_cli.with_appcontext
def admin(localpart, domain_name, password):
""" Create an admin user
"""
@@ -41,11 +60,17 @@ def admin(localpart, domain_name, password):
db.session.commit()
@manager.command
def user(localpart, domain_name, password,
hash_scheme=app.config['PASSWORD_SCHEME']):
@mailu.command()
@click.argument('localpart')
@click.argument('domain_name')
@click.argument('password')
@click.argument('hash_scheme')
@flask_cli.with_appcontext
def user(localpart, domain_name, password, hash_scheme=None):
""" Create a user
"""
if hash_scheme is None:
hash_scheme = app.config['PASSWORD_SCHEME']
domain = models.Domain.query.get(domain_name)
if not domain:
domain = models.Domain(name=domain_name)
@@ -60,10 +85,12 @@ def user(localpart, domain_name, password,
db.session.commit()
@manager.option('-n', '--domain_name', dest='domain_name')
@manager.option('-u', '--max_users', dest='max_users')
@manager.option('-a', '--max_aliases', dest='max_aliases')
@manager.option('-q', '--max_quota_bytes', dest='max_quota_bytes')
@mailu.command()
@click.option('-n', '--domain_name')
@click.option('-u', '--max_users')
@click.option('-a', '--max_aliases')
@click.option('-q', '--max_quota_bytes')
@flask_cli.with_appcontext
def domain(domain_name, max_users=0, max_aliases=0, max_quota_bytes=0):
domain = models.Domain.query.get(domain_name)
if not domain:
@@ -72,15 +99,17 @@ def domain(domain_name, max_users=0, max_aliases=0, max_quota_bytes=0):
db.session.commit()
@manager.command
def user_import(localpart, domain_name, password_hash,
hash_scheme=app.config['PASSWORD_SCHEME']):
""" Import a user along with password hash. Available hashes:
'SHA512-CRYPT'
'SHA256-CRYPT'
'MD5-CRYPT'
'CRYPT'
@mailu.command()
@click.argument('localpart')
@click.argument('domain_name')
@click.argument('password_hash')
@click.argument('hash_scheme')
@flask_cli.with_appcontext
def user_import(localpart, domain_name, password_hash, hash_scheme = None):
""" Import a user along with password hash.
"""
if hash_scheme is None:
hash_scheme = app.config['PASSWORD_SCHEME']
domain = models.Domain.query.get(domain_name)
if not domain:
domain = models.Domain(name=domain_name)
@@ -95,7 +124,10 @@ def user_import(localpart, domain_name, password_hash,
db.session.commit()
@manager.command
@mailu.command()
@click.option('-v', '--verbose')
@click.option('-d', '--delete_objects')
@flask_cli.with_appcontext
def config_update(verbose=False, delete_objects=False):
"""sync configuration with data from YAML-formatted stdin"""
import yaml
@@ -234,7 +266,9 @@ def config_update(verbose=False, delete_objects=False):
db.session.commit()
@manager.command
@mailu.command()
@click.argument('email')
@flask_cli.with_appcontext
def user_delete(email):
"""delete user"""
user = models.User.query.get(email)
@@ -243,7 +277,9 @@ def user_delete(email):
db.session.commit()
@manager.command
@mailu.command()
@click.argument('email')
@flask_cli.with_appcontext
def alias_delete(email):
"""delete alias"""
alias = models.Alias.query.get(email)
@@ -252,7 +288,11 @@ def alias_delete(email):
db.session.commit()
@manager.command
@mailu.command()
@click.argument('localpart')
@click.argument('domain_name')
@click.argument('destination')
@flask_cli.with_appcontext
def alias(localpart, domain_name, destination):
""" Create an alias
"""
@@ -269,24 +309,31 @@ def alias(localpart, domain_name, destination):
db.session.add(alias)
db.session.commit()
# Set limits to a domain
@manager.command
@mailu.command()
@click.argument('domain_name')
@click.argument('max_users')
@click.argument('max_aliases')
@click.argument('max_quota_bytes')
@flask_cli.with_appcontext
def setlimits(domain_name, max_users, max_aliases, max_quota_bytes):
""" Set domain limits
"""
domain = models.Domain.query.get(domain_name)
domain.max_users = max_users
domain.max_aliases = max_aliases
domain.max_quota_bytes = max_quota_bytes
db.session.add(domain)
db.session.commit()
# Make the user manager of a domain
@manager.command
@mailu.command()
@click.argument('domain_name')
@click.argument('user_name')
@flask_cli.with_appcontext
def setmanager(domain_name, user_name='manager'):
""" Make a user manager of a domain
"""
domain = models.Domain.query.get(domain_name)
manageruser = models.User.query.get(user_name + '@' + domain_name)
domain.managers.append(manageruser)
@@ -294,5 +341,5 @@ def setmanager(domain_name, user_name='manager'):
db.session.commit()
if __name__ == "__main__":
manager.run()
if __name__ == '__main__':
cli()

View File

@@ -1,22 +1,59 @@
from mailu import app, db, dkim, login_manager
from mailu import dkim
from sqlalchemy.ext import declarative
from passlib import context, hash
from datetime import datetime, date
from email.mime import text
from flask import current_app as app
import flask_sqlalchemy
import sqlalchemy
import re
import time
import os
import glob
import smtplib
import idna
import dns
# Many-to-many association table for domain managers
managers = db.Table('manager',
db.Column('domain_name', db.String(80), db.ForeignKey('domain.name')),
db.Column('user_email', db.String(255), db.ForeignKey('user.email'))
db = flask_sqlalchemy.SQLAlchemy()
class IdnaDomain(db.TypeDecorator):
""" Stores a Unicode string in it's IDNA representation (ASCII only)
"""
impl = db.String(80)
def process_bind_param(self, value, dialect):
return idna.encode(value).decode("ascii")
def process_result_value(self, value, dialect):
return idna.decode(value)
class IdnaEmail(db.TypeDecorator):
""" Stores a Unicode string in it's IDNA representation (ASCII only)
"""
impl = db.String(255, collation="NOCASE")
def process_bind_param(self, value, dialect):
try:
localpart, domain_name = value.split('@')
return "{0}@{1}".format(
localpart,
idna.encode(domain_name).decode('ascii'),
)
except ValueError:
pass
def process_result_value(self, value, dialect):
localpart, domain_name = value.split('@')
return "{0}@{1}".format(
localpart,
idna.decode(domain_name),
)
@@ -35,7 +72,35 @@ class CommaSeparatedList(db.TypeDecorator):
return ",".join(value)
def process_result_value(self, value, dialect):
return filter(bool, value.split(","))
return filter(bool, value.split(",")) if value else []
class JSONEncoded(db.TypeDecorator):
"""Represents an immutable structure as a json-encoded string.
"""
impl = db.String
def process_bind_param(self, value, dialect):
return json.dumps(value) if value else None
def process_result_value(self, value, dialect):
return json.loads(value) if value else None
class Config(db.Model):
""" In-database configuration values
"""
name = db.Column(db.String(255), primary_key=True, nullable=False)
value = db.Column(JSONEncoded)
# Many-to-many association table for domain managers
managers = db.Table('manager',
db.Column('domain_name', IdnaDomain, db.ForeignKey('domain.name')),
db.Column('user_email', IdnaEmail, db.ForeignKey('user.email'))
)
class Base(db.Model):
@@ -54,12 +119,13 @@ class Domain(Base):
"""
__tablename__ = "domain"
name = db.Column(db.String(80), primary_key=True, nullable=False)
name = db.Column(IdnaDomain, primary_key=True, nullable=False)
managers = db.relationship('User', secondary=managers,
backref=db.backref('manager_of'), lazy='dynamic')
max_users = db.Column(db.Integer, nullable=False, default=0)
max_aliases = db.Column(db.Integer, nullable=False, default=0)
max_quota_bytes = db.Column(db.Integer(), nullable=False, default=0)
signup_enabled = db.Column(db.Boolean(), nullable=False, default=False)
@property
def dkim_key(self):
@@ -92,6 +158,16 @@ class Domain(Base):
else:
return False
def check_mx(self):
try:
hostnames = app.config['HOSTNAMES'].split(',')
return any(
str(rset).split()[-1][:-1] in hostnames
for rset in dns.resolver.query(self.name, 'MX')
)
except Exception as e:
return False
def __str__(self):
return self.name
@@ -109,8 +185,8 @@ class Alternative(Base):
__tablename__ = "alternative"
name = db.Column(db.String(80), primary_key=True, nullable=False)
domain_name = db.Column(db.String(80), db.ForeignKey(Domain.name))
name = db.Column(IdnaDomain, primary_key=True, nullable=False)
domain_name = db.Column(IdnaDomain, db.ForeignKey(Domain.name))
domain = db.relationship(Domain,
backref=db.backref('alternatives', cascade='all, delete-orphan'))
@@ -140,33 +216,62 @@ class Email(object):
@declarative.declared_attr
def domain_name(cls):
return db.Column(db.String(80), db.ForeignKey(Domain.name),
nullable=False)
return db.Column(IdnaDomain, db.ForeignKey(Domain.name),
nullable=False, default=IdnaDomain)
# This field is redundant with both localpart and domain name.
# It is however very useful for quick lookups without joining tables,
# especially when the mail server il reading the database.
# especially when the mail server is reading the database.
@declarative.declared_attr
def email(cls):
updater = lambda context: "{0}@{1}".format(
context.current_parameters["localpart"],
context.current_parameters["domain_name"],
)
return db.Column(db.String(255, collation="NOCASE"),
return db.Column(IdnaEmail,
primary_key=True, nullable=False,
default=updater)
def sendmail(self, subject, body):
""" Send an email to the address.
"""
from_address = '{}@{}'.format(
app.config['POSTMASTER'], app.config['DOMAIN'])
with smtplib.SMTP('smtp', port=10025) as smtp:
from_address = "{0}@{1}".format(
app.config['POSTMASTER'],
idna.encode(app.config['DOMAIN']).decode('ascii'),
)
with smtplib.SMTP(app.config['HOST_AUTHSMTP'], port=10025) as smtp:
to_address = "{0}@{1}".format(
self.localpart,
idna.encode(self.domain_name).decode('ascii'),
)
msg = text.MIMEText(body)
msg['Subject'] = subject
msg['From'] = from_address
msg['To'] = self.email
smtp.sendmail(from_address, [self.email], msg.as_string())
msg['To'] = to_address
smtp.sendmail(from_address, [to_address], msg.as_string())
@classmethod
def resolve_domain(cls, email):
localpart, domain_name = email.split('@', 1) if '@' in email else (None, email)
alternative = Alternative.query.get(domain_name)
if alternative:
domain_name = alternative.domain_name
return (localpart, domain_name)
@classmethod
def resolve_destination(cls, localpart, domain_name, ignore_forward_keep=False):
alias = Alias.resolve(localpart, domain_name)
if alias:
return alias.destination
user = User.query.get('{}@{}'.format(localpart, domain_name))
if user:
if user.forward_enabled:
destination = user.forward_destination
if user.forward_keep or ignore_forward_keep:
destination.append(user.email)
else:
destination = [user.email]
return destination
def __str__(self):
return self.email
@@ -181,7 +286,9 @@ class User(Base, Email):
backref=db.backref('users', cascade='all, delete-orphan'))
password = db.Column(db.String(255), nullable=False)
quota_bytes = db.Column(db.Integer(), nullable=False, default=10**9)
quota_bytes_used = db.Column(db.Integer(), nullable=False, default=0)
global_admin = db.Column(db.Boolean(), nullable=False, default=False)
enabled = db.Column(db.Boolean(), nullable=False, default=True)
# Features
enable_imap = db.Column(db.Boolean(), nullable=False, default=True)
@@ -189,11 +296,13 @@ class User(Base, Email):
# Filters
forward_enabled = db.Column(db.Boolean(), nullable=False, default=False)
forward_destination = db.Column(db.String(255), nullable=True, default=None)
forward_destination = db.Column(CommaSeparatedList(), nullable=True, default=[])
forward_keep = db.Column(db.Boolean(), nullable=False, default=True)
reply_enabled = db.Column(db.Boolean(), nullable=False, default=False)
reply_subject = db.Column(db.String(255), nullable=True, default=None)
reply_body = db.Column(db.Text(), nullable=True, default=None)
reply_startdate = db.Column(db.Date, nullable=False,
default=date(1900, 1, 1))
reply_enddate = db.Column(db.Date, nullable=False,
default=date(2999, 12, 31))
@@ -210,28 +319,59 @@ class User(Base, Email):
def get_id(self):
return self.email
scheme_dict = {'SHA512-CRYPT': "sha512_crypt",
@property
def destination(self):
if self.forward_enabled:
result = self.forward_destination
if self.forward_keep:
result += ',' + self.email
return result
else:
return self.email
@property
def reply_active(self):
now = date.today()
return (
self.reply_enabled and
self.reply_startdate < now and
self.reply_enddate > now
)
scheme_dict = {'PBKDF2': "pbkdf2_sha512",
'BLF-CRYPT': "bcrypt",
'SHA512-CRYPT': "sha512_crypt",
'SHA256-CRYPT': "sha256_crypt",
'MD5-CRYPT': "md5_crypt",
'CRYPT': "des_crypt"}
pw_context = context.CryptContext(
schemes = scheme_dict.values(),
default=scheme_dict[app.config['PASSWORD_SCHEME']],
def get_password_context(self):
return context.CryptContext(
schemes=self.scheme_dict.values(),
default=self.scheme_dict[app.config['PASSWORD_SCHEME']],
)
def check_password(self, password):
context = self.get_password_context()
reference = re.match('({[^}]+})?(.*)', self.password).group(2)
return User.pw_context.verify(password, reference)
result = context.verify(password, reference)
if result and context.identify(reference) != context.default_scheme():
self.set_password(password)
db.session.add(self)
db.session.commit()
return result
def set_password(self, password, hash_scheme=app.config['PASSWORD_SCHEME'], raw=False):
def set_password(self, password, hash_scheme=None, raw=False):
"""Set password for user with specified encryption scheme
@password: plain text password to encrypt (if raw == True the hash itself)
"""
if hash_scheme is None:
hash_scheme = app.config['PASSWORD_SCHEME']
# for the list of hash schemes see https://wiki2.dovecot.org/Authentication/PasswordSchemes
if raw:
self.password = '{'+hash_scheme+'}' + password
else:
self.password = '{'+hash_scheme+'}' + User.pw_context.encrypt(password, self.scheme_dict[hash_scheme])
self.password = '{'+hash_scheme+'}' + self.get_password_context().encrypt(password, self.scheme_dict[hash_scheme])
def get_managed_domains(self):
if self.global_admin:
@@ -252,12 +392,14 @@ class User(Base, Email):
self.sendmail(app.config["WELCOME_SUBJECT"],
app.config["WELCOME_BODY"])
@classmethod
def get(cls, email):
return cls.query.get(email)
@classmethod
def login(cls, email, password):
user = cls.query.get(email)
return user if (user and user.check_password(password)) else None
login_manager.user_loader(User.query.get)
return user if (user and user.enabled and user.check_password(password)) else None
class Alias(Base, Email):
@@ -270,6 +412,22 @@ class Alias(Base, Email):
wildcard = db.Column(db.Boolean(), nullable=False, default=False)
destination = db.Column(CommaSeparatedList, nullable=False, default=[])
@classmethod
def resolve(cls, localpart, domain_name):
return cls.query.filter(
sqlalchemy.and_(cls.domain_name == domain_name,
sqlalchemy.or_(
sqlalchemy.and_(
cls.wildcard == False,
cls.localpart == localpart
), sqlalchemy.and_(
cls.wildcard == True,
sqlalchemy.bindparam("l", localpart).like(cls.localpart)
)
)
)
).order_by(cls.wildcard, sqlalchemy.func.char_length(cls.localpart).desc()).first()
class Token(Base):
""" A token is an application password for a given user.

View File

@@ -15,21 +15,23 @@ msgstr "Ungültige E-Mail-Adresse."
msgid "Confirm"
msgstr "Bestätigen"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:67
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr "E-Mail"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:68 mailu/ui/forms.py:85
#: mailu/ui/forms.py:146
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr "Passwort"
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:99
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr "Anmelden"
#: mailu/ui/forms.py:46 mailu/ui/templates/domain/details.html:21
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr "Domain-Name"
@@ -42,44 +44,45 @@ msgstr "Maximale Anzahl Benutzer"
msgid "Maximum alias count"
msgstr "Maximale Anzahl Aliase"
#: mailu/ui/forms.py:50 mailu/ui/forms.py:62 mailu/ui/forms.py:73
#: mailu/ui/forms.py:112 mailu/ui/forms.py:124
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr "Kommentar"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:56 mailu/ui/forms.py:63
#: mailu/ui/forms.py:116 mailu/ui/forms.py:125
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr "Erstellen"
#: mailu/ui/forms.py:69
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr "Passwort bestätigen"
#: mailu/ui/forms.py:70 mailu/ui/templates/user/list.html:22
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr "Quota"
#: mailu/ui/forms.py:71
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr "Zugriff via IMAP erlauben"
#: mailu/ui/forms.py:72
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr "Zugriff via POP3 erlauben"
#: mailu/ui/forms.py:74
#: mailu/ui/forms.py:85
msgid "Save"
msgstr "Speichern"
#: mailu/ui/forms.py:78
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr "Angezeigter Name"
#: mailu/ui/forms.py:79
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr "Spamfilter aktivieren"
@@ -87,80 +90,82 @@ msgstr "Spamfilter aktivieren"
msgid "Spam filter threshold"
msgstr "Schwellenwert für Spamfilter"
#: mailu/ui/forms.py:81
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr "Einstellungen speichern"
#: mailu/ui/forms.py:86
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr "Passwort wiederholen"
#: mailu/ui/forms.py:87 mailu/ui/templates/sidebar.html:16
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr "Passwort aktualisieren"
#: mailu/ui/forms.py:91
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr "Weiterleitung aktivieren"
#: mailu/ui/forms.py:94 mailu/ui/forms.py:123
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr "Ziel"
#: mailu/ui/forms.py:96 mailu/ui/forms.py:104
#: mailu/ui/forms.py:120
msgid "Update"
msgstr "Aktualisieren"
#: mailu/ui/forms.py:100
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr "Automatische Antwort aktivieren"
#: mailu/ui/forms.py:101
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr "Betreff"
#: mailu/ui/forms.py:102
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr "Text"
#: mailu/ui/forms.py:120
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr "Alias"
#: mailu/ui/forms.py:122
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr "SQL LIKE Syntax nutzen (z.B. für Catch-All-Aliase)"
#: mailu/ui/forms.py:129
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr "Administrator E-Mail"
#: mailu/ui/forms.py:130 mailu/ui/forms.py:135 mailu/ui/forms.py:148
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr "Absenden"
#: mailu/ui/forms.py:134
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr "Manager E-Mail"
#: mailu/ui/forms.py:139
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr "Protokoll"
#: mailu/ui/forms.py:142
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr "Hostname oder IP"
#: mailu/ui/forms.py:143
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr "Port"
#: mailu/ui/forms.py:144
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr "Verschlüsselung aktivieren"
#: mailu/ui/forms.py:145 mailu/ui/templates/fetch/list.html:20
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr "Benutzername"
@@ -188,34 +193,6 @@ msgstr "Konto"
msgid "to access the administration tools"
msgstr "für administrativen Zugriff"
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:44
msgid "Services status"
msgstr "Dienst-Status"
#: mailu/ui/templates/services.html:10
msgid "Service"
msgstr "Dienst"
#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11
msgid "Status"
msgstr "Status"
#: mailu/ui/templates/services.html:12
msgid "PID"
msgstr "PID"
#: mailu/ui/templates/services.html:13
msgid "Image"
msgstr "Image"
#: mailu/ui/templates/services.html:14
msgid "Started"
msgstr "Gestartet"
#: mailu/ui/templates/services.html:15
msgid "Last update"
msgstr "Letztes Update"
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
msgstr "Mein Konto"
@@ -224,28 +201,28 @@ msgstr "Mein Konto"
msgid "Settings"
msgstr "Einstellungen"
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr "Auto-Weiterleitung"
#: mailu/ui/templates/sidebar.html:26 mailu/ui/templates/user/list.html:36
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-reply"
msgstr "Auto-Antwort"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:31
#: mailu/ui/templates/user/list.html:37
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr "Abgerufene Konten"
#: mailu/ui/templates/sidebar.html:93
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr "Abmelden"
#: mailu/ui/templates/sidebar.html:40
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr "Administration"
#: mailu/ui/templates/sidebar.html:54
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr "Administratoren"
@@ -253,7 +230,7 @@ msgstr "Administratoren"
msgid "Mail domains"
msgstr "E-Mail-Domains"
#: mailu/ui/templates/sidebar.html:87
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr "Hilfe"
@@ -341,27 +318,27 @@ msgstr "Neue Domain"
msgid "Domain details"
msgstr "Domain-Details"
#: mailu/ui/templates/domain/details.html:13
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr "Schlüssel neu erzeugen"
#: mailu/ui/templates/domain/details.html:25
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr "DNS MX Eintrag"
#: mailu/ui/templates/domain/details.html:29
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr "DNS SPF Einträge"
#: mailu/ui/templates/domain/details.html:36
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr "DKIM öffentlicher Schlüssel"
#: mailu/ui/templates/domain/details.html:40
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr "DNS DKIM Eintrag"
#: mailu/ui/templates/domain/details.html:44
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr "DNS DMARC Eintrag"
@@ -433,15 +410,15 @@ msgstr "Manager"
msgid "Add manager"
msgstr "Manager hinzufügen"
#: mailu/ui/forms.py:152
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr "Betreff"
#: mailu/ui/forms.py:154
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr "Text"
#: mailu/ui/forms.py:156
#: mailu/ui/forms.py:172
msgid "Send"
msgstr "Absenden"
@@ -453,7 +430,7 @@ msgstr "Öffentliche Bekanntmachung"
msgid "from"
msgstr "von"
#: mailu/ui/templates/sidebar.html:49
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr "Bekanntmachung"
@@ -497,11 +474,11 @@ msgstr "Automatische Antwort"
msgid "Maximum user quota"
msgstr "Maximale Quota pro Benutzer"
#: mailu/ui/forms.py:92
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr "Kopie der E-Mails behalten"
#: mailu/ui/forms.py:147
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr "E-Mails auf dem Server belassen"
@@ -517,19 +494,19 @@ msgstr "ja"
msgid "no"
msgstr "nein"
#: mailu/ui/forms.py:55
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr "Alternativer Name"
#: mailu/ui/forms.py:60
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr "Relay-Domain-Name"
#: mailu/ui/forms.py:61 mailu/ui/templates/relay/list.html:18
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr "Entfernter Host"
#: mailu/ui/templates/sidebar.html:59
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr "Relay-Domains"
@@ -569,15 +546,15 @@ msgstr "Relay-Domains"
msgid "New relayed domain"
msgstr "Neue Relay-Domain"
#: mailu/ui/forms.py:109
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr "Token (bitte speichern, da er hier nach nicht mehr angezeigt wird)"
#: mailu/ui/forms.py:114 mailu/ui/templates/token/list.html:20
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr "Authorisierte IP-Adresse"
#: mailu/ui/templates/sidebar.html:36 mailu/ui/templates/token/list.html:4
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr "Authentifizierungs-Tokens"
@@ -589,7 +566,7 @@ msgstr "Wechseln zu"
msgid "Webmail"
msgstr "Webmail"
#: mailu/ui/templates/sidebar.html:82
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr "Website"
@@ -605,7 +582,7 @@ msgstr "Neuer Token"
msgid "General"
msgstr "Allgemein"
#: mailu/ui/templates/user/create.html:21
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr "Funktionen und Quotas"
@@ -613,11 +590,85 @@ msgstr "Funktionen und Quotas"
msgid "General settings"
msgstr "Allgemeine Einstellungen"
#: mailu/ui/templates/user/settings.html:18
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr "Antispam"
#: mailu/ui/forms.py:80
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr "Spamfilter-Grenzwert"
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr ""
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr ""
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr ""
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr ""
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr ""
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr ""
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr ""
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr ""
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr ""
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr ""
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr ""
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/signup.html:13
msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr ""
#: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
" please contact your DNS provider or administrator. Also, please wait a\n"
" couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires."
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr ""

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2017-11-05 17:17+0100\n"
"POT-Creation-Date: 2018-04-22 12:10+0200\n"
"PO-Revision-Date: 2016-10-02 15:02+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
@@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.5.1\n"
"Generated-By: Babel 2.5.3\n"
#: mailu/ui/forms.py:32
msgid "Invalid email address."
@@ -26,21 +26,23 @@ msgstr ""
msgid "Confirm"
msgstr ""
#: mailu/ui/forms.py:40 mailu/ui/forms.py:67
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr ""
#: mailu/ui/forms.py:41 mailu/ui/forms.py:68 mailu/ui/forms.py:85
#: mailu/ui/forms.py:146
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr ""
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:99
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr ""
#: mailu/ui/forms.py:46 mailu/ui/templates/domain/details.html:21
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr ""
@@ -57,165 +59,198 @@ msgstr ""
msgid "Maximum user quota"
msgstr ""
#: mailu/ui/forms.py:50 mailu/ui/forms.py:62 mailu/ui/forms.py:73
#: mailu/ui/forms.py:112 mailu/ui/forms.py:124
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr ""
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr ""
#: mailu/ui/forms.py:51 mailu/ui/forms.py:56 mailu/ui/forms.py:63
#: mailu/ui/forms.py:116 mailu/ui/forms.py:125
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr ""
#: mailu/ui/forms.py:55
msgid "Alternative name"
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr ""
#: mailu/ui/forms.py:60
msgid "Relayed domain name"
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr ""
#: mailu/ui/forms.py:61 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr ""
#: mailu/ui/forms.py:69
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr ""
#: mailu/ui/forms.py:70 mailu/ui/templates/user/list.html:22
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr ""
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr ""
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr ""
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr ""
#: mailu/ui/forms.py:71
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr ""
#: mailu/ui/forms.py:72
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr ""
#: mailu/ui/forms.py:74
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr ""
#: mailu/ui/forms.py:85
msgid "Save"
msgstr ""
#: mailu/ui/forms.py:78
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr ""
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr ""
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr ""
#: mailu/ui/forms.py:79
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr ""
#: mailu/ui/forms.py:80
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr ""
#: mailu/ui/forms.py:81
msgid "Save settings"
msgstr ""
#: mailu/ui/forms.py:86
msgid "Password check"
msgstr ""
#: mailu/ui/forms.py:87 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr ""
#: mailu/ui/forms.py:91
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr ""
#: mailu/ui/forms.py:92
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr ""
#: mailu/ui/forms.py:94 mailu/ui/forms.py:123
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr ""
#: mailu/ui/forms.py:96 mailu/ui/forms.py:104
msgid "Update"
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr ""
#: mailu/ui/forms.py:100
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr ""
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr ""
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr ""
#: mailu/ui/forms.py:101
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr ""
#: mailu/ui/forms.py:102
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr ""
#: mailu/ui/forms.py:109
msgid "Your token (write it down, as it will never be displayed again)"
msgstr ""
#: mailu/ui/forms.py:114 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr ""
#: mailu/ui/forms.py:120
msgid "Update"
msgstr ""
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr ""
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr ""
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr ""
#: mailu/ui/forms.py:122
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr ""
#: mailu/ui/forms.py:129
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr ""
#: mailu/ui/forms.py:130 mailu/ui/forms.py:135 mailu/ui/forms.py:148
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr ""
#: mailu/ui/forms.py:134
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr ""
#: mailu/ui/forms.py:139
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr ""
#: mailu/ui/forms.py:142
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr ""
#: mailu/ui/forms.py:143
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr ""
#: mailu/ui/forms.py:144
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr ""
#: mailu/ui/forms.py:145 mailu/ui/templates/fetch/list.html:20
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr ""
#: mailu/ui/forms.py:147
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr ""
#: mailu/ui/forms.py:152
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr ""
#: mailu/ui/forms.py:154
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr ""
#: mailu/ui/forms.py:156
#: mailu/ui/forms.py:172
msgid "Send"
msgstr ""
@@ -223,8 +258,16 @@ msgstr ""
msgid "Public announcement"
msgstr ""
#: mailu/ui/templates/announcement.html:8
msgid "from"
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr ""
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr ""
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr ""
#: mailu/ui/templates/confirm.html:4
@@ -248,34 +291,6 @@ msgstr ""
msgid "to access the administration tools"
msgstr ""
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:44
msgid "Services status"
msgstr ""
#: mailu/ui/templates/services.html:10
msgid "Service"
msgstr ""
#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11
msgid "Status"
msgstr ""
#: mailu/ui/templates/services.html:12
msgid "PID"
msgstr ""
#: mailu/ui/templates/services.html:13
msgid "Image"
msgstr ""
#: mailu/ui/templates/services.html:14
msgid "Started"
msgstr ""
#: mailu/ui/templates/services.html:15
msgid "Last update"
msgstr ""
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
msgstr ""
@@ -285,38 +300,38 @@ msgid "Settings"
msgstr ""
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-forward"
msgstr ""
#: mailu/ui/templates/sidebar.html:26 mailu/ui/templates/user/list.html:36
msgid "Auto-reply"
msgstr ""
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:31
#: mailu/ui/templates/user/list.html:37
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr ""
#: mailu/ui/templates/sidebar.html:36 mailu/ui/templates/token/list.html:4
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr ""
#: mailu/ui/templates/sidebar.html:40
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr ""
#: mailu/ui/templates/sidebar.html:49
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr ""
#: mailu/ui/templates/sidebar.html:54
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr ""
#: mailu/ui/templates/sidebar.html:59
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr ""
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr ""
#: mailu/ui/templates/sidebar.html:66
msgid "Mail domains"
msgstr ""
@@ -329,15 +344,19 @@ msgstr ""
msgid "Webmail"
msgstr ""
#: mailu/ui/templates/sidebar.html:82
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr ""
#: mailu/ui/templates/sidebar.html:87
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr ""
#: mailu/ui/templates/sidebar.html:93
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr ""
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr ""
@@ -441,27 +460,31 @@ msgstr ""
msgid "Domain details"
msgstr ""
#: mailu/ui/templates/domain/details.html:13
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr ""
#: mailu/ui/templates/domain/details.html:25
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr ""
#: mailu/ui/templates/domain/details.html:29
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr ""
#: mailu/ui/templates/domain/details.html:36
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr ""
#: mailu/ui/templates/domain/details.html:40
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr ""
#: mailu/ui/templates/domain/details.html:44
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr ""
@@ -505,6 +528,23 @@ msgstr ""
msgid "Alternatives"
msgstr ""
#: mailu/ui/templates/domain/signup.html:13
msgid ""
"In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr ""
#: mailu/ui/templates/domain/signup.html:18
msgid ""
"If you do not know how to setup an <code>MX</code> record for your DNS "
"zone,\n"
" please contact your DNS provider or administrator. Also, please wait "
"a\n"
" couple minutes after the <code>MX</code> is set so the local server "
"cache\n"
" expires."
msgstr ""
#: mailu/ui/templates/fetch/create.html:4
msgid "Add a fetched account"
msgstr ""
@@ -581,7 +621,7 @@ msgstr ""
msgid "General"
msgstr ""
#: mailu/ui/templates/user/create.html:21
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr ""
@@ -617,12 +657,20 @@ msgstr ""
msgid "Automatic reply"
msgstr ""
#: mailu/ui/templates/user/settings.html:14
msgid "General settings"
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr ""
#: mailu/ui/templates/user/settings.html:18
msgid "Antispam"
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr ""
#~ msgid "Your account"
@@ -631,3 +679,9 @@ msgstr ""
#~ msgid "Spam filter threshold"
#~ msgstr ""
#~ msgid "from"
#~ msgstr ""
#~ msgid "General settings"
#~ msgstr ""

View File

@@ -0,0 +1,674 @@
msgid ""
msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: POEditor.com\n"
"Project-Id-Version: Mailu\n"
"Language: es\n"
#: mailu/ui/forms.py:32
msgid "Invalid email address."
msgstr "Dirección de correo inválida."
#: mailu/ui/forms.py:36
msgid "Confirm"
msgstr "Confirmar"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr "Dirección de Correo"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr "Contraseña"
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr "Entrar"
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr "Nmbre de dominio"
#: mailu/ui/forms.py:47
msgid "Maximum user count"
msgstr "Máximo número de usuarios"
#: mailu/ui/forms.py:48
msgid "Maximum alias count"
msgstr "Máximo número de aliases"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr "Comentario"
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr "Crear"
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr "Confirmar contraseña"
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr "Cuota"
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr "Permitir acceso IMAP"
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr "Permitir acceso POP3"
#: mailu/ui/forms.py:85
msgid "Save"
msgstr "Guardar"
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr "Nombre a mostrar"
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr "Habilitar filtro de spam"
#: mailu/ui/forms.py:80
msgid "Spam filter threshold"
msgstr "Límite del filtro de spam"
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr "Guardar configuración"
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr "Revisar contraseña"
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr "Actualizar contraseña"
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr "Habilitar reenvío"
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr "Destino"
#: mailu/ui/forms.py:120
msgid "Update"
msgstr "Actualizar"
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr "Habilitar respuesta automática"
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr ""
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr ""
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr "Alias"
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr "Usar sintaxis SQL (p.ej. para abarcar todos los alias)"
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr ""
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr ""
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr ""
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr "Protocolo"
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr ""
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr "Puerto TCP"
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr "Habilitar TLS"
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr "Nombre de usuario"
#: mailu/ui/templates/confirm.html:4
msgid "Confirm action"
msgstr "Confirmar acción"
#: mailu/ui/templates/confirm.html:13
msgid "You are about to %(action)s. Please confirm your action."
msgstr ""
#: mailu/ui/templates/docker-error.html:4
msgid "Docker error"
msgstr "Error de Docker"
#: mailu/ui/templates/docker-error.html:12
msgid "An error occurred while talking to the Docker server."
msgstr "Ocurrió un error en la comunicación con el servidor Docker."
#: mailu/admin/templates/login.html:6
msgid "Your account"
msgstr ""
#: mailu/ui/templates/login.html:8
msgid "to access the administration tools"
msgstr "para acceder a las herramientas de administración"
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
msgstr "Mi cuenta"
#: mailu/ui/templates/sidebar.html:11 mailu/ui/templates/user/list.html:34
msgid "Settings"
msgstr "Configuración"
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr "Auto-reenvío"
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-reply"
msgstr "Auto-respuesta"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr ""
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr "Salir"
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr "Administración"
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr "Administradores"
#: mailu/ui/templates/sidebar.html:66
msgid "Mail domains"
msgstr "Dominios de correo"
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr "Ayuda"
#: mailu/ui/templates/working.html:4
msgid "We are still working on this feature!"
msgstr "Aún trabajamos en esta característica!"
#: mailu/ui/templates/admin/create.html:4
msgid "Add a global administrator"
msgstr "Añadir administrador global"
#: mailu/ui/templates/admin/list.html:4
msgid "Global administrators"
msgstr "Administradores globales"
#: mailu/ui/templates/admin/list.html:9
msgid "Add administrator"
msgstr "Añadr administrador"
#: mailu/ui/templates/admin/list.html:16 mailu/ui/templates/alias/list.html:18
#: mailu/ui/templates/alternative/list.html:18
#: mailu/ui/templates/domain/list.html:16 mailu/ui/templates/fetch/list.html:18
#: mailu/ui/templates/manager/list.html:18
#: mailu/ui/templates/relay/list.html:16 mailu/ui/templates/token/list.html:18
#: mailu/ui/templates/user/list.html:18
msgid "Actions"
msgstr "Acciones"
#: mailu/ui/templates/admin/list.html:17 mailu/ui/templates/alias/list.html:19
#: mailu/ui/templates/manager/list.html:19 mailu/ui/templates/user/list.html:20
msgid "Email"
msgstr "Correo"
#: mailu/ui/templates/admin/list.html:22 mailu/ui/templates/alias/list.html:29
#: mailu/ui/templates/alternative/list.html:25
#: mailu/ui/templates/domain/list.html:31 mailu/ui/templates/fetch/list.html:31
#: mailu/ui/templates/manager/list.html:24
#: mailu/ui/templates/relay/list.html:27 mailu/ui/templates/token/list.html:26
#: mailu/ui/templates/user/list.html:31
msgid "Delete"
msgstr "Eliminar"
#: mailu/ui/templates/alias/create.html:4
msgid "Create alias"
msgstr "Crear alias"
#: mailu/ui/templates/alias/edit.html:4
msgid "Edit alias"
msgstr "Editar alias"
#: mailu/ui/templates/alias/list.html:4
msgid "Alias list"
msgstr "Lista de alias"
#: mailu/ui/templates/alias/list.html:12
msgid "Add alias"
msgstr "Añadir alias"
#: mailu/ui/templates/alias/list.html:22
#: mailu/ui/templates/alternative/list.html:20
#: mailu/ui/templates/domain/list.html:22 mailu/ui/templates/fetch/list.html:24
#: mailu/ui/templates/relay/list.html:20 mailu/ui/templates/token/list.html:21
#: mailu/ui/templates/user/list.html:24
msgid "Created"
msgstr "Creado"
#: mailu/ui/templates/alias/list.html:23 mailu/ui/templates/domain/list.html:23
#: mailu/ui/templates/fetch/list.html:25 mailu/ui/templates/relay/list.html:21
#: mailu/ui/templates/user/list.html:25
msgid "Last edit"
msgstr "Última edición"
#: mailu/ui/templates/alias/list.html:28 mailu/ui/templates/domain/list.html:30
#: mailu/ui/templates/fetch/list.html:30 mailu/ui/templates/relay/list.html:26
#: mailu/ui/templates/user/list.html:30
msgid "Edit"
msgstr "Editar"
#: mailu/ui/templates/domain/create.html:4
#: mailu/ui/templates/domain/list.html:9
msgid "New domain"
msgstr "Nuevo dominio"
#: mailu/ui/templates/domain/details.html:4
msgid "Domain details"
msgstr "Detalle del domino"
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr "Regenerar llaves"
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr ""
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr ""
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr ""
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr ""
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr ""
#: mailu/ui/templates/domain/edit.html:4
msgid "Edit domain"
msgstr "Editar domino"
#: mailu/ui/templates/domain/list.html:4
msgid "Domain list"
msgstr "Lista de dominios"
#: mailu/ui/templates/domain/list.html:17
msgid "Manage"
msgstr ""
#: mailu/ui/templates/domain/list.html:19
msgid "Mailbox count"
msgstr ""
#: mailu/ui/templates/domain/list.html:20
msgid "Alias count"
msgstr ""
#: mailu/ui/templates/domain/list.html:28
msgid "Details"
msgstr "Detalles"
#: mailu/ui/templates/domain/list.html:35
msgid "Users"
msgstr "Usuarios"
#: mailu/ui/templates/domain/list.html:36
msgid "Aliases"
msgstr "Alias"
#: mailu/ui/templates/domain/list.html:37
msgid "Managers"
msgstr ""
#: mailu/ui/templates/fetch/create.html:4
msgid "Add a fetched account"
msgstr ""
#: mailu/ui/templates/fetch/edit.html:4
msgid "Update a fetched account"
msgstr ""
#: mailu/ui/templates/fetch/list.html:12
msgid "Add an account"
msgstr "Añadir una cuenta"
#: mailu/ui/templates/fetch/list.html:19
msgid "Endpoint"
msgstr ""
#: mailu/ui/templates/fetch/list.html:22
msgid "Last check"
msgstr "Último checkeo"
#: mailu/ui/templates/manager/create.html:4
msgid "Add a manager"
msgstr ""
#: mailu/ui/templates/manager/list.html:4
msgid "Manager list"
msgstr ""
#: mailu/ui/templates/manager/list.html:12
msgid "Add manager"
msgstr ""
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr ""
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr ""
#: mailu/ui/forms.py:172
msgid "Send"
msgstr "Enviar"
#: mailu/ui/templates/announcement.html:4
msgid "Public announcement"
msgstr "Anuncio público"
#: mailu/ui/templates/announcement.html:8
msgid "from"
msgstr ""
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr "Anuncio"
#: mailu/ui/templates/user/create.html:4
msgid "New user"
msgstr "Nuevo usuario"
#: mailu/ui/templates/user/edit.html:4
msgid "Edit user"
msgstr "Editar usuario"
#: mailu/ui/templates/user/forward.html:4
msgid "Forward emails"
msgstr ""
#: mailu/ui/templates/user/list.html:4
msgid "User list"
msgstr "Lista de usuarios"
#: mailu/ui/templates/user/list.html:12
msgid "Add user"
msgstr "Añadir usuario"
#: mailu/ui/templates/user/list.html:19 mailu/ui/templates/user/settings.html:4
msgid "User settings"
msgstr "Configuración de usuario"
#: mailu/ui/templates/user/list.html:21
msgid "Features"
msgstr "Características"
#: mailu/ui/templates/user/password.html:4
msgid "Password update"
msgstr "Actualizar contraseña"
#: mailu/ui/templates/user/reply.html:4
msgid "Automatic reply"
msgstr "Respuesta automática"
#: mailu/ui/forms.py:49
msgid "Maximum user quota"
msgstr ""
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr "Mantener una copia de los correos"
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr "Mantener los correos en el servidor"
#: mailu/ui/templates/fetch/list.html:21
msgid "Keep emails"
msgstr "Mantener los correos"
#: mailu/ui/templates/fetch/list.html:35
msgid "yes"
msgstr "si"
#: mailu/ui/templates/fetch/list.html:35
msgid "no"
msgstr "no"
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr ""
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr ""
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr ""
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr ""
#: mailu/ui/templates/alternative/create.html:4
msgid "Create alternative domain"
msgstr ""
#: mailu/ui/templates/alternative/list.html:4
msgid "Alternative domain list"
msgstr ""
#: mailu/ui/templates/alternative/list.html:12
msgid "Add alternative"
msgstr ""
#: mailu/ui/templates/alternative/list.html:19
msgid "Name"
msgstr "Nombre"
#: mailu/ui/templates/domain/list.html:39
msgid "Alternatives"
msgstr ""
#: mailu/ui/templates/relay/create.html:4
msgid "New relay domain"
msgstr ""
#: mailu/ui/templates/relay/edit.html:4
msgid "Edit relayd domain"
msgstr ""
#: mailu/ui/templates/relay/list.html:4
msgid "Relayed domain list"
msgstr ""
#: mailu/ui/templates/relay/list.html:9
msgid "New relayed domain"
msgstr ""
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr ""
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr ""
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr ""
#: mailu/ui/templates/sidebar.html:72
msgid "Go to"
msgstr ""
#: mailu/ui/templates/sidebar.html:76
msgid "Webmail"
msgstr ""
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr ""
#: mailu/ui/templates/token/create.html:4
msgid "Create an authentication token"
msgstr ""
#: mailu/ui/templates/token/list.html:12
msgid "New token"
msgstr ""
#: mailu/ui/templates/user/create.html:15
msgid "General"
msgstr ""
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr ""
#: mailu/ui/templates/user/settings.html:14
msgid "General settings"
msgstr ""
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr ""
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr ""
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr ""
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr ""
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr ""
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr ""
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr ""
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr ""
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr ""
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr ""
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr ""
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr ""
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr ""
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/signup.html:13
msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr ""
#: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
" please contact your DNS provider or administrator. Also, please wait a\n"
" couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires."
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr ""

View File

@@ -15,21 +15,23 @@ msgstr "Adresse e-mail invalide"
msgid "Confirm"
msgstr "Confirmer"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:67
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr "E-mail"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:68 mailu/ui/forms.py:85
#: mailu/ui/forms.py:146
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr "Mot de passe"
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:99
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr "Se connecter"
#: mailu/ui/forms.py:46 mailu/ui/templates/domain/details.html:21
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr "Nom de domaine"
@@ -42,44 +44,45 @@ msgstr "Nombre maximum d'utilisateurs"
msgid "Maximum alias count"
msgstr "Nombre maximum d'alias"
#: mailu/ui/forms.py:50 mailu/ui/forms.py:62 mailu/ui/forms.py:73
#: mailu/ui/forms.py:112 mailu/ui/forms.py:124
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr "Commentaire"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:56 mailu/ui/forms.py:63
#: mailu/ui/forms.py:116 mailu/ui/forms.py:125
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr "Créer"
#: mailu/ui/forms.py:69
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr "Confirmer le mot de passe"
#: mailu/ui/forms.py:70 mailu/ui/templates/user/list.html:22
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr "Quota"
#: mailu/ui/forms.py:71
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr "Autoriser l'accès IMAP"
#: mailu/ui/forms.py:72
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr "Autoriser l'accès POP3"
#: mailu/ui/forms.py:74
#: mailu/ui/forms.py:85
msgid "Save"
msgstr "Enregistrer"
#: mailu/ui/forms.py:78
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr "Nom affiché"
#: mailu/ui/forms.py:79
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr "Activer le filtre anti-spam"
@@ -87,80 +90,82 @@ msgstr "Activer le filtre anti-spam"
msgid "Spam filter threshold"
msgstr "Seuil du filtre anti-spam"
#: mailu/ui/forms.py:81
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr "Enregistrer les préférences"
#: mailu/ui/forms.py:86
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr "Vérifier le mot de passe"
#: mailu/ui/forms.py:87 mailu/ui/templates/sidebar.html:16
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr "Changer de mot de passe"
#: mailu/ui/forms.py:91
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr "Activer la redirection"
#: mailu/ui/forms.py:94 mailu/ui/forms.py:123
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr "Destination"
#: mailu/ui/forms.py:96 mailu/ui/forms.py:104
#: mailu/ui/forms.py:120
msgid "Update"
msgstr "Mettre à jour"
#: mailu/ui/forms.py:100
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr "Activer les réponses automatique"
#: mailu/ui/forms.py:101
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr "Sujet du message"
#: mailu/ui/forms.py:102
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr "Corps de la réponse"
#: mailu/ui/forms.py:120
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr "Alias"
#: mailu/ui/forms.py:122
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr "Utiliser la syntaxe SQL LIKE (par exemple pour les alias catch-all)"
#: mailu/ui/forms.py:129
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr "Email de l'administrateur"
#: mailu/ui/forms.py:130 mailu/ui/forms.py:135 mailu/ui/forms.py:148
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr "Valider"
#: mailu/ui/forms.py:134
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr "E-mail du gérant"
#: mailu/ui/forms.py:139
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr "Protocole"
#: mailu/ui/forms.py:142
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr "Nom d'hôte ou adresse IP"
#: mailu/ui/forms.py:143
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr "Port TCP"
#: mailu/ui/forms.py:144
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr "Activer TLS"
#: mailu/ui/forms.py:145 mailu/ui/templates/fetch/list.html:20
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr "Nom d'utilisateur"
@@ -188,34 +193,6 @@ msgstr "Votre compte"
msgid "to access the administration tools"
msgstr "pour accéder aux outils d'administration"
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:44
msgid "Services status"
msgstr "Etat des services"
#: mailu/ui/templates/services.html:10
msgid "Service"
msgstr "Service"
#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11
msgid "Status"
msgstr "Etat"
#: mailu/ui/templates/services.html:12
msgid "PID"
msgstr "PID"
#: mailu/ui/templates/services.html:13
msgid "Image"
msgstr "Image"
#: mailu/ui/templates/services.html:14
msgid "Started"
msgstr "Démarré depuis"
#: mailu/ui/templates/services.html:15
msgid "Last update"
msgstr "Dernière mise à jour"
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
msgstr "Mon compte"
@@ -224,28 +201,28 @@ msgstr "Mon compte"
msgid "Settings"
msgstr "Préférences"
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr "Redirection"
#: mailu/ui/templates/sidebar.html:26 mailu/ui/templates/user/list.html:36
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-reply"
msgstr "Réponse automatique"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:31
#: mailu/ui/templates/user/list.html:37
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr "Comptes externes"
#: mailu/ui/templates/sidebar.html:93
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr "Déconnexion"
#: mailu/ui/templates/sidebar.html:40
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr "Administration"
#: mailu/ui/templates/sidebar.html:54
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr "Administrateurs"
@@ -253,7 +230,7 @@ msgstr "Administrateurs"
msgid "Mail domains"
msgstr "Domaines"
#: mailu/ui/templates/sidebar.html:87
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr "Aide"
@@ -341,27 +318,27 @@ msgstr "Nouveau domaine"
msgid "Domain details"
msgstr "Détails du domaine"
#: mailu/ui/templates/domain/details.html:13
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr "Regénérer les clés"
#: mailu/ui/templates/domain/details.html:25
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr "Entrée DNS MX"
#: mailu/ui/templates/domain/details.html:29
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr "Entrées DNS SPF"
#: mailu/ui/templates/domain/details.html:36
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr "Clé publique DKIM"
#: mailu/ui/templates/domain/details.html:40
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr "Entrée DNS DKIM"
#: mailu/ui/templates/domain/details.html:44
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr "Entrée DNS DMARC"
@@ -433,15 +410,15 @@ msgstr "Liste des gérants"
msgid "Add manager"
msgstr "Ajouter le gérant"
#: mailu/ui/forms.py:152
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr "Sujet de l'annonce"
#: mailu/ui/forms.py:154
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr "Corps de l'annonce"
#: mailu/ui/forms.py:156
#: mailu/ui/forms.py:172
msgid "Send"
msgstr "Envoyer"
@@ -453,7 +430,7 @@ msgstr "Annonce globale"
msgid "from"
msgstr "de"
#: mailu/ui/templates/sidebar.html:49
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr "Annonce"
@@ -497,11 +474,11 @@ msgstr "Réponse automatique"
msgid "Maximum user quota"
msgstr "Quota maximum par utilisateur"
#: mailu/ui/forms.py:92
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr "Conserver une copie des messages"
#: mailu/ui/forms.py:147
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr "Conserver les messages sur le serveur"
@@ -517,19 +494,19 @@ msgstr "oui"
msgid "no"
msgstr "non"
#: mailu/ui/forms.py:55
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr "Nom alternatif"
#: mailu/ui/forms.py:60
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr "Nom du domaine relayé"
#: mailu/ui/forms.py:61 mailu/ui/templates/relay/list.html:18
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr "Hôte distant"
#: mailu/ui/templates/sidebar.html:59
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr "Domaines relayé"
@@ -569,15 +546,15 @@ msgstr "Liste des domaines relayés"
msgid "New relayed domain"
msgstr "Nouveau domaine relayé"
#: mailu/ui/forms.py:109
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr "Votre jeton (à conserver, il ne sera plus affiché par la suite)"
#: mailu/ui/forms.py:114 mailu/ui/templates/token/list.html:20
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr "Adresse IP autorisée"
#: mailu/ui/templates/sidebar.html:36 mailu/ui/templates/token/list.html:4
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr "Jetons d'authentification"
@@ -589,7 +566,7 @@ msgstr "Navigation"
msgid "Webmail"
msgstr "Webmail"
#: mailu/ui/templates/sidebar.html:82
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr "Site web"
@@ -605,7 +582,7 @@ msgstr "Nouveau jeton"
msgid "General"
msgstr "Général"
#: mailu/ui/templates/user/create.html:21
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr "Fonctionnalités et quotas"
@@ -613,11 +590,85 @@ msgstr "Fonctionnalités et quotas"
msgid "General settings"
msgstr "Général"
#: mailu/ui/templates/user/settings.html:18
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr "Antispam"
#: mailu/ui/forms.py:80
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr "Tolérance du filtre antispam"
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr "Autoriser l'inscription"
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr "Administrateur initial"
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr "Mot de passe administrateur"
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr "Activé"
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr "Adresse e-mail"
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr "S'inscrire"
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr "Fin du mode vacance"
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr "Configuration client"
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr "Protocole"
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr "Nom du serveur"
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr "Inscrire un domaine"
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr "Générer les clés"
#: mailu/ui/templates/domain/signup.html:13
msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr "Pour enregistrer un nouveau domaine, vous devez d'abord configurer la zone DNS de sorte que le <code>MX</code> du domaine pointe sur ce serveur."
#: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
" please contact your DNS provider or administrator. Also, please wait a\n"
" couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires."
msgstr "Si vous ne savez pas comment configurer un enregistrement <code>MX</code>, contactez votre fournisseur de DNS ou votre administrateur. Egalement, attendez quelques minutes après avoir modifié le <code>MX</code>, le temps que le cache local au serveur soit rafraîchi."
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr "choix du domaine pour le compte"
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr "Domaine"
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr "Places disponibles"

View File

@@ -15,21 +15,23 @@ msgstr "Indirizzo email non valido."
msgid "Confirm"
msgstr "Conferma"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:67
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr "E-mail"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:68 mailu/ui/forms.py:85
#: mailu/ui/forms.py:146
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr "Password"
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:99
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr "Entra"
#: mailu/ui/forms.py:46 mailu/ui/templates/domain/details.html:21
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr "Nome dominio"
@@ -42,44 +44,45 @@ msgstr ""
msgid "Maximum alias count"
msgstr ""
#: mailu/ui/forms.py:50 mailu/ui/forms.py:62 mailu/ui/forms.py:73
#: mailu/ui/forms.py:112 mailu/ui/forms.py:124
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr ""
#: mailu/ui/forms.py:51 mailu/ui/forms.py:56 mailu/ui/forms.py:63
#: mailu/ui/forms.py:116 mailu/ui/forms.py:125
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr "Crea"
#: mailu/ui/forms.py:69
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr "Conferma pasword"
#: mailu/ui/forms.py:70 mailu/ui/templates/user/list.html:22
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr "Quota"
#: mailu/ui/forms.py:71
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr "Consenti accesso IMAP"
#: mailu/ui/forms.py:72
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr "Consenti accesso POP3"
#: mailu/ui/forms.py:74
#: mailu/ui/forms.py:85
msgid "Save"
msgstr "Salva"
#: mailu/ui/forms.py:78
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr "Nome visualizzato"
#: mailu/ui/forms.py:79
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr "Abilita filtro antispam"
@@ -87,80 +90,82 @@ msgstr "Abilita filtro antispam"
msgid "Spam filter threshold"
msgstr "Soglia del filtro antispam"
#: mailu/ui/forms.py:81
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr "Salva impostazioni"
#: mailu/ui/forms.py:86
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr ""
#: mailu/ui/forms.py:87 mailu/ui/templates/sidebar.html:16
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr "Aggiorna password"
#: mailu/ui/forms.py:91
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr "Abilita inoltro"
#: mailu/ui/forms.py:94 mailu/ui/forms.py:123
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr "Destinazione"
#: mailu/ui/forms.py:96 mailu/ui/forms.py:104
#: mailu/ui/forms.py:120
msgid "Update"
msgstr "Aggiorna"
#: mailu/ui/forms.py:100
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr "Abilita risposta automatica"
#: mailu/ui/forms.py:101
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr "Soggetto risposta"
#: mailu/ui/forms.py:102
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr "Corpo risposta"
#: mailu/ui/forms.py:120
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr "Alias"
#: mailu/ui/forms.py:122
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr "Usa sintassi SQL LIKE (es. per alias catch-all)"
#: mailu/ui/forms.py:129
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr "Email amministratore"
#: mailu/ui/forms.py:130 mailu/ui/forms.py:135 mailu/ui/forms.py:148
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr "Invia"
#: mailu/ui/forms.py:134
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr "Email manager"
#: mailu/ui/forms.py:139
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr "Protocollo"
#: mailu/ui/forms.py:142
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr "Hostname o IP"
#: mailu/ui/forms.py:143
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr "Porta TCP"
#: mailu/ui/forms.py:144
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr "Abilita TLS"
#: mailu/ui/forms.py:145 mailu/ui/templates/fetch/list.html:20
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr "Username"
@@ -189,34 +194,6 @@ msgstr "Il tuo account"
msgid "to access the administration tools"
msgstr ""
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:44
msgid "Services status"
msgstr ""
#: mailu/ui/templates/services.html:10
msgid "Service"
msgstr ""
#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11
msgid "Status"
msgstr "Stato"
#: mailu/ui/templates/services.html:12
msgid "PID"
msgstr "PID"
#: mailu/ui/templates/services.html:13
msgid "Image"
msgstr "Immagine"
#: mailu/ui/templates/services.html:14
msgid "Started"
msgstr "Avviato"
#: mailu/ui/templates/services.html:15
msgid "Last update"
msgstr "Ultimo aggiornamento"
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
msgstr "Il mio account"
@@ -225,28 +202,28 @@ msgstr "Il mio account"
msgid "Settings"
msgstr "Impostazioni"
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr "Auto-inoltro"
#: mailu/ui/templates/sidebar.html:26 mailu/ui/templates/user/list.html:36
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-reply"
msgstr "Auto-risponditore"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:31
#: mailu/ui/templates/user/list.html:37
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr ""
#: mailu/ui/templates/sidebar.html:93
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr "Esci"
#: mailu/ui/templates/sidebar.html:40
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr "Amministrazione"
#: mailu/ui/templates/sidebar.html:54
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr "Amministratori"
@@ -254,7 +231,7 @@ msgstr "Amministratori"
msgid "Mail domains"
msgstr "Domini mail"
#: mailu/ui/templates/sidebar.html:87
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr "Aiuto"
@@ -342,27 +319,27 @@ msgstr "Nuovo dominio"
msgid "Domain details"
msgstr "Dettagli dominio"
#: mailu/ui/templates/domain/details.html:13
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr "Rigenera chiavi"
#: mailu/ui/templates/domain/details.html:25
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr ""
#: mailu/ui/templates/domain/details.html:29
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr ""
#: mailu/ui/templates/domain/details.html:36
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr ""
#: mailu/ui/templates/domain/details.html:40
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr ""
#: mailu/ui/templates/domain/details.html:44
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr ""
@@ -434,15 +411,15 @@ msgstr ""
msgid "Add manager"
msgstr "Aggiungi manager"
#: mailu/ui/forms.py:152
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr ""
#: mailu/ui/forms.py:154
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr "Corpo dell'annuncio"
#: mailu/ui/forms.py:156
#: mailu/ui/forms.py:172
msgid "Send"
msgstr "Invia"
@@ -454,7 +431,7 @@ msgstr "Annuncio pubblico"
msgid "from"
msgstr "da"
#: mailu/ui/templates/sidebar.html:49
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr "Annuncio"
@@ -498,11 +475,11 @@ msgstr "Risposta automatica"
msgid "Maximum user quota"
msgstr ""
#: mailu/ui/forms.py:92
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr "Conserva una copia delle email"
#: mailu/ui/forms.py:147
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr "Conserva email sul server"
@@ -518,19 +495,19 @@ msgstr "si"
msgid "no"
msgstr "no"
#: mailu/ui/forms.py:55
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr "Nome alternativo"
#: mailu/ui/forms.py:60
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr ""
#: mailu/ui/forms.py:61 mailu/ui/templates/relay/list.html:18
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr "Host remoto"
#: mailu/ui/templates/sidebar.html:59
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr ""
@@ -570,15 +547,15 @@ msgstr ""
msgid "New relayed domain"
msgstr ""
#: mailu/ui/forms.py:109
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr ""
#: mailu/ui/forms.py:114 mailu/ui/templates/token/list.html:20
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr "IP Autorizzato"
#: mailu/ui/templates/sidebar.html:36 mailu/ui/templates/token/list.html:4
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr "Token di autenticazione"
@@ -590,7 +567,7 @@ msgstr "Vai a"
msgid "Webmail"
msgstr "Webmail"
#: mailu/ui/templates/sidebar.html:82
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr "Sito web"
@@ -606,7 +583,7 @@ msgstr "Nuovo token"
msgid "General"
msgstr "Generale"
#: mailu/ui/templates/user/create.html:21
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr "Funzionalità e quota"
@@ -614,11 +591,85 @@ msgstr "Funzionalità e quota"
msgid "General settings"
msgstr "Impostazioni generali"
#: mailu/ui/templates/user/settings.html:18
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr "Antispam"
#: mailu/ui/forms.py:80
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr "Tolleranza filtro spam"
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr ""
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr ""
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr ""
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr ""
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr ""
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr ""
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr ""
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr ""
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr ""
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr ""
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr ""
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/signup.html:13
msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr ""
#: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
" please contact your DNS provider or administrator. Also, please wait a\n"
" couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires."
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr ""

View File

@@ -15,21 +15,23 @@ msgstr "Ongeldig e-mailadres."
msgid "Confirm"
msgstr "Bevestigen"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:67
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr "E-mail"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:68 mailu/ui/forms.py:85
#: mailu/ui/forms.py:146
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr "Wachtwoord"
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:99
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr "Aanmelden"
#: mailu/ui/forms.py:46 mailu/ui/templates/domain/details.html:21
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr "Domeinnaam"
@@ -42,44 +44,45 @@ msgstr "Maximaal aantal gebruikers"
msgid "Maximum alias count"
msgstr "Maximaal aantal aliasen"
#: mailu/ui/forms.py:50 mailu/ui/forms.py:62 mailu/ui/forms.py:73
#: mailu/ui/forms.py:112 mailu/ui/forms.py:124
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr "Opmerking"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:56 mailu/ui/forms.py:63
#: mailu/ui/forms.py:116 mailu/ui/forms.py:125
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr "Aanmaken"
#: mailu/ui/forms.py:69
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr "Bevestig wachtwoord"
#: mailu/ui/forms.py:70 mailu/ui/templates/user/list.html:22
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr "Quotum"
#: mailu/ui/forms.py:71
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr "IMAP toestaan"
#: mailu/ui/forms.py:72
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr "POP3 toestaan"
#: mailu/ui/forms.py:74
#: mailu/ui/forms.py:85
msgid "Save"
msgstr "Opslaan"
#: mailu/ui/forms.py:78
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr "Getoonde naam"
#: mailu/ui/forms.py:79
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr "Spamfilter inschakelen"
@@ -87,80 +90,82 @@ msgstr "Spamfilter inschakelen"
msgid "Spam filter threshold"
msgstr "Spamfilter drempel"
#: mailu/ui/forms.py:81
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr "Instellingen opslaan"
#: mailu/ui/forms.py:86
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr "Wachtwoord controle"
#: mailu/ui/forms.py:87 mailu/ui/templates/sidebar.html:16
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr "Wachtwoord veranderen"
#: mailu/ui/forms.py:91
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr "Doorsturen inschakelen"
#: mailu/ui/forms.py:94 mailu/ui/forms.py:123
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr "Bestemming"
#: mailu/ui/forms.py:96 mailu/ui/forms.py:104
#: mailu/ui/forms.py:120
msgid "Update"
msgstr "Bijwerken"
#: mailu/ui/forms.py:100
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr "Automatisch antwoord inschakelen"
#: mailu/ui/forms.py:101
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr "Antwoord onderwerp"
#: mailu/ui/forms.py:102
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr "Antwoord bericht"
#: mailu/ui/forms.py:120
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr "Alias"
#: mailu/ui/forms.py:122
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr "Gebruik SQL LIKE syntax (bijv. voor alles-afvangen aliasen)"
#: mailu/ui/forms.py:129
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr "Beheerder e-mail"
#: mailu/ui/forms.py:130 mailu/ui/forms.py:135 mailu/ui/forms.py:148
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr "Verzenden"
#: mailu/ui/forms.py:134
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr "Manager e-mail"
#: mailu/ui/forms.py:139
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr "Protocol"
#: mailu/ui/forms.py:142
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr "Hostnaam of IP"
#: mailu/ui/forms.py:143
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr "TCP poort"
#: mailu/ui/forms.py:144
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr "TLS inschakelen"
#: mailu/ui/forms.py:145 mailu/ui/templates/fetch/list.html:20
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr "Gebruikersnaam"
@@ -178,7 +183,7 @@ msgstr "Docker foutmelding"
#: mailu/ui/templates/docker-error.html:12
msgid "An error occurred while talking to the Docker server."
msgstr "Er is een fout opgetreden tijdens het praten met de Docker server."
msgstr "Er is een fout opgetreden tijdens het communiceren met de Docker server."
#: mailu/admin/templates/login.html:6
msgid "Your account"
@@ -186,35 +191,7 @@ msgstr "Uw account"
#: mailu/ui/templates/login.html:8
msgid "to access the administration tools"
msgstr ""
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:44
msgid "Services status"
msgstr "Status diensten"
#: mailu/ui/templates/services.html:10
msgid "Service"
msgstr "Dienst"
#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11
msgid "Status"
msgstr "Status"
#: mailu/ui/templates/services.html:12
msgid "PID"
msgstr "PID"
#: mailu/ui/templates/services.html:13
msgid "Image"
msgstr "Image"
#: mailu/ui/templates/services.html:14
msgid "Started"
msgstr "Gestart"
#: mailu/ui/templates/services.html:15
msgid "Last update"
msgstr "Laatste aanpassing"
msgstr "om toegang te krijgen tot systeembeheer"
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
@@ -224,28 +201,28 @@ msgstr "Mijn account"
msgid "Settings"
msgstr "Instellingen"
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr "Automatisch doorsturen"
#: mailu/ui/templates/sidebar.html:26 mailu/ui/templates/user/list.html:36
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-reply"
msgstr "Automatisch antwoorden"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:31
#: mailu/ui/templates/user/list.html:37
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr "Opgehaalde accounts"
#: mailu/ui/templates/sidebar.html:93
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr "Afmelden"
#: mailu/ui/templates/sidebar.html:40
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr "Beheer"
#: mailu/ui/templates/sidebar.html:54
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr "Beheerders"
@@ -253,7 +230,7 @@ msgstr "Beheerders"
msgid "Mail domains"
msgstr "E-mail domeinen"
#: mailu/ui/templates/sidebar.html:87
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr "Help"
@@ -341,29 +318,29 @@ msgstr "Nieuw domein"
msgid "Domain details"
msgstr "Domein details"
#: mailu/ui/templates/domain/details.html:13
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr "Hergenereer sleutels"
#: mailu/ui/templates/domain/details.html:25
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr ""
msgstr "DNS MX-record"
#: mailu/ui/templates/domain/details.html:29
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr ""
msgstr "DNS SPF-records"
#: mailu/ui/templates/domain/details.html:36
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr "DKIM publieke sleutel"
#: mailu/ui/templates/domain/details.html:40
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr ""
msgstr "DNS DKIM-record"
#: mailu/ui/templates/domain/details.html:44
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr ""
msgstr "DNS DMARC-record"
#: mailu/ui/templates/domain/edit.html:4
msgid "Edit domain"
@@ -415,7 +392,7 @@ msgstr "Account toevoegen"
#: mailu/ui/templates/fetch/list.html:19
msgid "Endpoint"
msgstr ""
msgstr "Endpoint"
#: mailu/ui/templates/fetch/list.html:22
msgid "Last check"
@@ -433,15 +410,15 @@ msgstr "Manager overzicht"
msgid "Add manager"
msgstr "Manager toevoegen"
#: mailu/ui/forms.py:152
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr "Mededeling onderwerp"
#: mailu/ui/forms.py:154
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr "Mededeling bericht"
#: mailu/ui/forms.py:156
#: mailu/ui/forms.py:172
msgid "Send"
msgstr "Versturen"
@@ -453,7 +430,7 @@ msgstr "Publieke mededeling"
msgid "from"
msgstr "van"
#: mailu/ui/templates/sidebar.html:49
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr "Mededeling"
@@ -467,7 +444,7 @@ msgstr "Gebruiker aanpassen"
#: mailu/ui/templates/user/forward.html:4
msgid "Forward emails"
msgstr ""
msgstr "E-mails doorsturen"
#: mailu/ui/templates/user/list.html:4
msgid "User list"
@@ -497,11 +474,11 @@ msgstr "Automatisch antwoord"
msgid "Maximum user quota"
msgstr "Maximum quotum gebruikers"
#: mailu/ui/forms.py:92
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr "Behoud een kopie van de e-mails"
#: mailu/ui/forms.py:147
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr "Behoud de e-mails op de server"
@@ -517,21 +494,21 @@ msgstr "ja"
msgid "no"
msgstr "nee"
#: mailu/ui/forms.py:55
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr "Alternatieve naam"
#: mailu/ui/forms.py:60
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr ""
msgstr "Relayed domainnaam"
#: mailu/ui/forms.py:61 mailu/ui/templates/relay/list.html:18
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr ""
msgstr "Externe host"
#: mailu/ui/templates/sidebar.html:59
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr ""
msgstr "Relayed domainen"
#: mailu/ui/templates/alternative/create.html:4
msgid "Create alternative domain"
@@ -555,69 +532,143 @@ msgstr "Alternatieven"
#: mailu/ui/templates/relay/create.html:4
msgid "New relay domain"
msgstr ""
msgstr "Nieuw relay domein"
#: mailu/ui/templates/relay/edit.html:4
msgid "Edit relayd domain"
msgstr ""
msgstr "Bewerk relay domein"
#: mailu/ui/templates/relay/list.html:4
msgid "Relayed domain list"
msgstr ""
msgstr "Overzicht relayed domeinen"
#: mailu/ui/templates/relay/list.html:9
msgid "New relayed domain"
msgstr ""
msgstr "Nieuw relayed domein"
#: mailu/ui/forms.py:109
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr ""
msgstr "Uw token (bewaar hem goed, want hij wordt nooit meer getoond)"
#: mailu/ui/forms.py:114 mailu/ui/templates/token/list.html:20
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr ""
msgstr "Toegestaan IP"
#: mailu/ui/templates/sidebar.html:36 mailu/ui/templates/token/list.html:4
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr ""
msgstr "Authenticatie tokens"
#: mailu/ui/templates/sidebar.html:72
msgid "Go to"
msgstr ""
msgstr "Ga naar"
#: mailu/ui/templates/sidebar.html:76
msgid "Webmail"
msgstr ""
msgstr "Webmail"
#: mailu/ui/templates/sidebar.html:82
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr ""
msgstr "Website"
#: mailu/ui/templates/token/create.html:4
msgid "Create an authentication token"
msgstr ""
msgstr "Authenticatie token aanmaken"
#: mailu/ui/templates/token/list.html:12
msgid "New token"
msgstr ""
msgstr "Nieuw token"
#: mailu/ui/templates/user/create.html:15
msgid "General"
msgstr ""
msgstr "Algemeen"
#: mailu/ui/templates/user/create.html:21
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr ""
msgstr "Functionaliteiten en quota"
#: mailu/ui/templates/user/settings.html:14
msgid "General settings"
msgstr ""
msgstr "Algemene instellingen"
#: mailu/ui/templates/user/settings.html:18
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr ""
msgstr "Anti-spam"
#: mailu/ui/forms.py:80
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr "Spam filter toleratie"
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr ""
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr ""
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr ""
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr ""
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr ""
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr ""
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr ""
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr ""
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr ""
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr ""
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr ""
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/signup.html:13
msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr ""
#: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
" please contact your DNS provider or administrator. Also, please wait a\n"
" couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires."
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr ""

View File

@@ -15,21 +15,23 @@ msgstr "Nieprawidłowy adres e-mail."
msgid "Confirm"
msgstr "Zatwierdź"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:67
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr "E-mail"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:68 mailu/ui/forms.py:85
#: mailu/ui/forms.py:146
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr "Hasło"
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:99
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr "Zaloguj"
#: mailu/ui/forms.py:46 mailu/ui/templates/domain/details.html:21
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr "Nazwa domeny"
@@ -43,44 +45,45 @@ msgid "Maximum alias count"
msgstr "Maksymalna liczba aliasów"
#. Needs more context - is that a verb or a noun?
#: mailu/ui/forms.py:50 mailu/ui/forms.py:62 mailu/ui/forms.py:73
#: mailu/ui/forms.py:112 mailu/ui/forms.py:124
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr "Komentarz"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:56 mailu/ui/forms.py:63
#: mailu/ui/forms.py:116 mailu/ui/forms.py:125
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr "Utwórz"
#: mailu/ui/forms.py:69
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr "Potwierdź hasło"
#: mailu/ui/forms.py:70 mailu/ui/templates/user/list.html:22
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr ""
#: mailu/ui/forms.py:71
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr "Zezwalaj na dostęp przez protokół IMAP"
#: mailu/ui/forms.py:72
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr "Zezwalaj na dostęp przez protokół POP3"
#: mailu/ui/forms.py:74
#: mailu/ui/forms.py:85
msgid "Save"
msgstr "Zapisz"
#: mailu/ui/forms.py:78
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr "Nazwa wyświetlana"
#: mailu/ui/forms.py:79
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr "Włącz filtr antyspamowy"
@@ -88,80 +91,82 @@ msgstr "Włącz filtr antyspamowy"
msgid "Spam filter threshold"
msgstr "Próg filtra antyspamowego"
#: mailu/ui/forms.py:81
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr "Zapisz ustawienia"
#: mailu/ui/forms.py:86
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr ""
#: mailu/ui/forms.py:87 mailu/ui/templates/sidebar.html:16
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr "Zmień hasło"
#: mailu/ui/forms.py:91
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr "Włącz przekierowanie poczty"
#: mailu/ui/forms.py:94 mailu/ui/forms.py:123
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr "Adres docelowy"
#: mailu/ui/forms.py:96 mailu/ui/forms.py:104
#: mailu/ui/forms.py:120
msgid "Update"
msgstr "Aktualizuj"
#: mailu/ui/forms.py:100
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr "Włącz automatyczną odpowiedź"
#: mailu/ui/forms.py:101
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr "Temat odpowiedzi"
#: mailu/ui/forms.py:102
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr "Treść odpowiedzi"
#: mailu/ui/forms.py:120
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr "Alias"
#: mailu/ui/forms.py:122
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr "Używaj składni SQL LIKE (np. do adresów catch-all)"
#: mailu/ui/forms.py:129
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr "E-mail administratora"
#: mailu/ui/forms.py:130 mailu/ui/forms.py:135 mailu/ui/forms.py:148
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr "Prześlij"
#: mailu/ui/forms.py:134
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr ""
#: mailu/ui/forms.py:139
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr "Protokół"
#: mailu/ui/forms.py:142
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr "Nazwa hosta lub adres IP"
#: mailu/ui/forms.py:143
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr "Port TCP"
#: mailu/ui/forms.py:144
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr "Włącz TLS"
#: mailu/ui/forms.py:145 mailu/ui/templates/fetch/list.html:20
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr "Nazwa użytkownika"
@@ -189,34 +194,6 @@ msgstr "Twoje konto"
msgid "to access the administration tools"
msgstr ""
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:44
msgid "Services status"
msgstr "Status usług"
#: mailu/ui/templates/services.html:10
msgid "Service"
msgstr "Usługa"
#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11
msgid "Status"
msgstr "Status"
#: mailu/ui/templates/services.html:12
msgid "PID"
msgstr ""
#: mailu/ui/templates/services.html:13
msgid "Image"
msgstr ""
#: mailu/ui/templates/services.html:14
msgid "Started"
msgstr ""
#: mailu/ui/templates/services.html:15
msgid "Last update"
msgstr "Ostatnia aktualizacja"
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
msgstr "Moje konto"
@@ -225,28 +202,28 @@ msgstr "Moje konto"
msgid "Settings"
msgstr "Ustawienia"
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr "Automatyczne przekierowanie"
#: mailu/ui/templates/sidebar.html:26 mailu/ui/templates/user/list.html:36
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-reply"
msgstr "Automatyczna odpowiedź"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:31
#: mailu/ui/templates/user/list.html:37
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr ""
#: mailu/ui/templates/sidebar.html:93
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr "Wyloguj"
#: mailu/ui/templates/sidebar.html:40
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr "Administracja"
#: mailu/ui/templates/sidebar.html:54
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr "Administratorzy"
@@ -254,7 +231,7 @@ msgstr "Administratorzy"
msgid "Mail domains"
msgstr "Domeny pocztowe"
#: mailu/ui/templates/sidebar.html:87
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr "Pomoc"
@@ -342,27 +319,27 @@ msgstr "Nowa domena"
msgid "Domain details"
msgstr "Szczegóły domeny"
#: mailu/ui/templates/domain/details.html:13
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr "Wygeneruj ponownie klucze"
#: mailu/ui/templates/domain/details.html:25
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr "Wpis MX DNS"
#: mailu/ui/templates/domain/details.html:29
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr "Wpisy SPF DNS"
#: mailu/ui/templates/domain/details.html:36
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr "Publiczny klucz DKIM"
#: mailu/ui/templates/domain/details.html:40
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr "Wpis DKIM DNS"
#: mailu/ui/templates/domain/details.html:44
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr "Wpis DMARC DNS"
@@ -434,15 +411,15 @@ msgstr ""
msgid "Add manager"
msgstr ""
#: mailu/ui/forms.py:152
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr "Temat ogłoszenia"
#: mailu/ui/forms.py:154
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr "Treść ogłoszenia"
#: mailu/ui/forms.py:156
#: mailu/ui/forms.py:172
msgid "Send"
msgstr "Wyślij"
@@ -454,7 +431,7 @@ msgstr "Publiczne ogłoszenie"
msgid "from"
msgstr "od"
#: mailu/ui/templates/sidebar.html:49
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr "Ogłoszenie"
@@ -498,11 +475,11 @@ msgstr "Automatyczna odpowiedź"
msgid "Maximum user quota"
msgstr ""
#: mailu/ui/forms.py:92
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr "Przechowuj kopię wiadomości"
#: mailu/ui/forms.py:147
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr "Przechowuj wiadomości na serwerze"
@@ -518,19 +495,19 @@ msgstr "Tak"
msgid "no"
msgstr "Nie"
#: mailu/ui/forms.py:55
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr ""
#: mailu/ui/forms.py:60
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr ""
#: mailu/ui/forms.py:61 mailu/ui/templates/relay/list.html:18
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr ""
#: mailu/ui/templates/sidebar.html:59
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr ""
@@ -570,15 +547,15 @@ msgstr ""
msgid "New relayed domain"
msgstr ""
#: mailu/ui/forms.py:109
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr ""
#: mailu/ui/forms.py:114 mailu/ui/templates/token/list.html:20
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr ""
#: mailu/ui/templates/sidebar.html:36 mailu/ui/templates/token/list.html:4
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr ""
@@ -590,7 +567,7 @@ msgstr ""
msgid "Webmail"
msgstr ""
#: mailu/ui/templates/sidebar.html:82
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr "Strona internetowa"
@@ -606,7 +583,7 @@ msgstr ""
msgid "General"
msgstr ""
#: mailu/ui/templates/user/create.html:21
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr ""
@@ -614,11 +591,85 @@ msgstr ""
msgid "General settings"
msgstr "Ustawienia ogólne"
#: mailu/ui/templates/user/settings.html:18
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr "Filtr antyspamowy"
#: mailu/ui/forms.py:80
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr ""
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr ""
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr ""
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr ""
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr ""
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr ""
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr ""
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr ""
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr ""
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr ""
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr ""
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr ""
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/signup.html:13
msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr ""
#: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
" please contact your DNS provider or administrator. Also, please wait a\n"
" couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires."
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr ""

View File

@@ -15,21 +15,23 @@ msgstr "Endereço de e-mail inválido"
msgid "Confirm"
msgstr "Confirmar"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:67
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr "E-mail"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:68 mailu/ui/forms.py:85
#: mailu/ui/forms.py:146
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr "Senha"
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:99
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr "Entrar"
#: mailu/ui/forms.py:46 mailu/ui/templates/domain/details.html:21
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr "Domínio"
@@ -42,44 +44,45 @@ msgstr "Quantidade máxima de usuários"
msgid "Maximum alias count"
msgstr "Quantidade máxima de alias"
#: mailu/ui/forms.py:50 mailu/ui/forms.py:62 mailu/ui/forms.py:73
#: mailu/ui/forms.py:112 mailu/ui/forms.py:124
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr "Comentário"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:56 mailu/ui/forms.py:63
#: mailu/ui/forms.py:116 mailu/ui/forms.py:125
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr "Criar"
#: mailu/ui/forms.py:69
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr "Confirmar senha"
#: mailu/ui/forms.py:70 mailu/ui/templates/user/list.html:22
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr "Quota"
#: mailu/ui/forms.py:71
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr "Permitir acesso IMAP"
#: mailu/ui/forms.py:72
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr "Permitir acesso POP3"
#: mailu/ui/forms.py:74
#: mailu/ui/forms.py:85
msgid "Save"
msgstr "Salvar"
#: mailu/ui/forms.py:78
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr "Nome de exibição"
#: mailu/ui/forms.py:79
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr "Habilitar filtro de spam"
@@ -87,80 +90,82 @@ msgstr "Habilitar filtro de spam"
msgid "Spam filter threshold"
msgstr "Limite de filtro de spam"
#: mailu/ui/forms.py:81
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr "Salvar configurações"
#: mailu/ui/forms.py:86
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr "Confirmação de senha"
#: mailu/ui/forms.py:87 mailu/ui/templates/sidebar.html:16
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr "Alterar senha"
#: mailu/ui/forms.py:91
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr "Habilitar encaminhamento"
#: mailu/ui/forms.py:94 mailu/ui/forms.py:123
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr "Destinatário"
#: mailu/ui/forms.py:96 mailu/ui/forms.py:104
#: mailu/ui/forms.py:120
msgid "Update"
msgstr "Atualizar"
#: mailu/ui/forms.py:100
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr "Habilitar resposta automática"
#: mailu/ui/forms.py:101
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr "Assunto da resposta"
#: mailu/ui/forms.py:102
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr "Corpo da resposta"
#: mailu/ui/forms.py:120
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr "Alias"
#: mailu/ui/forms.py:122
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr "Usar sintaxe estilo SQL(ex: for catch-all aliases)"
#: mailu/ui/forms.py:129
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr "E-mail do administrador"
#: mailu/ui/forms.py:130 mailu/ui/forms.py:135 mailu/ui/forms.py:148
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr "Enviar"
#: mailu/ui/forms.py:134
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr "E-mail do gerente"
#: mailu/ui/forms.py:139
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr "Protocolo"
#: mailu/ui/forms.py:142
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr "Hostname ou IP"
#: mailu/ui/forms.py:143
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr "Porta TCP"
#: mailu/ui/forms.py:144
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr "Habilitar TLS"
#: mailu/ui/forms.py:145 mailu/ui/templates/fetch/list.html:20
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr "Usuário"
@@ -188,34 +193,6 @@ msgstr "Sua conta"
msgid "to access the administration tools"
msgstr "para acessar as ferramentas administrativas"
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:44
msgid "Services status"
msgstr "Status do serviço"
#: mailu/ui/templates/services.html:10
msgid "Service"
msgstr "Serviço"
#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11
msgid "Status"
msgstr "Status"
#: mailu/ui/templates/services.html:12
msgid "PID"
msgstr "PID"
#: mailu/ui/templates/services.html:13
msgid "Image"
msgstr "Imagem"
#: mailu/ui/templates/services.html:14
msgid "Started"
msgstr "Iniciado"
#: mailu/ui/templates/services.html:15
msgid "Last update"
msgstr "Última atualização"
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
msgstr "Minha conta"
@@ -224,28 +201,28 @@ msgstr "Minha conta"
msgid "Settings"
msgstr "Configurações"
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr "Encaminhamento automático"
#: mailu/ui/templates/sidebar.html:26 mailu/ui/templates/user/list.html:36
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-reply"
msgstr "Resposta automática"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:31
#: mailu/ui/templates/user/list.html:37
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr "Contas importadas"
#: mailu/ui/templates/sidebar.html:93
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr "Sair"
#: mailu/ui/templates/sidebar.html:40
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr "Administração"
#: mailu/ui/templates/sidebar.html:54
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr "Administradores"
@@ -253,7 +230,7 @@ msgstr "Administradores"
msgid "Mail domains"
msgstr "Domínios de e-mail"
#: mailu/ui/templates/sidebar.html:87
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr "Ajuda"
@@ -341,27 +318,27 @@ msgstr "Novo domínio"
msgid "Domain details"
msgstr "Detalhes do domínio"
#: mailu/ui/templates/domain/details.html:13
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr "Gerar novas chaves"
#: mailu/ui/templates/domain/details.html:25
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr "Entrada DNS MX"
#: mailu/ui/templates/domain/details.html:29
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr "Entrada DNS SPF"
#: mailu/ui/templates/domain/details.html:36
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr "Chave pública do DKIM"
#: mailu/ui/templates/domain/details.html:40
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr "Entrada DNS DKIM"
#: mailu/ui/templates/domain/details.html:44
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr "Entrada DNS DMARC"
@@ -433,15 +410,15 @@ msgstr "Lista de gerentes"
msgid "Add manager"
msgstr "Adicionar gerente"
#: mailu/ui/forms.py:152
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr "Título do comunicado"
#: mailu/ui/forms.py:154
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr "Corpo do comunicado"
#: mailu/ui/forms.py:156
#: mailu/ui/forms.py:172
msgid "Send"
msgstr "Enviar"
@@ -453,7 +430,7 @@ msgstr "Comunicado geral"
msgid "from"
msgstr "de"
#: mailu/ui/templates/sidebar.html:49
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr "Comunicado"
@@ -497,11 +474,11 @@ msgstr "Resposta automática"
msgid "Maximum user quota"
msgstr "Cota máxima por usuário"
#: mailu/ui/forms.py:92
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr "Manter uma cópia dos emails"
#: mailu/ui/forms.py:147
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr "Manter os e-mails no servidor"
@@ -517,19 +494,19 @@ msgstr "sim"
msgid "no"
msgstr "não"
#: mailu/ui/forms.py:55
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr "Nome alternativo"
#: mailu/ui/forms.py:60
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr "Nome de domínio para encaminhar"
#: mailu/ui/forms.py:61 mailu/ui/templates/relay/list.html:18
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr "Host remoto"
#: mailu/ui/templates/sidebar.html:59
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr "Domínios para encaminhamento"
@@ -569,15 +546,15 @@ msgstr "Lista de domínios para encaminhamento"
msgid "New relayed domain"
msgstr "Novo domínio de encaminhamento"
#: mailu/ui/forms.py:109
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr ""
#: mailu/ui/forms.py:114 mailu/ui/templates/token/list.html:20
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr ""
#: mailu/ui/templates/sidebar.html:36 mailu/ui/templates/token/list.html:4
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr ""
@@ -589,7 +566,7 @@ msgstr ""
msgid "Webmail"
msgstr ""
#: mailu/ui/templates/sidebar.html:82
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr ""
@@ -605,7 +582,7 @@ msgstr ""
msgid "General"
msgstr ""
#: mailu/ui/templates/user/create.html:21
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr ""
@@ -613,11 +590,85 @@ msgstr ""
msgid "General settings"
msgstr ""
#: mailu/ui/templates/user/settings.html:18
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr ""
#: mailu/ui/forms.py:80
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr ""
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr ""
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr ""
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr ""
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr ""
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr ""
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr ""
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr ""
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr ""
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr ""
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr ""
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr ""
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/signup.html:13
msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr ""
#: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
" please contact your DNS provider or administrator. Also, please wait a\n"
" couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires."
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr ""

View File

@@ -0,0 +1,674 @@
msgid ""
msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: POEditor.com\n"
"Project-Id-Version: Mailu\n"
"Language: ru\n"
#: mailu/ui/forms.py:32
msgid "Invalid email address."
msgstr "Неправильный адрес электронной почты"
#: mailu/ui/forms.py:36
msgid "Confirm"
msgstr "Подтвердить"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr "Электронная почта"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr "Пароль"
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr "Войти"
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr "Доменное имя"
#: mailu/ui/forms.py:47
msgid "Maximum user count"
msgstr "Максимальное число пользователей"
#: mailu/ui/forms.py:48
msgid "Maximum alias count"
msgstr "Максимальное число псевдонимов"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr "Комментарий"
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr "Создать"
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr "Подтвердить пароль"
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr "Квота"
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr "Разрешить доступ через IMAP"
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr "Разрешить доступ через POP3"
#: mailu/ui/forms.py:85
msgid "Save"
msgstr "Сохранить"
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr "Отображаемое имя"
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr "Включить спам-фильтр"
#: mailu/ui/forms.py:80
msgid "Spam filter threshold"
msgstr "Порог чувствительности спам-фильтра"
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr "Сохранить настройки"
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr "Проверка пароля"
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr "Обновить пароль"
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr "Включить переадресацию"
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr "Адрес получателя"
#: mailu/ui/forms.py:120
msgid "Update"
msgstr "Обновить"
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr "Включить автоответчик"
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr "Заголовок автоответа"
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr "Сообщение автоответа"
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr "Псевдоним"
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr "Использовать SQL-подобный синтаксис"
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr "Адрес администратора"
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr "Отправить"
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr "Адрес менеджера"
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr "Протокол"
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr "Имя хоста или IP"
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr "Порт TCP"
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr "Включить TLS"
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr "Имя пользователя"
#: mailu/ui/templates/confirm.html:4
msgid "Confirm action"
msgstr "Подтвердить действие"
#: mailu/ui/templates/confirm.html:13
msgid "You are about to %(action)s. Please confirm your action."
msgstr "Вы собираетесь совершить %(action). Подтвердить?"
#: mailu/ui/templates/docker-error.html:4
msgid "Docker error"
msgstr "Ошибка Docker"
#: mailu/ui/templates/docker-error.html:12
msgid "An error occurred while talking to the Docker server."
msgstr "Произошла ошибка при обращении к серверу Docker"
#: mailu/admin/templates/login.html:6
msgid "Your account"
msgstr "Ваша учетная запись"
#: mailu/ui/templates/login.html:8
msgid "to access the administration tools"
msgstr "для доступа к утилитам администрирования"
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
msgstr "Моя учетная запись"
#: mailu/ui/templates/sidebar.html:11 mailu/ui/templates/user/list.html:34
msgid "Settings"
msgstr "Настройки"
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr "Автоматическая пересылка"
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-reply"
msgstr "Автоматический ответ"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr "Учетные записи сторонних серверов"
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr "Выйти"
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr "Администрирование"
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr "Администраторы"
#: mailu/ui/templates/sidebar.html:66
msgid "Mail domains"
msgstr "Почтовые домены"
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr "Помощь"
#: mailu/ui/templates/working.html:4
msgid "We are still working on this feature!"
msgstr "Мы еще работаем над данным функционалом!"
#: mailu/ui/templates/admin/create.html:4
msgid "Add a global administrator"
msgstr "Добавить глобального администратора"
#: mailu/ui/templates/admin/list.html:4
msgid "Global administrators"
msgstr "Глобальные администраторы"
#: mailu/ui/templates/admin/list.html:9
msgid "Add administrator"
msgstr "Добавить администратора"
#: mailu/ui/templates/admin/list.html:16 mailu/ui/templates/alias/list.html:18
#: mailu/ui/templates/alternative/list.html:18
#: mailu/ui/templates/domain/list.html:16 mailu/ui/templates/fetch/list.html:18
#: mailu/ui/templates/manager/list.html:18
#: mailu/ui/templates/relay/list.html:16 mailu/ui/templates/token/list.html:18
#: mailu/ui/templates/user/list.html:18
msgid "Actions"
msgstr "Действия"
#: mailu/ui/templates/admin/list.html:17 mailu/ui/templates/alias/list.html:19
#: mailu/ui/templates/manager/list.html:19 mailu/ui/templates/user/list.html:20
msgid "Email"
msgstr "Электронная почта"
#: mailu/ui/templates/admin/list.html:22 mailu/ui/templates/alias/list.html:29
#: mailu/ui/templates/alternative/list.html:25
#: mailu/ui/templates/domain/list.html:31 mailu/ui/templates/fetch/list.html:31
#: mailu/ui/templates/manager/list.html:24
#: mailu/ui/templates/relay/list.html:27 mailu/ui/templates/token/list.html:26
#: mailu/ui/templates/user/list.html:31
msgid "Delete"
msgstr "Удалить"
#: mailu/ui/templates/alias/create.html:4
msgid "Create alias"
msgstr "Создать псевдоним"
#: mailu/ui/templates/alias/edit.html:4
msgid "Edit alias"
msgstr "Изменить псевдоним"
#: mailu/ui/templates/alias/list.html:4
msgid "Alias list"
msgstr "Список псевдонимов"
#: mailu/ui/templates/alias/list.html:12
msgid "Add alias"
msgstr "Добавить псевдоним"
#: mailu/ui/templates/alias/list.html:22
#: mailu/ui/templates/alternative/list.html:20
#: mailu/ui/templates/domain/list.html:22 mailu/ui/templates/fetch/list.html:24
#: mailu/ui/templates/relay/list.html:20 mailu/ui/templates/token/list.html:21
#: mailu/ui/templates/user/list.html:24
msgid "Created"
msgstr "Создано"
#: mailu/ui/templates/alias/list.html:23 mailu/ui/templates/domain/list.html:23
#: mailu/ui/templates/fetch/list.html:25 mailu/ui/templates/relay/list.html:21
#: mailu/ui/templates/user/list.html:25
msgid "Last edit"
msgstr "Последнее изменение"
#: mailu/ui/templates/alias/list.html:28 mailu/ui/templates/domain/list.html:30
#: mailu/ui/templates/fetch/list.html:30 mailu/ui/templates/relay/list.html:26
#: mailu/ui/templates/user/list.html:30
msgid "Edit"
msgstr "Изменить"
#: mailu/ui/templates/domain/create.html:4
#: mailu/ui/templates/domain/list.html:9
msgid "New domain"
msgstr "Новый домен"
#: mailu/ui/templates/domain/details.html:4
msgid "Domain details"
msgstr "Подробности домена"
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr "Перегенерировать ключи"
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr "DNS MX запись"
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr "DNS SPF запись"
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr "Публичный ключ DKIM"
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr "DNS DKIM запись"
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr "DNS DMARC запись"
#: mailu/ui/templates/domain/edit.html:4
msgid "Edit domain"
msgstr "Изменить домен"
#: mailu/ui/templates/domain/list.html:4
msgid "Domain list"
msgstr "Список доменов"
#: mailu/ui/templates/domain/list.html:17
msgid "Manage"
msgstr "Управление"
#: mailu/ui/templates/domain/list.html:19
msgid "Mailbox count"
msgstr "Количество ящиков"
#: mailu/ui/templates/domain/list.html:20
msgid "Alias count"
msgstr "Количество псевдонимов"
#: mailu/ui/templates/domain/list.html:28
msgid "Details"
msgstr "Подробно"
#: mailu/ui/templates/domain/list.html:35
msgid "Users"
msgstr "Пользователи"
#: mailu/ui/templates/domain/list.html:36
msgid "Aliases"
msgstr "Псевдонимы"
#: mailu/ui/templates/domain/list.html:37
msgid "Managers"
msgstr "Менеджеры"
#: mailu/ui/templates/fetch/create.html:4
msgid "Add a fetched account"
msgstr "Добавить учетную запись стороннего сервера"
#: mailu/ui/templates/fetch/edit.html:4
msgid "Update a fetched account"
msgstr "Обновить учетную запись стороннего сервера"
#: mailu/ui/templates/fetch/list.html:12
msgid "Add an account"
msgstr "Добавить учетную запись"
#: mailu/ui/templates/fetch/list.html:19
msgid "Endpoint"
msgstr "Конечная точка"
#: mailu/ui/templates/fetch/list.html:22
msgid "Last check"
msgstr "Последняя проверка"
#: mailu/ui/templates/manager/create.html:4
msgid "Add a manager"
msgstr "Добавить менеджера"
#: mailu/ui/templates/manager/list.html:4
msgid "Manager list"
msgstr "Список менеджеров"
#: mailu/ui/templates/manager/list.html:12
msgid "Add manager"
msgstr "Добавить менеджера"
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr "Тема объявления"
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr "Содержание объявления"
#: mailu/ui/forms.py:172
msgid "Send"
msgstr "Отправить"
#: mailu/ui/templates/announcement.html:4
msgid "Public announcement"
msgstr "Публичное объявление"
#: mailu/ui/templates/announcement.html:8
msgid "from"
msgstr "От"
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr "Объявление"
#: mailu/ui/templates/user/create.html:4
msgid "New user"
msgstr "Новый пользователь"
#: mailu/ui/templates/user/edit.html:4
msgid "Edit user"
msgstr "Изменить пользователя"
#: mailu/ui/templates/user/forward.html:4
msgid "Forward emails"
msgstr "Перенаправлять письма"
#: mailu/ui/templates/user/list.html:4
msgid "User list"
msgstr "Список пользователей"
#: mailu/ui/templates/user/list.html:12
msgid "Add user"
msgstr "Добавить пользователя"
#: mailu/ui/templates/user/list.html:19 mailu/ui/templates/user/settings.html:4
msgid "User settings"
msgstr "Настройки пользователя"
#: mailu/ui/templates/user/list.html:21
msgid "Features"
msgstr "Функции"
#: mailu/ui/templates/user/password.html:4
msgid "Password update"
msgstr "Изменение пароля"
#: mailu/ui/templates/user/reply.html:4
msgid "Automatic reply"
msgstr "Автоматический ответ"
#: mailu/ui/forms.py:49
msgid "Maximum user quota"
msgstr "Квота на пользователя"
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr "Хранить копии писем"
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr "Хранить письма на сервере"
#: mailu/ui/templates/fetch/list.html:21
msgid "Keep emails"
msgstr "Сохранять письма"
#: mailu/ui/templates/fetch/list.html:35
msgid "yes"
msgstr "да"
#: mailu/ui/templates/fetch/list.html:35
msgid "no"
msgstr "нет"
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr "Имя альтернативного домена"
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr "Имя релейного домена"
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr "Удаленный хост"
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr "Релейные домены"
#: mailu/ui/templates/alternative/create.html:4
msgid "Create alternative domain"
msgstr "Создать альтернативный домен"
#: mailu/ui/templates/alternative/list.html:4
msgid "Alternative domain list"
msgstr "Список альтернативных доменов"
#: mailu/ui/templates/alternative/list.html:12
msgid "Add alternative"
msgstr "Добавить альтернативный домен"
#: mailu/ui/templates/alternative/list.html:19
msgid "Name"
msgstr "Имя"
#: mailu/ui/templates/domain/list.html:39
msgid "Alternatives"
msgstr "Альтернативные домены"
#: mailu/ui/templates/relay/create.html:4
msgid "New relay domain"
msgstr "Новый релейный домен"
#: mailu/ui/templates/relay/edit.html:4
msgid "Edit relayd domain"
msgstr "Изменить релейный домен"
#: mailu/ui/templates/relay/list.html:4
msgid "Relayed domain list"
msgstr "Список релейных доменов"
#: mailu/ui/templates/relay/list.html:9
msgid "New relayed domain"
msgstr "Новый релейный домен"
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr "Ваш токен (перепишите его, больше он показываться не будет)"
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr "Авторизованные IP-адреса"
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr "Авторизационные токены"
#: mailu/ui/templates/sidebar.html:72
msgid "Go to"
msgstr "Перейти к"
#: mailu/ui/templates/sidebar.html:76
msgid "Webmail"
msgstr "Электронная почта"
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr "Сайт"
#: mailu/ui/templates/token/create.html:4
msgid "Create an authentication token"
msgstr "Создать токен авторизации"
#: mailu/ui/templates/token/list.html:12
msgid "New token"
msgstr "Новый токен"
#: mailu/ui/templates/user/create.html:15
msgid "General"
msgstr "Общие"
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr "Функции и квоты"
#: mailu/ui/templates/user/settings.html:14
msgid "General settings"
msgstr "Общие настройки"
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr "Антиспам"
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr "Порог спам-фильтра"
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr ""
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr ""
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr ""
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr ""
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr ""
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr ""
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr ""
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr ""
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr ""
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr ""
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr ""
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/signup.html:13
msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr ""
#: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
" please contact your DNS provider or administrator. Also, please wait a\n"
" couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires."
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr ""

View File

@@ -15,21 +15,23 @@ msgstr "Ogiltig adress"
msgid "Confirm"
msgstr "Bekräfta"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:67
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr "E-post"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:68 mailu/ui/forms.py:85
#: mailu/ui/forms.py:146
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr "Lösenord"
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:99
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr "Logga in"
#: mailu/ui/forms.py:46 mailu/ui/templates/domain/details.html:21
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr "Domännamn"
@@ -42,44 +44,45 @@ msgstr "Max antal användare"
msgid "Maximum alias count"
msgstr "Max antal alias"
#: mailu/ui/forms.py:50 mailu/ui/forms.py:62 mailu/ui/forms.py:73
#: mailu/ui/forms.py:112 mailu/ui/forms.py:124
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr "Kommentar"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:56 mailu/ui/forms.py:63
#: mailu/ui/forms.py:116 mailu/ui/forms.py:125
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr "Skapa"
#: mailu/ui/forms.py:69
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr "Bekräfta lösenord"
#: mailu/ui/forms.py:70 mailu/ui/templates/user/list.html:22
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr "Quota"
#: mailu/ui/forms.py:71
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr "Tillåt IMAP"
#: mailu/ui/forms.py:72
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr "Tillåt POP3"
#: mailu/ui/forms.py:74
#: mailu/ui/forms.py:85
msgid "Save"
msgstr "Spara"
#: mailu/ui/forms.py:78
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr "Visat namn"
#: mailu/ui/forms.py:79
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr "Aktivera spamfilter"
@@ -87,80 +90,82 @@ msgstr "Aktivera spamfilter"
msgid "Spam filter threshold"
msgstr "Spamfilter gräns"
#: mailu/ui/forms.py:81
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr "Spara inställningar"
#: mailu/ui/forms.py:86
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr "Lösenordskoll"
#: mailu/ui/forms.py:87 mailu/ui/templates/sidebar.html:16
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr "Uppdatera lösenord"
#: mailu/ui/forms.py:91
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr "Aktivera vidarebefordring"
#: mailu/ui/forms.py:94 mailu/ui/forms.py:123
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr "Destination"
#: mailu/ui/forms.py:96 mailu/ui/forms.py:104
#: mailu/ui/forms.py:120
msgid "Update"
msgstr "Uppdatera"
#: mailu/ui/forms.py:100
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr "Aktivera autosvar"
#: mailu/ui/forms.py:101
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr "Svar ämne"
#: mailu/ui/forms.py:102
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr "Svar meddelande"
#: mailu/ui/forms.py:120
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr "Alias"
#: mailu/ui/forms.py:122
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr "Använd SQL-liknande syntax (t.ex. för catch-all alias)"
#: mailu/ui/forms.py:129
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr "Admin e-post"
#: mailu/ui/forms.py:130 mailu/ui/forms.py:135 mailu/ui/forms.py:148
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr "Skicka in"
#: mailu/ui/forms.py:134
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr "Manager e-post"
#: mailu/ui/forms.py:139
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr "Protokoll"
#: mailu/ui/forms.py:142
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr "Hostnamn eller IP"
#: mailu/ui/forms.py:143
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr "TCP port"
#: mailu/ui/forms.py:144
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr "Aktivera TLS"
#: mailu/ui/forms.py:145 mailu/ui/templates/fetch/list.html:20
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr "Användarnamn"
@@ -188,34 +193,6 @@ msgstr "Ditt konto"
msgid "to access the administration tools"
msgstr "att komma åt administrationsverktygen"
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:44
msgid "Services status"
msgstr "Tjänster status"
#: mailu/ui/templates/services.html:10
msgid "Service"
msgstr "Tjänst"
#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11
msgid "Status"
msgstr "Status"
#: mailu/ui/templates/services.html:12
msgid "PID"
msgstr "PID"
#: mailu/ui/templates/services.html:13
msgid "Image"
msgstr "Bild"
#: mailu/ui/templates/services.html:14
msgid "Started"
msgstr "Startad"
#: mailu/ui/templates/services.html:15
msgid "Last update"
msgstr "Senast uppdaterad"
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
msgstr "Mitt konto"
@@ -224,28 +201,28 @@ msgstr "Mitt konto"
msgid "Settings"
msgstr "Inställningar"
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr "Auto-forward"
#: mailu/ui/templates/sidebar.html:26 mailu/ui/templates/user/list.html:36
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-reply"
msgstr "Autosvar"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:31
#: mailu/ui/templates/user/list.html:37
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr "Hämtade konton"
#: mailu/ui/templates/sidebar.html:93
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr "Logga ut"
#: mailu/ui/templates/sidebar.html:40
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr "Administration"
#: mailu/ui/templates/sidebar.html:54
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr "Administratörer"
@@ -253,7 +230,7 @@ msgstr "Administratörer"
msgid "Mail domains"
msgstr "Domäner"
#: mailu/ui/templates/sidebar.html:87
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr "Hjälp"
@@ -341,27 +318,27 @@ msgstr "Ny domän"
msgid "Domain details"
msgstr "Domändetaljer"
#: mailu/ui/templates/domain/details.html:13
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr "Generera nycklar"
#: mailu/ui/templates/domain/details.html:25
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr "DNS MX post"
#: mailu/ui/templates/domain/details.html:29
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr "DNS SPF post"
#: mailu/ui/templates/domain/details.html:36
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr "Publik DKIM-nyckel"
#: mailu/ui/templates/domain/details.html:40
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr "DNS DKIM post"
#: mailu/ui/templates/domain/details.html:44
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr "DNS DMARC post"
@@ -433,15 +410,15 @@ msgstr "Managerlista"
msgid "Add manager"
msgstr "Skapa manager"
#: mailu/ui/forms.py:152
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr "Publikt meddelande ämne"
#: mailu/ui/forms.py:154
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr "Publikt meddelande"
#: mailu/ui/forms.py:156
#: mailu/ui/forms.py:172
msgid "Send"
msgstr "Skicka"
@@ -453,7 +430,7 @@ msgstr "Publikt meddelande"
msgid "from"
msgstr "från"
#: mailu/ui/templates/sidebar.html:49
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr "Meddelande"
@@ -497,11 +474,11 @@ msgstr "Automatiskt svar"
msgid "Maximum user quota"
msgstr "Max användar-quota"
#: mailu/ui/forms.py:92
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr "Behåll en kopia av e-posten"
#: mailu/ui/forms.py:147
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr "Behåll e-post på servern"
@@ -517,19 +494,19 @@ msgstr "ja"
msgid "no"
msgstr "nej"
#: mailu/ui/forms.py:55
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr "Aleternativt namn"
#: mailu/ui/forms.py:60
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr "Reläade domännamn"
#: mailu/ui/forms.py:61 mailu/ui/templates/relay/list.html:18
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr "Server"
#: mailu/ui/templates/sidebar.html:59
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr "Reläade domäner"
@@ -569,15 +546,15 @@ msgstr "Reläade domäner"
msgid "New relayed domain"
msgstr "Ny reläad domän"
#: mailu/ui/forms.py:109
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr "Din token (notera, eftersom den inte kommer att visas igen)"
#: mailu/ui/forms.py:114 mailu/ui/templates/token/list.html:20
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr "Autentiserat IP"
#: mailu/ui/templates/sidebar.html:36 mailu/ui/templates/token/list.html:4
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr "Autentiserade tokens"
@@ -589,7 +566,7 @@ msgstr "Gå till"
msgid "Webmail"
msgstr "Webmail"
#: mailu/ui/templates/sidebar.html:82
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr "Websida"
@@ -605,7 +582,7 @@ msgstr "Ny token"
msgid "General"
msgstr "Allmänt"
#: mailu/ui/templates/user/create.html:21
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr "Funktioner och quota"
@@ -613,11 +590,85 @@ msgstr "Funktioner och quota"
msgid "General settings"
msgstr "Allmäna inställningar"
#: mailu/ui/templates/user/settings.html:18
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr "Antispam"
#: mailu/ui/forms.py:80
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr ""
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr ""
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr ""
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr ""
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr ""
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr ""
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr ""
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr ""
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr ""
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr ""
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr ""
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr ""
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/signup.html:13
msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr ""
#: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
" please contact your DNS provider or administrator. Also, please wait a\n"
" couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires."
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr ""

View File

@@ -15,21 +15,23 @@ msgstr "无效的邮件地址"
msgid "Confirm"
msgstr "确认"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:67
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr "电子邮件"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:68 mailu/ui/forms.py:85
#: mailu/ui/forms.py:146
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr "密码"
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:99
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr "注册"
#: mailu/ui/forms.py:46 mailu/ui/templates/domain/details.html:21
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr "域名"
@@ -42,44 +44,45 @@ msgstr "最大用户数"
msgid "Maximum alias count"
msgstr "最大别名数"
#: mailu/ui/forms.py:50 mailu/ui/forms.py:62 mailu/ui/forms.py:73
#: mailu/ui/forms.py:112 mailu/ui/forms.py:124
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr "说明"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:56 mailu/ui/forms.py:63
#: mailu/ui/forms.py:116 mailu/ui/forms.py:125
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr "创建"
#: mailu/ui/forms.py:69
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr "确认密码"
#: mailu/ui/forms.py:70 mailu/ui/templates/user/list.html:22
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr "配额"
#: mailu/ui/forms.py:71
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr "允许IMAP访问"
#: mailu/ui/forms.py:72
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr "允许POP3访问"
#: mailu/ui/forms.py:74
#: mailu/ui/forms.py:85
msgid "Save"
msgstr "保存"
#: mailu/ui/forms.py:78
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr "显示名称"
#: mailu/ui/forms.py:79
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr "启用垃圾邮件过滤"
@@ -87,80 +90,82 @@ msgstr "启用垃圾邮件过滤"
msgid "Spam filter threshold"
msgstr "垃圾邮件过滤器阈值"
#: mailu/ui/forms.py:81
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr "保存设置"
#: mailu/ui/forms.py:86
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr "检查密码"
#: mailu/ui/forms.py:87 mailu/ui/templates/sidebar.html:16
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr "更新密码"
#: mailu/ui/forms.py:91
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr "启用转发"
#: mailu/ui/forms.py:94 mailu/ui/forms.py:123
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr "目的地址"
#: mailu/ui/forms.py:96 mailu/ui/forms.py:104
#: mailu/ui/forms.py:120
msgid "Update"
msgstr "更新"
#: mailu/ui/forms.py:100
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr "启用自动回复"
#: mailu/ui/forms.py:101
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr "回复主题"
#: mailu/ui/forms.py:102
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr "回复正文"
#: mailu/ui/forms.py:120
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr "别名"
#: mailu/ui/forms.py:122
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr "使用SQL LIKE语法例如用于全部别名"
#: mailu/ui/forms.py:129
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr "管理员邮箱"
#: mailu/ui/forms.py:130 mailu/ui/forms.py:135 mailu/ui/forms.py:148
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr "提交"
#: mailu/ui/forms.py:134
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr "管理员邮箱"
#: mailu/ui/forms.py:139
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr "协议"
#: mailu/ui/forms.py:142
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr "主机名或IP"
#: mailu/ui/forms.py:143
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr "TCP端口"
#: mailu/ui/forms.py:144
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr "启用TLS"
#: mailu/ui/forms.py:145 mailu/ui/templates/fetch/list.html:20
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr "用户名"
@@ -170,7 +175,7 @@ msgstr "确认操作"
#: mailu/ui/templates/confirm.html:13
msgid "You are about to %(action)s. Please confirm your action."
msgstr "即将%(action)s请确认您的操作。"
msgstr "即将%(action)s请确认您的操作。"
#: mailu/ui/templates/docker-error.html:4
msgid "Docker error"
@@ -188,34 +193,6 @@ msgstr "你的帐户"
msgid "to access the administration tools"
msgstr "访问管理员工具"
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:44
msgid "Services status"
msgstr "服务状态"
#: mailu/ui/templates/services.html:10
msgid "Service"
msgstr "服务"
#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11
msgid "Status"
msgstr "状态"
#: mailu/ui/templates/services.html:12
msgid "PID"
msgstr "进程ID"
#: mailu/ui/templates/services.html:13
msgid "Image"
msgstr "镜像"
#: mailu/ui/templates/services.html:14
msgid "Started"
msgstr "已开始"
#: mailu/ui/templates/services.html:15
msgid "Last update"
msgstr "最后更新"
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
msgstr "我的帐户"
@@ -224,28 +201,28 @@ msgstr "我的帐户"
msgid "Settings"
msgstr "设置"
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr "自动转发"
#: mailu/ui/templates/sidebar.html:26 mailu/ui/templates/user/list.html:36
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-reply"
msgstr "自动回复"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:31
#: mailu/ui/templates/user/list.html:37
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr "代收帐户"
#: mailu/ui/templates/sidebar.html:93
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr "登出"
#: mailu/ui/templates/sidebar.html:40
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr "管理"
#: mailu/ui/templates/sidebar.html:54
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr "管理员"
@@ -253,13 +230,13 @@ msgstr "管理员"
msgid "Mail domains"
msgstr "邮件域"
#: mailu/ui/templates/sidebar.html:87
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr "帮帮我"
msgstr "帮"
#: mailu/ui/templates/working.html:4
msgid "We are still working on this feature!"
msgstr "开发中……"
msgstr "该功能开发中……"
#: mailu/ui/templates/admin/create.html:4
msgid "Add a global administrator"
@@ -341,27 +318,27 @@ msgstr "新域"
msgid "Domain details"
msgstr "域详情"
#: mailu/ui/templates/domain/details.html:13
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr "重新生成密钥"
#: mailu/ui/templates/domain/details.html:25
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr "DNS MX条目"
#: mailu/ui/templates/domain/details.html:29
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr "DNS SPF条目"
#: mailu/ui/templates/domain/details.html:36
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr "DKIM公钥"
#: mailu/ui/templates/domain/details.html:40
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr "DNS DKIM条目"
#: mailu/ui/templates/domain/details.html:44
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr "DNS DMARC条目"
@@ -433,15 +410,15 @@ msgstr "管理员列表"
msgid "Add manager"
msgstr "添加管理员"
#: mailu/ui/forms.py:152
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr "公告主题"
#: mailu/ui/forms.py:154
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr "公告正文"
#: mailu/ui/forms.py:156
#: mailu/ui/forms.py:172
msgid "Send"
msgstr "发送"
@@ -453,7 +430,7 @@ msgstr "公告"
msgid "from"
msgstr "来自"
#: mailu/ui/templates/sidebar.html:49
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr "公告"
@@ -497,13 +474,13 @@ msgstr "自动回复"
msgid "Maximum user quota"
msgstr "最大用户容量"
#: mailu/ui/forms.py:92
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr "保留电子邮件副本"
#: mailu/ui/forms.py:147
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr "电子邮件保存在服务器上"
msgstr "保留电子邮件在服务器上"
#: mailu/ui/templates/fetch/list.html:21
msgid "Keep emails"
@@ -517,19 +494,19 @@ msgstr "是"
msgid "no"
msgstr "否"
#: mailu/ui/forms.py:55
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr "替代名称"
#: mailu/ui/forms.py:60
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr "中继域域名"
#: mailu/ui/forms.py:61 mailu/ui/templates/relay/list.html:18
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr "远程主机"
#: mailu/ui/templates/sidebar.html:59
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr "中继域"
@@ -569,15 +546,15 @@ msgstr "中继域列表"
msgid "New relayed domain"
msgstr "新的中继域"
#: mailu/ui/forms.py:109
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr "您的令牌(请保存下来,它只显示这一次)"
msgstr "您的令牌(请记录,它只显示这一次)"
#: mailu/ui/forms.py:114 mailu/ui/templates/token/list.html:20
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr "授权IP"
#: mailu/ui/templates/sidebar.html:36 mailu/ui/templates/token/list.html:4
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr "认证令牌"
@@ -589,7 +566,7 @@ msgstr "转到"
msgid "Webmail"
msgstr "网页邮箱"
#: mailu/ui/templates/sidebar.html:82
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr "网站"
@@ -603,9 +580,9 @@ msgstr "新的令牌"
#: mailu/ui/templates/user/create.html:15
msgid "General"
msgstr "一般"
msgstr "通用"
#: mailu/ui/templates/user/create.html:21
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr "功能和配额"
@@ -613,11 +590,85 @@ msgstr "功能和配额"
msgid "General settings"
msgstr "常规设置"
#: mailu/ui/templates/user/settings.html:18
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr "反垃圾邮件"
#: mailu/ui/forms.py:80
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr "垃圾邮件过滤器容忍度"
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr ""
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr ""
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr ""
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr ""
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr ""
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr ""
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr ""
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr ""
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr ""
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr ""
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr ""
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/signup.html:13
msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr ""
#: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
" please contact your DNS provider or administrator. Also, please wait a\n"
" couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires."
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr ""

View File

@@ -1,4 +1,4 @@
from mailu import db, models
from mailu import models
from mailu.ui import forms
import flask

View File

@@ -6,6 +6,7 @@ import flask_login
import flask_wtf
import re
LOCALPART_REGEX = "^[a-zA-Z0-9.!#$%&*+/=?^_`{|}~-]+$"
class DestinationField(fields.SelectMultipleField):
""" Allow for multiple emails selection from current user choices and
@@ -47,37 +48,62 @@ class DomainForm(flask_wtf.FlaskForm):
max_users = fields_.IntegerField(_('Maximum user count'), default=10)
max_aliases = fields_.IntegerField(_('Maximum alias count'), default=10)
max_quota_bytes = fields_.IntegerSliderField(_('Maximum user quota'), default=0)
signup_enabled = fields.BooleanField(_('Enable sign-up'), default=False)
comment = fields.StringField(_('Comment'))
submit = fields.SubmitField(_('Save'))
class DomainSignupForm(flask_wtf.FlaskForm):
name = fields.StringField(_('Domain name'), [validators.DataRequired()])
localpart = fields.StringField(_('Initial admin'), [validators.DataRequired()])
pw = fields.PasswordField(_('Admin password'), [validators.DataRequired()])
pw2 = fields.PasswordField(_('Confirm password'), [validators.EqualTo('pw')])
captcha = flask_wtf.RecaptchaField()
submit = fields.SubmitField(_('Create'))
class AlternativeForm(flask_wtf.FlaskForm):
name = fields.StringField(_('Alternative name'), [validators.DataRequired()])
submit = fields.SubmitField(_('Create'))
submit = fields.SubmitField(_('Save'))
class RelayForm(flask_wtf.FlaskForm):
name = fields.StringField(_('Relayed domain name'), [validators.DataRequired()])
smtp = fields.StringField(_('Remote host'))
comment = fields.StringField(_('Comment'))
submit = fields.SubmitField(_('Create'))
submit = fields.SubmitField(_('Save'))
class UserForm(flask_wtf.FlaskForm):
localpart = fields.StringField(_('E-mail'), [validators.DataRequired()])
localpart = fields.StringField(_('E-mail'), [validators.DataRequired(), validators.Regexp(LOCALPART_REGEX)])
pw = fields.PasswordField(_('Password'), [validators.DataRequired()])
pw2 = fields.PasswordField(_('Confirm password'), [validators.EqualTo('pw')])
quota_bytes = fields_.IntegerSliderField(_('Quota'), default=1000000000)
enable_imap = fields.BooleanField(_('Allow IMAP access'), default=True)
enable_pop = fields.BooleanField(_('Allow POP3 access'), default=True)
comment = fields.StringField(_('Comment'))
enabled = fields.BooleanField(_('Enabled'), default=True)
submit = fields.SubmitField(_('Save'))
class UserSignupForm(flask_wtf.FlaskForm):
localpart = fields.StringField(_('Email address'), [validators.DataRequired(), validators.Regexp(LOCALPART_REGEX)])
pw = fields.PasswordField(_('Password'), [validators.DataRequired()])
pw2 = fields.PasswordField(_('Confirm password'), [validators.EqualTo('pw')])
submit = fields.SubmitField(_('Sign up'))
class UserSignupFormCaptcha(UserSignupForm):
captcha = flask_wtf.RecaptchaField()
class UserSettingsForm(flask_wtf.FlaskForm):
displayed_name = fields.StringField(_('Displayed name'))
spam_enabled = fields.BooleanField(_('Enable spam filter'))
spam_threshold = fields_.IntegerSliderField(_('Spam filter tolerance'))
forward_enabled = fields.BooleanField(_('Enable forwarding'))
forward_keep = fields.BooleanField(_('Keep a copy of the emails'))
forward_destination = fields.StringField(
_('Destination'), [validators.Optional(), validators.Email()]
)
submit = fields.SubmitField(_('Save settings'))
@@ -87,20 +113,12 @@ class UserPasswordForm(flask_wtf.FlaskForm):
submit = fields.SubmitField(_('Update password'))
class UserForwardForm(flask_wtf.FlaskForm):
forward_enabled = fields.BooleanField(_('Enable forwarding'))
forward_keep = fields.BooleanField(_('Keep a copy of the emails'))
forward_destination = fields.StringField(
_('Destination'), [validators.Optional(), validators.Email()]
)
submit = fields.SubmitField(_('Update'))
class UserReplyForm(flask_wtf.FlaskForm):
reply_enabled = fields.BooleanField(_('Enable automatic reply'))
reply_subject = fields.StringField(_('Reply subject'))
reply_body = fields.StringField(_('Reply body'),
widget=widgets.TextArea())
reply_startdate = fields.html5.DateField(_('Start of vacation'))
reply_enddate = fields.html5.DateField(_('End of vacation'))
submit = fields.SubmitField(_('Update'))
@@ -114,7 +132,7 @@ class TokenForm(flask_wtf.FlaskForm):
ip = fields.StringField(
_('Authorized IP'), [validators.Optional(), validators.IPAddress()]
)
submit = fields.SubmitField(_('Create'))
submit = fields.SubmitField(_('Save'))
class AliasForm(flask_wtf.FlaskForm):
@@ -123,7 +141,7 @@ class AliasForm(flask_wtf.FlaskForm):
_('Use SQL LIKE Syntax (e.g. for catch-all aliases)'))
destination = DestinationField(_('Destination'))
comment = fields.StringField(_('Comment'))
submit = fields.SubmitField(_('Create'))
submit = fields.SubmitField(_('Save'))
class AdminForm(flask_wtf.FlaskForm):

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

View File

@@ -5,7 +5,7 @@
{% block styles %}
{{super()}}
<link rel="stylesheet" href="{{ url_for('.static', filename='select2/css/select2.min.css') }}">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<link rel="stylesheet" href="{{ url_for('.static', filename='fontawesome/css/font-awesome.min.css') }}">
<link rel="stylesheet" href="{{ url_for('.static', filename='adminlte/css/AdminLTE.min.css') }}">
<link rel="stylesheet" href="{{ url_for('.static', filename='adminlte/css/skin-blue.min.css') }}">
<link rel="stylesheet" href="{{ url_for('.static', filename='app.css') }}">

View File

@@ -0,0 +1,65 @@
{% extends "base.html" %}
{% block title %}
{% trans %}Client setup{% endtrans %}
{% endblock %}
{% block subtitle %}
configure your email client
{% endblock %}
{% block content %}
{% call macros.box(title="Incoming mail") %}
<table class="table table-bordered">
<tbody>
<tr>
<th>{% trans %}Mail protocol{% endtrans %}</th>
<td>IMAP</td>
</tr>
<tr>
<th>{% trans %}TCP port{% endtrans %}</th>
<td>{{ "143" if config["TLS_FLAVOR"] == "notls" else "993 (TLS) or 143 (STARTTLS)" }}</td>
</tr>
<tr>
<th>{% trans %}Server name{% endtrans %}</th>
<td><pre>{{ config["HOSTNAMES"].split(',')[0] }}</pre></td>
</tr>
<tr>
<th>{% trans %}Username{% endtrans %}</th>
<td><pre>{{ current_user if current_user.is_authenticated else "******" }}</pre></td>
</tr>
<tr>
<th>{% trans %}Password{% endtrans %}</th>
<td><pre>*******</pre></td>
</tr>
</tbody>
</table>
{% endcall %}
{% call macros.box(title="Outgoing mail") %}
<table class="table table-bordered">
<tbody>
<tr>
<th>{% trans %}Mail protocol{% endtrans %}</th>
<td>SMTP</td>
</tr>
<tr>
<th>{% trans %}TCP port{% endtrans %}</th>
<td>{{ "25" if config["TLS_FLAVOR"] == "notls" else "465 (TLS) or 587 (STARTTLS)" }}</td>
</tr>
<tr>
<th>{% trans %}Server name{% endtrans %}</th>
<td><pre>{{ config["HOSTNAMES"].split(',')[0] }}</pre></td>
</tr>
<tr>
<th>{% trans %}Username{% endtrans %}</th>
<td><pre>{{ current_user or "******" }}</pre></td>
</tr>
<tr>
<th>{% trans %}Password{% endtrans %}</th>
<td><pre>*******</pre></td>
</tr>
</tbody>
</table>
{% endcall %}
{% endblock %}

View File

@@ -13,6 +13,7 @@
{{ macros.form_field(form.max_quota_bytes, step=1000000000, max=50000000000,
prepend='<span class="input-group-addon"><span id="quota">'+((form.max_quota_bytes.data//1000000000).__str__() if form.max_quota_bytes.data else '∞')+'</span> GiB</span>',
oninput='$("#quota").text(this.value == 0 ? "∞" : this.value/1000000000);') }}
{{ macros.form_field(form.signup_enabled) }}
{{ macros.form_field(form.comment) }}
{{ macros.form_field(form.submit) }}
</form>

View File

@@ -10,7 +10,13 @@
{% block main_action %}
{% if current_user.global_admin %}
<a class="btn btn-primary" href="{{ url_for(".domain_genkeys", domain_name=domain.name) }}">{% trans %}Regenerate keys{% endtrans %}</a>
<a class="btn btn-primary" href="{{ url_for(".domain_genkeys", domain_name=domain.name) }}">
{% if domain.dkim_publickey %}
{% trans %}Regenerate keys{% endtrans %}
{% else %}
{% trans %}Generate keys{% endtrans %}
{% endif %}
</a>
{% endif %}
{% endblock %}
@@ -22,7 +28,7 @@
<td>{{ domain.name }}</td>
</tr>
<tr>
<th>{% trans %}DNS MX entry{% endtrans %}</th>
<th>{% trans %}DNS MX entry{% endtrans %} <i class="fa {{ 'fa-check-circle' if domain.check_mx() else 'fa-exclamation-circle' }}"></i></th>
<td><pre>{{ domain.name }}. 600 IN MX 10 {{ hostname }}.</pre></td>
</tr>
<tr>

View File

@@ -0,0 +1,36 @@
{% extends "base.html" %}
{% block title %}
{% trans %}Register a domain{% endtrans %}
{% endblock %}
{% block content %}
<form class="form" method="post" role="form">
{{ form.hidden_tag() }}
{% call macros.box(title="Requirements") %}
<p>{% trans %}In order to register a new domain, you must first setup the
domain zone so that the domain <code>MX</code> points to this server{% endtrans %}
(<code>{{ config["HOSTNAMES"].split(",")[0] }}</code>).
</p>
<p>
{% trans %}If you do not know how to setup an <code>MX</code> record for your DNS zone,
please contact your DNS provider or administrator. Also, please wait a
couple minutes after the <code>MX</code> is set so the local server cache
expires.{% endtrans %}
</p>
{% endcall %}
{% call macros.box() %}
{% if form.localpart %}
{{ macros.form_fields((form.localpart, form.name), append='<span class="input-group-addon">@</span>') }}
{{ macros.form_fields((form.pw, form.pw2)) }}
{% else %}
{{ macros.form_field(form.name) }}
{% endif %}
{{ macros.form_field(form.captcha) }}
{{ macros.form_field(form.submit) }}
{% endcall %}
</form>
{% endblock %}

View File

@@ -22,6 +22,10 @@
{{ macros.form_field(form.password) }}
{% endcall %}
{% call macros.box(title="Settings") %}
{{ macros.form_field(form.keep) }}
{% endcall %}
{{ macros.form_field(form.submit) }}
</form>
{% endblock %}

View File

@@ -1,28 +0,0 @@
{% extends "base.html" %}
{% block title %}
{% trans %}Services status{% endtrans %}
{% endblock %}
{% block content %}
{% call macros.table() %}
<tr>
<th>{% trans %}Service{% endtrans %}</th>
<th>{% trans %}Status{% endtrans %}</th>
<th>{% trans %}PID{% endtrans %}</th>
<th>{% trans %}Image{% endtrans %}</th>
<th>{% trans %}Started{% endtrans %}</th>
<th>{% trans %}Last update{% endtrans %}</th>
</tr>
{% for name, container in containers.items() %}
<tr>
<td>{{ name }}</td>
<td><span class="label label-{{ "success" if container['State']['Running'] else "danger" }}">{{ container['State']['Status'] }}</span></td>
<td>{{ container['State']['Pid'] }}</td>
<td>{{ container['Config']['Image'] }}</td>
<td>{{ container['State']['StartedAt'] }}</td>
<td>{{ container['Image']['Created'] }}
</tr>
{% endfor %}
{% endcall %}
{% endblock %}

View File

@@ -16,11 +16,6 @@
<i class="fa fa-lock"></i> <span>{% trans %}Update password{% endtrans %}</span>
</a>
</li>
<li>
<a href="{{ url_for('.user_forward') }}">
<i class="fa fa-share"></i> <span>{% trans %}Auto-forward{% endtrans %}</span>
</a>
</li>
<li>
<a href="{{ url_for('.user_reply') }}">
<i class="fa fa-plane"></i> <span>{% trans %}Auto-reply{% endtrans %}</span>
@@ -37,13 +32,10 @@
</a>
</li>
{% if current_user.manager_of or current_user.global_admin %}
<li class="header">{% trans %}Administration{% endtrans %}</li>
{% endif %}
{% if current_user.global_admin %}
<li>
<a href="{{ url_for('.services') }}">
<i class="fa fa-dashboard"></i> <span>{% trans %}Services status{% endtrans %}</span>
</a>
</li>
<li>
<a href="{{ url_for('.announcement') }}">
<i class="fa fa-bullhorn"></i> <span>{% trans %}Announcement{% endtrans %}</span>
@@ -82,6 +74,11 @@
</a>
</li>
{% endif %}
<li>
<a href="{{ url_for('.client') }}">
<i class="fa fa-laptop"></i> <span>{% trans %}Client setup{% endtrans %}</span>
</a>
</li>
<li>
<a href="{{ config["WEBSITE"] }}">
<i class="fa fa-globe"></i> <span>{% trans %}Website{% endtrans %}</span>
@@ -92,6 +89,13 @@
<i class="fa fa-life-ring"></i> <span>{% trans %}Help{% endtrans %}</span>
</a>
</li>
{% if config['DOMAIN_REGISTRATION'] %}
<li>
<a href="{{ url_for('.domain_signup') }}">
<i class="fa fa-plus-square"></i> <span>{% trans %}Register a domain{% endtrans %}</span>
</a>
</li>
{% endif %}
{% if current_user.is_authenticated %}
<li>
<a href="{{ url_for('.logout') }}">
@@ -100,10 +104,17 @@
</li>
{% else %}
<li>
<a href="#">
<a href="{{ url_for('.login') }}">
<i class="fa fa-sign-in"></i> <span>{% trans %}Sign in{% endtrans %}</span>
</a>
</li>
{% if signup_domains %}
<li>
<a href="{{ url_for('.user_signup') }}">
<i class="fa fa-user-plus"></i> <span>{% trans %}Sign up{% endtrans %}</span>
</a>
</li>
{% endif %}
{% endif %}
</ul>
</section>

View File

@@ -16,12 +16,13 @@
{{ macros.form_field(form.localpart, append='<span class="input-group-addon">@'+domain.name+'</span>') }}
{{ macros.form_fields((form.pw, form.pw2)) }}
{{ macros.form_field(form.comment) }}
{{ macros.form_field(form.enabled) }}
{% endcall %}
{% call macros.box(_("Features and quotas"), theme="success") %}
{{ macros.form_field(form.quota_bytes, step=1000000000, max=(max_quota_bytes or domain.max_quota_bytes or 50000000000),
prepend='<span class="input-group-addon"><span id="quota">'+(form.quota_bytes.data//1000000000).__str__()+'</span> GiB</span>',
oninput='$("#quota").text(this.value/1000000000);') }}
prepend='<span class="input-group-addon"><span id="quota">'+((form.quota_bytes.data//1000000000).__str__() if form.quota_bytes.data else '∞')+'</span> GiB</span>',
oninput='$("#quota").text(this.value == 0 ? "∞" : this.value/1000000000);') }}
{{ macros.form_field(form.enable_imap) }}
{{ macros.form_field(form.enable_pop) }}
{% endcall %}

View File

@@ -32,7 +32,6 @@
</td>
<td>
<a href="{{ url_for('.user_settings', user_email=user.email) }}" title="{% trans %}Settings{% endtrans %}"><i class="fa fa-wrench"></i></a>&nbsp;
<a href="{{ url_for('.user_forward', user_email=user.email) }}" title="{% trans %}Auto-forward{% endtrans %}"><i class="fa fa-share"></i></a>&nbsp;
<a href="{{ url_for('.user_reply', user_email=user.email) }}" title="{% trans %}Auto-reply{% endtrans %}"><i class="fa fa-plane"></i></a>&nbsp;
<a href="{{ url_for('.fetch_list', user_email=user.email) }}" title="{% trans %}Fetched accounts{% endtrans %}"><i class="fa fa-download"></i></a>&nbsp;
</td>
@@ -41,7 +40,7 @@
{% if user.enable_imap %}<span class="label label-info">imap</span>{% endif %}
{% if user.enable_pop %}<span class="label label-info">pop3</span>{% endif %}
</td>
<td>{{ user.quota_bytes | filesizeformat }}</td>
<td>{{ user.quota_bytes_used | filesizeformat }} / {{ (user.quota_bytes | filesizeformat) if user.quota_bytes else '∞' }}</td>
<td>{{ user.comment or '-' }}</td>
<td>{{ user.created_at }}</td>
<td>{{ user.updated_at or '' }}</td>

View File

@@ -13,7 +13,7 @@
<form class="form" method="post" role="form">
{{ form.hidden_tag() }}
{{ macros.form_field(form.reply_enabled,
onchange="if(this.checked){$('#reply_subject,#reply_body,#reply_enddate').removeAttr('readonly')}
onchange="if(this.checked){$('#reply_subject,#reply_body,#reply_enddate,#reply_startdate').removeAttr('readonly')}
else{$('#reply_subject,#reply_body,#reply_enddate').attr('readonly', '')}") }}
{{ macros.form_field(form.reply_subject,
**{("rw" if user.reply_enabled else "readonly"): ""}) }}
@@ -21,6 +21,9 @@
**{("rw" if user.reply_enabled else "readonly"): ""}) }}
{{ macros.form_field(form.reply_enddate,
**{("rw" if user.reply_enabled else "readonly"): ""}) }}
{{ macros.form_field(form.reply_startdate,
**{("rw" if user.reply_enabled else "readonly"): ""}) }}
{{ macros.form_field(form.submit) }}
</form>
{% endcall %}

View File

@@ -11,9 +11,6 @@
{% block content %}
<form class="form" method="post" role="form">
{{ form.hidden_tag() }}
{% call macros.box(title=_("General settings")) %}
{{ macros.form_field(form.displayed_name) }}
{% endcall %}
{% call macros.box(title=_("Antispam")) %}
{{ macros.form_field(form.spam_enabled) }}
@@ -21,6 +18,17 @@
prepend='<span class="input-group-addon"><span id="threshold">'+form.spam_threshold.data.__str__()+'</span>&nbsp;/&nbsp;100</span>',
oninput='$("#threshold").text(this.value);') }}
{% endcall %}
{% call macros.box(title=_("Auto-forward")) %}
{{ macros.form_field(form.forward_enabled,
onchange="if(this.checked){$('#forward_destination,#forward_keep').removeAttr('disabled')}
else{$('#forward_destination,#forward_keep').attr('disabled', '')}") }}
{{ macros.form_field(form.forward_keep,
**{("enabled" if user.forward_enabled else "disabled"): ""}) }}
{{ macros.form_field(form.forward_destination,
**{("enabled" if user.forward_enabled else "disabled"): ""}) }}
{% endcall %}
{{ macros.form_field(form.submit) }}
</form>
{% endblock %}

View File

@@ -0,0 +1,23 @@
{% extends "base.html" %}
{% block title %}
{% trans %}Sign up{% endtrans %}
{% endblock %}
{% block subtitle %}
{{ domain }}
{% endblock %}
{% block content %}
<form class="form" method="post" role="form">
{{ form.hidden_tag() }}
{% call macros.box() %}
{{ macros.form_field(form.localpart, append='<span class="input-group-addon">@'+domain.name+'</span>') }}
{{ macros.form_fields((form.pw, form.pw2)) }}
{% if form.captcha %}
{{ macros.form_field(form.captcha) }}
{% endif %}
{{ macros.form_field(form.submit) }}
{% endcall %}
</form>
{% endblock %}

View File

@@ -0,0 +1,26 @@
{% extends "base.html" %}
{% block title %}
{% trans %}Sign up{% endtrans %}
{% endblock %}
{% block subtitle %}
{% trans %}pick a domain for the new account{% endtrans %}
{% endblock %}
{% block content %}
{% call macros.table() %}
<tr>
<th>{% trans %}Domain{% endtrans %}</th>
<th>{% trans %}Available slots{% endtrans %}</th>
<th>{% trans %}Quota{% endtrans %}</th>
</tr>
{% for domain_name, domain in available_domains.items() %}
<tr>
<td><a href="{{ url_for('.user_signup', domain_name=domain_name) }}">{{ domain_name }}</a></td>
<td>{{ domain.max_users - (domain.users | count) if domain.max_users else '∞' }}</td>
<td>{{ domain.max_quota_bytes or config['DEFAULT_QUOTA'] | filesizeformat }}</td>
</tr>
{% endfor %}
{% endcall %}
{% endblock %}

View File

@@ -1,4 +1,4 @@
from mailu import db, models
from mailu import models
from mailu.ui import ui, forms, access
import flask
@@ -25,7 +25,7 @@ def admin_create():
user = models.User.query.get(form.admin.data)
if user:
user.global_admin = True
db.session.commit()
models.db.session.commit()
flask.flash('User %s is now admin' % user)
return flask.redirect(flask.url_for('.admin_list'))
else:
@@ -40,7 +40,7 @@ def admin_delete(admin):
user = models.User.query.get(admin)
if user:
user.global_admin = False
db.session.commit()
models.db.session.commit()
flask.flash('User %s is no longer admin' % user)
return flask.redirect(flask.url_for('.admin_list'))
else:

View File

@@ -1,4 +1,4 @@
from mailu import db, models
from mailu import models
from mailu.ui import ui, forms, access
import flask
@@ -27,8 +27,8 @@ def alias_create(domain_name):
else:
alias = models.Alias(domain=domain)
form.populate_obj(alias)
db.session.add(alias)
db.session.commit()
models.db.session.add(alias)
models.db.session.commit()
flask.flash('Alias %s created' % alias)
return flask.redirect(
flask.url_for('.alias_list', domain_name=domain.name))
@@ -45,7 +45,7 @@ def alias_edit(alias):
form.localpart.validators = []
if form.validate_on_submit():
form.populate_obj(alias)
db.session.commit()
models.db.session.commit()
flask.flash('Alias %s updated' % alias)
return flask.redirect(
flask.url_for('.alias_list', domain_name=alias.domain.name))
@@ -59,8 +59,8 @@ def alias_edit(alias):
def alias_delete(alias):
alias = models.Alias.query.get(alias) or flask.abort(404)
domain = alias.domain
db.session.delete(alias)
db.session.commit()
models.db.session.delete(alias)
models.db.session.commit()
flask.flash('Alias %s deleted' % alias)
return flask.redirect(
flask.url_for('.alias_list', domain_name=domain.name))

View File

@@ -1,4 +1,4 @@
from mailu import db, models
from mailu import models
from mailu.ui import ui, forms, access
import flask
@@ -26,8 +26,8 @@ def alternative_create(domain_name):
else:
alternative = models.Alternative(domain=domain)
form.populate_obj(alternative)
db.session.add(alternative)
db.session.commit()
models.db.session.add(alternative)
models.db.session.commit()
flask.flash('Alternative domain %s created' % alternative)
return flask.redirect(
flask.url_for('.alternative_list', domain_name=domain.name))
@@ -41,8 +41,8 @@ def alternative_create(domain_name):
def alternative_delete(alternative):
alternative = models.Alternative.query.get(alternative) or flask.abort(404)
domain = alternative.domain
db.session.delete(alternative)
db.session.commit()
models.db.session.delete(alternative)
models.db.session.commit()
flask.flash('Alternative %s deleted' % alternative)
return flask.redirect(
flask.url_for('.alternative_list', domain_name=domain.name))

View File

@@ -1,11 +1,9 @@
from mailu import dockercli, app, db, models
from mailu import models
from mailu.ui import ui, forms, access
import flask
import flask_login
from urllib import parse
@ui.route('/', methods=["GET"])
@access.authenticated
@@ -20,7 +18,7 @@ def login():
user = models.User.login(form.email.data, form.pw.data)
if user:
flask_login.login_user(user)
endpoint = flask.request.args.get('next')
endpoint = flask.request.args.get('next', '.index')
return flask.redirect(flask.url_for(endpoint)
or flask.url_for('.index'))
else:
@@ -35,16 +33,6 @@ def logout():
return flask.redirect(flask.url_for('.index'))
@ui.route('/services', methods=['GET'])
@access.global_admin
def services():
try:
containers = dockercli.get()
except Exception as error:
return flask.render_template('docker-error.html', error=error)
return flask.render_template('services.html', containers=containers)
@ui.route('/announcement', methods=['GET', 'POST'])
@access.global_admin
def announcement():
@@ -58,3 +46,8 @@ def announcement():
form.announcement_body.data = ''
flask.flash('Your announcement was sent', 'success')
return flask.render_template('announcement.html', form=form)
@ui.route('/client', methods=['GET'])
def client():
return flask.render_template('client.html')

View File

@@ -1,8 +1,11 @@
from mailu import app, db, models
from mailu import models
from mailu.ui import ui, forms, access
from flask import current_app as app
import flask
import flask_login
import wtforms_components
import dns.resolver
@ui.route('/domain', methods=['GET'])
@@ -24,8 +27,8 @@ def domain_create():
else:
domain = models.Domain()
form.populate_obj(domain)
db.session.add(domain)
db.session.commit()
models.db.session.add(domain)
models.db.session.commit()
flask.flash('Domain %s created' % domain)
return flask.redirect(flask.url_for('.domain_list'))
return flask.render_template('domain/create.html', form=form)
@@ -40,7 +43,7 @@ def domain_edit(domain_name):
form.name.validators = []
if form.validate_on_submit():
form.populate_obj(domain)
db.session.commit()
models.db.session.commit()
flask.flash('Domain %s saved' % domain)
return flask.redirect(flask.url_for('.domain_list'))
return flask.render_template('domain/edit.html', form=form,
@@ -52,8 +55,8 @@ def domain_edit(domain_name):
@access.confirmation_required("delete {domain_name}")
def domain_delete(domain_name):
domain = models.Domain.query.get(domain_name) or flask.abort(404)
db.session.delete(domain)
db.session.commit()
models.db.session.delete(domain)
models.db.session.commit()
flask.flash('Domain %s deleted' % domain)
return flask.redirect(flask.url_for('.domain_list'))
@@ -73,3 +76,44 @@ def domain_genkeys(domain_name):
domain.generate_dkim_key()
return flask.redirect(
flask.url_for(".domain_details", domain_name=domain_name))
@ui.route('/domain/signup', methods=['GET', 'POST'])
def domain_signup(domain_name=None):
if not app.config['DOMAIN_REGISTRATION']:
flask.abort(403)
form = forms.DomainSignupForm()
if flask_login.current_user.is_authenticated:
del form.localpart
del form.pw
del form.pw2
if form.validate_on_submit():
conflicting_domain = models.Domain.query.get(form.name.data)
conflicting_alternative = models.Alternative.query.get(form.name.data)
conflicting_relay = models.Relay.query.get(form.name.data)
if conflicting_domain or conflicting_alternative or conflicting_relay:
flask.flash('Domain %s is already used' % form.name.data, 'error')
else:
domain = models.Domain()
form.populate_obj(domain)
domain.max_quota_bytes = app.config['DEFAULT_QUOTA']
domain.max_users = 10
domain.max_aliases = 10
if domain.check_mx():
models.db.session.add(domain)
if flask_login.current_user.is_authenticated:
user = models.User.query.get(flask_login.current_user.email)
else:
user = models.User()
user.domain = domain
form.populate_obj(user)
user.set_password(form.pw.data)
user.quota_bytes = domain.max_quota_bytes
models.db.session.add(user)
domain.managers.append(user)
models.db.session.commit()
flask.flash('Domain %s created' % domain)
return flask.redirect(flask.url_for('.domain_list'))
else:
flask.flash('The MX record was not properly set', 'error')
return flask.render_template('domain/signup.html', form=form)

View File

@@ -1,4 +1,4 @@
from mailu import db, models
from mailu import models
from mailu.ui import ui, forms, access
import flask
@@ -24,8 +24,8 @@ def fetch_create(user_email):
if form.validate_on_submit():
fetch = models.Fetch(user=user)
form.populate_obj(fetch)
db.session.add(fetch)
db.session.commit()
models.db.session.add(fetch)
models.db.session.commit()
flask.flash('Fetch configuration created')
return flask.redirect(
flask.url_for('.fetch_list', user_email=user.email))
@@ -39,7 +39,7 @@ def fetch_edit(fetch_id):
form = forms.FetchForm(obj=fetch)
if form.validate_on_submit():
form.populate_obj(fetch)
db.session.commit()
models.db.session.commit()
flask.flash('Fetch configuration updated')
return flask.redirect(
flask.url_for('.fetch_list', user_email=fetch.user.email))
@@ -53,8 +53,8 @@ def fetch_edit(fetch_id):
def fetch_delete(fetch_id):
fetch = models.Fetch.query.get(fetch_id) or flask.abort(404)
user = fetch.user
db.session.delete(fetch)
db.session.commit()
models.db.session.delete(fetch)
models.db.session.commit()
flask.flash('Fetch configuration delete')
return flask.redirect(
flask.url_for('.fetch_list', user_email=user.email))

View File

@@ -1,4 +1,4 @@
from mailu import db, models
from mailu import models
from mailu.ui import ui, forms, access
import flask
@@ -30,7 +30,7 @@ def manager_create(domain_name):
flask.flash('User %s is already manager' % user, 'error')
else:
domain.managers.append(user)
db.session.commit()
models.db.session.commit()
flask.flash('User %s can now manage %s' % (user, domain.name))
return flask.redirect(
flask.url_for('.manager_list', domain_name=domain.name))
@@ -46,7 +46,7 @@ def manager_delete(domain_name, user_email):
user = models.User.query.get(user_email) or flask.abort(404)
if user in domain.managers:
domain.managers.remove(user)
db.session.commit()
models.db.session.commit()
flask.flash('User %s can no longer manager %s' % (user, domain))
else:
flask.flash('User %s is not manager' % user, 'error')

View File

@@ -1,4 +1,4 @@
from mailu import db, models
from mailu import models
from mailu.ui import ui, forms, access
import flask
@@ -25,8 +25,8 @@ def relay_create():
else:
relay = models.Relay()
form.populate_obj(relay)
db.session.add(relay)
db.session.commit()
models.db.session.add(relay)
models.db.session.commit()
flask.flash('Relayed domain %s created' % relay)
return flask.redirect(flask.url_for('.relay_list'))
return flask.render_template('relay/create.html', form=form)
@@ -41,7 +41,7 @@ def relay_edit(relay_name):
form.name.validators = []
if form.validate_on_submit():
form.populate_obj(relay)
db.session.commit()
models.db.session.commit()
flask.flash('Relayed domain %s saved' % relay)
return flask.redirect(flask.url_for('.relay_list'))
return flask.render_template('relay/edit.html', form=form,
@@ -53,8 +53,8 @@ def relay_edit(relay_name):
@access.confirmation_required("delete {relay_name}")
def relay_delete(relay_name):
relay = models.Relay.query.get(relay_name) or flask.abort(404)
db.session.delete(relay)
db.session.commit()
models.db.session.delete(relay)
models.db.session.commit()
flask.flash('Relayed domain %s deleted' % relay)
return flask.redirect(flask.url_for('.relay_list'))

View File

@@ -1,4 +1,4 @@
from mailu import db, models
from mailu import models
from mailu.ui import ui, forms, access
from passlib import pwd
@@ -32,8 +32,8 @@ def token_create(user_email):
token = models.Token(user=user)
token.set_password(form.raw_password.data)
form.populate_obj(token)
db.session.add(token)
db.session.commit()
models.db.session.add(token)
models.db.session.commit()
flask.flash('Authentication token created')
return flask.redirect(
flask.url_for('.token_list', user_email=user.email))
@@ -46,8 +46,8 @@ def token_create(user_email):
def token_delete(token_id):
token = models.Token.query.get(token_id) or flask.abort(404)
user = token.user
db.session.delete(token)
db.session.commit()
models.db.session.delete(token)
models.db.session.commit()
flask.flash('Authentication token deleted')
return flask.redirect(
flask.url_for('.token_list', user_email=user.email))

View File

@@ -1,5 +1,6 @@
from mailu import db, models
from mailu import models
from mailu.ui import ui, access, forms
from flask import current_app as app
import flask
import flask_login
@@ -33,8 +34,8 @@ def user_create(domain_name):
user = models.User(domain=domain)
form.populate_obj(user)
user.set_password(form.pw.data)
db.session.add(user)
db.session.commit()
models.db.session.add(user)
models.db.session.commit()
user.send_welcome()
flask.flash('User %s created' % user)
return flask.redirect(
@@ -63,7 +64,7 @@ def user_edit(user_email):
form.populate_obj(user)
if form.pw.data:
user.set_password(form.pw.data)
db.session.commit()
models.db.session.commit()
flask.flash('User %s updated' % user)
return flask.redirect(
flask.url_for('.user_list', domain_name=user.domain.name))
@@ -77,8 +78,8 @@ def user_edit(user_email):
def user_delete(user_email):
user = models.User.query.get(user_email) or flask.abort(404)
domain = user.domain
db.session.delete(user)
db.session.commit()
models.db.session.delete(user)
models.db.session.commit()
flask.flash('User %s deleted' % user)
return flask.redirect(
flask.url_for('.user_list', domain_name=domain.name))
@@ -93,7 +94,7 @@ def user_settings(user_email):
form = forms.UserSettingsForm(obj=user)
if form.validate_on_submit():
form.populate_obj(user)
db.session.commit()
models.db.session.commit()
flask.flash('Settings updated for %s' % user)
if user_email:
return flask.redirect(
@@ -113,7 +114,7 @@ def user_password(user_email):
flask.flash('Passwords do not match', 'error')
else:
user.set_password(form.pw.data)
db.session.commit()
models.db.session.commit()
flask.flash('Password updated for %s' % user)
if user_email:
return flask.redirect(flask.url_for('.user_list',
@@ -130,7 +131,7 @@ def user_forward(user_email):
form = forms.UserForwardForm(obj=user)
if form.validate_on_submit():
form.populate_obj(user)
db.session.commit()
models.db.session.commit()
flask.flash('Forward destination updated for %s' % user)
if user_email:
return flask.redirect(
@@ -147,9 +148,45 @@ def user_reply(user_email):
form = forms.UserReplyForm(obj=user)
if form.validate_on_submit():
form.populate_obj(user)
db.session.commit()
models.db.session.commit()
flask.flash('Auto-reply message updated for %s' % user)
if user_email:
return flask.redirect(
flask.url_for('.user_list', domain_name=user.domain.name))
return flask.render_template('user/reply.html', form=form, user=user)
@ui.route('/user/signup', methods=['GET', 'POST'])
@ui.route('/user/signup/<domain_name>', methods=['GET', 'POST'])
def user_signup(domain_name=None):
available_domains = {
domain.name: domain
for domain in models.Domain.query.filter_by(signup_enabled=True).all()
if not domain.max_users or len(domain.users) < domain.max_users
}
if not available_domains:
flask.flash('No domain available for registration')
if not domain_name:
return flask.render_template('user/signup_domain.html',
available_domains=available_domains)
domain = available_domains.get(domain_name) or flask.abort(404)
quota_bytes = domain.max_quota_bytes or app.config['DEFAULT_QUOTA']
if app.config['RECAPTCHA_PUBLIC_KEY'] == "" or app.config['RECAPTCHA_PRIVATE_KEY'] == "":
form = forms.UserSignupForm()
else:
form = forms.UserSignupFormCaptcha()
if form.validate_on_submit():
if domain.has_email(form.localpart.data):
flask.flash('Email is already used', 'error')
else:
user = models.User(domain=domain)
form.populate_obj(user)
user.set_password(form.pw.data)
user.quota_bytes = quota_bytes
models.db.session.add(user)
models.db.session.commit()
user.send_welcome()
flask.flash('Successfully signed up %s' % user)
return flask.redirect(flask.url_for('.index'))
return flask.render_template('user/signup.html', domain=domain, form=form)

53
core/admin/mailu/utils.py Normal file
View File

@@ -0,0 +1,53 @@
from mailu import models
import flask
import flask_login
import flask_script
import flask_migrate
import flask_babel
import flask_limiter
from werkzeug.contrib import fixers
# Login configuration
login = flask_login.LoginManager()
login.login_view = "ui.login"
@login.unauthorized_handler
def handle_needs_login():
return flask.redirect(
flask.url_for('ui.login', next=flask.request.endpoint)
)
# Request rate limitation
limiter = flask_limiter.Limiter(key_func=lambda: current_user.username)
# Application translation
babel = flask_babel.Babel()
@babel.localeselector
def get_locale():
translations = list(map(str, babel.list_translations()))
return flask.request.accept_languages.best_match(translations)
# Proxy fixer
class PrefixMiddleware(object):
def __call__(self, environ, start_response):
prefix = environ.get('HTTP_X_FORWARDED_PREFIX', '')
if prefix:
environ['SCRIPT_NAME'] = prefix
return self.app(environ, start_response)
def init_app(self, app):
self.app = fixers.ProxyFix(app.wsgi_app)
app.wsgi_app = self
proxy = PrefixMiddleware()
# Data migrate
migrate = flask_migrate.Migrate()

View File

@@ -1,21 +1,21 @@
# Translations template for PROJECT.
# Copyright (C) 2017 ORGANIZATION
# Copyright (C) 2018 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2017.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2018.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2017-11-05 17:17+0100\n"
"POT-Creation-Date: 2018-04-22 12:10+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.5.1\n"
"Generated-By: Babel 2.5.3\n"
#: mailu/ui/forms.py:32
msgid "Invalid email address."
@@ -25,21 +25,23 @@ msgstr ""
msgid "Confirm"
msgstr ""
#: mailu/ui/forms.py:40 mailu/ui/forms.py:67
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail"
msgstr ""
#: mailu/ui/forms.py:41 mailu/ui/forms.py:68 mailu/ui/forms.py:85
#: mailu/ui/forms.py:146
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password"
msgstr ""
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:99
#: mailu/ui/templates/sidebar.html:111
msgid "Sign in"
msgstr ""
#: mailu/ui/forms.py:46 mailu/ui/templates/domain/details.html:21
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name"
msgstr ""
@@ -56,165 +58,198 @@ msgstr ""
msgid "Maximum user quota"
msgstr ""
#: mailu/ui/forms.py:50 mailu/ui/forms.py:62 mailu/ui/forms.py:73
#: mailu/ui/forms.py:112 mailu/ui/forms.py:124
#: mailu/ui/forms.py:50
msgid "Enable sign-up"
msgstr ""
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23
msgid "Comment"
msgstr ""
#: mailu/ui/forms.py:51 mailu/ui/forms.py:56 mailu/ui/forms.py:63
#: mailu/ui/forms.py:116 mailu/ui/forms.py:125
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create"
msgstr ""
#: mailu/ui/forms.py:55
msgid "Alternative name"
#: mailu/ui/forms.py:57
msgid "Initial admin"
msgstr ""
#: mailu/ui/forms.py:60
msgid "Relayed domain name"
#: mailu/ui/forms.py:58
msgid "Admin password"
msgstr ""
#: mailu/ui/forms.py:61 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr ""
#: mailu/ui/forms.py:69
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password"
msgstr ""
#: mailu/ui/forms.py:70 mailu/ui/templates/user/list.html:22
#: mailu/ui/forms.py:65
msgid "Alternative name"
msgstr ""
#: mailu/ui/forms.py:70
msgid "Relayed domain name"
msgstr ""
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host"
msgstr ""
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota"
msgstr ""
#: mailu/ui/forms.py:71
#: mailu/ui/forms.py:81
msgid "Allow IMAP access"
msgstr ""
#: mailu/ui/forms.py:72
#: mailu/ui/forms.py:82
msgid "Allow POP3 access"
msgstr ""
#: mailu/ui/forms.py:74
#: mailu/ui/forms.py:84
msgid "Enabled"
msgstr ""
#: mailu/ui/forms.py:85
msgid "Save"
msgstr ""
#: mailu/ui/forms.py:78
#: mailu/ui/forms.py:89
msgid "Email address"
msgstr ""
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up"
msgstr ""
#: mailu/ui/forms.py:97
msgid "Displayed name"
msgstr ""
#: mailu/ui/forms.py:79
#: mailu/ui/forms.py:98
msgid "Enable spam filter"
msgstr ""
#: mailu/ui/forms.py:80
#: mailu/ui/forms.py:99
msgid "Spam filter tolerance"
msgstr ""
#: mailu/ui/forms.py:81
msgid "Save settings"
msgstr ""
#: mailu/ui/forms.py:86
msgid "Password check"
msgstr ""
#: mailu/ui/forms.py:87 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr ""
#: mailu/ui/forms.py:91
#: mailu/ui/forms.py:100
msgid "Enable forwarding"
msgstr ""
#: mailu/ui/forms.py:92
#: mailu/ui/forms.py:101
msgid "Keep a copy of the emails"
msgstr ""
#: mailu/ui/forms.py:94 mailu/ui/forms.py:123
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20
msgid "Destination"
msgstr ""
#: mailu/ui/forms.py:96 mailu/ui/forms.py:104
msgid "Update"
#: mailu/ui/forms.py:105
msgid "Save settings"
msgstr ""
#: mailu/ui/forms.py:100
#: mailu/ui/forms.py:110
msgid "Password check"
msgstr ""
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password"
msgstr ""
#: mailu/ui/forms.py:115
msgid "Enable automatic reply"
msgstr ""
#: mailu/ui/forms.py:101
#: mailu/ui/forms.py:116
msgid "Reply subject"
msgstr ""
#: mailu/ui/forms.py:102
#: mailu/ui/forms.py:117
msgid "Reply body"
msgstr ""
#: mailu/ui/forms.py:109
msgid "Your token (write it down, as it will never be displayed again)"
msgstr ""
#: mailu/ui/forms.py:114 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
#: mailu/ui/forms.py:119
msgid "End of vacation"
msgstr ""
#: mailu/ui/forms.py:120
msgid "Update"
msgstr ""
#: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)"
msgstr ""
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP"
msgstr ""
#: mailu/ui/forms.py:136
msgid "Alias"
msgstr ""
#: mailu/ui/forms.py:122
#: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr ""
#: mailu/ui/forms.py:129
#: mailu/ui/forms.py:145
msgid "Admin email"
msgstr ""
#: mailu/ui/forms.py:130 mailu/ui/forms.py:135 mailu/ui/forms.py:148
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit"
msgstr ""
#: mailu/ui/forms.py:134
#: mailu/ui/forms.py:150
msgid "Manager email"
msgstr ""
#: mailu/ui/forms.py:139
#: mailu/ui/forms.py:155
msgid "Protocol"
msgstr ""
#: mailu/ui/forms.py:142
#: mailu/ui/forms.py:158
msgid "Hostname or IP"
msgstr ""
#: mailu/ui/forms.py:143
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47
msgid "TCP port"
msgstr ""
#: mailu/ui/forms.py:144
#: mailu/ui/forms.py:160
msgid "Enable TLS"
msgstr ""
#: mailu/ui/forms.py:145 mailu/ui/templates/fetch/list.html:20
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username"
msgstr ""
#: mailu/ui/forms.py:147
#: mailu/ui/forms.py:163
msgid "Keep emails on the server"
msgstr ""
#: mailu/ui/forms.py:152
#: mailu/ui/forms.py:168
msgid "Announcement subject"
msgstr ""
#: mailu/ui/forms.py:154
#: mailu/ui/forms.py:170
msgid "Announcement body"
msgstr ""
#: mailu/ui/forms.py:156
#: mailu/ui/forms.py:172
msgid "Send"
msgstr ""
@@ -222,8 +257,16 @@ msgstr ""
msgid "Public announcement"
msgstr ""
#: mailu/ui/templates/announcement.html:8
msgid "from"
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup"
msgstr ""
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol"
msgstr ""
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name"
msgstr ""
#: mailu/ui/templates/confirm.html:4
@@ -247,75 +290,43 @@ msgstr ""
msgid "to access the administration tools"
msgstr ""
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:44
msgid "Services status"
msgstr ""
#: mailu/ui/templates/services.html:10
msgid "Service"
msgstr ""
#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11
msgid "Status"
msgstr ""
#: mailu/ui/templates/services.html:12
msgid "PID"
msgstr ""
#: mailu/ui/templates/services.html:13
msgid "Image"
msgstr ""
#: mailu/ui/templates/services.html:14
msgid "Started"
msgstr ""
#: mailu/ui/templates/services.html:15
msgid "Last update"
msgstr ""
#: mailu/ui/templates/sidebar.html:8
msgid "My account"
msgstr ""
#: mailu/ui/templates/sidebar.html:11 mailu/ui/templates/user/list.html:34
msgid "Settings"
msgstr ""
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-forward"
msgstr ""
#: mailu/ui/templates/sidebar.html:26 mailu/ui/templates/user/list.html:36
msgid "Auto-reply"
msgstr ""
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:31
#: mailu/ui/templates/user/list.html:37
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts"
msgstr ""
#: mailu/ui/templates/sidebar.html:36 mailu/ui/templates/token/list.html:4
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens"
msgstr ""
#: mailu/ui/templates/sidebar.html:40
#: mailu/ui/templates/sidebar.html:35
msgid "Administration"
msgstr ""
#: mailu/ui/templates/sidebar.html:49
#: mailu/ui/templates/sidebar.html:44
msgid "Announcement"
msgstr ""
#: mailu/ui/templates/sidebar.html:54
#: mailu/ui/templates/sidebar.html:49
msgid "Administrators"
msgstr ""
#: mailu/ui/templates/sidebar.html:59
#: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains"
msgstr ""
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam"
msgstr ""
#: mailu/ui/templates/sidebar.html:66
msgid "Mail domains"
msgstr ""
@@ -328,15 +339,19 @@ msgstr ""
msgid "Webmail"
msgstr ""
#: mailu/ui/templates/sidebar.html:82
#: mailu/ui/templates/sidebar.html:87
msgid "Website"
msgstr ""
#: mailu/ui/templates/sidebar.html:87
#: mailu/ui/templates/sidebar.html:92
msgid "Help"
msgstr ""
#: mailu/ui/templates/sidebar.html:93
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain"
msgstr ""
#: mailu/ui/templates/sidebar.html:105
msgid "Sign out"
msgstr ""
@@ -440,27 +455,31 @@ msgstr ""
msgid "Domain details"
msgstr ""
#: mailu/ui/templates/domain/details.html:13
#: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys"
msgstr ""
#: mailu/ui/templates/domain/details.html:25
#: mailu/ui/templates/domain/details.html:17
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry"
msgstr ""
#: mailu/ui/templates/domain/details.html:29
#: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries"
msgstr ""
#: mailu/ui/templates/domain/details.html:36
#: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key"
msgstr ""
#: mailu/ui/templates/domain/details.html:40
#: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry"
msgstr ""
#: mailu/ui/templates/domain/details.html:44
#: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry"
msgstr ""
@@ -504,6 +523,23 @@ msgstr ""
msgid "Alternatives"
msgstr ""
#: mailu/ui/templates/domain/signup.html:13
msgid ""
"In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server"
msgstr ""
#: mailu/ui/templates/domain/signup.html:18
msgid ""
"If you do not know how to setup an <code>MX</code> record for your DNS "
"zone,\n"
" please contact your DNS provider or administrator. Also, please wait "
"a\n"
" couple minutes after the <code>MX</code> is set so the local server "
"cache\n"
" expires."
msgstr ""
#: mailu/ui/templates/fetch/create.html:4
msgid "Add a fetched account"
msgstr ""
@@ -580,7 +616,7 @@ msgstr ""
msgid "General"
msgstr ""
#: mailu/ui/templates/user/create.html:21
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
msgstr ""
@@ -616,11 +652,19 @@ msgstr ""
msgid "Automatic reply"
msgstr ""
#: mailu/ui/templates/user/settings.html:14
msgid "General settings"
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
msgstr ""
#: mailu/ui/templates/user/settings.html:18
msgid "Antispam"
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
msgstr ""
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
msgstr ""

View File

@@ -0,0 +1,25 @@
""" Enforce the nocase collation on the email table
Revision ID: 049fed905da7
Revises: 49d77a93118e
Create Date: 2018-04-21 13:23:56.571524
"""
# revision identifiers, used by Alembic.
revision = '049fed905da7'
down_revision = '49d77a93118e'
from alembic import op
import sqlalchemy as sa
def upgrade():
with op.batch_alter_table('user') as batch:
batch.alter_column('email', type_=sa.String(length=255, collation="NOCASE"))
def downgrade():
with op.batch_alter_table('user') as batch:
batch.alter_column('email', type_=sa.String(length=255))

View File

@@ -0,0 +1,28 @@
""" Add a column for used quota
Revision ID: 25fd6c7bcb4a
Revises: 049fed905da7
Create Date: 2018-07-25 21:56:09.729153
"""
# revision identifiers, used by Alembic.
revision = '25fd6c7bcb4a'
down_revision = '049fed905da7'
from alembic import op
import sqlalchemy as sa
from alembic import op
import sqlalchemy as sa
def upgrade():
with op.batch_alter_table('user') as batch:
batch.add_column(sa.Column('quota_bytes_used', sa.Integer(), nullable=False, server_default='0'))
def downgrade():
with op.batch_alter_table('user') as batch:
batch.drop_column('user', 'quota_bytes_used')

View File

@@ -0,0 +1,24 @@
""" Add a start day for vacations
Revision ID: 3b281286c7bd
Revises: 25fd6c7bcb4a
Create Date: 2018-09-27 22:20:08.158553
"""
revision = '3b281286c7bd'
down_revision = '25fd6c7bcb4a'
from alembic import op
import sqlalchemy as sa
def upgrade():
with op.batch_alter_table('user') as batch:
batch.add_column(sa.Column('reply_startdate', sa.Date(), nullable=False,
server_default="1900-01-01"))
def downgrade():
with op.batch_alter_table('user') as batch:
batch.drop_column('reply_startdate')

View File

@@ -13,8 +13,6 @@ down_revision = '2335c80a6bc3'
from alembic import op
import sqlalchemy as sa
from mailu import app
fetch_table = sa.Table(
'fetch',
@@ -24,13 +22,7 @@ fetch_table = sa.Table(
def upgrade():
connection = op.get_bind()
op.add_column('fetch', sa.Column('keep', sa.Boolean(), nullable=False, server_default=sa.sql.expression.false()))
# also apply the current config value if set
if app.config.get("FETCHMAIL_KEEP", "False") == "True":
connection.execute(
fetch_table.update().values(keep=True)
)
def downgrade():

View File

@@ -0,0 +1,24 @@
""" Enable signup per domain
Revision ID: 423155f8fc15
Revises: 77aa22ad72e2
Create Date: 2017-12-02 15:07:40.052320
"""
# revision identifiers, used by Alembic.
revision = '423155f8fc15'
down_revision = '77aa22ad72e2'
from alembic import op
import sqlalchemy as sa
def upgrade():
with op.batch_alter_table('domain') as batch:
batch.add_column(sa.Column('signup_enabled', sa.Boolean(), nullable=False, server_default=sa.sql.expression.false()))
def downgrade():
with op.batch_alter_table('domain') as batch:
batch.drop_column('signup_enabled')

View File

@@ -0,0 +1,24 @@
""" Add enabled flag to user model
Revision ID: 49d77a93118e
Revises: 423155f8fc15
Create Date: 2018-04-15 11:17:32.306088
"""
# revision identifiers, used by Alembic.
revision = '49d77a93118e'
down_revision = '423155f8fc15'
from alembic import op
import sqlalchemy as sa
def upgrade():
with op.batch_alter_table('user') as batch:
batch.add_column(sa.Column('enabled', sa.Boolean(), nullable=False, server_default=sa.sql.expression.true()))
def downgrade():
with op.batch_alter_table('user') as batch:
batch.drop_column('user', 'enabled')

View File

@@ -0,0 +1,25 @@
""" Add a configuration table
Revision ID: cd79ed46d9c2
Revises: 25fd6c7bcb4a
Create Date: 2018-10-17 21:44:48.924921
"""
revision = 'cd79ed46d9c2'
down_revision = '3b281286c7bd'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table('config',
sa.Column('name', sa.String(length=255), nullable=False),
sa.Column('value', sa.String(length=255), nullable=True),
sa.PrimaryKeyConstraint('name')
)
def downgrade():
op.drop_table('config')

View File

@@ -1,51 +1,47 @@
alembic==0.9.6
asn1crypto==0.23.0
Babel==2.5.1
alembic==1.0.2
asn1crypto==0.24.0
Babel==2.6.0
bcrypt==3.1.5
blinker==1.4
certifi==2017.7.27.1
cffi==1.11.2
chardet==3.0.4
click==6.7
cryptography==2.1.2
decorator==4.1.2
docker-py==1.10.6
docker-pycreds==0.2.1
dominate==2.3.1
Flask==0.12.2
Flask-Babel==0.11.2
cffi==1.11.5
Click==7.0
cryptography==2.3.1
decorator==4.3.0
dnspython==1.16.0
dominate==2.3.4
Flask==1.0.2
Flask-Babel==0.12.2
Flask-Bootstrap==3.3.7.1
Flask-DebugToolbar==0.10.1
Flask-Limiter==0.9.5.1
Flask-Login==0.4.0
Flask-Migrate==2.1.1
Flask-Limiter==1.0.1
Flask-Login==0.4.1
Flask-Migrate==2.3.1
Flask-Script==2.0.6
Flask-SQLAlchemy==2.3.2
Flask-WTF==0.14.2
gunicorn==19.7.1
idna==2.6
gunicorn==19.9.0
idna==2.7
infinity==1.4
intervals==0.8.0
itsdangerous==0.24
Jinja2==2.9.6
limits==1.2.1
intervals==0.8.1
itsdangerous==1.1.0
Jinja2==2.10
limits==1.3
Mako==1.0.7
MarkupSafe==1.0
MarkupSafe==1.1.0
passlib==1.7.1
pycparser==2.18
pyOpenSSL==17.3.0
python-dateutil==2.6.1
pycparser==2.19
pyOpenSSL==18.0.0
python-dateutil==2.7.5
python-editor==1.0.3
pytz==2017.2
PyYAML==3.12
redis==2.10.6
requests==2.18.4
pytz==2018.7
PyYAML==3.13
redis==3.0.1
six==1.11.0
SQLAlchemy==1.1.14
tabulate==0.8.1
urllib3==1.22
validators==0.12.0
SQLAlchemy==1.2.13
tabulate==0.8.2
tenacity==5.0.2
validators==0.12.2
visitor==0.1.3
websocket-client==0.44.0
Werkzeug==0.12.2
WTForms==2.1
Werkzeug==0.14.1
WTForms==2.2.1
WTForms-Components==0.10.3

View File

@@ -12,7 +12,8 @@ redis
WTForms-Components
passlib
gunicorn
docker-py
tabulate
PyYAML
PyOpenSSL
dnspython
bcrypt

View File

@@ -1,7 +0,0 @@
import os
if __name__ == "__main__":
os.environ["DEBUG"] = "True"
from mailu import app
app.run()

7
core/admin/start.py Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/python3
import os
os.system("flask mailu advertise")
os.system("flask db upgrade")
os.system("gunicorn -w 4 -b :80 --access-logfile - --error-logfile - --preload 'mailu:create_app()'")

View File

@@ -1,5 +0,0 @@
#!/bin/sh
python manage.py advertise
python manage.py db upgrade
gunicorn -w 4 -b 0.0.0.0:80 --access-logfile - --error-logfile - --preload mailu:app

View File

@@ -1,12 +1,23 @@
FROM alpine:edge
RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \
&& apk add --no-cache \
dovecot dovecot-sqlite dovecot-pigeonhole-plugin dovecot-pigeonhole-plugin-extdata \
rspamd-client@testing python py-jinja2
FROM alpine:3.8
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip \
&& pip3 install --upgrade pip
# Shared layer between rspamd, postfix, dovecot, unbound and nginx
RUN pip3 install jinja2
# Shared layer between rspamd, postfix, dovecot
RUN pip3 install tenacity
# Image specific layers under this line
RUN apk add --no-cache \
dovecot dovecot-pigeonhole-plugin dovecot-fts-lucene rspamd-client bash \
&& pip3 install podop
COPY conf /conf
COPY sieve /var/lib/dovecot
COPY start.py /start.py
EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp
VOLUME ["/data", "/mail"]
CMD /start.py
HEALTHCHECK --start-period=350s CMD echo QUIT|nc localhost 110|grep "Dovecot ready."

View File

@@ -0,0 +1,5 @@
uri = proxy:/tmp/podop.socket:auth
iterate_disable = yes
default_pass_scheme = plain
password_key = passdb/%u
user_key = userdb/%u

4
core/dovecot/conf/bin/ham Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
tee >(rspamc -h antispam:11334 -P mailu learn_ham /dev/stdin) \
| rspamc -h antispam:11334 -P mailu -f 13 fuzzy_add /dev/stdin

4
core/dovecot/conf/bin/spam Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
tee >(rspamc -h antispam:11334 -P mailu learn_spam /dev/stdin) \
>(rspamc -h antispam:11334 -P mailu -f 11 fuzzy_add /dev/stdin)

View File

@@ -1,14 +0,0 @@
driver = sqlite
connect = /data/main.db
# Return the user hashed password
password_query = \
SELECT NULL as password, 'Y' as nopassword, '{{ FRONT_ADDRESS }}{% if WEBMAIL_ADDRESS %},{{ WEBMAIL_ADDRESS }}{% endif %}' as allow_nets \
FROM user \
WHERE user.email = '%u'
# Mostly get the user quota
user_query = \
SELECT '*:bytes=' || user.quota_bytes AS quota_rule \
FROM user \
WHERE user.email = '%u'

View File

@@ -5,19 +5,23 @@ log_path = /dev/stderr
protocols = imap pop3 lmtp sieve
postmaster_address = {{ POSTMASTER }}@{{ DOMAIN }}
hostname = {{ HOSTNAMES.split(",")[0] }}
mail_plugins = $mail_plugins quota
submission_host = front
submission_host = {{ FRONT_ADDRESS }}
service dict {
unix_listener dict {
group = mail
mode = 0660
}
}
{% if DISABLE_FTS_LUCENE != 'true' %}
###############
# Full-text search
###############
mail_plugins = $mail_plugins fts fts_lucene
dict {
sieve = sqlite:/etc/dovecot/pigeonhole-sieve.dict
plugin {
fts = lucene
fts_autoindex = yes
fts_autoindex_exclude = \Junk
fts_lucene = whitespace_chars=@.
}
{% endif %}
###############
# Mailboxes
@@ -31,41 +35,49 @@ mail_gid = mail
mail_privileged_group = mail
mail_access_groups = mail
maildir_stat_dirs = yes
mailbox_list_index = yes
mail_vsize_bg_after_count = 100
mail_plugins = $mail_plugins quota quota_clone zlib
namespace inbox {
inbox = yes
mailbox Trash {
{% for mailbox in ("Trash", "Drafts", "Sent", "Junk") %}
mailbox {{ mailbox }} {
auto = subscribe
special_use = \Trash
special_use = \{{ mailbox }}
}
mailbox Drafts {
auto = subscribe
special_use = \Drafts
}
mailbox Sent {
auto = subscribe
special_use = \Sent
}
mailbox Junk {
auto = subscribe
special_use = \Junk
{% endfor %}
}
plugin {
quota = count:User quota
quota_vsizes = yes
quota_clone_dict = proxy:/tmp/podop.socket:quota
{% if COMPRESSION in [ 'gz', 'bz2' ] %}
zlib_save = {{ COMPRESSION }}
{% endif %}
{% if COMPRESSION_LEVEL %}
zlib_save_level = {{ COMPRESSION_LEVEL }}
{% endif %}
}
###############
# Authentication
###############
auth_username_chars =
auth_mechanisms = plain login
disable_plaintext_auth = no
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
driver = dict
args = /etc/dovecot/auth.conf
}
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
driver = dict
args = /etc/dovecot/auth.conf
}
service auth {
@@ -86,7 +98,6 @@ service auth-worker {
###############
# IMAP & POP
###############
protocol imap {
mail_plugins = $mail_plugins imap_quota imap_sieve
}
@@ -104,7 +115,6 @@ service imap-login {
###############
# Delivery
###############
protocol lmtp {
mail_plugins = $mail_plugins sieve
recipient_delimiter = {{ RECIPIENT_DELIMITER }}
@@ -116,15 +126,9 @@ service lmtp {
}
}
plugin {
quota = maildir:User quota
}
###############
# Filtering
###############
service managesieve-login {
inet_listener sieve {
port = 4190
@@ -136,15 +140,13 @@ service managesieve {
plugin {
sieve = file:~/sieve;active=~/.dovecot.sieve
sieve_plugins = sieve_extdata sieve_imapsieve sieve_extprograms
sieve_global_extensions = +vnd.dovecot.extdata +spamtest +spamtestplus +vnd.dovecot.execute
sieve_before = /var/lib/dovecot/before.sieve
sieve_default = /var/lib/dovecot/default.sieve
sieve_after = /var/lib/dovecot/after.sieve
sieve_extdata_dict_uri = proxy::sieve
sieve_before = dict:proxy:/tmp/podop.socket:sieve
sieve_plugins = sieve_imapsieve sieve_extprograms
sieve_extensions = +spamtest +spamtestplus +editheader
sieve_global_extensions = +vnd.dovecot.execute
# Sieve execute
sieve_execute_bin_dir = /var/lib/dovecot/bin
sieve_execute_bin_dir = /conf/bin
# Send vacation replies even for aliases
# See the Pigeonhole documentation about warnings: http://wiki2.dovecot.org/Pigeonhole/Sieve/Extensions/Vacation
@@ -163,11 +165,11 @@ plugin {
# Learn from spam
imapsieve_mailbox1_name = Junk
imapsieve_mailbox1_causes = COPY
imapsieve_mailbox1_before = file:/var/lib/dovecot/report-spam.sieve
imapsieve_mailbox1_before = file:/conf/report-spam.sieve
imapsieve_mailbox2_name = *
imapsieve_mailbox2_from = Junk
imapsieve_mailbox2_causes = COPY
imapsieve_mailbox2_before = file:/var/lib/dovecot/report-ham.sieve
imapsieve_mailbox2_before = file:/conf/report-ham.sieve
}
###############

View File

@@ -1,43 +0,0 @@
connect = /data/main.db
map {
pattern = priv/spam_enabled
table = user
username_field = email
value_field = spam_enabled
}
map {
pattern = priv/spam_threshold
table = user
username_field = email
value_field = spam_threshold
}
map {
pattern = priv/reply_enabled
table = user
username_field = email
value_field = reply_enabled
}
map {
pattern = priv/reply_subject
table = user
username_field = email
value_field = reply_subject
}
map {
pattern = priv/reply_body
table = user
username_field = email
value_field = reply_body
}
map {
pattern = priv/reply_enddate
table = user
username_field = email
value_field = reply_enddate
}

View File

@@ -0,0 +1,11 @@
require ["vnd.dovecot.execute", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.mailbox" "*" {
set "mailbox" "${1}";
}
if string "${mailbox}" "Trash" {
stop;
}
execute :pipe "ham";

View File

@@ -0,0 +1,3 @@
require "vnd.dovecot.execute";
execute :pipe "spam";

View File

@@ -1,32 +0,0 @@
require "variables";
require "vacation";
require "fileinto";
require "envelope";
require "mailbox";
require "imap4flags";
require "regex";
require "relational";
require "date";
require "comparator-i;ascii-numeric";
require "vnd.dovecot.extdata";
require "vnd.dovecot.execute";
require "spamtestplus";
if allof (string :is "${extdata.spam_enabled}" "1",
spamtest :percent :value "gt" :comparator "i;ascii-numeric" "${extdata.spam_threshold}")
{
setflag "\\seen";
fileinto :create "Junk";
stop;
}
if exists "X-Virus" {
discard;
stop;
}
if allof (string :is "${extdata.reply_enabled}" "1",
currentdate :value "le" "date" "${extdata.reply_enddate}")
{
vacation :days 1 :subject "${extdata.reply_subject}" "${extdata.reply_body}";
}

View File

@@ -1,3 +0,0 @@
#!/bin/sh
rspamc -h antispam:11334 -P mailu "learn_$1" /dev/stdin <&0

View File

@@ -1,3 +0,0 @@
require "vnd.dovecot.execute";
execute :pipe "mailtrain" "ham";

View File

@@ -1,3 +0,0 @@
require "vnd.dovecot.execute";
execute :pipe "mailtrain" "spam";

View File

@@ -1,20 +1,37 @@
#!/usr/bin/python
#!/usr/bin/python3
import jinja2
import os
import socket
import glob
import multiprocessing
import tenacity
from tenacity import retry
from podop import run_server
def start_podop():
os.setuid(8)
run_server(3 if "DEBUG" in os.environ else 0, "dovecot", "/tmp/podop.socket", [
("quota", "url", "http://admin/internal/dovecot/§"),
("auth", "url", "http://admin/internal/dovecot/§"),
("sieve", "url", "http://admin/internal/dovecot/§"),
])
convert = lambda src, dst: open(dst, "w").write(jinja2.Template(open(src).read()).render(**os.environ))
# Actual startup script
os.environ["FRONT_ADDRESS"] = socket.gethostbyname("front")
resolve = retry(socket.gethostbyname, stop=tenacity.stop_after_attempt(100), wait=tenacity.wait_random(min=2, max=5))
os.environ["FRONT_ADDRESS"] = resolve(os.environ.get("FRONT_ADDRESS", "front"))
os.environ["REDIS_ADDRESS"] = resolve(os.environ.get("REDIS_ADDRESS", "redis"))
if os.environ["WEBMAIL"] != "none":
os.environ["WEBMAIL_ADDRESS"] = socket.gethostbyname("webmail")
os.environ["WEBMAIL_ADDRESS"] = resolve(os.environ.get("WEBMAIL_ADDRESS", "webmail"))
for dovecot_file in glob.glob("/conf/*"):
for dovecot_file in glob.glob("/conf/*.conf"):
convert(dovecot_file, os.path.join("/etc/dovecot", os.path.basename(dovecot_file)))
# Run postfix
os.system("chown -R mail:mail /mail /var/lib/dovecot")
# Run Podop, then postfix
multiprocessing.Process(target=start_podop).start()
os.system("chown -R mail:mail /mail /var/lib/dovecot /conf")
os.execv("/usr/sbin/dovecot", ["dovecot", "-c", "/etc/dovecot/dovecot.conf", "-F"])

View File

@@ -1,8 +1,21 @@
FROM alpine:edge
RUN apk add --no-cache nginx nginx-mod-mail python py-jinja2 certbot openssl
FROM alpine:3.8
# python3 shared with most images
RUN apk add --no-cache \
python3 py3-pip \
&& pip3 install --upgrade pip
# Shared layer between rspamd, postfix, dovecot, unbound and nginx
RUN pip3 install jinja2
# Image specific layers under this line
RUN apk add --no-cache certbot nginx nginx-mod-mail openssl curl \
&& pip3 install idna requests watchdog
COPY conf /conf
COPY *.py /
EXPOSE 80/tcp 443/tcp 110/tcp 143/tcp 465/tcp 587/tcp 993/tcp 995/tcp 25/tcp 10025/tcp 10143/tcp
VOLUME ["/certs"]
VOLUME ["/overrides"]
CMD /start.py
HEALTHCHECK CMD curl -k -f -L http://localhost/health || exit 1

63
core/nginx/certwatcher.py Executable file
View File

@@ -0,0 +1,63 @@
#!/usr/bin/python3
"""
Certificate watcher which reloads nginx or reconfigures it, depending on what
happens to externally supplied certificates. Only executed by start.py in case
of TLS_FLAVOR=[mail, cert]
"""
from os.path import exists, split as path_split
from os import system
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler, FileDeletedEvent, \
FileCreatedEvent, FileModifiedEvent, FileMovedEvent
class ChangeHandler(FileSystemEventHandler):
"watchdog-handler listening on any event, executing the correct configuration/reload steps"
@staticmethod
def reload_nginx():
"merely reload nginx without re-configuring everything"
if exists("/var/run/nginx.pid"):
print("Reloading a running nginx")
system("nginx -s reload")
@staticmethod
def reexec_config():
"execute a reconfiguration of the system, which also reloads"
print("Reconfiguring system")
system("/config.py")
def on_any_event(self, event):
"event-listener checking if the affected files are the cert-files we're interested in"
if event.is_directory:
return
filename = path_split(event.src_path)[-1]
if isinstance(event, FileMovedEvent):
filename = path_split(event.dest_path)[-1]
if filename in ['cert.pem', 'key.pem']:
# all cases except for FileModified need re-configure
if isinstance(event, (FileCreatedEvent, FileMovedEvent, FileDeletedEvent)):
ChangeHandler.reexec_config()
# file modification needs only a nginx reload without config.py
elif isinstance(event, FileModifiedEvent):
ChangeHandler.reload_nginx()
# cert files have been moved away, re-configure
elif isinstance(event, FileMovedEvent) and path_split(event.src_path)[-1] in ['cert.pem', 'key.pem']:
ChangeHandler.reexec_config()
if __name__ == '__main__':
observer = Observer()
handler = ChangeHandler()
observer.schedule(handler, "/certs", recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()

View File

@@ -0,0 +1,13 @@
-----BEGIN DH PARAMETERS-----
MIICCAKCAgEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3
7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32
nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZp4e
8W5vUsMWTfT7eTDp5OWIV7asfV9C1p9tGHdjzx1VA0AEh/VbpX4xzHpxNciG77Qx
iu1qHgEtnmgyqQdgCpGBMMRtx3j5ca0AOAkpmaMzy4t6Gh25PXFAADwqTs6p+Y0K
zAqCkc3OyX3Pjsm1Wn+IpGtNtahR9EGC4caKAH5eZV9q//////////8CAQI=
-----END DH PARAMETERS-----

View File

@@ -20,13 +20,29 @@ http {
absolute_redirect off;
resolver {{ RESOLVER }} valid=30s;
{% if REAL_IP_HEADER %}
real_ip_header {{ REAL_IP_HEADER }};
{% endif %}
{% if REAL_IP_FROM %}{% for from_ip in REAL_IP_FROM.split(',') %}
set_real_ip_from {{ from_ip }};
{% endfor %}{% endif %}
# Header maps
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
# Disable the main http server when on kubernetes (port 80 and 443)
{% if KUBERNETES_INGRESS != 'true' %}
# Main HTTP server
server {
# Variables for proxifying
set $admin admin;
set $antispam antispam:11334;
set $webmail webmail;
set $webdav webdav:5232;
set $admin {{ HOST_ADMIN }};
set $antispam {{ HOST_ANTISPAM }};
set $webmail {{ HOST_WEBMAIL }};
set $webdav {{ HOST_WEBDAV }};
# Always listen over HTTP
listen 80;
@@ -34,44 +50,61 @@ http {
# Only enable HTTPS if TLS is enabled with no error
{% if TLS and not TLS_ERROR %}
listen 443 ssl;
listen [::]:443 ssl;
listen 443 ssl http2;
listen [::]:443 ssl http2;
include /etc/nginx/tls.conf;
ssl_session_cache shared:SSLHTTP:50m;
add_header Strict-Transport-Security max-age=15768000;
add_header Strict-Transport-Security 'max-age=31536000';
{% if not TLS_FLAVOR == "mail" %}
if ($scheme = http) {
{% if not TLS_FLAVOR in [ 'mail', 'mail-letsencrypt' ] %}
if ($proxy_x_forwarded_proto = http) {
return 301 https://$host$request_uri;
}
{% endif %}
{% endif %}
add_header X-Frame-Options 'SAMEORIGIN';
add_header X-Content-Type-Options 'nosniff';
add_header X-Permitted-Cross-Domain-Policies 'none';
add_header X-XSS-Protection '1; mode=block';
add_header Referrer-Policy 'same-origin';
# In any case, enable the proxy for certbot if the flavor is letsencrypt
{% if TLS_FLAVOR == 'letsencrypt' %}
{% if TLS_FLAVOR in [ 'letsencrypt', 'mail-letsencrypt' ] %}
location ^~ /.well-known/acme-challenge/ {
proxy_pass http://127.0.0.1:8008;
}
{% endif %}
# If TLS is failing, prevent access to anything except certbot
{% if TLS_ERROR %}
{% if TLS_ERROR and not TLS_FLAVOR == "mail" %}
location / {
return 403;
}
{% else %}
# Actual logic
{% if WEBMAIL != 'none' %}
location / {
return 301 $scheme://$host/webmail/;
}
include /overrides/*.conf;
# Actual logic
{% if WEB_WEBMAIL != '/' %}
location / {
{% if WEBROOT_REDIRECT %}
return 301 {{ WEBROOT_REDIRECT }};
{% else %}
return 404;
{% endif %}
}
{% endif %}
{% if WEBMAIL != 'none' %}
location {{ WEB_WEBMAIL }} {
{% if WEB_WEBMAIL != '/' %}
rewrite ^({{ WEB_WEBMAIL }})$ $1/ permanent;
rewrite ^{{ WEB_WEBMAIL }}/(.*) /$1 break;
proxy_set_header Host $host;
{% endif %}
include /etc/nginx/proxy.conf;
client_max_body_size {{ MESSAGE_SIZE_LIMIT|int + 8388608 }};
proxy_pass http://$webmail;
}
{% endif %}
@@ -83,8 +116,8 @@ http {
location ~ {{ WEB_ADMIN }}/(ui|static) {
rewrite ^{{ WEB_ADMIN }}/(.*) /$1 break;
include /etc/nginx/proxy.conf;
proxy_set_header X-Forwarded-Prefix {{ WEB_ADMIN }};
proxy_set_header Host $host;
proxy_pass http://$admin;
}
@@ -102,9 +135,15 @@ http {
rewrite ^/webdav/(.*) /$1 break;
auth_request /internal/auth/basic;
auth_request_set $user $upstream_http_x_user;
include /etc/nginx/proxy.conf;
proxy_set_header X-Remote-User $user;
proxy_set_header X-Script-Name /webdav;
proxy_pass http://$webdav;
}
location ~ ^/.well-known/(carddav|caldav) {
return 301 /webdav/;
}
{% endif %}
{% endif %}
@@ -117,12 +156,17 @@ http {
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
location /health {
return 204;
}
}
{% endif %}
# Forwarding authentication server
server {
# Variables for proxifying
set $admin admin;
set $admin {{ HOST_ADMIN }};
listen 127.0.0.1:8000;
@@ -136,6 +180,7 @@ mail {
server_name {{ HOSTNAMES.split(",")[0] }};
auth_http http://127.0.0.1:8000/auth/email;
proxy_pass_error_message on;
resolver {{ RESOLVER }} valid=30s;
{% if TLS and not TLS_ERROR %}
include /etc/nginx/tls.conf;
@@ -206,7 +251,7 @@ mail {
listen 465 ssl;
listen [::]:465 ssl;
protocol smtp;
smtp_auth plain;
smtp_auth plain login;
}
server {

View File

@@ -0,0 +1,5 @@
# Default proxy setup
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;

View File

@@ -2,6 +2,7 @@ ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384';
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_tickets off;
ssl_certificate {{ TLS[0] }};
ssl_certificate_key {{ TLS[1] }};
ssl_dhparam /certs/dhparam.pem;
ssl_dhparam /conf/dhparam.pem;

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import jinja2
import os
@@ -12,13 +12,25 @@ with open("/etc/resolv.conf") as handle:
content = handle.read().split()
args["RESOLVER"] = content[content.index("nameserver") + 1]
if "HOST_WEBMAIL" not in args:
args["HOST_WEBMAIL"] = "webmail"
if "HOST_ADMIN" not in args:
args["HOST_ADMIN"] = "admin"
if "HOST_WEBDAV" not in args:
args["HOST_WEBDAV"] = "webdav:5232"
if "HOST_ANTISPAM" not in args:
args["HOST_ANTISPAM"] = "antispam:11334"
# TLS configuration
cert_name = os.getenv("TLS_CERT_FILENAME", default="cert.pem")
keypair_name = os.getenv("TLS_KEYPAIR_FILENAME", default="key.pem")
args["TLS"] = {
"cert": ("/certs/cert.pem", "/certs/key.pem"),
"mail": ("/certs/cert.pem", "/certs/key.pem"),
"cert": ("/certs/%s" % cert_name, "/certs/%s" % keypair_name),
"letsencrypt": ("/certs/letsencrypt/live/mailu/fullchain.pem",
"/certs/letsencrypt/live/mailu/privkey.pem"),
"mail": ("/certs/%s" % cert_name, "/certs/%s" % keypair_name),
"mail-letsencrypt": ("/certs/letsencrypt/live/mailu/fullchain.pem",
"/certs/letsencrypt/live/mailu/privkey.pem"),
"notls": None
}[args["TLS_FLAVOR"]]
@@ -26,8 +38,9 @@ if args["TLS"] and not all(os.path.exists(file_path) for file_path in args["TLS"
print("Missing cert or key file, disabling TLS")
args["TLS_ERROR"] = "yes"
# Build final configuration paths
convert("/conf/tls.conf", "/etc/nginx/tls.conf", args)
convert("/conf/proxy.conf", "/etc/nginx/proxy.conf", args)
convert("/conf/nginx.conf", "/etc/nginx/nginx.conf", args)
if os.path.exists("/var/run/nginx.pid"):
os.system("nginx -s reload")

Some files were not shown because too many files have changed in this diff Show More