Your own email: the connection takes a mail password or a send-mail grant, but nothing ever sends through it #361

Closed
opened 2026-10-01 10:46:08 +00:00 by tiagoagueda · 0 comments
Owner

Found on 2026-09-29 in a read-only review of postulo at 95348908d, searching for the callers of core/correspondence.py across the core, its tests and every sibling repository.

Checked again on 2026-10-01 against main at 0a5cad587: still present. The code is now at plugins/views.py:38 (the "Sending as yourself" group); the other locations have not moved, and the same search still finds no caller outside the two test files.

Settings → Connections offers Your own email, whose description promises "Send from your own address, over your own mail server". It asks for the person's mail password, or for consent from Google or Microsoft with a mail-sending scope, and keeps the secret. No page, API endpoint, task or plugin ever sends through it: correspondence.send() and correspondence.can_send_as_themselves() are called only from tests. The person hands over a long-lived credential that can send mail as them, and gets nothing for it.

  • Where: plugins/own_mail/__init__.py:48-60 (the manifest and its description), notifications/apps.py:34 (register_builtin("outbox", OwnMail), on by default), core/correspondence.py:66-68 (can_send_as_themselves) and :96-146 (send), plugins/views.py:37 (the "Sending as yourself" group), config/settings/base.py:410 and postulo.wiki/Configuration.md:300-309, 614-617, 655 (the outbox, its consent flow and POSTULO_OUTBOX_RATE described as working).
  • What happens: a person reads "Send from your own address" and sets the connection up with their mailbox password, or with Connect to Google or Microsoft, which grants a refresh token able to send mail as them. Test signs in and succeeds. After that, no screen offers to send anything from that address; a search of src/ (Python, templates, static/js), and of every postulo-* repository, finds no caller of correspondence.send or can_send_as_themselves outside tests/test_outbox.py and tests/test_mail_xoauth2.py. POSTULO_OUTBOX_RATE bounds a flow nobody can start.
  • Why it matters: the interface and the wiki describe a capability that does not exist, and the instance stores (encrypted) a password or a send-mail grant with no purpose. If the database and the field key ever leak together, these are credentials that could send mail as the person, kept for nothing.
  • Fix: until something sends through it, do not offer the kind: stop registering own-mail by default (or hide the outbox group in Settings → Connections), and mark the outbox paragraphs in Configuration and Writing a plugin as groundwork. When the workflow is built — a "send from my address" action on a follow-up letter or a contact, calling correspondence.send — register it again. Until then, if the connection stays visible, reword the description to say that no screen sends through it yet.

Related to #149 (closed), which built the outbox kind, the settings and the send path, but not the "distinct workflow" it named (sending a follow-up as oneself); and to #151 (closed), which added the OAuth sign-in for it.

Done when

  • A test in tests/test_outbox.py fails while Settings → Connections offers own-mail and no view, task or API endpoint calls correspondence.send; it passes once the kind is hidden or a real sending action exists (and, in the second case, a view test sends a letter through the outbox).
Found on 2026-09-29 in a read-only review of postulo at 95348908d, searching for the callers of `core/correspondence.py` across the core, its tests and every sibling repository. Checked again on 2026-10-01 against `main` at `0a5cad587`: still present. The code is now at `plugins/views.py:38` (the "Sending as yourself" group); the other locations have not moved, and the same search still finds no caller outside the two test files. *Settings → Connections* offers **Your own email**, whose description promises "Send from your own address, over your own mail server". It asks for the person's mail password, or for consent from Google or Microsoft with a mail-sending scope, and keeps the secret. No page, API endpoint, task or plugin ever sends through it: `correspondence.send()` and `correspondence.can_send_as_themselves()` are called only from tests. The person hands over a long-lived credential that can send mail as them, and gets nothing for it. - **Where:** `plugins/own_mail/__init__.py:48-60` (the manifest and its description), `notifications/apps.py:34` (`register_builtin("outbox", OwnMail)`, on by default), `core/correspondence.py:66-68` (`can_send_as_themselves`) and `:96-146` (`send`), `plugins/views.py:37` (the "Sending as yourself" group), `config/settings/base.py:410` and `postulo.wiki/Configuration.md:300-309, 614-617, 655` (the outbox, its consent flow and `POSTULO_OUTBOX_RATE` described as working). - **What happens:** a person reads "Send from your own address" and sets the connection up with their mailbox password, or with *Connect* to Google or Microsoft, which grants a refresh token able to send mail as them. *Test* signs in and succeeds. After that, no screen offers to send anything from that address; a search of `src/` (Python, templates, `static/js`), and of every `postulo-*` repository, finds no caller of `correspondence.send` or `can_send_as_themselves` outside `tests/test_outbox.py` and `tests/test_mail_xoauth2.py`. `POSTULO_OUTBOX_RATE` bounds a flow nobody can start. - **Why it matters:** the interface and the wiki describe a capability that does not exist, and the instance stores (encrypted) a password or a send-mail grant with no purpose. If the database and the field key ever leak together, these are credentials that could send mail as the person, kept for nothing. - **Fix:** until something sends through it, do not offer the kind: stop registering `own-mail` by default (or hide the `outbox` group in *Settings → Connections*), and mark the outbox paragraphs in *Configuration* and *Writing a plugin* as groundwork. When the workflow is built — a "send from my address" action on a follow-up letter or a contact, calling `correspondence.send` — register it again. Until then, if the connection stays visible, reword the description to say that no screen sends through it yet. Related to #149 (closed), which built the outbox kind, the settings and the send path, but not the "distinct workflow" it named (sending a follow-up as oneself); and to #151 (closed), which added the OAuth sign-in for it. ## Done when - A test in `tests/test_outbox.py` fails while *Settings → Connections* offers `own-mail` and no view, task or API endpoint calls `correspondence.send`; it passes once the kind is hidden or a real sending action exists (and, in the second case, a view test sends a letter through the outbox).
tiagoagueda added this to the 0.5.0 milestone 2026-10-01 10:46:08 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#361
No description provided.