diff --git a/app/_layout.tsx b/app/_layout.tsx index cd64108..2021613 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -13,7 +13,7 @@ import * as React from "react"; import { SafeAreaView } from "react-native"; import { NAV_THEME } from "~/lib/constants"; import { useColorScheme } from "~/lib/useColorScheme"; -import PolyfillCrypto from "~/polyfill-crypto"; +import PolyfillCrypto from "react-native-webview-crypto"; import { SWRConfig } from "swr"; import { swrConfiguration } from "lib/swr"; import Toast from "react-native-toast-message"; diff --git a/package.json b/package.json index 0d53372..b56fe95 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "react-native-toast-message": "^2.2.0", "react-native-url-polyfill": "^2.0.0", "react-native-webview": "13.8.6", - "webview-crypto": "^0.1.13", + "react-native-webview-crypto": "^0.0.26", "swr": "^2.2.5", "tailwind-merge": "^2.3.0", "text-encoding": "^0.7.0", @@ -66,4 +66,4 @@ "typescript": "~5.3.3" }, "private": true -} \ No newline at end of file +} diff --git a/polyfill-crypto/index.js b/polyfill-crypto/index.js deleted file mode 100644 index d2e3a43..0000000 --- a/polyfill-crypto/index.js +++ /dev/null @@ -1,202 +0,0 @@ -// This code modifies `react-native-webview-crypto` package to handle -// `onContentProcessDidTerminate` by remounting the `WebView` and re-initializing -// the worker. - -// TODO: replace this with webview-crypto/react-native-webview-crypto package once -// https://github.com/webview-crypto/react-native-webview-crypto/pull/30 is merged - -const React = require("react"); -const { StyleSheet, View } = require("react-native"); -const { WebView } = require("react-native-webview"); -const { MainWorker, webViewWorkerString } = require("webview-crypto"); - -const styles = StyleSheet.create({ - hide: { - display: "none", - position: "absolute", - - width: 0, - height: 0, - - flexGrow: 0, - flexShrink: 1 - } -}); - -const internalLibrary = ` -(function () { - function postMessage (message) { - if (window.ReactNativeWebView.postMessage === undefined) { - setTimeout(postMessage, 200, message) - } else { - window.ReactNativeWebView.postMessage(message) - } - } - var wvw = new WebViewWorker(postMessage) - // for android - window.document.addEventListener('message', function (e) {wvw.onMainMessage(e.data);}) - // for ios - window.addEventListener('message', function (e) {wvw.onMainMessage(e.data);}) -}()) -`; - -let resolveWorker; -let workerPromise = new Promise(resolve => { - resolveWorker = resolve; -}); - -function sendToWorker(message) { - workerPromise.then(worker => worker.onWebViewMessage(message)); -} - -const subtle = { - fake: true, - decrypt(...args) { - return workerPromise.then(worker => worker.crypto.subtle.decrypt(...args)); - }, - deriveBits(...args) { - return workerPromise.then(worker => - worker.crypto.subtle.deriveBits(...args) - ); - }, - deriveKey(...args) { - return workerPromise.then(worker => - worker.crypto.subtle.deriveKey(...args) - ); - }, - digest(...args) { - return workerPromise.then(worker => worker.crypto.subtle.digest(...args)); - }, - encrypt(...args) { - return workerPromise.then(worker => worker.crypto.subtle.encrypt(...args)); - }, - exportKey(...args) { - return workerPromise.then(worker => - worker.crypto.subtle.exportKey(...args) - ); - }, - generateKey(...args) { - return workerPromise.then(worker => - worker.crypto.subtle.generateKey(...args) - ); - }, - importKey(...args) { - return workerPromise.then(worker => - worker.crypto.subtle.importKey(...args) - ); - }, - sign(...args) { - return workerPromise.then(worker => worker.crypto.subtle.sign(...args)); - }, - unwrapKey(...args) { - return workerPromise.then(worker => - worker.crypto.subtle.unwrapKey(...args) - ); - }, - verify(...args) { - return workerPromise.then(worker => worker.crypto.subtle.verify(...args)); - }, - wrapKey(...args) { - return workerPromise.then(worker => worker.crypto.subtle.wrapKey(...args)); - } -}; - -class PolyfillCrypto extends React.Component { - constructor(props) { - super(props); - this.props = props; - this.webViewRef = React.createRef(); - this.state = { - webViewKey: 0, - }; - } - - shouldComponentUpdate(nextProps, nextState) { - return nextState.webViewKey !== this.state.webViewKey; - } - - // reset promise so it can be resolved on next re-mount - componentWillUnmount() { - resolveWorker = undefined; - workerPromise = new Promise((resolve) => { - resolveWorker = resolve; - }); - } - - componentDidMount() { - const webView = this.webViewRef.current; - - resolveWorker( - new MainWorker(msg => { - webView.postMessage(msg); - }, this.props.debug) - ); - } - - componentDidUpdate(prevProps, prevState) { - if (prevState.webViewKey !== this.state.webViewKey) { - const webView = this.webViewRef.current; - resolveWorker( - new MainWorker( - (msg) => { - webView.postMessage(msg); - }, - this.props.debug - ) - ); - } - } - - onContentProcessDidTerminate = (event) => { - const { nativeEvent } = event; - console.warn("Content process terminated, reloading", nativeEvent); - resolveWorker = undefined; - workerPromise = new Promise((resolve) => { - resolveWorker = resolve; - }); - this.setState((prevState) => ({ webViewKey: prevState.webViewKey + 1 })); - }; - - render() { - const code = `((function () {${webViewWorkerString};${internalLibrary}})())`; - const html = `
` - // The uri 'about:blank' doesn't have access to crypto.subtle on android -// const uri = "file:///android_asset/blank.html"; - - // Base64 dance is to work around https://github.com/facebook/react-native/issues/20365 -// const source = Platform.select({ -// android: { source: { uri } }, -// ios: undefined -// }); - return ( -