@quiltt/react-native 3.3.2 → 3.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/components/QuilttConnector.tsx +28 -6
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var b=Object.defineProperty;var
|
|
1
|
+
"use strict";var b=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var $=Object.prototype.hasOwnProperty;var K=(a,o)=>{for(var c in o)b(a,c,{get:o[c],enumerable:!0})},j=(a,o,c,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of T(o))!$.call(a,s)&&s!==c&&b(a,s,{get:()=>o[s],enumerable:!(r=Q(o,s))||r.enumerable});return a};var M=a=>j(b({},"__esModule",{value:!0}),a);var C=(a,o,c)=>new Promise((r,s)=>{var i=l=>{try{d(c.next(l))}catch(u){s(u)}},m=l=>{try{d(c.throw(l))}catch(u){s(u)}},d=l=>l.done?r(l.value):Promise.resolve(l.value).then(i,m);d((c=c.apply(a,o)).next())});var _={};K(_,{QuilttConnector:()=>g,default:()=>H});module.exports=M(_);var v=require("core-js/stable/atob"),x=require("core-js/stable/url");var n=require("@quiltt/core"),h=require("react"),k=require("react-native"),q=require("react-native-webview");var p=require("react-native"),R=require("react/jsx-runtime"),A=({children:a})=>(0,R.jsx)(p.SafeAreaView,{style:I.AndroidSafeArea,children:a}),I=p.StyleSheet.create({AndroidSafeArea:{flex:1,backgroundColor:"white",paddingTop:p.Platform.OS==="android"?p.StatusBar.currentHeight:0}});var L=require("@quiltt/react");var w=require("react/jsx-runtime"),J=({connectorId:a,connectionId:o,oauthRedirectUrl:c,onEvent:r,onLoad:s,onExit:i,onExitSuccess:m,onExitAbort:d,onExitError:l})=>{let u=(0,h.useRef)(null),{session:f}=(0,L.useQuilttSession)();c=encodeURIComponent(c);let O=`https://${a}.quiltt.app/?mode=webview&oauth_redirect_url=${c}&sdk=react-native`,P=(0,h.useCallback)(()=>{var e;let t=` const options = { source: 'quiltt', type: 'Options', token: '${f==null?void 0:f.token}', connectorId: '${a}', connectionId: '${o}', }; const compactedOptions = Object.keys(options).reduce((acc, key) => { if (options[key] !== 'undefined') { acc[key] = options[key]; } return acc; }, {}); window.postMessage(compactedOptions); `;(e=u.current)==null||e.injectJavaScript(t)},[o,a,f==null?void 0:f.token]),U=["quiltt.app","quiltt.dev","moneydesktop.com","cdn.plaid.com/link/v2/stable/link.html"],V=t=>U.some(e=>t.href.includes(e)),W=t=>{let e=new URL(t.url);return V(e)?!0:e.protocol==="quilttconnector:"?(D(e),!1):(y(e),!1)},S=()=>{var e;let t="localStorage.clear();";(e=u.current)==null||e.injectJavaScript(t)},D=t=>{t.searchParams.delete("source"),t.searchParams.append("connectorId",a);let e=Object.fromEntries(t.searchParams);switch(t.host){case"Load":P(),r==null||r(n.ConnectorSDKEventType.Load,e),s==null||s(e);break;case"ExitAbort":S(),r==null||r(n.ConnectorSDKEventType.ExitAbort,e),i==null||i(n.ConnectorSDKEventType.ExitAbort,e),d==null||d(e);break;case"ExitError":S(),r==null||r(n.ConnectorSDKEventType.ExitError,e),i==null||i(n.ConnectorSDKEventType.ExitError,e),l==null||l(e);break;case"ExitSuccess":S(),r==null||r(n.ConnectorSDKEventType.ExitSuccess,e),i==null||i(n.ConnectorSDKEventType.ExitSuccess,e),m==null||m(e);break;case"Authenticate":break;case"OauthRequested":y(new URL(t.searchParams.get("oauthUrl")));break;default:console.log("unhandled event",t);break}},y=t=>C(void 0,null,function*(){if(t.protocol!=="https:"){console.log(`handleOAuthUrl - Skipping non https url - ${t.href}`);return}(yield k.Linking.canOpenURL(t.href))&&k.Linking.openURL(t.href)});return(0,w.jsx)(A,{children:(0,w.jsx)(q.WebView,{ref:u,originWhitelist:["https://*","quilttconnector://*"],source:{uri:O},onShouldStartLoadWithRequest:W,javaScriptEnabled:!0,domStorageEnabled:!0,webviewDebuggingEnabled:!0})})},g=J;var H=g;0&&(module.exports={QuilttConnector});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/QuilttConnector.tsx","../src/components/AndroidSafeAreaView.tsx"],"sourcesContent":["// Hermes doesn't have atob\n// https://github.com/facebook/hermes/issues/1178\nimport 'core-js/stable/atob'\n// React Native's URL implementation is incomplete\n// https://github.com/facebook/react-native/issues/16434\nimport 'core-js/stable/url'\nimport QuilttConnector from './components/QuilttConnector'\n\nexport { QuilttConnector }\nexport default QuilttConnector\n","import {\n ConnectorSDKCallbackMetadata,\n ConnectorSDKCallbacks,\n ConnectorSDKEventType,\n} from '@quiltt/core'\nimport { useCallback, useRef } from 'react'\nimport { Linking } from 'react-native'\nimport { WebView } from 'react-native-webview'\nimport { AndroidSafeAreaView } from './AndroidSafeAreaView'\nimport type { ShouldStartLoadRequest } from 'react-native-webview/lib/WebViewTypes'\nimport { useQuilttSession } from '@quiltt/react'\n\ntype QuilttConnectorProps = {\n connectorId: string\n connectionId?: string\n oauthRedirectUrl: string\n} & ConnectorSDKCallbacks\n\nexport const QuilttConnector = ({\n connectorId,\n connectionId,\n oauthRedirectUrl,\n onEvent,\n onLoad,\n onExit,\n onExitSuccess,\n onExitAbort,\n onExitError,\n}: QuilttConnectorProps) => {\n const webViewRef = useRef<WebView>(null)\n const { session } = useQuilttSession()\n oauthRedirectUrl = encodeURIComponent(oauthRedirectUrl)\n const connectorUrl = `https://${connectorId}.quiltt.app/?mode=webview&oauth_redirect_url=${oauthRedirectUrl}&sdk=react-native` // @todo append version from package.json\n\n const initInjectedJavaScript = useCallback(() => {\n const script = `\\\n const options = {\\\n source: 'quiltt',\\\n type: 'Options',\\\n token: '${session?.token}',\\\n connectorId: '${connectorId}',\\\n connectionId: '${connectionId}',\\\n };\\\n const compactedOptions = Object.keys(options).reduce((acc, key) => {\\\n if (options[key] !== 'undefined') {\\\n acc[key] = options[key];\\\n }\\\n return acc;\\\n }, {});\\\n window.postMessage(compactedOptions);\\\n `\n webViewRef.current?.injectJavaScript(script)\n }, [connectionId, connectorId, session?.token])\n\n const
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/QuilttConnector.tsx","../src/components/AndroidSafeAreaView.tsx"],"sourcesContent":["// Hermes doesn't have atob\n// https://github.com/facebook/hermes/issues/1178\nimport 'core-js/stable/atob'\n// React Native's URL implementation is incomplete\n// https://github.com/facebook/react-native/issues/16434\nimport 'core-js/stable/url'\nimport QuilttConnector from './components/QuilttConnector'\n\nexport { QuilttConnector }\nexport default QuilttConnector\n","import {\n ConnectorSDKCallbackMetadata,\n ConnectorSDKCallbacks,\n ConnectorSDKEventType,\n} from '@quiltt/core'\nimport { useCallback, useRef } from 'react'\nimport { Linking } from 'react-native'\nimport { WebView } from 'react-native-webview'\nimport { AndroidSafeAreaView } from './AndroidSafeAreaView'\nimport type { ShouldStartLoadRequest } from 'react-native-webview/lib/WebViewTypes'\nimport { useQuilttSession } from '@quiltt/react'\n\ntype QuilttConnectorProps = {\n connectorId: string\n connectionId?: string\n oauthRedirectUrl: string\n} & ConnectorSDKCallbacks\n\nexport const QuilttConnector = ({\n connectorId,\n connectionId,\n oauthRedirectUrl,\n onEvent,\n onLoad,\n onExit,\n onExitSuccess,\n onExitAbort,\n onExitError,\n}: QuilttConnectorProps) => {\n const webViewRef = useRef<WebView>(null)\n const { session } = useQuilttSession()\n oauthRedirectUrl = encodeURIComponent(oauthRedirectUrl)\n const connectorUrl = `https://${connectorId}.quiltt.app/?mode=webview&oauth_redirect_url=${oauthRedirectUrl}&sdk=react-native` // @todo append version from package.json\n\n const initInjectedJavaScript = useCallback(() => {\n const script = `\\\n const options = {\\\n source: 'quiltt',\\\n type: 'Options',\\\n token: '${session?.token}',\\\n connectorId: '${connectorId}',\\\n connectionId: '${connectionId}',\\\n };\\\n const compactedOptions = Object.keys(options).reduce((acc, key) => {\\\n if (options[key] !== 'undefined') {\\\n acc[key] = options[key];\\\n }\\\n return acc;\\\n }, {});\\\n window.postMessage(compactedOptions);\\\n `\n webViewRef.current?.injectJavaScript(script)\n }, [connectionId, connectorId, session?.token])\n\n // allowedListUrl & shouldRender ensure we are only rendering Quiltt, MX and Plaid content in Webview\n // For other urls, we assume those are bank urls, which needs to be handle in external browser.\n // @todo Convert it to a list from Quiltt Server to prevent MX/ Plaid changes.\n const allowedListUrl = [\n 'quiltt.app',\n 'quiltt.dev',\n 'moneydesktop.com',\n 'cdn.plaid.com/link/v2/stable/link.html',\n ]\n const shouldRender = (url: URL) => allowedListUrl.some((href) => url.href.includes(href))\n\n const requestHandler = (request: ShouldStartLoadRequest) => {\n const url = new URL(request.url)\n if (shouldRender(url)) return true\n if (url.protocol === 'quilttconnector:') {\n handleQuilttEvent(url)\n return false\n }\n // Plaid set oauth url by doing window.location.href = url\n // This is the only way I know to handle this.\n handleOAuthUrl(url)\n return false\n }\n\n const clearLocalStorage = () => {\n const script = 'localStorage.clear();'\n webViewRef.current?.injectJavaScript(script)\n }\n\n const handleQuilttEvent = (url: URL) => {\n url.searchParams.delete('source')\n url.searchParams.append('connectorId', connectorId)\n const metadata = Object.fromEntries(url.searchParams) as ConnectorSDKCallbackMetadata\n\n const eventType = url.host\n switch (eventType) {\n case 'Load':\n initInjectedJavaScript()\n onEvent?.(ConnectorSDKEventType.Load, metadata)\n onLoad?.(metadata)\n break\n case 'ExitAbort':\n clearLocalStorage()\n onEvent?.(ConnectorSDKEventType.ExitAbort, metadata)\n onExit?.(ConnectorSDKEventType.ExitAbort, metadata)\n onExitAbort?.(metadata)\n break\n case 'ExitError':\n clearLocalStorage()\n onEvent?.(ConnectorSDKEventType.ExitError, metadata)\n onExit?.(ConnectorSDKEventType.ExitError, metadata)\n onExitError?.(metadata)\n break\n case 'ExitSuccess':\n clearLocalStorage()\n onEvent?.(ConnectorSDKEventType.ExitSuccess, metadata)\n onExit?.(ConnectorSDKEventType.ExitSuccess, metadata)\n onExitSuccess?.(metadata)\n break\n case 'Authenticate':\n // @todo handle Authenticate\n break\n case 'OauthRequested':\n handleOAuthUrl(new URL(url.searchParams.get('oauthUrl') as string))\n break\n default:\n console.log('unhandled event', url)\n break\n }\n }\n\n const handleOAuthUrl = async (oauthUrl: URL) => {\n if (oauthUrl.protocol !== 'https:') {\n console.log(`handleOAuthUrl - Skipping non https url - ${oauthUrl.href}`)\n return\n }\n if (await Linking.canOpenURL(oauthUrl.href)) {\n Linking.openURL(oauthUrl.href)\n }\n }\n\n return (\n <AndroidSafeAreaView>\n <WebView\n ref={webViewRef}\n originWhitelist={['https://*', 'quilttconnector://*']} // Maybe relax this to *?\n source={{ uri: connectorUrl }}\n onShouldStartLoadWithRequest={requestHandler}\n javaScriptEnabled\n domStorageEnabled // To enable localStorage in Android webview\n webviewDebuggingEnabled // Not sure if this works\n />\n </AndroidSafeAreaView>\n )\n}\n\nexport default QuilttConnector\n","import { SafeAreaView, StyleSheet, Platform, StatusBar } from 'react-native'\nimport { PropsWithChildren } from 'react'\n\nexport const AndroidSafeAreaView = ({ children }: PropsWithChildren) => (\n <SafeAreaView style={styles.AndroidSafeArea}>{children}</SafeAreaView>\n)\n\nconst styles = StyleSheet.create({\n AndroidSafeArea: {\n flex: 1,\n backgroundColor: 'white',\n paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0,\n },\n})\n"],"mappings":"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","names":["src_exports","__export","QuilttConnector_default","src_default","__toCommonJS","import_atob","import_url","import_core","import_react","import_react_native","import_react_native_webview","import_react_native","import_jsx_runtime","AndroidSafeAreaView","children","styles","import_react","import_jsx_runtime","QuilttConnector","connectorId","connectionId","oauthRedirectUrl","onEvent","onLoad","onExit","onExitSuccess","onExitAbort","onExitError","webViewRef","session","connectorUrl","initInjectedJavaScript","_a","script","allowedListUrl","shouldRender","url","href","requestHandler","request","handleQuilttEvent","handleOAuthUrl","clearLocalStorage","metadata","oauthUrl","__async","AndroidSafeAreaView","QuilttConnector_default","src_default","QuilttConnector_default"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"core-js/stable/atob";import"core-js/stable/url";import{ConnectorSDKEventType as
|
|
1
|
+
var S=(c,f,s)=>new Promise((r,n)=>{var a=o=>{try{i(s.next(o))}catch(l){n(l)}},u=o=>{try{i(s.throw(o))}catch(l){n(l)}},i=o=>o.done?r(o.value):Promise.resolve(o.value).then(a,u);i((s=s.apply(c,f)).next())});import"core-js/stable/atob";import"core-js/stable/url";import{ConnectorSDKEventType as p}from"@quiltt/core";import{useCallback as Q,useRef as T}from"react";import{Linking as k}from"react-native";import{WebView as $}from"react-native-webview";import{SafeAreaView as O,StyleSheet as P,Platform as U,StatusBar as V}from"react-native";import{jsx as D}from"react/jsx-runtime";var b=({children:c})=>D(O,{style:W.AndroidSafeArea,children:c}),W=P.create({AndroidSafeArea:{flex:1,backgroundColor:"white",paddingTop:U.OS==="android"?V.currentHeight:0}});import{useQuilttSession as K}from"@quiltt/react";import{jsx as w}from"react/jsx-runtime";var j=({connectorId:c,connectionId:f,oauthRedirectUrl:s,onEvent:r,onLoad:n,onExit:a,onExitSuccess:u,onExitAbort:i,onExitError:o})=>{let l=T(null),{session:d}=K();s=encodeURIComponent(s);let y=`https://${c}.quiltt.app/?mode=webview&oauth_redirect_url=${s}&sdk=react-native`,C=Q(()=>{var e;let t=` const options = { source: 'quiltt', type: 'Options', token: '${d==null?void 0:d.token}', connectorId: '${c}', connectionId: '${f}', }; const compactedOptions = Object.keys(options).reduce((acc, key) => { if (options[key] !== 'undefined') { acc[key] = options[key]; } return acc; }, {}); window.postMessage(compactedOptions); `;(e=l.current)==null||e.injectJavaScript(t)},[f,c,d==null?void 0:d.token]),A=["quiltt.app","quiltt.dev","moneydesktop.com","cdn.plaid.com/link/v2/stable/link.html"],R=t=>A.some(e=>t.href.includes(e)),q=t=>{let e=new URL(t.url);return R(e)?!0:e.protocol==="quilttconnector:"?(L(e),!1):(h(e),!1)},m=()=>{var e;let t="localStorage.clear();";(e=l.current)==null||e.injectJavaScript(t)},L=t=>{t.searchParams.delete("source"),t.searchParams.append("connectorId",c);let e=Object.fromEntries(t.searchParams);switch(t.host){case"Load":C(),r==null||r(p.Load,e),n==null||n(e);break;case"ExitAbort":m(),r==null||r(p.ExitAbort,e),a==null||a(p.ExitAbort,e),i==null||i(e);break;case"ExitError":m(),r==null||r(p.ExitError,e),a==null||a(p.ExitError,e),o==null||o(e);break;case"ExitSuccess":m(),r==null||r(p.ExitSuccess,e),a==null||a(p.ExitSuccess,e),u==null||u(e);break;case"Authenticate":break;case"OauthRequested":h(new URL(t.searchParams.get("oauthUrl")));break;default:console.log("unhandled event",t);break}},h=t=>S(void 0,null,function*(){if(t.protocol!=="https:"){console.log(`handleOAuthUrl - Skipping non https url - ${t.href}`);return}(yield k.canOpenURL(t.href))&&k.openURL(t.href)});return w(b,{children:w($,{ref:l,originWhitelist:["https://*","quilttconnector://*"],source:{uri:y},onShouldStartLoadWithRequest:q,javaScriptEnabled:!0,domStorageEnabled:!0,webviewDebuggingEnabled:!0})})},g=j;var ae=g;export{g as QuilttConnector,ae as default};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/QuilttConnector.tsx","../src/components/AndroidSafeAreaView.tsx"],"sourcesContent":["// Hermes doesn't have atob\n// https://github.com/facebook/hermes/issues/1178\nimport 'core-js/stable/atob'\n// React Native's URL implementation is incomplete\n// https://github.com/facebook/react-native/issues/16434\nimport 'core-js/stable/url'\nimport QuilttConnector from './components/QuilttConnector'\n\nexport { QuilttConnector }\nexport default QuilttConnector\n","import {\n ConnectorSDKCallbackMetadata,\n ConnectorSDKCallbacks,\n ConnectorSDKEventType,\n} from '@quiltt/core'\nimport { useCallback, useRef } from 'react'\nimport { Linking } from 'react-native'\nimport { WebView } from 'react-native-webview'\nimport { AndroidSafeAreaView } from './AndroidSafeAreaView'\nimport type { ShouldStartLoadRequest } from 'react-native-webview/lib/WebViewTypes'\nimport { useQuilttSession } from '@quiltt/react'\n\ntype QuilttConnectorProps = {\n connectorId: string\n connectionId?: string\n oauthRedirectUrl: string\n} & ConnectorSDKCallbacks\n\nexport const QuilttConnector = ({\n connectorId,\n connectionId,\n oauthRedirectUrl,\n onEvent,\n onLoad,\n onExit,\n onExitSuccess,\n onExitAbort,\n onExitError,\n}: QuilttConnectorProps) => {\n const webViewRef = useRef<WebView>(null)\n const { session } = useQuilttSession()\n oauthRedirectUrl = encodeURIComponent(oauthRedirectUrl)\n const connectorUrl = `https://${connectorId}.quiltt.app/?mode=webview&oauth_redirect_url=${oauthRedirectUrl}&sdk=react-native` // @todo append version from package.json\n\n const initInjectedJavaScript = useCallback(() => {\n const script = `\\\n const options = {\\\n source: 'quiltt',\\\n type: 'Options',\\\n token: '${session?.token}',\\\n connectorId: '${connectorId}',\\\n connectionId: '${connectionId}',\\\n };\\\n const compactedOptions = Object.keys(options).reduce((acc, key) => {\\\n if (options[key] !== 'undefined') {\\\n acc[key] = options[key];\\\n }\\\n return acc;\\\n }, {});\\\n window.postMessage(compactedOptions);\\\n `\n webViewRef.current?.injectJavaScript(script)\n }, [connectionId, connectorId, session?.token])\n\n const
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/QuilttConnector.tsx","../src/components/AndroidSafeAreaView.tsx"],"sourcesContent":["// Hermes doesn't have atob\n// https://github.com/facebook/hermes/issues/1178\nimport 'core-js/stable/atob'\n// React Native's URL implementation is incomplete\n// https://github.com/facebook/react-native/issues/16434\nimport 'core-js/stable/url'\nimport QuilttConnector from './components/QuilttConnector'\n\nexport { QuilttConnector }\nexport default QuilttConnector\n","import {\n ConnectorSDKCallbackMetadata,\n ConnectorSDKCallbacks,\n ConnectorSDKEventType,\n} from '@quiltt/core'\nimport { useCallback, useRef } from 'react'\nimport { Linking } from 'react-native'\nimport { WebView } from 'react-native-webview'\nimport { AndroidSafeAreaView } from './AndroidSafeAreaView'\nimport type { ShouldStartLoadRequest } from 'react-native-webview/lib/WebViewTypes'\nimport { useQuilttSession } from '@quiltt/react'\n\ntype QuilttConnectorProps = {\n connectorId: string\n connectionId?: string\n oauthRedirectUrl: string\n} & ConnectorSDKCallbacks\n\nexport const QuilttConnector = ({\n connectorId,\n connectionId,\n oauthRedirectUrl,\n onEvent,\n onLoad,\n onExit,\n onExitSuccess,\n onExitAbort,\n onExitError,\n}: QuilttConnectorProps) => {\n const webViewRef = useRef<WebView>(null)\n const { session } = useQuilttSession()\n oauthRedirectUrl = encodeURIComponent(oauthRedirectUrl)\n const connectorUrl = `https://${connectorId}.quiltt.app/?mode=webview&oauth_redirect_url=${oauthRedirectUrl}&sdk=react-native` // @todo append version from package.json\n\n const initInjectedJavaScript = useCallback(() => {\n const script = `\\\n const options = {\\\n source: 'quiltt',\\\n type: 'Options',\\\n token: '${session?.token}',\\\n connectorId: '${connectorId}',\\\n connectionId: '${connectionId}',\\\n };\\\n const compactedOptions = Object.keys(options).reduce((acc, key) => {\\\n if (options[key] !== 'undefined') {\\\n acc[key] = options[key];\\\n }\\\n return acc;\\\n }, {});\\\n window.postMessage(compactedOptions);\\\n `\n webViewRef.current?.injectJavaScript(script)\n }, [connectionId, connectorId, session?.token])\n\n // allowedListUrl & shouldRender ensure we are only rendering Quiltt, MX and Plaid content in Webview\n // For other urls, we assume those are bank urls, which needs to be handle in external browser.\n // @todo Convert it to a list from Quiltt Server to prevent MX/ Plaid changes.\n const allowedListUrl = [\n 'quiltt.app',\n 'quiltt.dev',\n 'moneydesktop.com',\n 'cdn.plaid.com/link/v2/stable/link.html',\n ]\n const shouldRender = (url: URL) => allowedListUrl.some((href) => url.href.includes(href))\n\n const requestHandler = (request: ShouldStartLoadRequest) => {\n const url = new URL(request.url)\n if (shouldRender(url)) return true\n if (url.protocol === 'quilttconnector:') {\n handleQuilttEvent(url)\n return false\n }\n // Plaid set oauth url by doing window.location.href = url\n // This is the only way I know to handle this.\n handleOAuthUrl(url)\n return false\n }\n\n const clearLocalStorage = () => {\n const script = 'localStorage.clear();'\n webViewRef.current?.injectJavaScript(script)\n }\n\n const handleQuilttEvent = (url: URL) => {\n url.searchParams.delete('source')\n url.searchParams.append('connectorId', connectorId)\n const metadata = Object.fromEntries(url.searchParams) as ConnectorSDKCallbackMetadata\n\n const eventType = url.host\n switch (eventType) {\n case 'Load':\n initInjectedJavaScript()\n onEvent?.(ConnectorSDKEventType.Load, metadata)\n onLoad?.(metadata)\n break\n case 'ExitAbort':\n clearLocalStorage()\n onEvent?.(ConnectorSDKEventType.ExitAbort, metadata)\n onExit?.(ConnectorSDKEventType.ExitAbort, metadata)\n onExitAbort?.(metadata)\n break\n case 'ExitError':\n clearLocalStorage()\n onEvent?.(ConnectorSDKEventType.ExitError, metadata)\n onExit?.(ConnectorSDKEventType.ExitError, metadata)\n onExitError?.(metadata)\n break\n case 'ExitSuccess':\n clearLocalStorage()\n onEvent?.(ConnectorSDKEventType.ExitSuccess, metadata)\n onExit?.(ConnectorSDKEventType.ExitSuccess, metadata)\n onExitSuccess?.(metadata)\n break\n case 'Authenticate':\n // @todo handle Authenticate\n break\n case 'OauthRequested':\n handleOAuthUrl(new URL(url.searchParams.get('oauthUrl') as string))\n break\n default:\n console.log('unhandled event', url)\n break\n }\n }\n\n const handleOAuthUrl = async (oauthUrl: URL) => {\n if (oauthUrl.protocol !== 'https:') {\n console.log(`handleOAuthUrl - Skipping non https url - ${oauthUrl.href}`)\n return\n }\n if (await Linking.canOpenURL(oauthUrl.href)) {\n Linking.openURL(oauthUrl.href)\n }\n }\n\n return (\n <AndroidSafeAreaView>\n <WebView\n ref={webViewRef}\n originWhitelist={['https://*', 'quilttconnector://*']} // Maybe relax this to *?\n source={{ uri: connectorUrl }}\n onShouldStartLoadWithRequest={requestHandler}\n javaScriptEnabled\n domStorageEnabled // To enable localStorage in Android webview\n webviewDebuggingEnabled // Not sure if this works\n />\n </AndroidSafeAreaView>\n )\n}\n\nexport default QuilttConnector\n","import { SafeAreaView, StyleSheet, Platform, StatusBar } from 'react-native'\nimport { PropsWithChildren } from 'react'\n\nexport const AndroidSafeAreaView = ({ children }: PropsWithChildren) => (\n <SafeAreaView style={styles.AndroidSafeArea}>{children}</SafeAreaView>\n)\n\nconst styles = StyleSheet.create({\n AndroidSafeArea: {\n flex: 1,\n backgroundColor: 'white',\n paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0,\n },\n})\n"],"mappings":"6MAEA,MAAO,sBAGP,MAAO,qBCLP,OAGE,yBAAAA,MACK,eACP,OAAS,eAAAC,EAAa,UAAAC,MAAc,QACpC,OAAS,WAAAC,MAAe,eACxB,OAAS,WAAAC,MAAe,uBCPxB,OAAS,gBAAAC,EAAc,cAAAC,EAAY,YAAAC,EAAU,aAAAC,MAAiB,eAI5D,cAAAC,MAAA,oBADK,IAAMC,EAAsB,CAAC,CAAE,SAAAC,CAAS,IAC7CF,EAACJ,EAAA,CAAa,MAAOO,EAAO,gBAAkB,SAAAD,EAAS,EAGnDC,EAASN,EAAW,OAAO,CAC/B,gBAAiB,CACf,KAAM,EACN,gBAAiB,QACjB,WAAYC,EAAS,KAAO,UAAYC,EAAU,cAAgB,CACpE,CACF,CAAC,EDHD,OAAS,oBAAAK,MAAwB,gBA+H3B,cAAAC,MAAA,oBAvHC,IAAMC,EAAkB,CAAC,CAC9B,YAAAC,EACA,aAAAC,EACA,iBAAAC,EACA,QAAAC,EACA,OAAAC,EACA,OAAAC,EACA,cAAAC,EACA,YAAAC,EACA,YAAAC,CACF,IAA4B,CAC1B,IAAMC,EAAaC,EAAgB,IAAI,EACjC,CAAE,QAAAC,CAAQ,EAAIC,EAAiB,EACrCV,EAAmB,mBAAmBA,CAAgB,EACtD,IAAMW,EAAe,WAAWb,iDAA2DE,qBAErFY,EAAyBC,EAAY,IAAM,CAlCnD,IAAAC,EAmCI,IAAMC,EAAS,2FAIDN,GAAA,YAAAA,EAAS,gCACHX,6BACCC,8PAUrBe,EAAAP,EAAW,UAAX,MAAAO,EAAoB,iBAAiBC,EACvC,EAAG,CAAChB,EAAcD,EAAaW,GAAA,YAAAA,EAAS,KAAK,CAAC,EAKxCO,EAAiB,CACrB,aACA,aACA,mBACA,wCACF,EACMC,EAAgBC,GAAaF,EAAe,KAAMG,GAASD,EAAI,KAAK,SAASC,CAAI,CAAC,EAElFC,EAAkBC,GAAoC,CAC1D,IAAMH,EAAM,IAAI,IAAIG,EAAQ,GAAG,EAC/B,OAAIJ,EAAaC,CAAG,EAAU,GAC1BA,EAAI,WAAa,oBACnBI,EAAkBJ,CAAG,EACd,KAITK,EAAeL,CAAG,EACX,GACT,EAEMM,EAAoB,IAAM,CA9ElC,IAAAV,EA+EI,IAAMC,EAAS,yBACfD,EAAAP,EAAW,UAAX,MAAAO,EAAoB,iBAAiBC,EACvC,EAEMO,EAAqBJ,GAAa,CACtCA,EAAI,aAAa,OAAO,QAAQ,EAChCA,EAAI,aAAa,OAAO,cAAepB,CAAW,EAClD,IAAM2B,EAAW,OAAO,YAAYP,EAAI,YAAY,EAGpD,OADkBA,EAAI,KACH,CACjB,IAAK,OACHN,EAAuB,EACvBX,GAAA,MAAAA,EAAUyB,EAAsB,KAAMD,GACtCvB,GAAA,MAAAA,EAASuB,GACT,MACF,IAAK,YACHD,EAAkB,EAClBvB,GAAA,MAAAA,EAAUyB,EAAsB,UAAWD,GAC3CtB,GAAA,MAAAA,EAASuB,EAAsB,UAAWD,GAC1CpB,GAAA,MAAAA,EAAcoB,GACd,MACF,IAAK,YACHD,EAAkB,EAClBvB,GAAA,MAAAA,EAAUyB,EAAsB,UAAWD,GAC3CtB,GAAA,MAAAA,EAASuB,EAAsB,UAAWD,GAC1CnB,GAAA,MAAAA,EAAcmB,GACd,MACF,IAAK,cACHD,EAAkB,EAClBvB,GAAA,MAAAA,EAAUyB,EAAsB,YAAaD,GAC7CtB,GAAA,MAAAA,EAASuB,EAAsB,YAAaD,GAC5CrB,GAAA,MAAAA,EAAgBqB,GAChB,MACF,IAAK,eAEH,MACF,IAAK,iBACHF,EAAe,IAAI,IAAIL,EAAI,aAAa,IAAI,UAAU,CAAW,CAAC,EAClE,MACF,QACE,QAAQ,IAAI,kBAAmBA,CAAG,EAClC,KACJ,CACF,EAEMK,EAAwBI,GAAkBC,EAAA,wBAC9C,GAAID,EAAS,WAAa,SAAU,CAClC,QAAQ,IAAI,6CAA6CA,EAAS,MAAM,EACxE,QAEE,MAAME,EAAQ,WAAWF,EAAS,IAAI,IACxCE,EAAQ,QAAQF,EAAS,IAAI,CAEjC,GAEA,OACE/B,EAACkC,EAAA,CACC,SAAAlC,EAACmC,EAAA,CACC,IAAKxB,EACL,gBAAiB,CAAC,YAAa,qBAAqB,EACpD,OAAQ,CAAE,IAAKI,CAAa,EAC5B,6BAA8BS,EAC9B,kBAAiB,GACjB,kBAAiB,GACjB,wBAAuB,GACzB,EACF,CAEJ,EAEOY,EAAQnC,ED7If,IAAOoC,GAAQC","names":["ConnectorSDKEventType","useCallback","useRef","Linking","WebView","SafeAreaView","StyleSheet","Platform","StatusBar","jsx","AndroidSafeAreaView","children","styles","useQuilttSession","jsx","QuilttConnector","connectorId","connectionId","oauthRedirectUrl","onEvent","onLoad","onExit","onExitSuccess","onExitAbort","onExitError","webViewRef","useRef","session","useQuilttSession","connectorUrl","initInjectedJavaScript","useCallback","_a","script","allowedListUrl","shouldRender","url","href","requestHandler","request","handleQuilttEvent","handleOAuthUrl","clearLocalStorage","metadata","ConnectorSDKEventType","oauthUrl","__async","Linking","AndroidSafeAreaView","WebView","QuilttConnector_default","src_default","QuilttConnector_default"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quiltt/react-native",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.3",
|
|
4
4
|
"description": "React Native components for Quiltt Connector",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"core-js": "3.33.2",
|
|
25
25
|
"react-native-webview": "13.6.2",
|
|
26
|
-
"@quiltt/core": "3.3.
|
|
27
|
-
"@quiltt/react": "3.3.
|
|
26
|
+
"@quiltt/core": "3.3.3",
|
|
27
|
+
"@quiltt/react": "3.3.3"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@apollo/client": "3.7.16",
|
|
@@ -52,16 +52,27 @@ export const QuilttConnector = ({
|
|
|
52
52
|
webViewRef.current?.injectJavaScript(script)
|
|
53
53
|
}, [connectionId, connectorId, session?.token])
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
// allowedListUrl & shouldRender ensure we are only rendering Quiltt, MX and Plaid content in Webview
|
|
56
|
+
// For other urls, we assume those are bank urls, which needs to be handle in external browser.
|
|
57
|
+
// @todo Convert it to a list from Quiltt Server to prevent MX/ Plaid changes.
|
|
58
|
+
const allowedListUrl = [
|
|
59
|
+
'quiltt.app',
|
|
60
|
+
'quiltt.dev',
|
|
61
|
+
'moneydesktop.com',
|
|
62
|
+
'cdn.plaid.com/link/v2/stable/link.html',
|
|
63
|
+
]
|
|
64
|
+
const shouldRender = (url: URL) => allowedListUrl.some((href) => url.href.includes(href))
|
|
65
|
+
|
|
66
|
+
const requestHandler = (request: ShouldStartLoadRequest) => {
|
|
56
67
|
const url = new URL(request.url)
|
|
57
|
-
if (url
|
|
68
|
+
if (shouldRender(url)) return true
|
|
58
69
|
if (url.protocol === 'quilttconnector:') {
|
|
59
70
|
handleQuilttEvent(url)
|
|
60
71
|
return false
|
|
61
72
|
}
|
|
62
73
|
// Plaid set oauth url by doing window.location.href = url
|
|
63
74
|
// This is the only way I know to handle this.
|
|
64
|
-
handleOAuthUrl(url
|
|
75
|
+
handleOAuthUrl(url)
|
|
65
76
|
return false
|
|
66
77
|
}
|
|
67
78
|
|
|
@@ -100,8 +111,11 @@ export const QuilttConnector = ({
|
|
|
100
111
|
onExit?.(ConnectorSDKEventType.ExitSuccess, metadata)
|
|
101
112
|
onExitSuccess?.(metadata)
|
|
102
113
|
break
|
|
114
|
+
case 'Authenticate':
|
|
115
|
+
// @todo handle Authenticate
|
|
116
|
+
break
|
|
103
117
|
case 'OauthRequested':
|
|
104
|
-
handleOAuthUrl(url.searchParams.get('oauthUrl') as string)
|
|
118
|
+
handleOAuthUrl(new URL(url.searchParams.get('oauthUrl') as string))
|
|
105
119
|
break
|
|
106
120
|
default:
|
|
107
121
|
console.log('unhandled event', url)
|
|
@@ -109,7 +123,15 @@ export const QuilttConnector = ({
|
|
|
109
123
|
}
|
|
110
124
|
}
|
|
111
125
|
|
|
112
|
-
const handleOAuthUrl = (oauthUrl:
|
|
126
|
+
const handleOAuthUrl = async (oauthUrl: URL) => {
|
|
127
|
+
if (oauthUrl.protocol !== 'https:') {
|
|
128
|
+
console.log(`handleOAuthUrl - Skipping non https url - ${oauthUrl.href}`)
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
if (await Linking.canOpenURL(oauthUrl.href)) {
|
|
132
|
+
Linking.openURL(oauthUrl.href)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
113
135
|
|
|
114
136
|
return (
|
|
115
137
|
<AndroidSafeAreaView>
|
|
@@ -117,7 +139,7 @@ export const QuilttConnector = ({
|
|
|
117
139
|
ref={webViewRef}
|
|
118
140
|
originWhitelist={['https://*', 'quilttconnector://*']} // Maybe relax this to *?
|
|
119
141
|
source={{ uri: connectorUrl }}
|
|
120
|
-
onShouldStartLoadWithRequest={
|
|
142
|
+
onShouldStartLoadWithRequest={requestHandler}
|
|
121
143
|
javaScriptEnabled
|
|
122
144
|
domStorageEnabled // To enable localStorage in Android webview
|
|
123
145
|
webviewDebuggingEnabled // Not sure if this works
|