diff --git a/web/js/app.js b/web/js/app.js index a227f46..475f54f 100644 --- a/web/js/app.js +++ b/web/js/app.js @@ -950,8 +950,14 @@ async function sendMail(toText, subject, body, replyTo, anonymous) { // first reply from them reaches our main tier. const accepted = store.accepted(addr.short); if (accepted?.active) fields.push(["Accept", b32encode(tokenFor(master, accepted.identity))]); + // Trimmed before the payload is signed, so the signature covers exactly the + // text the author meant. A trailing newline is not content — but it becomes + // content the moment it is signed, and nothing downstream can strip it + // without invalidating the signature. smolboid, for one, refuses a post + // whose text carries a line break, because a published record is one line + // of a feed. const bodyBytes = utf8Bytes(buildFrontmatter(fields.filter(([, v]) => v), - body.replace(/\s+$/, "") + "\n")); + body.trim())); const envelope = seal(me, recipient, bodyBytes); // §5.8: our token for their mailbox, if they have given us one. const held = store.tokenFrom(addr.short);