Repository navigation
Say so when part of a search fails; send the help form via our own route (#321) - #400
Merged
Merged
Conversation
Each of these turned a failure into less, silently: - a protein batch that failed was dropped, so the list came up short; - a group's page number moved before its entries, so a failed page change labelled the old entries with the new number; - a failed site-page index was replaced, for the rest of the session, by an empty one, so the website's pages were missing from every search; - a help-desk message that failed to send was thanked for anyway. Each now says so where its results would be. The site index is retried by the next search. Also, the help form: - posted every message twice, as both (submit) and (ngSubmit) were bound; - left Send disabled for good if the captcha was solved before the email was typed, since nothing re-checked the fields as they changed. And the "Icon" result type asked for an SVG that does not exist, logging an error on every search with icon results; it is served from general/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From review: - The pages notice now shows whatever the data search found, including nothing, where the pages were the half that might have had something. - A new search resets the help form: its failure, sent state and readiness, and draws it a captcha of its own. Drawn once, a later form had none and could not be sent; a solved token carried over and enabled Send with an empty email. The captcha script loads once and its failure is reported. - Pages are paged on the client, as they are built there: asking the search service for "Pages" put its data results under that heading. - A group page that comes back empty keeps the number on what is shown. - An earlier search's requests are cancelled, so they cannot write into the next one's results. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The form posted to ContentService's /contact, which takes only an hCaptcha token checked with a secret held there; the site's other human checks are Cloudflare Turnstile. /contact is now ours (serve-prod): it checks a Turnstile token on every message, limits how often one address writes, and hands the mail to the local MTA. Where it goes and whom it is from are settings, CONTACT_TO and CONTACT_FROM; without them, or without Turnstile's keys, it says it cannot send, and the form says to email help@reactome.org. The form draws a Turnstile widget per form, re-arms it after a failed send, and says so when the widget or the route is unavailable. "Send me a copy" is gone: mailing whatever address is typed in would let the form mail anyone. Also: an all-failed search no longer also claims "only Reactome data is shown"; a cancelled protein fetch no longer leaves the list marked loading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From review of the contact route: - A message spends the shared hourly budget only once its Turnstile token is accepted; a refused token spends only its sender's. Unverified calls from a few addresses could otherwise close the form for everyone. - sendmail has a timeout, and an error writing to it (EPIPE) is the request's failure rather than an uncaught one that stops the server. - The Turnstile check times out, and is given the reader's address. - The body is quoted-printable, so a long paragraph is not broken at 998 characters; a long subject is folded into encoded words of legal length. - The signature no longer repeats the request's Host header. - Send waits for its answer, so a double click sends once; the widget and its request are cleaned up with the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Checking the limit and counting the message were split around the Turnstile check, so messages sent together all passed before any was counted. An address's slot is now taken at once; only the shared total waits for the check. Cloudflare is given the reader's address only when it is one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #321.
Silent failures, now said
A 404 "No entries found" is still read as no results.
The help form now uses our own route and Cloudflare Turnstile
The form posted to ContentService's
/contact, which accepts only an hCaptcha token checked with a secret held there. The site's other human checks use Cloudflare Turnstile./contactis now a node route inserve-prod(contact-route.js):sendmail -t -i), with a timeout. Recipients come only from settings. The reader's address appears only inReply-To, after validation. The subject is RFC 2047 encoded and the body is quoted-printable.CONTACT_TOandCONTACT_FROM. Without them, or without Turnstile's keys,GET /contactanswers 503 and the form says to email help@reactome.org.Also fixed
(submit)and(ngSubmit)were both bound. A double click now sends once as well.general/.Tests
e2e (
e2e/search-errors.spec.ts). Each test is shown failing first. The help-form tests stand in for Cloudflare and for/contact, so nothing is ever sent.vitest (
contact-route.spec.mjs). These cover:sendmailinvocation, run against a stand-in script, including a hang and an exit before reading.To deploy: set
CONTACT_TOandCONTACT_FROMin the service's environment, then restartserve-prod.🤖 Generated with Claude Code