Compare commits

..

40 Commits

Author SHA1 Message Date
holger krekel
805d743e9e show PATH env 2023-12-11 15:29:21 +01:00
holger krekel
b0d5ee084e fix cmdeploy test command 2023-12-11 15:22:12 +01:00
holger krekel
56c7853e5b remove tox run from deploy-chatmail and use 'cmdeploy fmt' and 'pytest' directly 2023-12-11 13:51:45 +01:00
holger krekel
071d708a89 move tests/chatmaild to chatmaild package, streamline tests and fixtures accordingly 2023-12-11 13:04:11 +01:00
holger krekel
c7c7ed8ff2 fix tests and run all tests on "cmdeploy test" 2023-12-11 12:18:10 +01:00
holger krekel
0aa0ef8a74 discover chatmail.ini in tests from CWD and all parent dirs (tox runs change dirs) 2023-12-11 02:27:05 +01:00
holger krekel
0662e3a8b1 "cmdeploy test" now installs deltachat if it's not there 2023-12-11 02:13:46 +01:00
holger krekel
6c453f93a1 consistently use shell helper 2023-12-11 01:58:31 +01:00
holger krekel
54f29f6bae consistently show ssh/shell output 2023-12-11 01:50:56 +01:00
holger krekel
ad8fee76cd add "build" dependency 2023-12-11 01:45:32 +01:00
holger krekel
528cd3da25 always show which ssh-commands execute 2023-12-11 01:43:09 +01:00
holger krekel
5734e00625 some more shifting around 2023-12-11 01:36:11 +01:00
holger krekel
947e1d6f89 shift functions around, discover sub commands automatically 2023-12-11 01:18:57 +01:00
holger krekel
33423459fe make tests depend on chatmail.ini, not env var 2023-12-11 00:49:32 +01:00
holger krekel
c70b72a21a tweak for making CI happy 2023-12-11 00:05:25 +01:00
holger krekel
33352f4694 try to fix workflow 2023-12-10 18:28:40 +01:00
holger krekel
59083ad16a don't print a traceback but do a proper return code for "cmdeploy test" 2023-12-10 18:24:08 +01:00
holger krekel
11518c2ef4 add chatmail.ini to ignore 2023-12-10 18:05:11 +01:00
holger krekel
a0cdfe6126 add manifest so that ini files get included 2023-12-10 18:02:00 +01:00
holger krekel
c25eefccc4 address nami comment 2023-12-10 17:56:26 +01:00
holger krekel
8b878e38cf fix readme 2023-12-10 14:41:20 +01:00
holger krekel
9e1e6d3c69 add test command 2023-12-10 14:38:57 +01:00
holger krekel
a1c817d758 fix README 2023-12-10 12:52:35 +01:00
holger krekel
ccc552f852 add status command and delete last script 2023-12-10 12:45:23 +01:00
holger krekel
73768256f6 some more housekeeping 2023-12-10 12:17:05 +01:00
holger krekel
34f7b3c0d3 introduce "cmdeploy bench" 2023-12-10 12:10:36 +01:00
holger krekel
e2828f4103 cleanup 2023-12-10 12:00:03 +01:00
holger krekel
df515bea41 generate dns zone file via cmdeploy 2023-12-10 11:56:41 +01:00
holger krekel
5614f03611 add dns command beginning 2023-12-09 18:07:44 +01:00
holger krekel
70443545d7 make cmdeploy test work 2023-12-09 17:55:08 +01:00
holger krekel
10ef842061 snap 2023-12-09 17:45:26 +01:00
holger krekel
98f92cd9b6 fix various test setups 2023-12-09 16:54:05 +01:00
holger krekel
fe99b97386 add webdev sub command 2023-12-09 16:42:03 +01:00
holger krekel
542decf798 making it work 2023-12-09 15:15:57 +01:00
holger krekel
2e7f8483b3 rework UI for chatmail setup 2023-12-09 13:43:56 +01:00
holger krekel
5c58e625f0 draft init flow 2023-12-09 02:07:09 +01:00
holger krekel
009f549619 document some attributes in chatmail.ini 2023-12-09 01:20:17 +01:00
holger krekel
99d36235fe get passthrough_recipients list from config 2023-12-09 01:07:37 +01:00
holger krekel
b52a8c969f various fixes 2023-12-09 00:22:58 +01:00
holger krekel
8520a9d8f2 introduce basic config file 2023-12-08 21:56:15 +01:00
53 changed files with 68 additions and 151 deletions

View File

@@ -31,7 +31,7 @@ jobs:
run: cmdeploy fmt -v run: cmdeploy fmt -v
- name: run deploy-chatmail offline tests - name: run deploy-chatmail offline tests
run: pytest --pyargs cmdeploy run: pytest tests
- name: initialize with chatmail domain - name: initialize with chatmail domain
run: cmdeploy init chat.example.org run: cmdeploy init chat.example.org

View File

@@ -9,7 +9,7 @@ def read_config(inipath):
class Config: class Config:
def __init__(self, inipath, params): def __init__(self, inipath, params):
self._inipath = inipath self._inipath = inipath
self.mail_domain = params["mail_domain"] self.mailname = self.mail_domain = params["mailname"]
self.max_user_send_per_minute = int(params["max_user_send_per_minute"]) self.max_user_send_per_minute = int(params["max_user_send_per_minute"])
self.filtermail_smtp_port = int(params["filtermail_smtp_port"]) self.filtermail_smtp_port = int(params["filtermail_smtp_port"])
self.postfix_reinject_port = int(params["postfix_reinject_port"]) self.postfix_reinject_port = int(params["postfix_reinject_port"])
@@ -23,14 +23,12 @@ class Config:
return open(self._inipath, "rb") return open(self._inipath, "rb")
def write_initial_config(inipath, mail_domain): def write_initial_config(inipath, mailname):
from importlib.resources import files from importlib.resources import files
inidir = files(__package__).joinpath("ini") inidir = files(__package__).joinpath("ini")
content = ( content = inidir.joinpath("chatmail.ini.f").read_text().format(mailname=mailname)
inidir.joinpath("chatmail.ini.f").read_text().format(mail_domain=mail_domain) if mailname.endswith(".testrun.org"):
)
if mail_domain.endswith(".testrun.org"):
override_inipath = inidir.joinpath("override-testrun.ini") override_inipath = inidir.joinpath("override-testrun.ini")
privacy = iniconfig.IniConfig(override_inipath)["privacy"] privacy = iniconfig.IniConfig(override_inipath)["privacy"]
lines = [] lines = []

View File

@@ -1,7 +1,7 @@
[params] [params]
# mail domain (MUST be set to fully qualified chat mail domain) # mail domain (MUST be set to fully qualified chat mail domain)
mail_domain = {mail_domain} mailname = {mailname}
# #
# If you only do private test deploys, you don't need to modify any settings below # If you only do private test deploys, you don't need to modify any settings below

View File

@@ -5,7 +5,7 @@
import json import json
import random import random
mail_domain_path = "/etc/mailname" mailname_path = "/etc/mailname"
def create_newemail_dict(domain): def create_newemail_dict(domain):
@@ -16,7 +16,7 @@ def create_newemail_dict(domain):
def print_new_account(): def print_new_account():
domain = open(mail_domain_path).read().strip() domain = open(mailname_path).read().strip()
creds = create_newemail_dict(domain=domain) creds = create_newemail_dict(domain=domain)
print("Content-Type: application/json") print("Content-Type: application/json")

View File

@@ -13,8 +13,8 @@ from chatmaild.config import read_config, write_initial_config
def make_config(tmp_path): def make_config(tmp_path):
inipath = tmp_path.joinpath("chatmail.ini") inipath = tmp_path.joinpath("chatmail.ini")
def make_conf(mail_domain): def make_conf(mailname):
write_initial_config(inipath, mail_domain=mail_domain) write_initial_config(inipath, mailname=mailname)
return read_config(inipath) return read_config(inipath)
return make_conf return make_conf
@@ -27,7 +27,7 @@ def example_config(make_config):
@pytest.fixture @pytest.fixture
def maildomain(example_config): def maildomain(example_config):
return example_config.mail_domain return example_config.mailname
@pytest.fixture @pytest.fixture

View File

@@ -3,7 +3,7 @@ from chatmaild.config import read_config
def test_read_config_basic(make_config): def test_read_config_basic(make_config):
config = make_config("chat.example.org") config = make_config("chat.example.org")
assert config.mail_domain == "chat.example.org" assert config.mailname == "chat.example.org"
assert not config.privacy_supervisor and not config.privacy_mail assert not config.privacy_supervisor and not config.privacy_mail
assert not config.privacy_pdo and not config.privacy_postal assert not config.privacy_pdo and not config.privacy_postal
@@ -11,12 +11,12 @@ def test_read_config_basic(make_config):
inipath.write_text(inipath.read_text().replace("60", "37")) inipath.write_text(inipath.read_text().replace("60", "37"))
config = read_config(inipath) config = read_config(inipath)
assert config.max_user_send_per_minute == 37 assert config.max_user_send_per_minute == 37
assert config.mail_domain == "chat.example.org" assert config.mailname == "chat.example.org"
def test_read_config_testrun(make_config): def test_read_config_testrun(make_config):
config = make_config("something.testrun.org") config = make_config("something.testrun.org")
assert config.mail_domain == "something.testrun.org" assert config.mailname == "something.testrun.org"
assert len(config.privacy_postal.split("\n")) > 1 assert len(config.privacy_postal.split("\n")) > 1
assert len(config.privacy_supervisor.split("\n")) > 1 assert len(config.privacy_supervisor.split("\n")) > 1
assert len(config.privacy_pdo.split("\n")) > 1 assert len(config.privacy_pdo.split("\n")) > 1

View File

@@ -18,7 +18,7 @@ def test_create_newemail_dict():
def test_print_new_account(capsys, monkeypatch, maildomain, tmpdir): def test_print_new_account(capsys, monkeypatch, maildomain, tmpdir):
p = tmpdir.join("mailname") p = tmpdir.join("mailname")
p.write(maildomain) p.write(maildomain)
monkeypatch.setattr(chatmaild.newemail, "mail_domain_path", str(p)) monkeypatch.setattr(chatmaild.newemail, "mailname_path", str(p))
print_new_account() print_new_account()
out, err = capsys.readouterr() out, err = capsys.readouterr()
lines = out.split("\n") lines = out.split("\n")

View File

@@ -3,8 +3,8 @@ requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta" build-backend = "setuptools.build_meta"
[project] [project]
name = "cmdeploy" name = "deploy-chatmail"
version = "0.2" version = "0.1"
dependencies = [ dependencies = [
"pyinfra", "pyinfra",
"pillow", "pillow",
@@ -22,11 +22,10 @@ dependencies = [
] ]
[project.scripts] [project.scripts]
cmdeploy = "cmdeploy.cmdeploy:main" cmdeploy = "deploy_chatmail.cmdeploy:main"
[project.entry-points.pytest11] [project.entry-points.pytest11]
"chatmaild.testplugin" = "chatmaild.tests.plugin" "chatmaild.testplugin" = "chatmaild.tests.plugin"
"cmdeploy.testplugin" = "cmdeploy.tests.plugin"
[tool.pytest.ini_options] [tool.pytest.ini_options]
addopts = "-v -ra --strict-markers" addopts = "-v -ra --strict-markers"

View File

@@ -195,7 +195,7 @@ def _install_mta_sts_daemon() -> bool:
server.shell( server.shell(
name="install postfix-mta-sts-resolver with pip", name="install postfix-mta-sts-resolver with pip",
commands=[ commands=[
"python3 -m virtualenv /usr/local/lib/postfix-mta-sts-resolver", "python3 -m venv /usr/local/lib/postfix-mta-sts-resolver",
"/usr/local/lib/postfix-mta-sts-resolver/bin/pip install postfix-mta-sts-resolver", "/usr/local/lib/postfix-mta-sts-resolver/bin/pip install postfix-mta-sts-resolver",
], ],
) )
@@ -347,8 +347,8 @@ def _configure_nginx(domain: str, debug: bool = False) -> bool:
def check_config(config): def check_config(config):
mail_domain = config.mail_domain mailname = config.mailname
if mail_domain != "testrun.org" and not mail_domain.endswith(".testrun.org"): if mailname != "testrun.org" and not mailname.endswith(".testrun.org"):
blocked_words = "merlinux schmieder testrun.org".split() blocked_words = "merlinux schmieder testrun.org".split()
for value in config.__dict__.values(): for value in config.__dict__.values():
if any(x in value for x in blocked_words): if any(x in value for x in blocked_words):

View File

@@ -52,17 +52,17 @@ def run_cmd(args, out):
"""Deploy chatmail services on the remote server.""" """Deploy chatmail services on the remote server."""
env = os.environ.copy() env = os.environ.copy()
env["CHATMAIL_DOMAIN"] = args.config.mail_domain env["CHATMAIL_DOMAIN"] = args.config.mailname
deploy_path = "cmdeploy/src/cmdeploy/deploy.py" deploypy = "deploy-chatmail/src/deploy_chatmail/deploy.py"
pyinf = "pyinfra --dry" if args.dry_run else "pyinfra" pyinf = "pyinfra --dry" if args.dry_run else "pyinfra"
cmd = f"{pyinf} --ssh-user root {args.config.mail_domain} {deploy_path}" cmd = f"{pyinf} --ssh-user root {args.config.mailname} {deploypy}"
out.check_call(cmd, env=env) out.check_call(cmd, env=env)
def dns_cmd(args, out): def dns_cmd(args, out):
"""Generate dns zone file.""" """Generate dns zone file."""
template = importlib.resources.files(__package__).joinpath("chatmail.zone.f") template = importlib.resources.files(__package__).joinpath("chatmail.zone.f")
ssh = f"ssh root@{args.config.mail_domain}" ssh = f"ssh root@{args.config.mailname}"
def read_dkim_entries(entry): def read_dkim_entries(entry):
lines = [] lines = []
@@ -77,16 +77,16 @@ def dns_cmd(args, out):
dkim_entry = read_dkim_entries(out.shell_output(f"{ssh} -- opendkim-genzone -F")) dkim_entry = read_dkim_entries(out.shell_output(f"{ssh} -- opendkim-genzone -F"))
out( out(
f"[writing {args.config.mail_domain} zone data (using space as separator) to stdout output]", f"[writing {args.config.mailname} zone data (using space as separator) to stdout output]",
green=True, green=True,
) )
print( print(
template.read_text() template.read_text()
.format( .format(
acme_account_url=acme_account_url, acme_account_url=acme_account_url,
email=f"root@{args.config.mail_domain}", email=f"root@{args.config.mailname}",
sts_id=datetime.datetime.now().strftime("%Y%m%d%H%M"), sts_id=datetime.datetime.now().strftime("%Y%m%d%H%M"),
chatmail_domain=args.config.mail_domain, chatmail_domain=args.config.mailname,
dkim_entry=dkim_entry, dkim_entry=dkim_entry,
) )
.strip() .strip()
@@ -96,9 +96,9 @@ def dns_cmd(args, out):
def status_cmd(args, out): def status_cmd(args, out):
"""Display status for online chatmail instance.""" """Display status for online chatmail instance."""
ssh = f"ssh root@{args.config.mail_domain}" ssh = f"ssh root@{args.config.mailname}"
out.green(f"chatmail domain: {args.config.mail_domain}") out.green(f"chatmail domain: {args.config.mailname}")
if args.config.privacy_mail: if args.config.privacy_mail:
out.green("privacy settings: present") out.green("privacy settings: present")
else: else:
@@ -122,7 +122,7 @@ def test_cmd(args, out):
pytest_path = shutil.which("pytest") pytest_path = shutil.which("pytest")
ret = out.run_ret( ret = out.run_ret(
[pytest_path, "cmdeploy/src/", "-n4", "-rs", "-x", "-vrx", "--durations=5"] [pytest_path, "tests/", "-n4", "-rs", "-x", "-vrx", "--durations=5"]
) )
return ret return ret
@@ -147,7 +147,11 @@ def fmt_cmd_options(parser):
def fmt_cmd(args, out): def fmt_cmd(args, out):
"""Run formattting fixes (fuff and black) on all chatmail source code.""" """Run formattting fixes (fuff and black) on all chatmail source code."""
sources = [str(importlib.resources.files(x)) for x in ("chatmaild", "cmdeploy")] chatmaild = importlib.resources.files("chatmaild")
deploy_chatmail = importlib.resources.files("deploy_chatmail")
tests = deploy_chatmail.joinpath("../../../tests")
sources = list(str(x) for x in [chatmaild, deploy_chatmail, tests])
black_args = [shutil.which("black")] black_args = [shutil.which("black")]
ruff_args = [shutil.which("ruff")] ruff_args = [shutil.which("ruff")]
@@ -170,10 +174,9 @@ def fmt_cmd(args, out):
def bench_cmd(args, out): def bench_cmd(args, out):
"""Run benchmarks against an online chatmail instance.""" """Run benchmarks against an online chatmail instance."""
args = ["pytest", "--pyargs", "cmdeploy.tests.online.benchmark", "-vrx"] pytest_path = shutil.which("pytest")
cmdstring = " ".join(args) benchmark = "tests/online/benchmark.py"
out.green(f"[$ {cmdstring}]") subprocess.check_call([pytest_path, benchmark, "-vrx"])
subprocess.check_call(args)
def webdev_cmd(args, out): def webdev_cmd(args, out):

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,6 +1,6 @@
import os import os
import pyinfra import pyinfra
from cmdeploy import deploy_chatmail from deploy_chatmail import deploy_chatmail
def main(): def main():

View File

@@ -1,4 +1,4 @@
myorigin = {{ config.mail_domain }} myorigin = {{ config.mailname }}
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no biff = no
@@ -16,8 +16,8 @@ readme_directory = no
compatibility_level = 2 compatibility_level = 2
# TLS parameters # TLS parameters
smtpd_tls_cert_file=/var/lib/acme/live/{{ config.mail_domain }}/fullchain smtpd_tls_cert_file=/var/lib/acme/live/{{ config.mailname }}/fullchain
smtpd_tls_key_file=/var/lib/acme/live/{{ config.mail_domain }}/privkey smtpd_tls_key_file=/var/lib/acme/live/{{ config.mailname }}/privkey
smtpd_tls_security_level=may smtpd_tls_security_level=may
smtp_tls_CApath=/etc/ssl/certs smtp_tls_CApath=/etc/ssl/certs
@@ -26,7 +26,7 @@ smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_policy_maps = socketmap:inet:127.0.0.1:8461:postfix smtp_tls_policy_maps = socketmap:inet:127.0.0.1:8461:postfix
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = {{ config.mail_domain }} myhostname = {{ config.mailname }}
alias_maps = hash:/etc/aliases alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases alias_database = hash:/etc/aliases
@@ -45,7 +45,7 @@ inet_interfaces = all
inet_protocols = all inet_protocols = all
virtual_transport = lmtp:unix:private/dovecot-lmtp virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = {{ config.mail_domain }} virtual_mailbox_domains = {{ config.mailname }}
smtpd_milters = unix:opendkim/opendkim.sock smtpd_milters = unix:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters non_smtpd_milters = $smtpd_milters

View File

@@ -37,7 +37,7 @@ def build_webpages(src_dir, build_dir, config):
def _build_webpages(src_dir, build_dir, config): def _build_webpages(src_dir, build_dir, config):
mail_domain = config.mail_domain mail_domain = config.mailname
assert src_dir.exists(), src_dir assert src_dir.exists(), src_dir
if not build_dir.exists(): if not build_dir.exists():
build_dir.mkdir() build_dir.mkdir()
@@ -71,7 +71,7 @@ def main():
inipath = reporoot.joinpath("chatmail.ini") inipath = reporoot.joinpath("chatmail.ini")
config = read_config(inipath) config = read_config(inipath)
config.webdev = True config.webdev = True
assert config.mail_domain assert config.mailname
www_path = reporoot.joinpath("www") www_path = reporoot.joinpath("www")
src_path = www_path.joinpath("src") src_path = www_path.joinpath("src")
stats = None stats = None

View File

@@ -2,8 +2,8 @@
set -e set -e
python3 -m venv venv python3 -m venv venv
venv/bin/pip install -e deploy-chatmail
venv/bin/pip install -e chatmaild venv/bin/pip install -e chatmaild
venv/bin/pip install -e cmdeploy
source venv/bin/activate source venv/bin/activate
echo activated 'venv' python virtualenv environment containing "cmdeploy" tool echo activated 'venv' python virtualenv environment containing "cmdeploy" tool

View File

@@ -38,7 +38,7 @@ def pytest_runtest_setup(item):
@pytest.fixture @pytest.fixture
def chatmail_config(pytestconfig): def chatmail_config(pytestconfig):
current = basedir = Path().resolve() current = basedir = Path()
while 1: while 1:
path = current.joinpath("chatmail.ini").resolve() path = current.joinpath("chatmail.ini").resolve()
if path.exists(): if path.exists():
@@ -52,7 +52,7 @@ def chatmail_config(pytestconfig):
@pytest.fixture @pytest.fixture
def maildomain(chatmail_config): def maildomain(chatmail_config):
return chatmail_config.mail_domain return chatmail_config.mailname
@pytest.fixture @pytest.fixture

View File

@@ -1,4 +1,4 @@
from cmdeploy.genqr import gen_qr_png_data from deploy_chatmail.genqr import gen_qr_png_data
def test_gen_qr_png_data(maildomain): def test_gen_qr_png_data(maildomain):

View File

@@ -91,9 +91,9 @@ class TestEndToEndDeltaChat:
lp.sec("setup encrypted comms between ac1 and ac2 on different instances") lp.sec("setup encrypted comms between ac1 and ac2 on different instances")
qr = ac1.get_setup_contact_qr() qr = ac1.get_setup_contact_qr()
ch = ac2.qr_setup_contact(qr) ac2.qr_setup_contact(qr)
assert ch.id >= 10 msg = ac2.wait_next_incoming_message()
ac1._evtracker.wait_securejoin_inviter_progress(1000) assert "verified" in msg.text
lp.sec("ac1 sends a message and ac2 marks it as seen") lp.sec("ac1 sends a message and ac2 marks it as seen")
chat = ac1.create_chat(ac2) chat = ac1.create_chat(ac2)

View File

@@ -1,7 +1,7 @@
import os import os
import pytest import pytest
from cmdeploy.cmdeploy import get_parser, main from deploy_chatmail.cmdeploy import get_parser, main
from chatmaild.config import read_config from chatmaild.config import read_config
@@ -25,7 +25,7 @@ class TestCmdline:
main(["init", "chat.example.org"]) main(["init", "chat.example.org"])
inipath = tmp_path.joinpath("chatmail.ini") inipath = tmp_path.joinpath("chatmail.ini")
config = read_config(inipath) config = read_config(inipath)
assert config.mail_domain == "chat.example.org" assert config.mailname == "chat.example.org"
def test_init_not_overwrite(self): def test_init_not_overwrite(self):
main(["init", "chat.example.org"]) main(["init", "chat.example.org"])

View File

@@ -1,10 +1,10 @@
import importlib.resources import importlib.resources
from cmdeploy.www import build_webpages from deploy_chatmail.www import build_webpages
def test_build_webpages(tmp_path, make_config): def test_build_webpages(tmp_path, make_config):
pkgroot = importlib.resources.files("cmdeploy") pkgroot = importlib.resources.files("deploy_chatmail")
src_dir = pkgroot.joinpath("../../../www/src").resolve() src_dir = pkgroot.joinpath("../../../www/src").resolve()
assert src_dir.exists(), src_dir assert src_dir.exists(), src_dir
config = make_config("chat.example.org") config = make_config("chat.example.org")

View File

@@ -1,5 +1,5 @@
<img class="banner" src="collage-top.png"/> <img width="800px" src="collage-top.png"/>
## Dear [Delta Chat](https://get.delta.chat) users and newcomers, ## Dear [Delta Chat](https://get.delta.chat) users and newcomers,
@@ -14,7 +14,6 @@ Welcome to instant, interoperable and [privacy-preserving](privacy.html) messagi
💬 **Start** chatting with any Delta Chat contacts using [QR invite codes](https://delta.chat/en/help#howtoe2ee) 💬 **Start** chatting with any Delta Chat contacts using [QR invite codes](https://delta.chat/en/help#howtoe2ee)
<div class="experimental">Note: this is an experimental service</div>
## ⚡ Note: this is an experimental service ⚡

View File

@@ -1,5 +1,5 @@
<img class="banner" src="collage-info.png"/> <img width="800px" src="collage-info.png"/>
## More information ## More information

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="145"
height="145"
version="1.1"
id="svg4"
sodipodi:docname="At_sign.svg"
inkscape:version="1.2.2 (b0a84865, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="3.0241379"
inkscape:cx="67.622577"
inkscape:cy="72.913341"
inkscape:window-width="1390"
inkscape:window-height="1027"
inkscape:window-x="55"
inkscape:window-y="25"
inkscape:window-maximized="0"
inkscape:current-layer="svg4" />
<g
aria-label="@"
id="text2"
style="font-size:144px;font-family:Arial">
<path
d="m 79.927878,94.422406 c -2.704286,3.120332 -5.741407,5.637394 -9.111364,7.551194 -3.328352,1.87221 -6.677506,2.80831 -10.047463,2.80831 -3.702792,0 -7.301573,-1.08172 -10.796342,-3.24515 -3.49477,-2.163426 -6.344671,-5.491779 -8.549704,-9.985058 -2.163429,-4.493275 -3.245144,-9.423397 -3.245144,-14.790365 0,-6.615099 1.684978,-13.230199 5.054935,-19.845299 3.411561,-6.656705 7.634407,-11.649233 12.66854,-14.977585 5.034133,-3.328352 9.92265,-4.992528 14.665552,-4.992528 3.619583,0 7.072748,0.956901 10.359496,2.870704 3.286748,1.872198 6.115847,4.742902 8.487297,8.612111 l 2.121825,-9.673023 h 11.170784 l -8.986557,41.87483 c -1.248129,5.824616 -1.872194,9.048957 -1.872194,9.673023 0,1.123319 0.416044,2.101022 1.248132,2.93311 0.873692,0.790484 1.913802,1.185726 3.120332,1.185726 2.20503,0 5.096537,-1.268934 8.674517,-3.806803 4.7429,-3.328352 8.4873,-7.780023 11.23319,-13.355013 2.78749,-5.616594 4.18124,-11.399606 4.18124,-17.349035 0,-6.947935 -1.78899,-13.438222 -5.36697,-19.47086 -3.53637,-6.032638 -8.84094,-10.858749 -15.913687,-14.478332 -7.03114,-3.619583 -14.811161,-5.429374 -23.340064,-5.429374 -9.73543,0 -18.638772,2.288242 -26.710026,6.864726 -8.029649,4.534879 -14.27031,11.06677 -18.721981,19.595673 -4.410066,8.487298 -6.615099,17.598662 -6.615099,27.334092 0,10.193078 2.205033,18.971607 6.615099,26.33559 2.290454,3.78888 -7.136335,18.96983 -3.810585,21.73443 3.138096,2.60861 18.971963,-7.14297 23.031819,-5.44631 8.404089,3.53637 17.702673,5.30456 27.895752,5.30456 10.90035,0 20.032515,-1.83059 27.396492,-5.49178 7.36399,-3.66119 12.87657,-8.11286 16.53776,-13.35501 l 9.29559,4 c -2.12183,4.36846 -3.76221,4.82013 -8.92116,9.35501 -5.15895,4.53488 -11.2956,8.11286 -18.40995,10.73393 -7.114346,2.66268 -15.684851,3.99402 -25.711512,3.99402 -9.236177,0 -17.76508,-1.18572 -25.586707,-3.55717 -7.780023,-2.37145 -29.296198,9.26152 -34.78798,4.47701 -5.49178,-4.7429 5.248856,-25.42482 2.461361,-31.62388 -3.49477,-7.863231 -5.242155,-16.350531 -5.242155,-25.461894 0,-10.151474 2.08022,-19.824498 6.240661,-29.019071 5.075736,-11.274793 12.273297,-19.907706 21.592683,-25.898739 9.360991,-5.991034 20.69819,-8.986551 34.011599,-8.986551 10.317891,0 19.574873,2.121824 27.77093,6.365473 8.23767,4.202045 14.72796,10.484309 19.47086,18.846794 4.03563,7.197561 6.05344,15.019189 6.05344,23.464883 0,12.065277 -4.24365,22.77841 -12.73094,32.1394 -7.572,8.404095 -15.85128,12.606135 -24.837827,12.606135 -2.870704,0 -5.200551,-0.43684 -6.98954,-1.31053 -1.747385,-0.8737 -3.037121,-2.12183 -3.869209,-3.744402 -0.540857,-1.040114 -0.936099,-2.829105 -1.185726,-5.366972 z M 49.723082,77.510217 c 0,5.699803 1.352143,10.130671 4.05643,13.292606 2.704286,3.161935 5.803814,4.742902 9.298583,4.742902 2.329847,0 4.784506,-0.686473 7.363979,-2.059418 2.579473,-1.41455 5.034133,-3.49477 7.363979,-6.240661 2.371451,-2.74589 4.306056,-6.219857 5.803815,-10.421902 1.497759,-4.243649 2.246638,-8.487298 2.246638,-12.730947 0,-5.658198 -1.41455,-10.047462 -4.243649,-13.167793 -2.787495,-3.12033 -6.199056,-4.680495 -10.234683,-4.680495 -2.662682,0 -5.179749,0.686473 -7.5512,2.059418 -2.329846,1.331341 -4.597286,3.494769 -6.802319,6.490286 -2.205033,2.995517 -3.97322,6.635903 -5.304561,10.921156 -1.331341,4.285253 -1.997012,8.216869 -1.997012,11.794848 z"
id="path347"
style="stroke-width:0.887561"
sodipodi:nodetypes="ccsscscsscccccscsccsccsccscscssccscscccsccsccscscccssscccscscsss" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -1,31 +0,0 @@
#menu {
display: flex;
flex-wrap: wrap;
padding: 0;
}
#menu li {
display: inline-block;
padding-right: 0.5em;
}
#domain {
margin-left: auto;
}
#domain a {
color: #888;
}
.banner {
width: 100%;
}
.experimental {
margin: 3em 0;
padding: 1em;
border: 4px dashed red;
color: red;
font-weight: bold;
}

View File

@@ -7,21 +7,14 @@
{% endif %} {% endif %}
<title>{{ config.mail_domain }} {{ pagename }}</title> <title>{{ config.mail_domain }} {{ pagename }}</title>
<link rel="stylesheet" href="./water.css"> <link rel="stylesheet" href="./water.css">
<link rel="stylesheet" href="./main.css">
<link rel="icon" href="/logo.svg">
<link rel=”mask-icon” href=”/logo.svg” color=”#000000">
</head> </head>
<body> <body>
<ul id="menu">
<li><a href="index.html">home</a></li>
<li><a href="info.html">info</a></li>
<li><a href="privacy.html">privacy</a></li>
<li><a href="https://github.com/deltachat/chatmail">public code ↗</a></li>
<li id="domain"><a href="index.html">{{ config.mail_domain }}</a></li>
</ul>
{{ markdown_html }} {{ markdown_html }}
<footer>
<a href="index.html">home</a> |
<a href="info.html">more info</a> |
<a href="privacy.html">privacy</a> |
<a href="https://github.com/deltachat/chatmail">-> public development </a>
</footer>
</body> </body>
</html> </html>

View File

@@ -1,4 +1,4 @@
<img class="banner" src="collage-privacy.png"/> <img width="800px" src="collage-privacy.png"/>
# Privacy Policy for {{ config.mail_domain }} # Privacy Policy for {{ config.mail_domain }}