@bumail/smtp 0.10.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/roadmap.md CHANGED
@@ -20,8 +20,7 @@ Nothing is under way besides what is marked shipped below.
20
20
 
21
21
  ## Later
22
22
 
23
- - **UTF-8 address types in DSNs** (RFC 6533) — internationalized addresses
24
- in the `ORCPT` parameter and in the reports built from it.
23
+ Nothing yet.
25
24
 
26
25
  ## Not planned
27
26
 
@@ -33,26 +32,46 @@ Nothing is under way besides what is marked shipped below.
33
32
 
34
33
  ## Shipped
35
34
 
36
- ### Unreleased — merged, not yet published
35
+ ### 0.11.0
36
+
37
+ - **UTF-8 `ORCPT` (RFC 6533)**: the server decodes `ORCPT=utf-8;…`
38
+ (`utf-8-addr-xtext` with `\x{HEX}`, and raw UTF-8 under `SMTPUTF8`); the
39
+ client sends a
40
+ `utf-8` `ORCPT` in the form the transaction allows instead of leaving it
41
+ out. The reports built from it, in `@bumail/queue`, are not part of this.
42
+
43
+ ### 0.10.0
37
44
 
38
45
  - **DSN requests (RFC 3461)**: the server accepts `RET`, `ENVID`, `NOTIFY`
39
46
  and `ORCPT` and hands them to the app, and always lists `DSN` in its
40
47
  `EHLO` reply, so these parameters are no longer refused with `555 5.5.4`
41
48
  (a client that relied on that refusal has to adapt). The client sends
42
49
  them when the next hop lists `DSN`, and its result reports `dsnOffered`.
50
+
51
+ ### 0.9.0
52
+
43
53
  - **The envelope on an `afterData` error**: `SmtpError.accepted` and
44
54
  `rejected` list the recipients the server took and refused at `RCPT TO`
45
55
  when the session failed after the final dot.
56
+
57
+ ### 0.8.0
58
+
46
59
  - **A message holding a NUL byte is refused**: the server reads it to its
47
60
  end, then answers `554 5.6.0 Message holds a NUL byte`, and the content
48
61
  stream errors with `SmtpError` code `NUL_BYTE`, so `onData` never takes
49
62
  it.
63
+
64
+ ### 0.6.0
65
+
50
66
  - **A renewed certificate without a restart**, `server.setTls({ key, cert
51
67
  })`: the next STARTTLS upgrade and the next implicit TLS connection use
52
68
  it, the sessions open keep their TLS, and a pair that cannot be used
53
69
  throws `INVALID_OPTION` and leaves the old one. Implicit TLS without a
54
70
  proxy now listens in clear and upgrades each socket as it opens, since
55
71
  a native Bun TLS listener cannot swap its certificate.
72
+
73
+ ### 0.5.0
74
+
56
75
  - **Behind a TCP proxy, the client's own address**, with `proxyProtocol:
57
76
  { trusted: [...] }`: the server reads the PROXY protocol, versions 1 and
58
77
  2, from the proxies listed — a Traefik TCP router, HAProxy — so
@@ -1157,7 +1157,8 @@ a token`; `orcpt.address of <address> must be a non-empty string`; `orcpt of
1157
1157
  <address> is over 500 characters once encoded`.
1158
1158
 
1159
1159
  **Why**: RFC 3461 §4.4 and §4.2 cap the parameters as sent, so a character that
1160
- xtext writes as `+XX` counts three.
1160
+ xtext writes as `+XX` counts three (for a `utf-8` `orcpt`, the unitext form:
1161
+ raw UTF-8 octets, `\x{HH}` = 6; for another type, the type, the `;` and the xtext form).
1161
1162
 
1162
1163
  **Fix**: shorten the value, or give the type as letters, digits and hyphens.
1163
1164
 
@@ -1171,18 +1172,24 @@ await sendMail(message, { host, from, to, envid: 'q-1042' }); // not 'q 1042 …
1171
1172
  than `FULL` or `HDRS`; `ENVID` empty, longer than 100 characters as sent,
1172
1173
  not printable ASCII or not xtext; `NOTIFY` mixing `NEVER` with another
1173
1174
  event, naming an event twice or an unknown one; `ORCPT` with no
1174
- `addr-type;` prefix, an address that is not xtext, or more than 500
1175
- characters as sent (RFC 3461 §4.2).
1175
+ `addr-type;` prefix, an address that does not decode (not xtext for
1176
+ `rfc822`; for `utf-8`, RFC 6533's `\x{HEX}` form, with raw UTF-8 only when
1177
+ the transaction used `SMTPUTF8`), or more than 500 characters as sent (RFC
1178
+ 3461 §4.2).
1176
1179
 
1177
1180
  **Why**: RFC 3461 §4. The server refuses the command rather than hand a
1178
1181
  wrong value to `onData`.
1179
1182
 
1180
1183
  **Fix**, as a client: encode the value as xtext (`+` and `=`, spaces and
1181
- non-ASCII bytes as `+XX`), and send `NOTIFY=NEVER` alone.
1184
+ non-ASCII bytes as `+XX`), and send `NOTIFY=NEVER` alone. For
1185
+ `ORCPT=utf-8;` use RFC 6533 instead: `\x{E9}` for `é`, and `\x{2B}` for `+`
1186
+ (not `+2B`), or raw UTF-8 after `MAIL FROM … SMTPUTF8`.
1182
1187
 
1183
1188
  ```text
1184
1189
  C: RCPT TO:<bob@example.com> NOTIFY=SUCCESS,FAILURE ORCPT=rfc822;bob+2Btag@example.com
1185
1190
  S: 250 2.1.5 OK
1191
+ C: RCPT TO:<bob@example.com> ORCPT=utf-8;\x{E9}l\x{E8}ve@example.com
1192
+ S: 250 2.1.5 OK
1186
1193
  ```
1187
1194
 
1188
1195
  ### `501 5.5.4 … given twice`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bumail/smtp",
3
- "version": "0.10.0",
3
+ "version": "0.11.1",
4
4
  "description": "An SMTP server on Bun.listen — RFC 5321 with PIPELINING, SIZE, 8BITMIME, SMTPUTF8, STARTTLS and AUTH after TLS, policy hooks, and no open relay — and a client that delivers a message to a smarthost or by MX",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -48,8 +48,8 @@
48
48
  },
49
49
  "devDependencies": {
50
50
  "@bumail/auth": "^0.5.0",
51
- "@bumail/dns": "^0.2.1",
52
- "@bumail/store": "^0.6.0",
51
+ "@bumail/dns": "^0.2.2",
52
+ "@bumail/store": "^0.6.1",
53
53
  "@types/bun": "^1.4.2"
54
54
  },
55
55
  "peerDependencies": {