Opening a Listing to Strangers

· Pavel · release

placementrescuegroupsprivacy

Somebody shares a listing for a cat in a local group chat. Eleven people look at it. One of them wants to ask a single question: is she okay with dogs?

That person is not going to create an account to ask it. They are going to type the question into the chat where they saw the link, where the rescue will never see it, and the cat will stay where she is for another month.

The last few releases have been about that gap. v1.18.5, v1.19.4, v1.19.5 and v1.19.6 shorten the path between a person who might help and the animal who needs them, and then deal with what going public actually costs.

Answering Without Building a Profile First

Helper profiles were the first toll gate. To respond to an adoption or free-foster request you had to build one, which meant a form standing between an impulse to help and the act of helping. Impulses do not survive forms.

Signed-in people can now answer adoption and free-foster requests in one tap, without a pre-existing helper profile. If you are not signed in when you tap, your response resumes after sign-in and gets confirmed in the notification bell, so you are not left wondering whether the click went anywhere. Helper profiles still exist and still matter for the serious fostering and sitting workflows. They are no longer the entry fee for saying “I can take her.”

The listing itself also had to travel better. Placement requests now generate safe social previews, use native sharing where the device supports it, fall back to the clipboard where it does not, and produce printable QR codes. That last one is for the vet clinic noticeboard, which is still one of the most effective rehoming channels in existence and has no API.

The Page a Stranger Actually Lands On

Once links started traveling, the landing page stopped being good enough.

v1.19.4 puts the pet, the context, and the response action together in one focused card that works the same on a phone and a desktop. Request cards and guest response actions now lead to the placement request itself instead of scattering people across the app. And closed requests read as records: status and history, rather than an adoption invitation for an animal who found a home three weeks ago. Inviting someone to adopt a cat who is already placed is a small thing that makes a project look careless about the animals in it.

Rehoming Is Group Work

Placements used to belong to one owner account. Real rescue does not work that way. A group takes in an animal, several people share the fostering, and whoever is awake when a responder writes should be able to answer.

Group members now carry owner-side authority over their group’s pets: they can create, manage, and finalize placements, and placement events fan out to the whole group instead of landing in one person’s notifications. Ownership handover on an accepted placement hands over the right relationships, and two people accepting at the same moment no longer both succeed.

Every conversation between a rescue and a responder now lives in one shared thread, with the group’s identity shown in it. Before, the same responder could end up in several parallel chats with different members of the same rescue, all missing context the others had. Responding to a placement also only offers your own helper profiles now, which was an embarrassing thing to have to fix.

Anonymous Questions, With a Catch

Anyone can now ask a public question on a listing without an account. The asker confirms by email, questions can be translated, and answers publish only once the rescue side replies.

That last rule is the one I thought hardest about. A public question board attached to an animal in distress is an obvious place for a pile-on, and questions appearing before anyone has answered them turns a listing into a comment section. Publishing the pair means the rescue always speaks in the same breath as the question. The admin panel can moderate questions, and Altcha guards the form. The Altcha package had a replay hole, which we closed with a single-use rule rather than waiting for upstream.

What Public Pages Were Leaking

Here is the uncomfortable part of this release cycle.

Opening things up made me audit what was already open, and the audit found real leaks on publicly viewable pet pages: applicant email addresses, Telegram and Google account ids, and helper-profile phone numbers and addresses. None of that should ever have been reachable without authorization. It is fixed in v1.19.6, along with a set of related holes:

  • Listing a pet’s microchips now requires owner or editor rights instead of being readable on any public pet.
  • Transfer request access follows current pet rights, so a previous owner loses it after a handover and group members who manage the pet gain it.
  • SVG uploads are rejected everywhere, and files served from /storage/ carry full security headers with a stricter CSP.
  • The Telegram bot ignores /start outside private chats, so a login link can no longer be posted into a group chat.
  • Rate-limit gates were missing on the responder-profile endpoint and eleven anonymous pet and helper reads. They are there now.
  • API tokens can be minted with any of the 26 scopes the routes actually name, instead of quietly falling back to one blanket ability.

I could have shipped the placement features and stayed quiet about that list. I would rather write it down. A rehoming listing asks strangers to trust a rescue with their contact details and asks a rescue to put an animal’s situation on the public internet. That trust is the actual product, and it is worth more than looking competent.

Rehoming is slow, human, and emotional work. Software cannot make it fast. It can stop being one more obstacle between a cat and the person who was already willing.