Files
thepraandClaude Opus 5.5 b45321f28d Following an account brings its earlier posts to its profile
Once a follow holds, OutboxBackfill reads the account's latest public posts from its outbox's first page (twenty at
most, once a day) and keeps them as any fetched post: its profile shows them at once instead of only what it posts from
then on. Homes still get only what arrives afterwards, as on Mastodon. Announces and other servers' objects in the
outbox are left out. Checked live against Mastodon (scenarios/pins.sh, now 9 checks).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
2026-10-06 02:15:49 +02:00

63 lines
4.7 KiB
Bash

# Pinned posts across servers (featured, FEP-e232's Add and Remove): a Mastodon account pins and unpins while alice
# follows it; alice pins and unpins while it follows her; an account that pinned before PrivaPub ever saw it shows its
# pins once resolved (its featured collection, read with its counts), and following it brings its earlier posts (its
# outbox). Needs the mastodon peer.
M=https://mastodon.test:6443
mcurl() { curl -sk --resolve mastodon.test:6443:127.0.0.1 "$@"; }
. "$here/peers/mastodon.sh"
p_pinned() { curl -s -H "$PH" "$P/api/v1/accounts/$1/statuses?pinned=true" | j "print(' '.join(s['uri'] for s in d))"; }
m_pinned() { mcurl -H "$MH" "$M/api/v1/accounts/$1/statuses?pinned=true" | j "print(' '.join(s['uri'] for s in d))"; }
echo "pins"
PT=$(privapub_token alice_pins)
PH="Authorization: Bearer $PT"
[ -n "$PT" ] && ok "PrivaPub token for alice_pins" || { ko "PrivaPub token for alice_pins"; return 1; }
run=$(date +%s)
mastodon_user pinner
MT=$(mastodon_token pinner)
MH="Authorization: Bearer $MT"
[ -n "$MT" ] && ok "Mastodon token for pinner" || { ko "Mastodon token for pinner"; return 1; }
echo " following each other"
pinner_on_p=$(curl -s -H "$PH" "$P/api/v2/search?q=pinner@mastodon.test&resolve=true&type=accounts" | j "print(d['accounts'][0]['id'])")
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/accounts/$pinner_on_p/follow"
alice_on_m=$(mcurl -H "$MH" "$M/api/v2/search?q=@alice_pins@privapub.test&resolve=true&type=accounts" | j "print(d['accounts'][0]['id'])")
mcurl -o /dev/null -X POST -H "$MH" "$M/api/v1/accounts/$alice_on_m/follow"
until_true 45 '[ "$(curl -s -H "$PH" "$P/api/v1/accounts/relationships?id[]=$pinner_on_p" | j "print(d[0][\"following\"] and d[0][\"followed_by\"])")" = "True" ]' \
&& ok "alice and pinner follow each other" || ko "the follows between alice and pinner never took"
echo " pinner pins"
m_post=$(mcurl -X POST -H "$MH" "$M/api/v1/statuses" -d "status=a Mastodon post worth pinning $run&visibility=public")
m_post_id=$(echo "$m_post" | j "print(d['id'])"); m_post_uri=$(echo "$m_post" | j "print(d['uri'])")
mcurl -o /dev/null -X POST -H "$MH" "$M/api/v1/statuses/$m_post_id/pin"
until_true 45 '[ "$(p_pinned $pinner_on_p)" = "$m_post_uri" ]' && ok "pinner's pin shows on its profile here" || ko "pinner's pin never arrived ($(p_pinned $pinner_on_p))"
mcurl -o /dev/null -X POST -H "$MH" "$M/api/v1/statuses/$m_post_id/unpin"
until_true 45 '[ -z "$(p_pinned $pinner_on_p)" ]' && ok "and its unpin takes it off" || ko "pinner's unpin never arrived"
echo " alice pins"
p_post=$(curl -s -X POST -H "$PH" "$P/api/v1/statuses" -d "status=a PrivaPub post worth pinning $run&visibility=public")
p_post_id=$(echo "$p_post" | j "print(d['id'])"); p_post_uri=$(echo "$p_post" | j "print(d['uri'])")
until_true 45 '[ "$(mcurl -H "$MH" "$M/api/v1/accounts/$alice_on_m/statuses?limit=5" | j "print(any(s[\"uri\"] == \"$p_post_uri\" for s in d))")" = "True" ]'
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/statuses/$p_post_id/pin"
until_true 45 '[ "$(m_pinned $alice_on_m)" = "$p_post_uri" ]' && ok "alice's pin shows on her profile on Mastodon" || ko "alice's pin never reached Mastodon ($(m_pinned $alice_on_m))"
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/statuses/$p_post_id/unpin"
until_true 45 '[ -z "$(m_pinned $alice_on_m)" ]' && ok "and her unpin takes it off" || ko "alice's unpin never reached Mastodon"
echo " pins made before"
# a fresh account pins first; PrivaPub reads its featured collection when it first fetches it
early="early$run"
mastodon_user "$early"
ET=$(mastodon_token "$early")
e_post=$(mcurl -X POST -H "Authorization: Bearer $ET" "$M/api/v1/statuses" -d "status=pinned before anyone looked $run&visibility=public")
mcurl -o /dev/null -X POST -H "Authorization: Bearer $ET" "$M/api/v1/statuses/$(echo "$e_post" | j "print(d['id'])")/pin"
early_on_p=$(curl -s -H "$PH" "$P/api/v2/search?q=$early@mastodon.test&resolve=true&type=accounts" | j "print(d['accounts'][0]['id'])")
until_true 45 '[ "$(p_pinned $early_on_p)" = "$(echo "$e_post" | j "print(d[\"uri\"])")" ]' \
&& ok "an account's earlier pin shows once it is resolved" || ko "the earlier pin never showed ($(p_pinned $early_on_p))"
echo " posts made before"
# alice follows the fresh account: its outbox's latest public posts come to its profile here (OutboxBackfill)
e_other=$(mcurl -X POST -H "Authorization: Bearer $ET" "$M/api/v1/statuses" -d "status=written before anyone followed $run&visibility=public" | j "print(d['uri'])")
curl -s -o /dev/null -X POST -H "$PH" "$P/api/v1/accounts/$early_on_p/follow"
until_true 60 '[ "$(curl -s -H "$PH" "$P/api/v1/accounts/$early_on_p/statuses?limit=40" | j "print(any(s[\"uri\"] == \"$e_other\" for s in d))")" = "True" ]' \
&& ok "following an account brings its earlier posts to its profile" || ko "the account's earlier posts never came"