π¦ New version release - #549
Merged
Merged
Conversation
brentrager
force-pushed
the
changeset-release/main
branch
from
August 25, 2026 13:40
7623771 to
fd39610
Compare
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.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@smooai/smooth-operator@1.58.4
Patch Changes
a8cb4bb: fix(server): an anonymous widget visitor who gives an email is no longer locked out of its own session
Seen in production on smoo.ai, as a total outage of the public chat.
create_conversation_session { agentId, userEmail }answered 200, and the verynext
send_messageon the same socket answeredSESSION_NOT_FOUNDfor asession that plainly existed.
userEmailalone was the trigger β the samecreate without it, or with only
userNameorbrowserFingerprint, streamedfine.
The widget's pre-chat form collects name + email, so the email lands on the
visitor's own
userparticipant, andmay_read_conversationcounts anyuserparticipant with a non-blank email as making the conversation owned. A
public widget visitor has no verified principal, which on a multi-user
deployment is
UserScope::Denied, whose arm was!owned. So the visitor wasowner-checked against an identity it does not have, and denied the session it
had itself created one frame earlier. The widget's recovery path then created a
fresh session carrying the same email and was denied identically β so real
visitors saw an unbounded retry loop and "We couldn't reach the chat", not a
transient blip. This is th-909995 recurring for the emailful case, against
server::anonymous_scope's own assertion that "it can still create a freshsession, so the anonymous widget flow keeps working": it could create, but not
use.
An anonymous connection can never satisfy an ownership check, so it no longer
faces one β narrowly:
Reach::ById),where the unguessable session/conversation id is the visitor's entire
capability, exactly as it was before scoping shipped.
list_conversations(Reach::Listing) stays strict for everyone. Anonymouslisting falls back to the SEED org, which is precisely where widget
conversations pool, so granting the exception there would have leaked
visitors' chats to each other. A negative control caught that before it
shipped.
auth_org.is_none(), set only by thetokenless and degraded-token branches of
resolve_ws_access), not on thescope β an authenticated principal whose token carries no
emailclaim stillfails closed.
SESSION_NOT_FOUNDfrom thestorage-blip work still leaks nothing: "not found" and "not yours" remain
byte-identical.
Fixed at the single
may_read_conversationchokepoint, sosend_message,get_session,get_conversation_messages,confirm_tool_action,submit_interaction,verify_otpand conversation resume all change together.rust/smooth-operator-server/tests/user_scoping.rsgains the create-with-userEmail-then-send round trip, which is what every existing test missed: theyexercised capture and ownership separately and never the round trip a real
visitor makes. It asserts the session row exists after the create (the failure
was always an authorization denial, never a failed create), then that the send
reaches the turn. Four negative controls ride with it:
SESSION_NOT_FOUNDisstill producible for that same caller on an unknown id, an authenticated
emailless principal still cannot reach an owned session, another authenticated
user still cannot reach the visitor's session or see it in a list, and an
anonymous connection still cannot enumerate authenticated users' conversations.
No API change.
@smooai/smooth-operator-web-chat-example@0.0.117
Patch Changes