muc, bookmarks: do not let autojoin recreate a destroyed room #27

Closed
asxpi wants to merge 1 commit from fix/C34-destroyed-room-autojoin into develop
Member

What and why

A room destroyed with destroy_room kept its autojoin bookmark. At the next
sign-in, autojoin sent the join presence even though the room's disco#info
answered item-not-found, so the server made the room again: empty, ours,
with its default configuration (interop issue 1, C34; XEP-0045 §10.9,
XEP-0402).

  • The bookmark goes with the room. It is removed after destroy_room is
    answered with a result, and on a <destroy/> presence, including one from
    another owner and one for a MUC/Sub room. This is the same way M22
    (da2984cc) takes back an accepted invite's bookmark. The alternate venue
    stays in <Destroyed> and is not joined.
  • Autojoin does not create rooms. Joins the account makes by itself
    (autojoin at sign-in, a rejoin, another device's bookmark) now go through
    muc JoinIfThere. It waits for the room's disco#info and sends no
    presence if the answer is item-not-found or gone. The join then fails
    as muc <Error> item-not-found, and bookmarks shows "Room does not exist".
    Joins the host asks for (muc join, bookmarks item, force_join,
    accept_invite) still go out at once and may create a room.

Docs: the schema's bookmarks item autojoin, destroy_room and
<Destroyed> entries, and the XEP-0402 row ("since 1.2.2").

Choices to review:

  • The bookmark is removed rather than only having its autojoin cleared.
  • A non-persistent room that the server removes when it empties is no
    longer recreated by autojoin.
  • Each autojoin waits one disco#info round trip.

Tests

New:

  • test_muc_admin: muc-destroy-room-takes-the-bookmark-back
  • test_muc: muc-destroy-presence-takes-the-bookmark-back
  • test_bookmarks: bookmarks-autojoin-skips-a-room-that-is-not-there
  • test_bookmarks: bookmarks-explicit-join-still-creates-a-room. This
    guards against a regression, so it also passes on develop.

The first three fail on develop. Ten existing tests that drive an autojoin
now answer the room's disco#info first.

With the fix, the whole Tcl suite runs 8130 tests: 8085 passed, 0 failed,
45 skipped. api.py check is clean. The server rigs were not run.

Verified

anotherim-server, slot 3, repro-C34.py. The script makes a room,
bookmarks it, destroys it, signs in again, puts back a stale autojoin
bookmark, and signs in again:

Fixes #26

## What and why A room destroyed with `destroy_room` kept its autojoin bookmark. At the next sign-in, autojoin sent the join presence even though the room's disco#info answered `item-not-found`, so the server made the room again: empty, ours, with its default configuration (interop issue 1, C34; XEP-0045 §10.9, XEP-0402). - **The bookmark goes with the room.** It is removed after `destroy_room` is answered with a result, and on a `<destroy/>` presence, including one from another owner and one for a MUC/Sub room. This is the same way M22 (da2984cc) takes back an accepted invite's bookmark. The alternate venue stays in `<Destroyed>` and is not joined. - **Autojoin does not create rooms.** Joins the account makes by itself (autojoin at sign-in, a rejoin, another device's bookmark) now go through `muc JoinIfThere`. It waits for the room's disco#info and sends no presence if the answer is `item-not-found` or `gone`. The join then fails as `muc <Error> item-not-found`, and bookmarks shows "Room does not exist". Joins the host asks for (`muc join`, `bookmarks item`, `force_join`, `accept_invite`) still go out at once and may create a room. Docs: the schema's `bookmarks item` autojoin, `destroy_room` and `<Destroyed>` entries, and the XEP-0402 row ("since 1.2.2"). Choices to review: - The bookmark is removed rather than only having its autojoin cleared. - A non-persistent room that the server removes when it empties is no longer recreated by autojoin. - Each autojoin waits one disco#info round trip. ## Tests New: - `test_muc_admin`: `muc-destroy-room-takes-the-bookmark-back` - `test_muc`: `muc-destroy-presence-takes-the-bookmark-back` - `test_bookmarks`: `bookmarks-autojoin-skips-a-room-that-is-not-there` - `test_bookmarks`: `bookmarks-explicit-join-still-creates-a-room`. This guards against a regression, so it also passes on develop. The first three fail on develop. Ten existing tests that drive an autojoin now answer the room's disco#info first. With the fix, the whole Tcl suite runs 8130 tests: 8085 passed, 0 failed, 45 skipped. `api.py check` is clean. The server rigs were not run. ## Verified anotherim-server, slot 3, `repro-C34.py`. The script makes a room, bookmarks it, destroys it, signs in again, puts back a stale autojoin bookmark, and signs in again: - v1.2.1, fail (bookmark kept, status 201 at both sign-ins): https://dev.another.im/another-im/interop/src/branch/ai-runs-2026-11-07/runs/20261107-234000-XEP-0402-slixmpp-anotherim-server - this branch, pass (bookmark removed, no join sent, room_state `error` "Room does not exist"): https://dev.another.im/another-im/interop/src/branch/ai-runs-2026-11-07/runs/20261107-234035-XEP-0402-slixmpp-anotherim-server Fixes #26
A room destroyed with destroy_room kept its XEP-0402 bookmark with
autojoin='true': neither destroy_room nor the <destroy/> presence
touched bookmarks. At the next sign-in autojoin asked the room's
disco#info, got item-not-found, and sent the join presence anyway, so
the server made the room again: empty, owned by us, with its default
configuration, under the address the owner had just given up (interop
issue 1, C34; XEP-0045 10.9, XEP-0402).

Take the bookmark back once the room is destroyed, as accept_invite
does for a room that refuses the join for good (M22): after
destroy_room is answered, and on a <destroy/> presence (another
owner's destroy, or a MUC/Sub room's). The alternate venue stays in
<Destroyed> and is not joined.

Joins the account makes by itself (autojoin at sign-in, a rejoin after
being put out, another device's bookmark) now wait for the room's
disco#info and are not sent to a room answering item-not-found or
gone; they fail as <Error> item-not-found, which bookmarks shows as
"Room does not exist". A join the host asks for (muc join, bookmarks
item, force_join) still goes out at once and may create a room.

Tests: destroy_room and a destroy presence take the bookmark back;
autojoin skips a room that is not there; an explicit join still
creates one. Tests that drove an autojoin now answer the room's
disco#info first.

Assisted-by: Claude:opus-5-5
Owner

Thank you for the careful fix, the repro script and the interop runs. The same bug (C34) was fixed on develop in parallel (1aed459c, with follow-ups aa20b054 and d04ed76a) and released in 1.2.2, so this PR now conflicts and has nothing left to add. Autojoin goes through muc JoinIfExists, and a room answering item-not-found or gone is not joined (muc <Gone>, then <Error>). One deliberate difference: on a destroy, 1.2.2 clears the bookmark's autojoin and keeps the bookmark, rather than removing it. A bookmark is synced user data, and another owner's destroy should not delete it on every device. I'm closing this as fixed in 1.2.2. If you see a case that 1.2.2 still gets wrong, please open an issue or a PR against develop.

Thank you for the careful fix, the repro script and the interop runs. The same bug (C34) was fixed on develop in parallel (1aed459c, with follow-ups aa20b054 and d04ed76a) and released in 1.2.2, so this PR now conflicts and has nothing left to add. Autojoin goes through `muc JoinIfExists`, and a room answering item-not-found or gone is not joined (`muc <Gone>`, then `<Error>`). One deliberate difference: on a destroy, 1.2.2 clears the bookmark's autojoin and keeps the bookmark, rather than removing it. A bookmark is synced user data, and another owner's destroy should not delete it on every device. I'm closing this as fixed in 1.2.2. If you see a case that 1.2.2 still gets wrong, please open an issue or a PR against develop.
ann closed this pull request 2026-11-09 17:19:22 +00:00

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
another-im/libtacky!27
No description provided.