From 20f112be602f42f8dae243bd24951632af396634 Mon Sep 17 00:00:00 2001 From: Wes Risenmay Date: Mon, 2 Feb 2026 11:00:42 -0700 Subject: [PATCH 1/7] moved the app routes into src --- example/app.json | 7 ++++++- example/{ => src}/app/_layout.tsx | 0 example/{ => src}/app/budgets.tsx | 0 example/{ => src}/app/connect.tsx | 2 +- example/{ => src}/app/goals.tsx | 0 example/{ => src}/app/index.tsx | 0 example/{ => src}/app/oauth_complete.tsx | 0 example/{ => src}/app/pulse.tsx | 0 example/{ => src}/app/spending.tsx | 0 example/{ => src}/app/transactions.tsx | 0 10 files changed, 7 insertions(+), 2 deletions(-) rename example/{ => src}/app/_layout.tsx (100%) rename example/{ => src}/app/budgets.tsx (100%) rename example/{ => src}/app/connect.tsx (98%) rename example/{ => src}/app/goals.tsx (100%) rename example/{ => src}/app/index.tsx (100%) rename example/{ => src}/app/oauth_complete.tsx (100%) rename example/{ => src}/app/pulse.tsx (100%) rename example/{ => src}/app/spending.tsx (100%) rename example/{ => src}/app/transactions.tsx (100%) diff --git a/example/app.json b/example/app.json index 521138a..89e12a2 100644 --- a/example/app.json +++ b/example/app.json @@ -28,7 +28,12 @@ "favicon": "./assets/images/favicon.png" }, "plugins": [ - "expo-router", + [ + "expo-router", + { + "origin": false + } + ], [ "expo-splash-screen", { diff --git a/example/app/_layout.tsx b/example/src/app/_layout.tsx similarity index 100% rename from example/app/_layout.tsx rename to example/src/app/_layout.tsx diff --git a/example/app/budgets.tsx b/example/src/app/budgets.tsx similarity index 100% rename from example/app/budgets.tsx rename to example/src/app/budgets.tsx diff --git a/example/app/connect.tsx b/example/src/app/connect.tsx similarity index 98% rename from example/app/connect.tsx rename to example/src/app/connect.tsx index c483683..2ad2cb2 100644 --- a/example/app/connect.tsx +++ b/example/src/app/connect.tsx @@ -21,7 +21,7 @@ export default function Connect() { return ( { console.error(`SSO URL load error: ${error}`) diff --git a/example/app/goals.tsx b/example/src/app/goals.tsx similarity index 100% rename from example/app/goals.tsx rename to example/src/app/goals.tsx diff --git a/example/app/index.tsx b/example/src/app/index.tsx similarity index 100% rename from example/app/index.tsx rename to example/src/app/index.tsx diff --git a/example/app/oauth_complete.tsx b/example/src/app/oauth_complete.tsx similarity index 100% rename from example/app/oauth_complete.tsx rename to example/src/app/oauth_complete.tsx diff --git a/example/app/pulse.tsx b/example/src/app/pulse.tsx similarity index 100% rename from example/app/pulse.tsx rename to example/src/app/pulse.tsx diff --git a/example/app/spending.tsx b/example/src/app/spending.tsx similarity index 100% rename from example/app/spending.tsx rename to example/src/app/spending.tsx diff --git a/example/app/transactions.tsx b/example/src/app/transactions.tsx similarity index 100% rename from example/app/transactions.tsx rename to example/src/app/transactions.tsx From 34432096e5cb8cf7ec14db7a5b598301ad7beafd Mon Sep 17 00:00:00 2001 From: Wes Risenmay Date: Tue, 3 Feb 2026 13:09:52 -0700 Subject: [PATCH 2/7] the connect widget is now fetching its own url --- example/src/app/connect.tsx | 79 ++++++++++++++++++++----------------- example/src/shared/api.ts | 58 +++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 36 deletions(-) create mode 100644 example/src/shared/api.ts diff --git a/example/src/app/connect.tsx b/example/src/app/connect.tsx index 2ad2cb2..7ae04fc 100644 --- a/example/src/app/connect.tsx +++ b/example/src/app/connect.tsx @@ -1,12 +1,10 @@ -import React from "react" -import { StyleSheet, Platform } from "react-native" +import React, { useEffect, useState } from "react" +import { StyleSheet } from "react-native" import { SafeAreaView } from "react-native-safe-area-context" import * as Linking from "expo-linking" import { ConnectWidget } from "@mxenabled/react-native-widget-sdk" - -const baseUrl = Platform.OS === "android" ? "http://10.0.2.2:8089" : "http://localhost:8089" -const proxy = `${baseUrl}/user/widget_urls` +import { fetchWidgetUrl } from "../shared/api" const styles = StyleSheet.create({ page: { @@ -18,39 +16,48 @@ const styles = StyleSheet.create({ export default function Connect() { const clientRedirectUrl = Linking.createURL("connect") + const [url, setUrl] = useState(null) + + useEffect(() => { + fetchWidgetUrl({ clientRedirectUrl, widgetType: "connect_widget" }).then((url) => { + setUrl(url) + }) + }, [clientRedirectUrl]) + return ( - { - console.error(`SSO URL load error: ${error}`) - }} - onMessage={(url) => { - console.log(`Got a message: ${url}`) - }} - onInvalidMessageError={(url, _error) => { - console.log(`Got an unknown message: ${url}`) - }} - onLoad={(_payload) => { - console.log("Widget is loading") - }} - onLoaded={(_payload) => { - console.log("Widget has loaded") - }} - onMemberConnected={(payload) => { - console.log(`Member connected with payload: ${JSON.stringify(payload)}`) - }} - onOAuthRequested={(payload) => { - console.log(`OAuth requested with URL: ${payload.url}`) - }} - onStepChange={(payload) => { - console.log(`Moving from ${payload.previous} to ${payload.current}`) - }} - onSelectedInstitution={(payload) => { - console.log(`Selecting ${payload.name}`) - }} - /> + {url && ( + { + console.error(`SSO URL load error: ${error}`) + }} + onMessage={(url) => { + console.log(`Got a message: ${url}`) + }} + onInvalidMessageError={(url, _error) => { + console.log(`Got an unknown message: ${url}`) + }} + onLoad={(_payload) => { + console.log("Widget is loading") + }} + onLoaded={(_payload) => { + console.log("Widget has loaded") + }} + onMemberConnected={(payload) => { + console.log(`Member connected with payload: ${JSON.stringify(payload)}`) + }} + onOAuthRequested={(payload) => { + console.log(`OAuth requested with URL: ${payload.url}`) + }} + onStepChange={(payload) => { + console.log(`Moving from ${payload.previous} to ${payload.current}`) + }} + onSelectedInstitution={(payload) => { + console.log(`Selecting ${payload.name}`) + }} + /> + )} ) } diff --git a/example/src/shared/api.ts b/example/src/shared/api.ts new file mode 100644 index 0000000..2b58bf7 --- /dev/null +++ b/example/src/shared/api.ts @@ -0,0 +1,58 @@ +import { Platform } from "react-native" + +const baseUrl = Platform.OS === "android" ? "http://10.0.2.2:8089" : "http://localhost:8089" +const proxyUrl = `${baseUrl}/user/widget_urls` + +interface FetchWidgetUrlProps { + clientRedirectUrl: string + widgetType: string +} + +export function buildWidgetConfiguration({ clientRedirectUrl, widgetType }: FetchWidgetUrlProps) { + return { + ...(widgetType === "connect_widget" + ? { data_request: { products: ["identity_verification"] } } + : {}), + client_redirect_url: clientRedirectUrl, + is_mobile_webview: true, + ui_message_version: 4, + widget_type: widgetType, + } +} + +interface WidgetUrlResponse { + widget_url: { + url: string + } +} + +export const fetchWidgetUrl = async (props: FetchWidgetUrlProps) => { + const headers: Record = { + "Accept-Version": "v20250224", + "Content-Type": "application/json", + } + + const method = "POST" + const body = JSON.stringify({ + widget_url: buildWidgetConfiguration(props), + }) + + try { + const response = await fetch(proxyUrl, { + body, + headers, + method, + }) + + if (!response.ok) { + throw new Error(`Failed to fetch widget URL: ${response.status} ${response.statusText}`) + } + + const data: WidgetUrlResponse = await response.json() + + return data.widget_url.url + } catch (error) { + console.error("Error fetching widget URL:", error) + throw error + } +} From acf7f87fa479f95709f69cc9efcc331c49dbba55 Mon Sep 17 00:00:00 2001 From: Wes Risenmay Date: Tue, 3 Feb 2026 14:20:53 -0700 Subject: [PATCH 3/7] updated the changelog and improved the abstraction for fetching widget urls --- CHANGELOG.md | 1 + example/src/app/connect.tsx | 4 ++-- example/src/shared/api.ts | 42 ++++++++++++++++++++----------------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da57861..9af8ca7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Custom onLoadUrlInBrowser and onLoadUrlInBrowserError props - uiMessageWebviewUrlScheme is no longer supported. The default scheme of the mx widgets will be used which is "mx". clientRedirectUrl has been the recommended method for redirecting from oauth for [years](https://docs.mx.com/release-notes/2022/#february) +- The proxy property has been removed from all widgets. Before a widget is rendered a widget url should be fetched and then provided to the widget. ### Changed diff --git a/example/src/app/connect.tsx b/example/src/app/connect.tsx index 7ae04fc..1dae6ac 100644 --- a/example/src/app/connect.tsx +++ b/example/src/app/connect.tsx @@ -4,7 +4,7 @@ import { SafeAreaView } from "react-native-safe-area-context" import * as Linking from "expo-linking" import { ConnectWidget } from "@mxenabled/react-native-widget-sdk" -import { fetchWidgetUrl } from "../shared/api" +import { fetchConnectWidgetUrl } from "../shared/api" const styles = StyleSheet.create({ page: { @@ -19,7 +19,7 @@ export default function Connect() { const [url, setUrl] = useState(null) useEffect(() => { - fetchWidgetUrl({ clientRedirectUrl, widgetType: "connect_widget" }).then((url) => { + fetchConnectWidgetUrl(clientRedirectUrl).then((url) => { setUrl(url) }) }, [clientRedirectUrl]) diff --git a/example/src/shared/api.ts b/example/src/shared/api.ts index 2b58bf7..cb8e1d1 100644 --- a/example/src/shared/api.ts +++ b/example/src/shared/api.ts @@ -3,30 +3,13 @@ import { Platform } from "react-native" const baseUrl = Platform.OS === "android" ? "http://10.0.2.2:8089" : "http://localhost:8089" const proxyUrl = `${baseUrl}/user/widget_urls` -interface FetchWidgetUrlProps { - clientRedirectUrl: string - widgetType: string -} - -export function buildWidgetConfiguration({ clientRedirectUrl, widgetType }: FetchWidgetUrlProps) { - return { - ...(widgetType === "connect_widget" - ? { data_request: { products: ["identity_verification"] } } - : {}), - client_redirect_url: clientRedirectUrl, - is_mobile_webview: true, - ui_message_version: 4, - widget_type: widgetType, - } -} - interface WidgetUrlResponse { widget_url: { url: string } } -export const fetchWidgetUrl = async (props: FetchWidgetUrlProps) => { +const fetchWidgetUrl = async (widgetConfiguration: object) => { const headers: Record = { "Accept-Version": "v20250224", "Content-Type": "application/json", @@ -34,7 +17,7 @@ export const fetchWidgetUrl = async (props: FetchWidgetUrlProps) => { const method = "POST" const body = JSON.stringify({ - widget_url: buildWidgetConfiguration(props), + widget_url: widgetConfiguration, }) try { @@ -56,3 +39,24 @@ export const fetchWidgetUrl = async (props: FetchWidgetUrlProps) => { throw error } } + +const createWidgetConfiguration = (overrides: Record) => { + const baseWidgetConfiguration = { + is_mobile_webview: true, + ui_message_version: 4, + } + + return { + ...baseWidgetConfiguration, + ...overrides, + } +} + +export const fetchConnectWidgetUrl = async (clientRedirectUrl: string) => { + const widgetConfiguration = createWidgetConfiguration({ + client_redirect_url: clientRedirectUrl, + widget_type: "connect_widget", + }) + + return fetchWidgetUrl(widgetConfiguration) +} From 0260179c130dc44f76eb3add8de697f7e5542ff0 Mon Sep 17 00:00:00 2001 From: Wes Risenmay Date: Wed, 4 Feb 2026 06:42:39 -0700 Subject: [PATCH 4/7] remove request abstraction --- example/src/shared/api.ts | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/example/src/shared/api.ts b/example/src/shared/api.ts index cb8e1d1..0e22201 100644 --- a/example/src/shared/api.ts +++ b/example/src/shared/api.ts @@ -9,7 +9,7 @@ interface WidgetUrlResponse { } } -const fetchWidgetUrl = async (widgetConfiguration: object) => { +export const fetchConnectWidgetUrl = async (clientRedirectUrl: string) => { const headers: Record = { "Accept-Version": "v20250224", "Content-Type": "application/json", @@ -17,7 +17,13 @@ const fetchWidgetUrl = async (widgetConfiguration: object) => { const method = "POST" const body = JSON.stringify({ - widget_url: widgetConfiguration, + widget_url: { + client_redirect_url: clientRedirectUrl, + is_mobile_webview: true, + ui_message_version: 4, + widget_type: "connect_widget", + data_request: { products: ["identity_verification"] }, + }, }) try { @@ -39,24 +45,3 @@ const fetchWidgetUrl = async (widgetConfiguration: object) => { throw error } } - -const createWidgetConfiguration = (overrides: Record) => { - const baseWidgetConfiguration = { - is_mobile_webview: true, - ui_message_version: 4, - } - - return { - ...baseWidgetConfiguration, - ...overrides, - } -} - -export const fetchConnectWidgetUrl = async (clientRedirectUrl: string) => { - const widgetConfiguration = createWidgetConfiguration({ - client_redirect_url: clientRedirectUrl, - widget_type: "connect_widget", - }) - - return fetchWidgetUrl(widgetConfiguration) -} From 7da9e8dad2477abdec52dde9eec170281e900361 Mon Sep 17 00:00:00 2001 From: Wes Risenmay Date: Wed, 4 Feb 2026 09:34:15 -0700 Subject: [PATCH 5/7] removing unnecessary functionality --- example/src/app/connect.tsx | 3 + src/components/ConnectWidgets.test.tsx | 93 --------------------- src/components/ConnectWidgets.tsx | 8 +- src/components/oauth.ts | 111 ------------------------- src/components/renderer.tsx | 22 ++--- 5 files changed, 10 insertions(+), 227 deletions(-) delete mode 100644 src/components/ConnectWidgets.test.tsx delete mode 100644 src/components/oauth.ts diff --git a/example/src/app/connect.tsx b/example/src/app/connect.tsx index 1dae6ac..39744ab 100644 --- a/example/src/app/connect.tsx +++ b/example/src/app/connect.tsx @@ -47,6 +47,9 @@ export default function Connect() { onMemberConnected={(payload) => { console.log(`Member connected with payload: ${JSON.stringify(payload)}`) }} + onOAuthError={(payload) => { + console.log(`OAuth error with payload: ${JSON.stringify(payload)}`) + }} onOAuthRequested={(payload) => { console.log(`OAuth requested with URL: ${payload.url}`) }} diff --git a/src/components/ConnectWidgets.test.tsx b/src/components/ConnectWidgets.test.tsx deleted file mode 100644 index 49f09e3..0000000 --- a/src/components/ConnectWidgets.test.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { render, waitFor } from "@testing-library/react-native" -import { ConnectWidget } from "./ConnectWidgets" -import { fullWidgetComponentTestSuite } from "./widgets.test" -import { triggerUrlChange } from "../../test/mocks/react_native" - -jest.mock("expo-web-browser", () => { - return { - openAuthSessionAsync: jest.fn().mockResolvedValue({ type: "success" }), - } -}) - -describe("ConnectWidget", () => { - fullWidgetComponentTestSuite(ConnectWidget) - - describe("OAuth", () => { - const testCases: { - label: string - url: string - check: (msg: string) => void - }[] = [ - { - label: - "an OAuth deeplink triggers a post message to the web view (public URL with matching host)", - url: "appscheme://oauth_complete?member_guid=MBR-123&status=success", - check: (msg) => expect(msg).toContain("MBR-123"), - }, - { - label: - "an OAuth deeplink triggers a post message to the web view (local URL with matching path)", - url: "exp://127.0.0.1:19000/--/oauth_complete?member_guid=MBR-123&status=success", - check: (msg) => expect(msg).toContain("MBR-123"), - }, - { - label: - "an OAuth deeplink triggers a post message to the web view (public URL with matching path)", - url: "exp://exp.host/@community/with-webbrowser-redirect/--/oauth_complete?member_guid=MBR-123&status=success", - check: (msg) => expect(msg).toContain("MBR-123"), - }, - { - label: - "an OAuth success deeplink includes the right status (public URL with matching host)", - url: "appscheme://oauth_complete?member_guid=MBR-123&status=success", - check: (msg) => expect(msg).toContain("oauthComplete/success"), - }, - { - label: "an OAuth success deeplink includes the right status (local URL with matching path)", - url: "exp://127.0.0.1:19000/--/oauth_complete?member_guid=MBR-123&status=success", - check: (msg) => expect(msg).toContain("oauthComplete/success"), - }, - { - label: - "an OAuth success deeplink includes the right status (public URL with matching path)", - url: "exp://exp.host/@community/with-webbrowser-redirect/--/oauth_complete?member_guid=MBR-123&status=success", - check: (msg) => expect(msg).toContain("oauthComplete/success"), - }, - { - label: - "an OAuth failure deeplink includes the right status (public URL with matching host)", - url: "appscheme://oauth_complete?member_guid=MBR-123&status=error", - check: (msg) => expect(msg).toContain("oauthComplete/error"), - }, - { - label: "an OAuth failure deeplink includes the right status (local URL with matching path)", - url: "exp://127.0.0.1:19000/--/oauth_complete?member_guid=MBR-123&status=error", - check: (msg) => expect(msg).toContain("oauthComplete/error"), - }, - { - label: - "an OAuth failure deeplink includes the right status (public URL with matching path)", - url: "exp://exp.host/@community/with-webbrowser-redirect/--/oauth_complete?member_guid=MBR-123&status=error", - check: (msg) => expect(msg).toContain("oauthComplete/error"), - }, - ] - - testCases.forEach((testCase) => { - test(testCase.label, async () => { - expect.assertions(1) - - const component = render( - { - testCase.check(msg) - }} - />, - ) - - await waitFor(() => component.findByTestId("widget_webview")) - triggerUrlChange(testCase.url) - }) - }) - }) -}) diff --git a/src/components/ConnectWidgets.tsx b/src/components/ConnectWidgets.tsx index 3b05339..0c27b5e 100644 --- a/src/components/ConnectWidgets.tsx +++ b/src/components/ConnectWidgets.tsx @@ -7,12 +7,10 @@ import { import { Type, SsoUrlProps, ConnectWidgetConfigurationProps } from "../sso" import * as WebBrowser from "expo-web-browser" import { makeWidgetComponentWithDefaults } from "./make_component" -import { useOAuthDeeplink, OAuthProps } from "./oauth" -import { useWidgetRendererWithRef, StylingProps } from "./renderer" +import { StylingProps, useWidgetRenderer } from "./renderer" export type ConnectWidgetProps = SsoUrlProps & StylingProps & - OAuthProps & ConnectPostMessageCallbackProps & ConnectWidgetConfigurationProps & JSX.IntrinsicAttributes @@ -40,12 +38,10 @@ export function ConnectWidget(props: ConnectWidgetProps) { onOAuthRequested, } - const [ref, elem] = useWidgetRendererWithRef( + const elem = useWidgetRenderer( { ...modifiedProps, widgetType: Type.ConnectWidget }, dispatchConnectLocationChangeEvent, ) - useOAuthDeeplink(ref, modifiedProps) - return elem } diff --git a/src/components/oauth.ts b/src/components/oauth.ts deleted file mode 100644 index 2b3abf7..0000000 --- a/src/components/oauth.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { useEffect, useState } from "react" -import { parse as parseUrl, UrlWithParsedQuery } from "url" -import { WebViewRef } from "./webview" -import { onUrlChange } from "../platform/deeplink" - -/* Used when handling and parsing an OAuth deeplink. This is what the OAuth - * flow uses to communicate state and status back to the app. - */ -const OAuthCompleteHost = "oauth_complete" -const OAuthStatusSuccess = "success" - -/* Used when sending a postMessage to the widget. This is what the app uses to - * communicate the result of an OAuth request after it is redirected back to - * the app. - */ -const OAuthTypeSuccess = "oauthComplete/success" -const OAuthTypeError = "oauthComplete/error" - -type OAuthSuccessRedirectEvent = { - type: "success" - success: boolean - memberGuid: string -} - -type OAuthErrorRedirectEvent = { - type: "error" - success: boolean -} - -export type OAuthRedirectEvent = OAuthSuccessRedirectEvent | OAuthErrorRedirectEvent - -export type OAuthProps = { - sendOAuthPostMessage?: (webViewRef: WebViewRef, msg: string) => void -} - -export function useOAuthDeeplink( - webViewRef: WebViewRef, - props: OAuthProps, -): OAuthRedirectEvent | null { - const [ev, setEvent] = useState(null) - - useEffect(() => { - return onUrlChange(({ url: rawUrl }) => { - const url = parseUrl(rawUrl, true) - - /** - * When the ui_message_webview_url_scheme setting is used, our backend - * will generate a URL which looks like this: - * - * ://? - * - * For URLs like these, we need to check the host. - * - * However, when a client is using Expo in dev/qa mode and doesn't have - * access to their app's scheme, they rely on the client_redirect_url - * setting which must use the host to specify Expo's application - * location. In this case, the redirect URL has to have the specified - * event as part of the path: - * - * exp:///--/? - * - * For URLs like these, we need to check the path. - */ - const isOAuthEventUrl = - url.host === OAuthCompleteHost || url.pathname?.includes(OAuthCompleteHost) - if (!isOAuthEventUrl) { - return - } - - const event = buildOAuthRedirectEvent(url) - setEvent(event) - postOAuthMessage(event, webViewRef, props) - }) - }, []) - - return ev -} - -function buildOAuthRedirectEvent(url: UrlWithParsedQuery): OAuthRedirectEvent { - const success = url.query["status"] === OAuthStatusSuccess - const memberGuid = url.query["amp;member_guid"] || url.query["member_guid"] - if (success && typeof memberGuid === "string") { - return { type: "success", success, memberGuid } - } - - return { type: "error", success: false } -} - -function postOAuthMessage(ev: OAuthRedirectEvent, webViewRef: WebViewRef, props: OAuthProps) { - if (!webViewRef.current) { - return - } - - let type: string - let metadata: Record - if (ev.type === "success") { - type = OAuthTypeSuccess - metadata = { member_guid: ev.memberGuid } - } else { - type = OAuthTypeError - metadata = {} - } - - const message = JSON.stringify({ mx: true, type, metadata }) - - if (props.sendOAuthPostMessage) { - props.sendOAuthPostMessage(webViewRef, message) - } else { - webViewRef.current.postMessage(message) - } -} diff --git a/src/components/renderer.tsx b/src/components/renderer.tsx index f2016b5..cac668d 100644 --- a/src/components/renderer.tsx +++ b/src/components/renderer.tsx @@ -1,4 +1,4 @@ -import React, { useRef, MutableRefObject, ReactElement } from "react" +import React, { ReactElement } from "react" import { StyleProp, ViewStyle, View } from "react-native" import { WebView } from "react-native-webview" import { Payload } from "@mxenabled/widget-post-message-definitions" @@ -13,28 +13,18 @@ export type StylingProps = { webViewStyle?: StyleProp } -type MaybeWebViewRef = MutableRefObject type BaseProps = Props & StylingProps export function useWidgetRenderer( props: BaseProps, dispatchEvent: (url: string, callbacks: BaseProps) => Payload | undefined, ): ReactElement { - const [_ref, elem] = useWidgetRendererWithRef(props, dispatchEvent) - return elem -} - -export function useWidgetRendererWithRef( - props: BaseProps, - dispatchEvent: (url: string, callbacks: BaseProps) => Payload | undefined, -): [MaybeWebViewRef, ReactElement] { - const ref = useRef(null) const url = useSsoUrl(props) const fullscreenStyles = useFullscreenStyles() const style = props.style || fullscreenStyles if (!url) { - return [ref, ] + return } const handler = makeRequestInterceptor(url, { @@ -47,13 +37,11 @@ export function useWidgetRendererWithRef( window.MXReactNativeSDKVersion = "${sdkVersion}"; ` - return [ - ref, + return ( ( onShouldStartLoadWithRequest={handler} onError={props.onWebViewError} /> - , - ] + + ) } From 4e121faaa797b49b53054fc8e760d5eb40f6d6b7 Mon Sep 17 00:00:00 2001 From: Wes Risenmay Date: Wed, 4 Feb 2026 09:42:13 -0700 Subject: [PATCH 6/7] audit fix --- example/package-lock.json | 6 +++--- package-lock.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/example/package-lock.json b/example/package-lock.json index 2bc3ae3..1e2e9ca 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -2330,9 +2330,9 @@ } }, "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", + "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", "license": "MIT", "dependencies": { "@isaacs/balanced-match": "^4.0.1" diff --git a/package-lock.json b/package-lock.json index 1a237fa..2389fc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3765,9 +3765,9 @@ } }, "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", + "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", "license": "MIT", "dependencies": { "@isaacs/balanced-match": "^4.0.1" From d391ae208d06ca541f92d0b9a3b80319f4d5dc89 Mon Sep 17 00:00:00 2001 From: Wes Risenmay Date: Wed, 4 Feb 2026 09:54:01 -0700 Subject: [PATCH 7/7] fix changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9af8ca7..0e8ef51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Custom onLoadUrlInBrowser and onLoadUrlInBrowserError props - uiMessageWebviewUrlScheme is no longer supported. The default scheme of the mx widgets will be used which is "mx". clientRedirectUrl has been the recommended method for redirecting from oauth for [years](https://docs.mx.com/release-notes/2022/#february) -- The proxy property has been removed from all widgets. Before a widget is rendered a widget url should be fetched and then provided to the widget. +- The proxy property has been removed from the connect widget. Before a connect widget is rendered a widget url should be fetched and then provided to the widget. ### Changed