From d082d3708c94065e5385da70de427bdc2ee43a46 Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Tue, 28 Nov 2023 10:56:32 -0800 Subject: [PATCH 1/3] Fix: Remove check for isReadyForRequest, add isConnectedToInternet --- .../@magic-sdk/provider/src/core/view-controller.ts | 13 ++++--------- .../test/spec/core/view-controller/post.spec.ts | 13 ++++--------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/packages/@magic-sdk/provider/src/core/view-controller.ts b/packages/@magic-sdk/provider/src/core/view-controller.ts index 6e575c577..a5417bbfc 100644 --- a/packages/@magic-sdk/provider/src/core/view-controller.ts +++ b/packages/@magic-sdk/provider/src/core/view-controller.ts @@ -89,9 +89,9 @@ async function persistMagicEventRefreshToken(event: MagicMessageEvent) { } export abstract class ViewController { - private isReadyForRequest = false; public checkIsReadyForRequest: Promise; protected readonly messageHandlers = new Set<(event: MagicMessageEvent) => any>(); + protected isConnectedToInternet = true; /** * Create an instance of `ViewController` @@ -132,17 +132,13 @@ export abstract class ViewController { payload: JsonRpcRequestPayload | JsonRpcRequestPayload[], ): Promise | JsonRpcResponse[]> { return createPromise(async (resolve, reject) => { - if (SDKEnvironment.platform !== 'react-native') { - await this.checkIsReadyForRequest; - } else if (!this.isReadyForRequest) { - // On a mobile environment, `this.checkIsReadyForRequest` never resolves - // if the app was initially opened without internet connection. That is - // why we reject the promise without waiting and just let them call it - // again when internet connection is re-established. + if (!this.isConnectedToInternet) { const error = createModalNotReadyError(); reject(error); } + await this.checkIsReadyForRequest; + const batchData: JsonRpcResponse[] = []; const batchIds = Array.isArray(payload) ? payload.map((p) => p.id) : []; const msg = await createMagicRequest(`${msgType}-${this.parameters}`, payload); @@ -207,7 +203,6 @@ export abstract class ViewController { return new Promise((resolve) => { this.on(MagicIncomingWindowMessage.MAGIC_OVERLAY_READY, () => { resolve(); - this.isReadyForRequest = true; }); }); } diff --git a/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts b/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts index f03975cb6..9b92a3fc3 100644 --- a/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts +++ b/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts @@ -201,14 +201,15 @@ test('Sends payload and stores rt if response event contains rt', async () => { expect(FAKE_STORE.rt).toEqual(FAKE_RT); }); -test('does not wait for ready and throws error when platform is react-native', async () => { - SDKEnvironment.platform = 'react-native'; +test('throws MODAL_NOT_READY error when not connected to the internet', async () => { const eventWithRt = { data: { ...responseEvent().data } }; const viewController = createViewController('asdf'); const { handlerSpy, onSpy } = stubViewController(viewController, [ [MagicIncomingWindowMessage.MAGIC_HANDLE_RESPONSE, eventWithRt], ]); - viewController.checkIsReadyForRequest = new Promise(() => null); + + // @ts-ignore protected variable + viewController.isConnectedToInternet = false; const payload = requestPayload(); @@ -217,9 +218,6 @@ test('does not wait for ready and throws error when platform is react-native', a } catch (e) { expect(e).toEqual(createModalNotReadyError()); } - expect(createJwtStub).not.toHaveBeenCalledWith(); - expect(onSpy.mock.calls[0][0]).toEqual(MagicIncomingWindowMessage.MAGIC_HANDLE_RESPONSE); - expect(handlerSpy).not.toHaveBeenCalled(); }); test('does not call web crypto api if platform is not web', async () => { @@ -231,9 +229,6 @@ test('does not call web crypto api if platform is not web', async () => { ]); const payload = requestPayload(); - // @ts-ignore isReadyForRequest is private - viewController.isReadyForRequest = true; - const response = await viewController.post(MagicOutgoingWindowMessage.MAGIC_HANDLE_REQUEST, payload); expect(createJwtStub).not.toHaveBeenCalledWith(); From 5610a66ffb302b5b63478a4cc0558cc9d059d7b2 Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Tue, 28 Nov 2023 10:57:11 -0800 Subject: [PATCH 2/3] Set isConnectedToInternet with value coming from @react-native-community/netinfo --- .../src/react-native-webview-controller.tsx | 8 +++++++- .../src/react-native-webview-controller.tsx | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/@magic-sdk/react-native-bare/src/react-native-webview-controller.tsx b/packages/@magic-sdk/react-native-bare/src/react-native-webview-controller.tsx index 6ecaeef67..91f619fee 100644 --- a/packages/@magic-sdk/react-native-bare/src/react-native-webview-controller.tsx +++ b/packages/@magic-sdk/react-native-bare/src/react-native-webview-controller.tsx @@ -1,4 +1,4 @@ -import React, { useState, useCallback, useMemo } from 'react'; +import React, { useState, useCallback, useMemo, useEffect } from 'react'; import { Linking, StyleSheet, View } from 'react-native'; import { WebView } from 'react-native-webview'; import { SafeAreaView } from 'react-native-safe-area-context'; @@ -6,6 +6,7 @@ import { ViewController, createModalNotReadyError } from '@magic-sdk/provider'; import { MagicMessageEvent } from '@magic-sdk/types'; import { isTypedArray } from 'lodash'; import Global = NodeJS.Global; +import { useInternetConnection } from './hooks'; const MAGIC_PAYLOAD_FLAG_TYPED_ARRAY = 'MAGIC_PAYLOAD_FLAG_TYPED_ARRAY'; const OPEN_IN_DEVICE_BROWSER = 'open_in_device_browser'; @@ -79,6 +80,11 @@ export class ReactNativeWebViewController extends ViewController { /* istanbul ignore next */ public Relayer: React.FC<{ backgroundColor?: string }> = (backgroundColor) => { const [show, setShow] = useState(false); + const isConnected = useInternetConnection(); + + useEffect(() => { + this.isConnectedToInternet = isConnected; + }, [isConnected]); /** * Saves a reference to the underlying `` node so we can interact diff --git a/packages/@magic-sdk/react-native-expo/src/react-native-webview-controller.tsx b/packages/@magic-sdk/react-native-expo/src/react-native-webview-controller.tsx index 2c1f523ba..0c1dc7a53 100644 --- a/packages/@magic-sdk/react-native-expo/src/react-native-webview-controller.tsx +++ b/packages/@magic-sdk/react-native-expo/src/react-native-webview-controller.tsx @@ -1,4 +1,4 @@ -import React, { useState, useCallback, useMemo } from 'react'; +import React, { useState, useCallback, useMemo, useEffect } from 'react'; import { Linking, StyleSheet, View } from 'react-native'; import { WebView } from 'react-native-webview'; import { SafeAreaView } from 'react-native-safe-area-context'; @@ -6,6 +6,7 @@ import { ViewController, createModalNotReadyError } from '@magic-sdk/provider'; import { MagicMessageEvent } from '@magic-sdk/types'; import { isTypedArray } from 'lodash'; import Global = NodeJS.Global; +import { useInternetConnection } from './hooks'; const MAGIC_PAYLOAD_FLAG_TYPED_ARRAY = 'MAGIC_PAYLOAD_FLAG_TYPED_ARRAY'; const OPEN_IN_DEVICE_BROWSER = 'open_in_device_browser'; @@ -79,6 +80,11 @@ export class ReactNativeWebViewController extends ViewController { /* istanbul ignore next */ public Relayer: React.FC<{ backgroundColor?: string }> = ({ backgroundColor }) => { const [show, setShow] = useState(false); + const isConnected = useInternetConnection(); + + useEffect(() => { + this.isConnectedToInternet = isConnected; + }, [isConnected]); /** * Saves a reference to the underlying `` node so we can interact From 253ff7045ec3aa4798c240ca7d7942a82e3658f0 Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Tue, 28 Nov 2023 10:58:04 -0800 Subject: [PATCH 3/3] Bump patch versions --- packages/@magic-sdk/react-native-bare/package.json | 2 +- packages/@magic-sdk/react-native-expo/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@magic-sdk/react-native-bare/package.json b/packages/@magic-sdk/react-native-bare/package.json index 1c093da6f..af05f1be6 100644 --- a/packages/@magic-sdk/react-native-bare/package.json +++ b/packages/@magic-sdk/react-native-bare/package.json @@ -1,6 +1,6 @@ { "name": "@magic-sdk/react-native-bare", - "version": "22.3.0", + "version": "22.3.1", "description": "Passwordless authentication for React Native (Bare).", "author": "Magic Labs (https://magic.link/)", "license": "MIT", diff --git a/packages/@magic-sdk/react-native-expo/package.json b/packages/@magic-sdk/react-native-expo/package.json index b8d760db8..1f3e1b272 100644 --- a/packages/@magic-sdk/react-native-expo/package.json +++ b/packages/@magic-sdk/react-native-expo/package.json @@ -1,6 +1,6 @@ { "name": "@magic-sdk/react-native-expo", - "version": "22.3.0", + "version": "22.3.1", "description": "Passwordless authentication for React Native (Expo).", "author": "Magic Labs (https://magic.link/)", "license": "MIT",