process now splits by whether the sender owns a feed. The owner path runs first, so a rotated owner is never mistaken for a registration, and behaves exactly as before for ordinary mail. The stranger path is the new one, and every branch of it is gated. No signed Reply-To means no address to verify or answer, so it stays a silent drop. The blocked check runs before anything touches the network, so Twt-Block cannot be sidestepped by re-registering. Silent mode stays silent, which is how every version before this behaved — except for an admin, who would otherwise have no way to turn registration back on. Then the gate the whole change rests on: before any outbound mail, the claimed address is resolved on its own server and the resolved key must equal the key that signed the request. Without it a signed Reply-To naming someone else's address would be enough to take their feed, and replying to the claimed smol:// URI would pin the sender's key as verified under that address — a permanent denial of service against whoever really owns it. Every reply is queued against the short form for the same reason; nothing hands a self-certifying URI to send. Registration attempts are counted before the dial rather than after, since one that fails its key check costs the same connection. A per-cycle dial budget bounds how long the state lock is held, and a mail over budget keeps its row instead of being dropped. Admin commands are recognised only from an admin address, and only Admit, Block and Registration count as admin commands — an admin's Twt-Help means Twt-Help. A non-admin sending one gets the ordinary answer and is never told admin commands exist. Rig still passes, so the owner path is unchanged in practice as well as in intent.
154 lines
5.5 KiB
Text
154 lines
5.5 KiB
Text
## Loaded once by `src/i18n.rs`; every string the daemon mails to an author
|
|
## lives here, grouped by the mail it belongs to. Operator-facing CLI output is
|
|
## deliberately not here — see the module header.
|
|
##
|
|
## Keep the `-32` style placeables out: these bodies are read in plain-text
|
|
## mail clients and on phones, so they stay short lines and no markup.
|
|
|
|
## Error replies — a mail the daemon could not apply
|
|
|
|
reply-subject = twtxt: { $reason }
|
|
reply-body =
|
|
Your mail could not be applied.
|
|
|
|
Reason: { $reason }
|
|
|
|
Quoted mail:
|
|
{ $quoted }
|
|
|
|
## Retention — the one-time warning as a feed approaches its size cap
|
|
|
|
cap-warning-subject = twtxt: feed at 90% of its size cap
|
|
cap-warning-body =
|
|
Your feed has reached 90% of the { $cap }-byte cap.
|
|
|
|
In hard-limit mode (the default) a full feed rejects new records; delete
|
|
some with Twt-Delete, or choose FIFO pruning with Twt-Prune: fifo, which
|
|
drops the oldest records to make room.
|
|
|
|
## Admission — the mail that hands over the accept token
|
|
|
|
welcome-subject = twtxt: your feed is ready
|
|
welcome-body =
|
|
Your smolboid feed is live: { $url }
|
|
|
|
Post by sending mail to this address with the twt as the body. Manage it
|
|
with the Twt-Nick, Twt-Delete, Twt-Repost and Twt-Prune frontmatter
|
|
fields, and send Twt-Help to get this list again.
|
|
|
|
## Rejection reasons — one per `reason::Reason` variant, rendered into the
|
|
## reply subject and body above. Each is a sentence fragment completing
|
|
## "your mail could not be applied because …", so they start lowercase and
|
|
## carry the fix where there is one.
|
|
|
|
reason-body-not-utf8 = body is not UTF-8
|
|
reason-post-not-canonical = post mail is not in canonical form
|
|
reason-repost-not-canonical = repost mail is not in canonical form
|
|
reason-fields-beyond-reply-to =
|
|
post mail carries fields beyond Reply-To (Subject, headers or an Accept
|
|
token); resend the bare text
|
|
reason-nick-invalid = nick must be 1-30 bytes of a-z, 0-9 or hyphen
|
|
reason-delete-needs-timestamp = Twt-Delete needs an RFC 3339 UTC timestamp
|
|
reason-prune-mode-unknown = unknown prune mode `{ $got }`, want fifo or off
|
|
|
|
## Post rules, from core::rules::RuleError
|
|
|
|
reason-too-many-codepoints = more than 160 Unicode code points
|
|
reason-too-many-bytes = more than 640 bytes
|
|
reason-forbidden-char = contains TAB, LF, CR or U+2028
|
|
reason-bad-timestamp = not an RFC 3339 UTC timestamp at second precision
|
|
reason-duplicate-timestamp = timestamp already exists in this feed
|
|
|
|
## Retention and quota, from the apply step
|
|
|
|
reason-over-quota-post = daily post quota exceeded; try tomorrow
|
|
reason-over-quota-repost = daily repost quota exceeded; try tomorrow
|
|
reason-collision = timestamp { $timestamp } already exists; wait a second and resend
|
|
reason-feed-full =
|
|
feed is at its size cap; delete records with Twt-Delete or choose
|
|
Twt-Prune: fifo
|
|
reason-reply-to-changed =
|
|
your Reply-To does not match the feed's bound author { $author }; send from
|
|
that address or mail the operator
|
|
reason-no-record-at = no record at { $timestamp }
|
|
|
|
## Mailbox requests — register, help and the admin commands
|
|
|
|
reason-one-command-per-mail =
|
|
one command per mail: send Twt-Register, Twt-Help, Twt-Admit, Twt-Block or
|
|
Twt-Registration on its own, and feed commands in a separate mail
|
|
reason-bad-address = `{ $got }` is not a smolmail address
|
|
reason-registration-mode-unknown =
|
|
unknown registration mode `{ $got }`, want open, closed or silent
|
|
|
|
## First contact — an unknown sender who may register
|
|
|
|
info-subject = twtxt: how to get a feed
|
|
info-body =
|
|
You can publish a twtxt feed here by sending mail.
|
|
|
|
Two steps. First accept this address in your client, so our replies reach
|
|
your inbox instead of your requests tier:
|
|
|
|
fumi accept { $mailbox }
|
|
|
|
Then ask for a feed, optionally naming the nick you want:
|
|
|
|
fumi send { $mailbox } --header "Twt-Register: yournick"
|
|
|
|
We will reply with your feed's address and the commands for managing it.
|
|
Nothing is published until you ask for a feed, and this mail is the only
|
|
one you get until you do.
|
|
|
|
## First contact while registration is closed
|
|
|
|
info-closed-subject = twtxt: registration is closed
|
|
info-closed-body =
|
|
Thanks for writing. This instance is not taking new feeds at the moment,
|
|
so there is nothing for you to do here yet.
|
|
|
|
Nothing was published and nothing was kept.
|
|
|
|
## Twt-Help — the command reference
|
|
|
|
help-subject = twtxt: your commands
|
|
help-body =
|
|
Your feed: { $url }
|
|
|
|
Post by sending mail to this address with the twt as the body. The body is
|
|
published byte for byte, at most 160 characters.
|
|
|
|
Management fields, one per mail:
|
|
|
|
Twt-Nick: yournick set the displayed nick
|
|
Twt-Delete: <timestamp> remove one post or repost
|
|
Twt-Repost: <mention> <#id> publish a repost
|
|
Twt-Prune: fifo | off what a full feed does at its size cap
|
|
Twt-Help: send this list again
|
|
|
|
help-admin-section =
|
|
|
|
Admin, from your address:
|
|
|
|
Twt-Admit: user@host give someone a feed
|
|
Twt-Block: user@host withdraw someone's token
|
|
Twt-Registration: open | closed | silent
|
|
|
|
## Admin notifications
|
|
|
|
admin-notify-subject = twtxt: new feed { $slug }
|
|
admin-notify-body =
|
|
A feed was created.
|
|
|
|
Address: { $address }
|
|
Feed: { $url }
|
|
Fingerprint: { $fingerprint }
|
|
|
|
Verify that fingerprint out of band if you do not already know this
|
|
author. Twt-Block withdraws their token.
|
|
|
|
admin-ack-subject = twtxt: { $what }
|
|
admin-ack-body =
|
|
{ $what }
|
|
|
|
Sent because your address is listed as an admin of this instance.
|