Skip to content

0.25.0: mail login, sign in to any provider that still takes a password - #49

Merged
ralyodio merged 3 commits into
masterfrom
feat/mail-login
Sep 5, 2026
Merged

0.25.0: mail login, sign in to any provider that still takes a password#49
ralyodio merged 3 commits into
masterfrom
feat/mail-login

Conversation

@ralyodio

@ralyodio ralyodio commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

What

mail login <provider|address> [address] [--as NAME] — sign in to any mail provider that still takes a password over IMAP and SMTP. Follows #48, which shipped mail with two providers.

  • Says which kind of password before asking. Gmail, Yahoo, AOL, iCloud, Fastmail and Yandex refuse the account password over IMAP on purpose, and the refusal reads like a typo. The prompt names the kind (app password, per-alias password, bridge password, or the account one), where to make it, and anything to switch on first.
  • Tries IMAP and SMTP, stores nothing on a refusal. A stored password that does not work makes every later command fail further from the cause. An SMTP-only refusal stores the account with a warning, because reading still works. --no-verify opts out.
  • Reads the provider off the address. A webmail domain maps directly; a custom domain's MX records identify Google, Zoho, Fastmail, Proton, iCloud, Forward Email, Migadu and the rest, so mail login you@yourdomain.com needs no --provider. A failed lookup is simply "say which".
  • mail providers lists the fifteen built in — Forward Email, Gmail / Workspace, Yahoo, AOL, iCloud, Fastmail, Zoho, Proton (through Proton Mail Bridge on localhost), GMX, Yandex, mail.com, Posteo, mailbox.org, Migadu, Purelymail — with hosts, ports and the password rule, then the hosts a password cannot reach: Outlook.com / Hotmail / Microsoft 365 (Microsoft removed basic auth; OAuth2 only, app passwords no longer count), Tuta and HEY (no IMAP or SMTP at all). mail login outlook explains instead of failing a login.
  • Certificate verification is never switched off. Proton Mail Bridge signs for itself on localhost, so an account can pin a PEM file to trust in place of the system roots (--tls-ca, MAIL_<NAME>_TLS_CA), and the Proton preset finds the copy Bridge keeps at its usual path on Linux, macOS and Windows by itself. A pinned path that cannot be read is an error at connect time, never a silent downgrade. (The first push used rejectUnauthorized: false; ThreatCrush flagged it, rightly, and this replaces it.)
  • Accounts also gain imapSecure (IMAP STARTTLS on 1143, for the Bridge), readable from the vault as _IMAP_SECURE; --imap-starttls for custom.
  • Every login failure now names the provider's fix, not only Gmail's.
  • Plugin command /mail:login; plugin 0.2.0; README and plugin docs.

Verified

  • 674 tests pass (70 in test/mail.test.ts, 19 new: the table's self-consistency, domain and MX inference, the unreachable list, verifyAccount with injected probes, certificate pinning, vault and file round-trips of the new fields); typecheck clean apart from the two pre-existing free-names errors on master. (test/torrent.test.ts talks to a live tracker and timed out once on the dev box, unrelated.)
  • Live, 2026-09-05: mail login <business address> --as worktest with no provider named read Forward Email off the MX records, verified both IMAP and SMTP, stored the account; mail ls -a worktest listed the inbox; accounts rm removed it.
  • mail login outlook …, a Hotmail address, an unknown provider name, a bare address on an unknown domain, and a wrong Gmail password each produce the intended message and store nothing.
  • Not exercised live: Proton Bridge itself (no Bridge on the dev box). Its certificate should carry 127.0.0.1 / localhost in its SAN for pinning to pass hostname verification; if a Bridge user reports a hostname mismatch, that is the place to look.

🤖 Generated with Claude Code

https://claude.ai/code/session_013h8jopY81BGQ4Pn22NfZTu

ralyodio and others added 2 commits September 5, 2026 23:23
`mail login <provider|address> [address]` says which kind of password the
host wants before asking for it — Gmail, Yahoo, AOL, iCloud, Fastmail and
Yandex refuse the account password over IMAP and their refusal reads like a
typo — then tries IMAP and SMTP and stores nothing on a refusal. The
provider comes off the name, a webmail domain, or a custom domain's MX
records, so a domain hosted at Google, Zoho, Fastmail, Proton, iCloud or
Forward Email needs no --provider.

Fifteen providers are built in (Forward Email, Gmail, Yahoo, AOL, iCloud,
Fastmail, Zoho, Proton via its Bridge on localhost, GMX, Yandex, mail.com,
Posteo, mailbox.org, Migadu, Purelymail); `mail providers` lists them with
hosts, ports and the password rule. Outlook.com / Microsoft 365, Tuta and
HEY are listed as unreachable with the reason, since Microsoft takes only
OAuth2 now and the other two have no IMAP at all.

Accounts gain imapSecure and insecureTls (IMAP STARTTLS and a self-signed
bridge certificate, both needed for Proton), readable from the vault as
_IMAP_SECURE / _INSECURE_TLS. The login-failure message names the fix per
provider instead of only for Gmail. Plugin command /mail:login.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013h8jopY81BGQ4Pn22NfZTu
Version bump for the login work: the mail plugin goes to 0.2.0 with its
third command, /mail:login.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013h8jopY81BGQ4Pn22NfZTu
Comment thread src/mail.ts Fixed
Comment thread src/mail.ts Fixed
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

ThreatCrush Security Scan

10 finding(s)

HIGH/CRITICAL: 2 | MEDIUM: 4 | LOW: 4

Severity Rule Location
HIGH sh-remote-script-execution root-ubuntu.sh:2816
HIGH sh-remote-script-execution root-ubuntu.sh:2820
MEDIUM sh-remote-script-execution root-ubuntu.sh:2969
MEDIUM sh-remote-script-execution root-ubuntu.sh:3998
MEDIUM redos-nested-quantifier src/domain-free.ts:56
MEDIUM redos-nested-quantifier src/mail.ts:1042
LOW secret-generic-credential src/credentials.ts:36
LOW secret-generic-api-key test/credentials.test.ts:208
LOW secret-generic-credential test/mail.test.ts:135
LOW secret-generic-credential test/shorten.test.ts:36

Snippets are redacted; ThreatCrush never prints matched credential material.

ThreatCrush flagged rejectUnauthorized: false (CWE-295) in the IMAP and SMTP
clients, there for Proton Mail Bridge's self-signed certificate on localhost.
Verification now stays on everywhere: an account can name a PEM file to
trust in place of the system roots (--tls-ca, MAIL_<NAME>_TLS_CA), and the
Proton preset finds the copy Bridge keeps at its usual path on Linux, macOS
and Windows by itself. A pinned path that cannot be read is an error at
connect time, never a silent downgrade.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013h8jopY81BGQ4Pn22NfZTu
@ralyodio
ralyodio merged commit a15421e into master Sep 5, 2026
5 checks passed
@ralyodio
ralyodio deleted the feat/mail-login branch September 5, 2026 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants