Repository navigation
feat(widget): userToken can be a function that returns a fresh token - #476
Conversation
…odercops#461) The widget calls it once each time it asks the server for a session, not per message. A function that throws, rejects, returns a non-string or takes over 5 seconds means the session starts without the visitor, with a console warning. A string still works as before, and setUser() replaces the function.
anurag629
left a comment
There was a problem hiding this comment.
Thanks @Saifjafri212213, this is what #461 asked for. The function is called once per /session request (client.ts:177), a failure or a call that takes over 5 s starts the session without the identity and logs it, the string form works as before, and UserToken is exported. With current dev merged in: build, typecheck, test:coverage, lint (same as dev), api:check, docs:check, size (panel 17.15 of 18 kB) and the full e2e suite (76, in Chrome, with your real-server test) pass.
One optional follow-up for consistency: setUser({ token }) still takes only a string (widget.ts:501), so a site that uses setUser can't hand over a function. Widening its type to UserToken would make the two ways of giving a token match. That's a separate small PR if you want it.
Merging once CI is green.
|
Merged, thanks @Saifjafri212213. |
Summary
userTokencan now be a function (sync or async) that returns a fresh signed token. The widget calls it right before it asks the server for a session, so a page that stays open for hours no longer sends an expired token. A string still works as before.Closes #461
What changed
packages/widget/src/api/client.ts: newUserTokentype (string | (() => string | undefined | Promise<string | undefined>)). The client resolves it in the/sessionrequest only, so it runs once per session request and never per message. If the function throws, rejects, returns something that is not a non-empty string, or takes over 5 seconds, the session starts without an identity, and the first two and the timeout log aconsole.warn. The timer is cleared when the function answers.userTokeninWidgetConfigtakes the new type, andUserTokenis exported.ChatCops.setUser({ token })still sets a fixed string, and replaces the function (as it replaced the old string).setUser(null)signs out as before.widget/api.mdxnext tosetUser, a new "A fresh token for each session" section inserver/setup.mdx, and the type in theconfiguration.mdxlisting.api/widget.api.mdregenerated, and a changeset for@chatcops/widget(minor).Notes for review
USER_TOKEN_TIMEOUT). I picked it so a stuck token endpoint does not leave the visitor waiting for the whole 30 second request timeout. Say if you want another value, or an option.data-user-tokenstays a string, since a script tag cannot hold a function.How I Tested This
tests/api/session.test.ts(client): the provider's token reaches/session; sync and async; not called when the server has no sessions; once per session request across three messages; a new call for the next session once the session token expired;undefinedfor a signed-out visitor; throws, rejects, non-string and empty string; the error being logged; the timeout (at 4.9 s it still waits, at 5.1 s it goes on) and no timer left behind; a fixed string as before;setUserTokenreplacing the function and being set later.tests/user-token.test.ts(widget): called on the first message and not when the page loads, throughChatCops.init(), replaced bysetUser,setUser(null), and a fixed string.api.test-d.ts.dev), size is within the limits, andpnpm docs:checkfinds no errors in the widget docs or my new section. The whole e2e suite passes except the threeS7 reply with sourcestests, which fail on a cleandevtoo. Other packages' docs samples fail the check here for missing builds.AI assistance
An AI coding assistant helped write the change and the tests. I ran the checks listed above, including the real-server e2e in Chrome.