mirror of
https://github.com/chatmail/relay.git
synced 2026-05-11 00:14:36 +00:00
Compare commits
1 Commits
refine-rea
...
streamline
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
131e7b9387 |
4
.github/CODE_OF_CONDUCT.md
vendored
4
.github/CODE_OF_CONDUCT.md
vendored
@@ -1,4 +0,0 @@
|
||||
|
||||
Please refer to
|
||||
[Delta Chat community standards and practices](https://delta.chat/en/community-standards)
|
||||
which also apply for all chatmail developments.
|
||||
21
LICENSE
21
LICENSE
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023, chatmail and delta chat teams
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
178
README.md
178
README.md
@@ -18,7 +18,14 @@ after which the initially specified password is required for using them.
|
||||
We subsequently use `CHATMAIL_DOMAIN` as a placeholder for your fully qualified
|
||||
DNS domain name (FQDN), for example `chat.example.org`.
|
||||
|
||||
1. Install the `cmdeploy` command in a virtualenv
|
||||
1. Setup DNS `A` and `AAAA` records for your `CHATMAIL_DOMAIN`.
|
||||
Verify that DNS is set and SSH root login works:
|
||||
|
||||
```
|
||||
ssh root@CHATMAIL_DOMAIN
|
||||
```
|
||||
|
||||
2. Install the `cmdeploy` command in a virtualenv
|
||||
|
||||
```
|
||||
git clone https://github.com/deltachat/chatmail
|
||||
@@ -26,20 +33,12 @@ DNS domain name (FQDN), for example `chat.example.org`.
|
||||
scripts/initenv.sh
|
||||
```
|
||||
|
||||
2. Create chatmail configuration file `chatmail.ini`:
|
||||
3. Create chatmail configuration file `chatmail.ini`:
|
||||
|
||||
```
|
||||
scripts/cmdeploy init CHATMAIL_DOMAIN
|
||||
```
|
||||
|
||||
3. Setup first DNS records for your `CHATMAIL_DOMAIN`,
|
||||
according to the hints provided by `cmdeploy init`.
|
||||
Verify that SSH root login works:
|
||||
|
||||
```
|
||||
ssh root@CHATMAIL_DOMAIN
|
||||
```
|
||||
|
||||
4. Deploy to the remote chatmail server:
|
||||
|
||||
```
|
||||
@@ -53,106 +52,111 @@ DNS domain name (FQDN), for example `chat.example.org`.
|
||||
scripts/cmdeploy dns
|
||||
```
|
||||
|
||||
### Other helpful commands:
|
||||
6. To check status of your remotely running chatmail service:
|
||||
|
||||
To check the status of your remotely running chatmail service:
|
||||
```
|
||||
scripts/cmdeploy status
|
||||
```
|
||||
|
||||
```
|
||||
scripts/cmdeploy status
|
||||
7. To test your chatmail service:
|
||||
|
||||
```
|
||||
scripts/cmdeploy test
|
||||
```
|
||||
|
||||
8. To benchmark your chatmail service:
|
||||
|
||||
```
|
||||
scripts/cmdeploy bench
|
||||
```
|
||||
|
||||
### Refining the web pages
|
||||
|
||||
|
||||
```
|
||||
scripts/cmdeploy webdev
|
||||
```
|
||||
|
||||
To test whether your chatmail service is working correctly:
|
||||
This starts a local live development cycle for chatmail Web pages:
|
||||
|
||||
```
|
||||
scripts/cmdeploy test
|
||||
```
|
||||
- uses the `www/src/page-layout.html` file for producing static
|
||||
HTML pages from `www/src/*.md` files
|
||||
|
||||
To measure the performance of your chatmail service:
|
||||
- continously builds the web presence reading files from `www/src` directory
|
||||
and generating html files and copying assets to the `www/build` directory.
|
||||
|
||||
```
|
||||
scripts/cmdeploy bench
|
||||
```
|
||||
|
||||
## Overview of this repository
|
||||
|
||||
This repository drives the development of "chatmail instances",
|
||||
comprised of minimal setups of
|
||||
|
||||
- [postfix smtp server](https://www.postfix.org)
|
||||
- [dovecot imap server](https://www.dovecot.org)
|
||||
|
||||
as well as custom services that are integrated with these two:
|
||||
|
||||
- `chatmaild/src/chatmaild/doveauth.py` implements
|
||||
create-on-login account creation semantics and is used
|
||||
by Dovecot during login authentication and by Postfix
|
||||
which in turn uses [Dovecot SASL](https://doc.dovecot.org/configuration_manual/authentication/dict/#complete-example-for-authenticating-via-a-unix-socket)
|
||||
to authenticate users
|
||||
to send mails for them.
|
||||
|
||||
- `chatmaild/src/chatmaild/filtermail.py` prevents
|
||||
unencrypted e-mail from leaving the chatmail instance
|
||||
and is integrated into postfix's outbound mail pipelines.
|
||||
|
||||
There is also the `cmdeploy/src/cmdeploy/cmdeploy.py` command line tool
|
||||
which helps with setting up and managing the chatmail service.
|
||||
`cmdeploy run` uses [pyinfra-based scripting](https://pyinfra.com/)
|
||||
in `cmdeploy/src/cmdeploy/__init__.py`
|
||||
to automatically install all chatmail components on a server.
|
||||
- Starts a browser window automatically where you can "refresh" as needed.
|
||||
|
||||
|
||||
### Home page and getting started for users
|
||||
### Home page and getting started for users
|
||||
|
||||
`cmdeploy run` also creates default static Web pages and deploys them
|
||||
to an nginx web server under `https://CHATMAIL_DOMAIN`.
|
||||
`cmdeploy run` sets up mail services,
|
||||
and also creates default static Web pages and deploys them:
|
||||
|
||||
- a default `index.html` along with a QR code that users can click to
|
||||
- a default `index.html` along with a QR code that users can click to
|
||||
create accounts on your chatmail provider,
|
||||
|
||||
- a default `info.html` that is linked from the home page,
|
||||
|
||||
- a default `policy.html` that is linked from the home page.
|
||||
- a default `policy.html` that is linked from the home page.
|
||||
|
||||
All `.html` files are generated
|
||||
All `.html` files are generated
|
||||
by the according markdown `.md` file in the `www/src` directory.
|
||||
|
||||
|
||||
### Refining the web pages
|
||||
|
||||
|
||||
```
|
||||
scripts/cmdeploy webdev
|
||||
```
|
||||
|
||||
This starts a local live development cycle for chatmail Web pages:
|
||||
|
||||
- uses the `www/src/page-layout.html` file for producing static
|
||||
HTML pages from `www/src/*.md` files
|
||||
|
||||
- continously builds the web presence reading files from `www/src` directory
|
||||
and generating html files and copying assets to the `www/build` directory.
|
||||
|
||||
- Starts a browser window automatically where you can "refresh" as needed.
|
||||
|
||||
|
||||
## Emergency Commands to disable automatic account creation
|
||||
|
||||
If you need to stop account creation,
|
||||
e.g. because some script is wildly creating accounts,
|
||||
login to the server with ssh and run:
|
||||
|
||||
```
|
||||
touch /etc/chatmail-nocreate
|
||||
```
|
||||
|
||||
While this file is present, account creation will be blocked.
|
||||
|
||||
### Ports
|
||||
|
||||
Postfix listens on ports 25 (smtp) and 587 (submission) and 465 (submissions).
|
||||
Dovecot listens on ports 143(imap) and 993 (imaps).
|
||||
|
||||
Delta Chat apps will, however, discover all ports and configurations
|
||||
automatically by reading the `autoconfig.xml` file from the chatmail service.
|
||||
Delta Chat will, however, discover all ports and configurations
|
||||
automatically by reading the `autoconfig.xml` file from the chatmail instance.
|
||||
|
||||
|
||||
## Emergency Commands to disable automatic account creation
|
||||
|
||||
If you need to stop account creation,
|
||||
e.g. because some script is wildly creating accounts, run:
|
||||
|
||||
touch /etc/chatmail-nocreate
|
||||
|
||||
While this file is present, account creation will be blocked.
|
||||
|
||||
|
||||
## Running tests and benchmarks (offline and online)
|
||||
|
||||
1. Set `CHATMAIL_SSH` so that `ssh root@$CHATMAIL_SSH` allows
|
||||
to login to the chatmail instance server.
|
||||
|
||||
2. To run local and online tests:
|
||||
|
||||
scripts/test.sh
|
||||
|
||||
3. To run benchmarks against your chatmail instance:
|
||||
|
||||
scripts/bench.sh
|
||||
|
||||
|
||||
## Development Background for chatmail instances
|
||||
|
||||
This repository drives the development of "chatmail instances",
|
||||
comprised of minimal setups of
|
||||
|
||||
- [postfix smtp server](https://www.postfix.org)
|
||||
- [dovecot imap server](https://www.dovecot.org)
|
||||
|
||||
as well as two custom services that are integrated with these two:
|
||||
|
||||
- `chatmaild/src/chatmaild/doveauth.py` implements
|
||||
create-on-login account creation semantics and is used
|
||||
by Dovecot during login authentication and by Postfix
|
||||
which in turn uses [Dovecot SASL](https://doc.dovecot.org/configuration_manual/authentication/dict/#complete-example-for-authenticating-via-a-unix-socket)
|
||||
to authenticate users
|
||||
to send mails for them.
|
||||
|
||||
- `chatmaild/src/chatmaild/filtermail.py` prevents
|
||||
unencrypted e-mail from leaving the chatmail instance
|
||||
and is integrated into postfix's outbound mail pipelines.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -130,15 +130,7 @@ def test_cmd(args, out):
|
||||
out.check_call(f"{sys.executable} -m pip install deltachat")
|
||||
|
||||
pytest_path = shutil.which("pytest")
|
||||
pytest_args = [
|
||||
pytest_path,
|
||||
"cmdeploy/src/",
|
||||
"-n4",
|
||||
"-rs",
|
||||
"-x",
|
||||
"-vrx",
|
||||
"--durations=5",
|
||||
]
|
||||
pytest_args = [pytest_path, "cmdeploy/src/", "-n4", "-rs", "-x", "-vrx", "--durations=5"]
|
||||
if args.slow:
|
||||
pytest_args.append("--slow")
|
||||
ret = out.run_ret(pytest_args)
|
||||
|
||||
@@ -30,31 +30,31 @@ def test_login_smtp(benchmark, smtp, gencreds):
|
||||
|
||||
class TestDC:
|
||||
def test_autoconfigure(self, benchmark, cmfactory):
|
||||
def dc_autoconfig_and_idle_ready():
|
||||
def autoconfig_and_idle_ready():
|
||||
cmfactory.get_online_accounts(1)
|
||||
|
||||
benchmark(dc_autoconfig_and_idle_ready, 5)
|
||||
benchmark(autoconfig_and_idle_ready, 5)
|
||||
|
||||
def test_ping_pong(self, benchmark, cmfactory):
|
||||
ac1, ac2 = cmfactory.get_online_accounts(2)
|
||||
chat = cmfactory.get_accepted_chat(ac1, ac2)
|
||||
|
||||
def dc_ping_pong():
|
||||
def ping_pong():
|
||||
chat.send_text("ping")
|
||||
msg = ac2.wait_next_incoming_message()
|
||||
msg.chat.send_text("pong")
|
||||
ac1.wait_next_incoming_message()
|
||||
|
||||
benchmark(dc_ping_pong, 5)
|
||||
benchmark(ping_pong, 5)
|
||||
|
||||
def test_send_10_receive_10(self, benchmark, cmfactory, lp):
|
||||
ac1, ac2 = cmfactory.get_online_accounts(2)
|
||||
chat = cmfactory.get_accepted_chat(ac1, ac2)
|
||||
|
||||
def dc_send_10_receive_10():
|
||||
def send_10_receive_10():
|
||||
for i in range(10):
|
||||
chat.send_text(f"hello {i}")
|
||||
for i in range(10):
|
||||
ac2.wait_next_incoming_message()
|
||||
|
||||
benchmark(dc_send_10_receive_10, 5)
|
||||
benchmark(send_10_receive_10, 5)
|
||||
|
||||
@@ -34,7 +34,7 @@ class TestEndToEndDeltaChat:
|
||||
Example input: 100M, 2.4T, 500 K
|
||||
"""
|
||||
units = {"B": 1, "K": 2**10, "M": 2**20, "G": 2**30, "T": 2**40}
|
||||
size = re.sub(r"([KMGT])", r" \1", limit.upper())
|
||||
size = re.sub(r'([KMGT])', r' \1', limit.upper())
|
||||
number, unit = [string.strip() for string in size.split()]
|
||||
return int(float(number) * units[unit])
|
||||
|
||||
|
||||
@@ -36,53 +36,6 @@ def build_webpages(src_dir, build_dir, config):
|
||||
print(traceback.format_exc())
|
||||
|
||||
|
||||
def timespan_to_english(timespan):
|
||||
val = int(timespan[:-1])
|
||||
c = timespan[-1].lower()
|
||||
match c:
|
||||
case "y":
|
||||
return f"{val} years"
|
||||
case "m":
|
||||
return f"{val} months"
|
||||
case "w":
|
||||
return f"{val} weeks"
|
||||
case "d":
|
||||
return f"{val} days"
|
||||
case "h":
|
||||
return f"{val} hours"
|
||||
case "c":
|
||||
return f"{val} seconds"
|
||||
case _:
|
||||
raise ValueError(
|
||||
c
|
||||
+ " is not a valid time unit. Try [y]ears, [w]eeks, [d]ays, or [h]ours"
|
||||
)
|
||||
|
||||
|
||||
def int_to_english(number):
|
||||
if number >= 0 and number <= 12:
|
||||
a = [
|
||||
"zero",
|
||||
"one",
|
||||
"two",
|
||||
"three",
|
||||
"four",
|
||||
"five",
|
||||
"six",
|
||||
"seven",
|
||||
"eight",
|
||||
"nine",
|
||||
"ten",
|
||||
"eleven",
|
||||
"twelve",
|
||||
]
|
||||
return a[number]
|
||||
elif number <= 50:
|
||||
return str(number)
|
||||
if number > 50:
|
||||
return "more"
|
||||
|
||||
|
||||
def _build_webpages(src_dir, build_dir, config):
|
||||
mail_domain = config.mail_domain
|
||||
assert src_dir.exists(), src_dir
|
||||
@@ -95,18 +48,6 @@ def _build_webpages(src_dir, build_dir, config):
|
||||
for path in src_dir.iterdir():
|
||||
if path.suffix == ".md":
|
||||
render_vars, content = prepare_template(path)
|
||||
render_vars["username_min_length"] = int_to_english(
|
||||
config.username_min_length
|
||||
)
|
||||
render_vars["username_max_length"] = int_to_english(
|
||||
config.username_max_length
|
||||
)
|
||||
render_vars["password_min_length"] = int_to_english(
|
||||
config.password_min_length
|
||||
)
|
||||
render_vars["delete_mails_after"] = timespan_to_english(
|
||||
config.delete_mails_after
|
||||
)
|
||||
target = build_dir.joinpath(path.stem + ".html")
|
||||
|
||||
# recursive jinja2 rendering
|
||||
|
||||
@@ -9,21 +9,10 @@ In the Delta Chat account setup
|
||||
you may tap `LOG INTO YOUR E-MAIL ACCOUNT`
|
||||
and fill the two fields like this:
|
||||
|
||||
- `Address`: invent a word with
|
||||
{% if username_min_length == username_max_length %}
|
||||
*exactly* {{ username_min_length }}
|
||||
{% else %}
|
||||
{{ username_min_length}}
|
||||
{% if username_max_length == "more" %}
|
||||
or more
|
||||
{% else %}
|
||||
to {{ username_max_length }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
characters
|
||||
and append `@{{config.mail_domain}}` to it.
|
||||
- `Address`: invent a word with *exactly* nine characters
|
||||
and append `@{{config.mail_domain}}` to it.
|
||||
|
||||
- `Password`: invent at least {{ password_min_length }} characters.
|
||||
- `Password`: invent at least 9 characters.
|
||||
|
||||
If the e-mail address is not yet taken, you'll get that account.
|
||||
The first login sets your password.
|
||||
@@ -35,11 +24,11 @@ The first login sets your password.
|
||||
{{config.mail_domain}} but setting up contact via [QR invite codes](https://delta.chat/en/help#howtoe2ee)
|
||||
allows your messages to pass freely to any outside recipients.
|
||||
|
||||
- You may send up to {{ config.max_user_send_per_minute }} messages per minute.
|
||||
- You may send up to 60 messages per minute
|
||||
|
||||
- Seen messages are removed {{ delete_mails_after }} after arriving on the server.
|
||||
- Seen messages are removed 40 days after arriving on the server
|
||||
|
||||
- You can store up to [{{ config.max_mailbox_size }} messages on the server](https://delta.chat/en/help#what-happens-if-i-turn-on-delete-old-messages-from-server).
|
||||
- You can store up to [100MB messages on the server](https://delta.chat/en/help#what-happens-if-i-turn-on-delete-old-messages-from-server)
|
||||
|
||||
|
||||
### Who are the operators? Which software is running?
|
||||
|
||||
@@ -1,47 +1,4 @@
|
||||
|
||||
body {
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', sans-serif;
|
||||
line-height: 1.4;
|
||||
font-size: 1.2em;
|
||||
max-width: 800px;
|
||||
margin: 20px auto;
|
||||
padding: 0 10px;
|
||||
color: #363636;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.2em;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: #000;
|
||||
margin-bottom: 12px;
|
||||
margin-top: 24px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #0076d1;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
img, video {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
code {
|
||||
background: #efefef;
|
||||
padding: 2.5px 5px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
#menu {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
{% if config.webdev %}
|
||||
<meta http-equiv="refresh" content="3">
|
||||
{% endif %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
||||
<title>{{ config.mail_domain }} {{ pagename }}</title>
|
||||
<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">
|
||||
|
||||
1690
www/src/water.css
Normal file
1690
www/src/water.css
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user