mirror of
https://github.com/chatmail/relay.git
synced 2026-05-16 23:58:58 +00:00
feat: support self-signed TLS via underscore domain convention Domains starting with "_" (e.g. _chat.example.org) automatically use self-signed TLS certificates instead of ACME/Let's Encrypt. The TLS mode is derived from the domain name — no separate config option needed. Internally, when config.tls_cert_mode is "self" (underscore domain): - Generate self-signed certificates via openssl - Set Postfix smtp_tls_security_level to "encrypt" (opportunistic TLS) - Add smtp_tls_policy_map entry for underscore domains - Skip ACME, MTA-STS and www CNAME checks in `cmdeploy dns` - Serve /new via GET (not redirect to dcaccount:) with rate-limiting (nginx limit_req, 2r/s burst=5) - Return dclogin: URLs with ic=3 (AcceptInvalidCertificates) from /new - Render QR codes client-side via JavaScript and qrcode-svg - Use config.tls_cert_path/tls_key_path in Postfix, Dovecot and nginx templates instead of hardcoded ACME paths
61 lines
1.8 KiB
Python
61 lines
1.8 KiB
Python
import json
|
|
|
|
import chatmaild
|
|
from chatmaild.newemail import (
|
|
create_dclogin_url,
|
|
create_newemail_dict,
|
|
print_new_account,
|
|
)
|
|
|
|
|
|
def test_create_newemail_dict(example_config):
|
|
ac1 = create_newemail_dict(example_config)
|
|
assert "@" in ac1["email"]
|
|
assert len(ac1["password"]) >= 10
|
|
|
|
ac2 = create_newemail_dict(example_config)
|
|
|
|
assert ac1["email"] != ac2["email"]
|
|
assert ac1["password"] != ac2["password"]
|
|
|
|
|
|
def test_create_dclogin_url():
|
|
url = create_dclogin_url("user@example.org", "p@ss w+rd")
|
|
assert url.startswith("dclogin:")
|
|
assert "v=1" in url
|
|
assert "ic=3" in url
|
|
|
|
assert "user@example.org" in url
|
|
# password special chars must be encoded
|
|
assert "p%40ss" in url
|
|
assert "w%2Brd" in url
|
|
|
|
|
|
def test_print_new_account(capsys, monkeypatch, maildomain, tmpdir, example_config):
|
|
monkeypatch.setattr(chatmaild.newemail, "CONFIG_PATH", str(example_config._inipath))
|
|
print_new_account()
|
|
out, err = capsys.readouterr()
|
|
lines = out.split("\n")
|
|
assert lines[0] == "Content-Type: application/json"
|
|
assert not lines[1]
|
|
dic = json.loads(lines[2])
|
|
assert dic["email"].endswith(f"@{example_config.mail_domain}")
|
|
assert len(dic["password"]) >= 10
|
|
# default tls_cert=acme should not include dclogin_url
|
|
assert "dclogin_url" not in dic
|
|
|
|
|
|
def test_print_new_account_self_signed(capsys, monkeypatch, make_config):
|
|
config = make_config("_test.example.org")
|
|
monkeypatch.setattr(chatmaild.newemail, "CONFIG_PATH", str(config._inipath))
|
|
print_new_account()
|
|
out, err = capsys.readouterr()
|
|
lines = out.split("\n")
|
|
dic = json.loads(lines[2])
|
|
assert "dclogin_url" in dic
|
|
url = dic["dclogin_url"]
|
|
assert url.startswith("dclogin:")
|
|
assert "ic=3" in url
|
|
|
|
assert dic["email"].split("@")[0] in url
|