1
0
mirror of https://github.com/Mailu/Mailu.git synced 2024-12-12 10:45:38 +02:00

Merge branch 'master' of https://github.com/Mailu/Mailu into fetchmail-improvements

This commit is contained in:
Florent Daigniere 2022-11-21 10:40:02 +01:00
commit 3fc0a0e7fa
16 changed files with 60 additions and 21 deletions

View File

@ -5,7 +5,6 @@ FROM node:16-alpine3.16
WORKDIR /work
COPY package.json ./
COPY webpack.config.js ./
RUN set -euxo pipefail \
; npm config set update-notifier false \
@ -17,6 +16,7 @@ RUN set -euxo pipefail \
done
COPY assets/ ./assets/
COPY webpack.config.js ./
RUN set -euxo pipefail \
; node_modules/.bin/webpack-cli --color

View File

@ -1,8 +1,3 @@
require('./app.css');
import logo from './mailu.png';
import modules from "./*.json";
// Inspired from https://github.com/mehdibo/hibp-js/blob/master/hibp.js
function sha1(string) {
var buffer = new TextEncoder("utf-8").encode(string);

View File

@ -1,5 +1,5 @@
// AdminLTE
import 'admin-lte/plugins/jquery/jquery.min.js';
window.$ = window.jQuery = require('admin-lte/plugins/jquery/jquery.min.js');
import 'admin-lte/plugins/bootstrap/js/bootstrap.bundle.min.js';
import 'admin-lte/build/scss/adminlte.scss';
import 'admin-lte/build/js/AdminLTE.js';
@ -18,7 +18,7 @@ import 'admin-lte/plugins/datatables/jquery.dataTables.min.js';
import 'admin-lte/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js';
import 'admin-lte/plugins/datatables-responsive/js/dataTables.responsive.min.js';
import 'admin-lte/plugins/datatables-responsive/js/responsive.bootstrap4.min.js';
import modules from "./*.json";
// clipboard.js
import 'clipboard/dist/clipboard.min.js';
window.ClipboardJS = require('clipboard/dist/clipboard.min.js');

View File

@ -9,7 +9,7 @@ module.exports = {
mode: 'production',
entry: {
app: {
import: './assets/app.js',
import: ['./assets/app.css', './assets/mailu.png', './assets/app.js'],
dependOn: 'vendor',
},
vendor: './assets/vendor.js',

View File

@ -13,17 +13,19 @@ DEFAULT_CONFIG = {
'RATELIMIT_STORAGE_URL': '',
'DEBUG': False,
'DEBUG_PROFILER': False,
'DEBUG_TB_INTERCEPT_REDIRECTS': False,
'DEBUG_ASSETS': '',
'DOMAIN_REGISTRATION': False,
'TEMPLATES_AUTO_RELOAD': True,
'MEMORY_SESSIONS': False,
'FETCHMAIL_ENABLED': False,
# Database settings
'DB_FLAVOR': None,
'DB_USER': 'mailu',
'DB_PW': None,
'DB_HOST': 'database',
'DB_NAME': 'mailu',
'SQLITE_DATABASE_FILE':'data/main.db',
'SQLITE_DATABASE_FILE': 'data/main.db',
'SQLALCHEMY_DATABASE_URI': 'sqlite:////data/main.db',
'SQLALCHEMY_TRACK_MODIFICATIONS': False,
# Statistics management
@ -60,7 +62,7 @@ DEFAULT_CONFIG = {
# Web settings
'SITENAME': 'Mailu',
'WEBSITE': 'https://mailu.io',
'ADMIN' : 'none',
'ADMIN': 'none',
'WEB_ADMIN': '/admin',
'WEB_WEBMAIL': '/webmail',
'WEBMAIL': 'none',
@ -73,7 +75,7 @@ DEFAULT_CONFIG = {
'SESSION_KEY_BITS': 128,
'SESSION_TIMEOUT': 3600,
'PERMANENT_SESSION_LIFETIME': 30*24*3600,
'SESSION_COOKIE_SECURE': True,
'SESSION_COOKIE_SECURE': None,
'CREDENTIAL_ROUNDS': 12,
'TLS_PERMISSIVE': True,
'TZ': 'Etc/UTC',
@ -156,6 +158,8 @@ class ConfigManager:
self.config['SESSION_STORAGE_URL'] = f'redis://{self.config["REDIS_ADDRESS"]}/3'
self.config['SESSION_COOKIE_SAMESITE'] = 'Strict'
self.config['SESSION_COOKIE_HTTPONLY'] = True
if self.config['SESSION_COOKIE_SECURE'] is None:
self.config['SESSION_COOKIE_SECURE'] = self.config['TLS_FLAVOR'] != 'notls'
self.config['SESSION_PERMANENT'] = True
self.config['SESSION_TIMEOUT'] = int(self.config['SESSION_TIMEOUT'])
self.config['PERMANENT_SESSION_LIFETIME'] = int(self.config['PERMANENT_SESSION_LIFETIME'])

View File

@ -31,12 +31,14 @@
<p>{% trans %}Auto-reply{% endtrans %}</p>
</a>
</li>
{%- if config["FETCHMAIL_ENABLED"] %}
<li class="nav-item" role="none">
<a href="{{ url_for('.fetch_list') }}" class="nav-link" role="menuitem">
<i class="nav-icon fas fa-download"></i>
<p>{% trans %}Fetched accounts{% endtrans %}</p>
</a>
</li>
{%- endif %}
<li class="nav-item" role="none">
<a href="{{ url_for('.token_list') }}" class="nav-link" role="menuitem">
<i class="nav-icon fas fa-ticket-alt"></i>

View File

@ -1,5 +1,6 @@
from mailu import models, utils
from mailu.ui import ui, forms, access
from flask import current_app as app
import flask
import flask_login
@ -10,6 +11,8 @@ import wtforms
@ui.route('/fetch/list/<path:user_email>', methods=['GET'])
@access.owner(models.User, 'user_email')
def fetch_list(user_email):
if not app.config['FETCHMAIL_ENABLED']:
flask.abort(404)
user_email = user_email or flask_login.current_user.email
user = models.User.query.get(user_email) or flask.abort(404)
return flask.render_template('fetch/list.html', user=user)
@ -19,6 +22,8 @@ def fetch_list(user_email):
@ui.route('/fetch/create/<path:user_email>', methods=['GET', 'POST'])
@access.owner(models.User, 'user_email')
def fetch_create(user_email):
if not app.config['FETCHMAIL_ENABLED']:
flask.abort(404)
user_email = user_email or flask_login.current_user.email
user = models.User.query.get(user_email) or flask.abort(404)
form = forms.FetchForm()
@ -40,6 +45,8 @@ def fetch_create(user_email):
@ui.route('/fetch/edit/<fetch_id>', methods=['GET', 'POST'])
@access.owner(models.Fetch, 'fetch_id')
def fetch_edit(fetch_id):
if not app.config['FETCHMAIL_ENABLED']:
flask.abort(404)
fetch = models.Fetch.query.get(fetch_id) or flask.abort(404)
form = forms.FetchForm(obj=fetch)
utils.formatCSVField(form.folders)
@ -61,6 +68,8 @@ def fetch_edit(fetch_id):
@access.confirmation_required("delete a fetched account")
@access.owner(models.Fetch, 'fetch_id')
def fetch_delete(fetch_id):
if not app.config['FETCHMAIL_ENABLED']:
flask.abort(404)
fetch = models.Fetch.query.get(fetch_id) or flask.abort(404)
user = fetch.user
models.db.session.delete(fetch)

View File

@ -64,10 +64,11 @@ def user_edit(user_email):
form.quota_bytes.validators = [
wtforms.validators.NumberRange(max=max_quota_bytes)]
if form.validate_on_submit():
if msg := utils.isBadOrPwned(form):
flask.flash(msg, "error")
return flask.render_template('user/edit.html', form=form, user=user,
domain=user.domain, max_quota_bytes=max_quota_bytes)
if form.pw.data:
if msg := utils.isBadOrPwned(form):
flask.flash(msg, "error")
return flask.render_template('user/edit.html', form=form, user=user,
domain=user.domain, max_quota_bytes=max_quota_bytes)
form.populate_obj(user)
if form.pw.data:
user.set_password(form.pw.data)

View File

@ -1,4 +1,4 @@
"""empty message
""" Add fetch.scan and fetch.folders
Revision ID: f4f0f89e0047
Revises: 8f9ea78776f4

View File

@ -73,7 +73,7 @@ ENV \
DEBUG="true" \
DEBUG_PROFILER="${DEV_PROFILER}" \
DEBUG_ASSETS="/app/static" \
DEBUG_TB_ENABLED="true" \
DEBUG_TB_INTERCEPT_REDIRECTS=False \
\
IMAP_ADDRESS="127.0.0.1" \
POP3_ADDRESS="127.0.0.1" \

View File

@ -12,7 +12,16 @@ ARG MAILU_GID=1000
RUN set -euxo pipefail \
; addgroup -Sg ${MAILU_GID} mailu \
; adduser -Sg ${MAILU_UID} -G mailu -h /app -g "mailu app" -s /bin/bash mailu \
; apk add --no-cache bash ca-certificates curl python3 tzdata
; apk add --no-cache bash ca-certificates curl python3 tzdata \
; machine="$(uname -m)" \
; ! [[ "${machine}" == x86_64 ]] \
|| apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing hardened-malloc
ENV LD_PRELOAD=/usr/lib/libhardened_malloc.so
ENV CXXFLAGS="-g -O2 -fdebug-prefix-map=/app=. -fstack-protector-strong -Wformat -Werror=format-security -fstack-clash-protection -fexceptions"
ENV CFLAGS="-g -O2 -fdebug-prefix-map=/app=. -fstack-protector-strong -Wformat -Werror=format-security -fstack-clash-protection -fexceptions"
ENV CPPFLAGS="-Wdate-time -D_FORTIFY_SOURCE=2"
ENV LDFLAGS="-Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now"
WORKDIR /app

View File

@ -104,6 +104,9 @@ support or e.g. mismatching TLS versions to deliver emails to Mailu.
.. _fetchmail:
When ``FETCHMAIL_ENABLED`` is set to ``True``, the fetchmail functionality is enabled in the admin interface.
The container itself still needs to be deployed manually. ``FETCHMAIL_ENABLED`` defaults to ``True``.
The ``FETCHMAIL_DELAY`` is a delay (in seconds) for the fetchmail service to
go and fetch new email if available. Do not use too short delays if you do not
want to be blacklisted by external services, but not too long delays if you
@ -287,6 +290,10 @@ The admin service stores configurations in a database.
- ``DB_USER``: the database user for mailu admin service. (when not ``sqlite``)
- ``DB_NAME``: the database name for mailu admin service. (when not ``sqlite``)
Alternatively, if you need more control, you can use a `DB URL`_ : do not set any of the ``DB_`` settings and set ``SQLALCHEMY_DATABASE_URI`` instead.
.. _`DB URL`: https://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls
The roundcube service stores configurations in a database.
- ``ROUNDCUBE_DB_FLAVOR``: the database type for roundcube service. (``sqlite``, ``postgresql``, ``mysql``)

View File

@ -119,6 +119,13 @@ if __name__ == "__main__":
os.setgid(id_fetchmail.pw_gid)
os.setuid(id_fetchmail.pw_uid)
while True:
time.sleep(int(os.environ.get("FETCHMAIL_DELAY", 60)))
delay = int(os.environ.get("FETCHMAIL_DELAY", 60))
print("Sleeping for {} seconds".format(delay))
time.sleep(delay)
if not os.environ.get("FETCHMAIL_ENABLED", 'True') in ('True', 'true'):
print("Fetchmail disabled, skipping...")
continue
run(os.environ.get("DEBUG", None) == "True")
sys.stdout.flush()

View File

@ -79,6 +79,9 @@ RELAYNETS=
# Will relay all outgoing mails if configured
RELAYHOST={{ relayhost }}
# Show fetchmail functionality in admin interface
FETCHMAIL_ENABLED={{ fetchmail_enabled or 'False' }}
# Fetchmail delay
FETCHMAIL_DELAY={{ fetchmail_delay or '600' }}

View File

@ -0,0 +1 @@
Add FETCHMAIL_ENABLED to toggle the fetchmail functionality in the admin interface

View File

@ -0,0 +1 @@
Switch to GrapheneOS's hardened_malloc