Version Packages#68
Open
github-actions[bot] wants to merge 1 commit into
Open
Conversation
github-actions
Bot
force-pushed
the
changeset-release/main
branch
26 times, most recently
from
July 20, 2026 23:59
a13ec24 to
daf19c5
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
July 21, 2026 01:38
daf19c5 to
e74d193
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
@seamless-auth/react@0.5.0
Minor Changes
e591d09: Rename the bundled
AuthRoutespaths to a consistent kebab-case set. The previous mixed-case paths are no longer served./passKeyLogin/passkey-login/verifyPhoneOTP/verify-phone-otp/verifyEmailOTP/verify-email-otp/registerPasskey/register-passkey/magiclinks-sent/magic-link-sentBREAKING: anything linking directly to an old path now falls through to
/login. Apps that only renderAuthRoutesand rely on its internal navigation need no change./login,/verify-magiclink, and/oauth/callbackare unchanged. The latter two are fixed by contracts outside this package: the auth API builds the magic-link URL when it sends the email, and the OAuth callback is registered with providers as an allowed redirect URI.7931828: Standardize the headless client on a single result convention. Every request method now resolves to a
SeamlessAuthResult<T>:BREAKING: the client previously mixed three conventions. Most methods returned a raw
Response, a few returned a result object with asuccessflag, andlistOAuthProvidersandstartOAuthLoginthrew a genericErrorthat discarded the server's detail. All of them now return{ data, error }.What this changes for callers:
Response: replaceresponse.okandawait response.json()witherroranddata. The response body is now parsed and typed, soCurrentUserResult,LoginStartResult,OrganizationsResult,TotpStatus, and friends are real return types instead of types you cast to by hand.loginWithPasskey,registerPasskey, and the step-up verifiers: replaceresult.successwith!result.error. Their payloads moved todata, soresult.prfbecomesresult.data.prf, andresult.credentialIdbecomesresult.data.credentialId.listOAuthProvidersandstartOAuthLogin: these no longer throw. Checkerrorinstead of wrapping the call intry/catch.PasskeyLoginResult,PasskeyLoginWithPrfResult,PasskeyRegistrationResult,StepUpVerificationResult, andStepUpWithPasskeyPrfResult. Replaced byPasskeyLoginData,PasskeyRegistrationData,StepUpPrfData, and the sharedSeamlessAuthResult.Failures no longer throw for HTTP or transport errors, so an expected auth outcome such as a wrong code or an expired link is a value rather than an exception.
SeamlessAuthErrorcarries the servermessage, HTTPstatus, and parsedbody, and a transport failure is reported withstatus0.02c99f3: Request magic links over
POST /auth/magic-linkinstead ofGET.GET /auth/magic-linkwas a state-changing route reachable as a simple cross-site request, so an<img src>on any page could trigger unbounded magic-link emails to a signed-in user. The Express adapter removed the GET route and replaced it with POST.The request now carries an empty JSON body. The adapter ignores it, but the resulting JSON content type forces a CORS preflight, which is what actually keeps the route from being reachable cross-site. A bodyless POST would still be a simple request.
BREAKING: this release requires an adapter with the POST route (
@seamless-auth/express0.9.0 or later). Against an older adapter,requestMagicLinkgets a 404. Callers ofrequestMagicLink()need no code change.0a37241: Surface the auth server's error detail when an OAuth callback fails.
finishOAuthLogin()previously discarded the response body and threw a genericError('Failed to finish OAuth login'), so consuming apps could not tell users what went wrong.It now throws a
SeamlessAuthErrorcarrying the server message, the HTTPstatus, and the parsedbody.SeamlessAuthErroris exported so callers can narrow withinstanceofand map known failures to their own messaging. A body that is empty or not JSON is handled gracefully and falls back to the previous generic message.Callers matching on the exact string
'Failed to finish OAuth login'should switch to inspectingstatusorbody.2dccbed: Request OTP generation over
POSTinstead ofGET.requestPhoneOtp,requestEmailOtp,requestLoginPhoneOtp, andrequestLoginEmailOtpeach caused an SMS or email to be sent, so they were state changing. Sent as aGET, they were simple cross-site requests, so an<img src>on any page could trigger unbounded OTP messages to a signed-in user. They now POST an empty JSON body, which forces a CORS preflight and closes the vector. This mirrors therequestMagicLinkchange.BREAKING: this requires an adapter serving these routes over POST (
@seamless-auth/expresswith the OTP POST change, released alongside this). Against an older adapter the four request methods get a 404. Callers need no code change.f0c4bd9: Unify
useAuth()on the same result convention as the headless client. Every provider helper now returnsSeamlessAuthResultand none of them throw, so the whole SDK reports failure one way.BREAKING:
useAuth()previously mixed four styles. Seven helpers threw, four returned a result,handlePasskeyLoginreturned a boolean, andrefreshStepUpStatusreturnedStepUpStatus | null.Migration:
deleteUser,updateCredential,deleteCredential,switchOrganization,listOAuthProviders,startOAuthLogin, andfinishOAuthLoginno longer throw. Replacetry/catchwith anerrorcheck.handlePasskeyLoginreturns a result instead of a boolean. Replaceif (await handlePasskeyLogin())withif (!(await handlePasskeyLogin()).error).refreshStepUpStatusreturns a result instead ofStepUpStatus | null. Readdatainstead of the return value directly.updateCredentialreturns the credential underdata.logout,logoutAllSessions, andrefreshSessionnow return a result. Existing callers that ignore the return value keep working.Helpers that mutate provider state still do so only when the call succeeds.
dda670b: Remove the unused
mfaRequiredfield fromPasskeyLoginResult(and the inheritedPasskeyLoginWithPrfResult). The backend never gated passkey login on a second factor, so the field was alwaysfalseand the related fail-closed path inhandlePasskeyLoginwas dead code.BREAKING: consumers reading
result.mfaRequiredfromloginWithPasskey()should remove that check. A successful passkey login is now indicated solely byresult.success.Patch Changes
d4e455d: Correct the response types for credential and session endpoints, checked against the API's response schemas.
updateCredential()onuseAuth()now returns the credential itself. It previously returned the{ message, credential }wrapper while declaringPromise<Credential>, so callers reading a field such asfriendlyNamegotundefined, and the cast hid the mismatch from TypeScript.Client return types corrected to match the server schemas:
updateCredentialreturnsCredentialUpdateResult({ message, credential }), replacingCredentialMutationResult, which modelledcredentialas optional when the API always sends itdeleteCredentialreturnsMessageResultlogout,logoutAllSessions, anddeleteUserreturnMessageResultrather than being typed as returning no bodyCredentialMutationResultis removed and replaced byCredentialUpdateResult.c17cf9c: Expand the custom UI documentation with worked examples for registration, OTP and magic-link continuation, and credential management. The OTP and magic-link section documents that
requestMagicLink(),requestLoginEmailOtp(), andrequestLoginPhoneOtp()take no identifier and depend on server-side state from a precedinglogin()call, which is not evident from their signatures.Also corrects README references left stale by the result-object change: the
useAuth()signature block, the step-up examples that usedresult.success, and the PRF example that readresult.prf.41ebb86: Emit relative import paths in the published type declarations. The build kept the
@/*tsconfig path aliases in the generated.d.tsfiles, which no consumer canresolve, so every downstream project silently saw the SDK's public surface as
any(masked byskipLibCheck). Atsc-aliaspost-build step now rewrites thealiases to relative paths, restoring real types for consumers.
597f6d2: The bundled registration screen now asks for an email only. It previously required a phone number as well, but registration only needs an email (the API treats phone as optional and it can be added and verified later), so the field was a mismatch that blocked email-only sign-up.
RegisterInput.phoneis now optional (phone?: string | null) and is only sent when a caller provides one, so headless consumers can still submit a phone at registration if they want to.ede35a8: Encode the magic-link token before placing it in the request path. The token is read from a link's query string, so it is untrusted input, and leaving it unencoded let path segments inside it redirect the request to a different endpoint under
/auth. Because requests are sent with credentials, a crafted link could cause a signed-in user's browser to call unintended endpoints, including ones that send an SMS or email. Affects 0.4.0 and earlier.0f2d686: Improve request hygiene in the shared auth fetch helper. It no longer sends a JSON
Content-Typeon bodyless requests (some proxies reject a GET that advertises a request content type), and it no longer logs aconsole.warnon every non-ok response. Callers already inspectresponse.ok, and caller-provided headers still take precedence.46f2a7c: Fix the magic-link waiting screen treating an unused link as completed. The poll endpoint answers
204with no body until the emailed link is consumed, so checking only for a non-error response redirected on the first poll, before the user clicked the link. It now waits for the endpoint to report success.0e208b4: Fix magic-link verification so the tab that completes the link refreshes provider state and lands authenticated, instead of relying on another tab or a manual reload.
90b7c14: Fix the bundled OAuth provider buttons so the callback redirect URI respects the router basename. Apps mounted under a non-root basename (for example
/app) now send/app/oauth/callbackinstead of/oauth/callback, which previously failed redirect URI allowlisting or landed on a route that did not exist. Apps mounted at the root are unaffected.1c4f4d2: Correct the organization response types, checked against the API's declared response schemas.
addOrganizationMemberandupdateOrganizationMemberreturnOrganizationMembershipResult({ membership }). They were typed as returning a members list, so reading.membersgaveundefined.removeOrganizationMemberreturnsMessageResult, not a members list.switchOrganizationreturnsOrganizationSwitchResult({ message, organizationId, organization }), which describes what the endpoint actually sends.OrganizationMembershipResultandOrganizationSwitchResultare new exports.aa2fda8: Improve browser detection used for passkey device labels. Opera, Vivaldi, Samsung Internet, and Brave are now identified instead of being reported as Chrome, and Chrome and Firefox on iOS are recognized through their
CriOSandFxiOStokens. Chromium derivatives are now matched before the generic chrome token, so the result no longer depends on check ordering.Brave is detected through
navigator.bravebecause it ships a user agent identical to Chrome's. Arc exposes no distinguishing marker and is still reported as chrome.a9580e8: Raise the
react-router-domv7 peer floor to^7.15.1to steer adopters off versions affected by a high-severity advisory (GHSA in react-router's vendored turbo-stream, affecting react-router 7.0.0 through 7.15.0). React Router 6 is unaffected, so the^6.4.0range is unchanged.This is a peer range change, so adopters on a vulnerable v7 (7.0.0 to 7.15.0) will see an npm warning until they upgrade to 7.15.1 or later. No SDK code change and no runtime behavior change.
5d865ab: Make the platform authenticator capability check safe to evaluate in a server environment.
isPlatformAuthenticatorAvailablepreviously readwindowwithout a guard and threw aReferenceErrorduring server-side rendering. It now returnsfalsewhen there is nowindow, matching the guard already used by the WebAuthn availability check.