- Official hosted instance of
mailpot-web
crate: https://lists.meli.delivery/ - Rendered rustdoc: https://meli.github.io/mailpot/docs/mailpot/
- CLI manpage:
mpot.1
Rendered
âšī¸ Interested in contributing? Consult CONTRIBUTING.md . |
---|
mailpot
the core librarymailpot-cli
a command line tool to manage listsmailpot-web
anaxum
based web server capable of serving archives and authenticating list owners and membersmailpot-archives
static web archive generation or with a dynamic http servermailpot-http
a REST http server to manage lists
- easy setup
- extensible through Rust API as a library
- basic management through CLI tool
- optional lightweight web archiver (static and dynamic)
- useful for both newsletters, communities and for static article comments
- extensible through HTTP REST API as an HTTP server, with webhooks
Create a configuration file and a database:
$ mkdir -p /home/user/.config/mailpot
$ export MPOT_CONFIG=/home/user/.config/mailpot/config.toml
$ cargo run --bin mpot -- sample-config > "$MPOT_CONFIG"
$ # edit config and set database path e.g. "/home/user/.local/share/mailpot/mpot.db"
$ cargo run --bin mpot -- -c "$MPOT_CONFIG" list-lists
No lists found.
This creates the database file in the configuration file as if you executed the following:
$ sqlite3 /home/user/.local/share/mailpot/mpot.db < ./core/src/schema.sql
% mpot help
GNU Affero version 3 or later <https://www.gnu.org/licenses/>
Tool for mailpot mailing list management.
Usage: mpot [OPTIONS] <COMMAND>
Commands:
sample-config
Prints a sample config file to STDOUT
dump-database
Dumps database data to STDOUT
list-lists
Lists all registered mailing lists
list
Mailing list management
create-list
Create new list
post
Post message from STDIN to list
flush-queue
Flush outgoing e-mail queue
error-queue
Mail that has not been handled properly end up in the error queue
queue
Mail that has not been handled properly end up in the error queue
import-maildir
Import a maildir folder into an existing list
update-postfix-config
Update postfix maps and master.cf (probably needs root permissions)
print-postfix-config
Print postfix maps and master.cf entry to STDOUT
accounts
All Accounts
account-info
Account info
add-account
Add account
remove-account
Remove account
update-account
Update account info
repair
Show and fix possible data mistakes or inconsistencies
help
Print this message or the help of the given subcommand(s)
Options:
-d, --debug
Print logs
-c, --config <CONFIG>
Configuration file to use
-q, --quiet
Silence all output
-v, --verbose...
Verbose mode (-v, -vv, -vvv, etc)
-t, --ts <TS>
Debug log timestamp (sec, ms, ns, none)
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
$ cat list-request.eml | cargo run --bin mpot -- -vvvvvv post --dry-run
output
TRACE - Received envelope to post: Envelope {
Subject: "unsubscribe",
Date: "Tue, 04 Aug 2020 14:10:13 +0300",
From: [
Address::Mailbox {
display_name: "Mxxxx Pxxxxxxxxxxxx",
address_spec: "exxxxx@localhost",
},
],
To: [
Address::Mailbox {
display_name: "",
address_spec: "test-announce+request@localhost",
},
],
Message-ID: "<ejduu.fddf8sgen4j7@localhost>",
In-Reply-To: None,
References: None,
Hash: 12581897380059220314,
}
TRACE - unsubscribe action for addresses [Address::Mailbox { display_name: "Mxxxx Pxxxxxxxxxxxx", address_spec: "exxxxx@localhost" }] in list [#2 test-announce] test announcements <test-announce@localhost>
TRACE - Is post related to list [#1 test] Test list <test@localhost>? false
$ cat list-post.eml | cargo run --bin mpot -- -vvvvvv post --dry-run
output
TRACE - Received envelope to post: Envelope {
Subject: "[test-announce] new test releases",
Date: "Tue, 04 Aug 2020 14:10:13 +0300",
From: [
Address::Mailbox {
display_name: "Mxxxx Pxxxxxxxxxxxx",
address_spec: "exxxxx@localhost",
},
],
To: [
Address::Mailbox {
display_name: "",
address_spec: "test-announce@localhost",
},
],
Message-ID: "<ejduu.sddf8sgen4j7@localhost>",
In-Reply-To: None,
References: None,
Hash: 10220641455578979007,
}
TRACE - Is post related to list [#1 test] Test list <test@localhost>? false
TRACE - Is post related to list [#2 test-announce] test announcements <test-announce@localhost>? true
TRACE - Examining list "test announcements" <test-announce@localhost>
TRACE - List subscriptions [
ListSubscription {
list: 2,
address: "exxxxx@localhost",
name: None,
digest: false,
hide_address: false,
receive_duplicates: false,
receive_own_posts: true,
receive_confirmation: true,
enabled: true,
},
]
TRACE - Running FixCRLF filter
TRACE - Running PostRightsCheck filter
TRACE - Running AddListHeaders filter
TRACE - Running FinalizeRecipients filter
TRACE - examining subscription ListSubscription { list: 2, address: "exxxxx@localhost", name: None, digest: false, hide_address: false, receive_duplicates: false, receive_own_posts: true, receive_confirmation: true, enabled: true }
TRACE - subscription is submitter
TRACE - subscription gets copy
TRACE - result Ok(
Post {
list: MailingList {
pk: 2,
name: "test announcements",
id: "test-announce",
address: "test-announce@localhost",
description: None,
archive_url: None,
},
from: Address::Mailbox {
display_name: "Mxxxx Pxxxxxxxxxxxx",
address_spec: "exxxxx@localhost",
},
subscriptions: 1,
bytes: 851,
policy: None,
to: [
Address::Mailbox {
display_name: "",
address_spec: "test-announce@localhost",
},
],
action: Accept {
recipients: [
Address::Mailbox {
display_name: "",
address_spec: "exxxxx@localhost",
},
],
digests: [],
},
},
)
use mailpot::{models::*, *};
use tempfile::TempDir;
let tmp_dir = TempDir::new().unwrap();
let db_path = tmp_dir.path().join("mpot.db");
let config = Configuration {
send_mail: SendMail::ShellCommand("/usr/bin/false".to_string()),
db_path: db_path.clone(),
data_path: tmp_dir.path().to_path_buf(),
administrators: vec!["[email protected]".to_string()],
};
let db = Connection::open_or_create_db(config)?.trusted();
// Create a new mailing list
let list_pk = db.create_list(MailingList {
pk: 0,
name: "foobar chat".into(),
id: "foo-chat".into(),
address: "[email protected]".into(),
description: None,
topics: vec![],
archive_url: None,
})?.pk;
db.set_list_post_policy(
PostPolicy {
pk: 0,
list: list_pk,
announce_only: false,
subscription_only: true,
approval_needed: false,
open: false,
custom: false,
},
)?;
// Drop privileges; we can only process new e-mail and modify subscriptions from now on.
let mut db = db.untrusted();
assert_eq!(db.list_subscriptions(list_pk)?.len(), 0);
assert_eq!(db.list_posts(list_pk, None)?.len(), 0);
// Process a subscription request e-mail
let subscribe_bytes = b"From: Name <[email protected]>
To: <[email protected]>
Subject: subscribe
Date: Thu, 29 Oct 2020 13:58:16 +0000
Message-ID: <[email protected]>
";
let envelope = melib::Envelope::from_bytes(subscribe_bytes, None)?;
db.post(&envelope, subscribe_bytes, /* dry_run */ false)?;
assert_eq!(db.list_subscriptions(list_pk)?.len(), 1);
assert_eq!(db.list_posts(list_pk, None)?.len(), 0);
// Process a post
let post_bytes = b"From: Name <[email protected]>
To: <[email protected]>
Subject: my first post
Date: Thu, 29 Oct 2020 14:01:09 +0000
Message-ID: <[email protected]>
Hello
";
let envelope =
melib::Envelope::from_bytes(post_bytes, None).expect("Could not parse message");
db.post(&envelope, post_bytes, /* dry_run */ false)?;
assert_eq!(db.list_subscriptions(list_pk)?.len(), 1);
assert_eq!(db.list_posts(list_pk, None)?.len(), 1);
# Ok::<(), Error>(())
mailpot's People
Forkers
div72mailpot's Issues
mpot-archives: add http static archives
Use https://github.com/oxidecomputer/typify for JSON schema types
Add convert_html_to_plaintext filter
Add manpage generation with clap_mangen
Add threading to web view.
author header
Switch to rinja for html templates
ARC signing
Use mdoc instead of roff for manpages
Parse DKIM header
See what headers are signed by reading the DKIM header to avoid messing with them.
Consider if migration to `axum-login` v0.7.0 is appropriate
Hi there,
I'm reaching out because we've recently released axum-login
v0.7.0. This release replaces axum-sessions
with tower-sessions
, eliminating potential deadlocking issues, but also reimagines the axum-login
API.
Because this is a significant breaking change, it may not make sense for all applications to migrate. On the other hand, future development will be on this new API and so I want to make sure crate consumers are aware.
I'm also happy to help answer any questions or otherwise be of assistance to folks looking to migrate.
Setup docker container network with postfix for testing
Beyond integration tests, we need a real-world testcase: a bunch of user postfixes talking to a mailing list postfix. This can be done with a docker setup.
A simple debian slim image can be used for this.
Reference for postfix on docker: https://www.frakkingsweet.com/postfix-in-a-container/
Integrate majordomo's taboos list
Add NNTP gateways
Question: implement LMTP?
Add MIME type filter
Queue all outgoing message for later submission by different process.
Add code coverage reports with grcov
Possible Postfix integrations
- local delivery with
postdrop(1)
instead of SMTP - log with
postlog(1)
- sqlite maps https://www.postfix.org/SQLITE_README.html
Add integration tests for CLI binaries
Provide warnings/lints if there are no policies set when generating postfix configuration
If there are no post/subscription policies, the configuration will be empty without any context/explanation. This is confusing for the end-user.
OAuth2
Use oauth2
crate: https://docs.rs/oauth2/latest/oauth2/
Use gitea as auth backend: https://docs.gitea.io/en-us/oauth2-provider/
Add shell completions
mpot-postfix: postfix integration
Add crate to generate postfix configuration from configured lists.
See https://docs.mailman3.org/projects/mailman/en/latest/src/mailman/docs/mta.html for what mailman3 does.
Provide a step-by-step tutorial from zero to postfix deployment
Preferably in both mdoc
, section 7 and a web-friendly format like common markdown or markdeep
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
đ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. đđđ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google â¤ī¸ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.