UNPKG

@passageidentity/passage-react-native

Version:

Passkey Complete for React Native - Go completely passwordless with a standalone auth solution in your React Native app with Passage by 1Password

63 lines (60 loc) 2.14 kB
import { AppState, Linking } from 'react-native'; const getUrlParamValue = (url: string, param: string): string | null => { const queryString = url.split('?')[1]; const queryParams = queryString ? queryString.split('&').reduce((acc, current) => { const [key, value] = current.split('='); if (key && value) { acc[key] = decodeURIComponent(value); } return acc; }, {} as Record<string, string>) : {}; return queryParams[param] || null; }; /** * Call this function when expecting a redirect into the application when the app has * become inactive or backgrounded. * * Note that this function works best in a "singleTask" Android app. * * @param parameters Array of parameters to return from Deep Link. * @returns object * @throws */ export const waitForDeepLinkQueryValues = async ( parameters: string[] ): Promise<{ [key: string]: string }> => { return new Promise(async (resolve, reject) => { // We need to listen for a Deep Link url event, and attempt to extract the parameters // from the redirect url. const linkingListener = Linking.addEventListener('url', async (event) => { appStateListener.remove(); linkingListener.remove(); const { url } = event; const result: { [key: string]: string } = {}; for (let parameter of parameters) { const value = getUrlParamValue(url, parameter); if (!value) { return reject( new Error(`Missing query parameter ${parameter} in redirect url.`) ); } result[parameter] = value; } resolve(result); }); // We need to listen for an AppState change event in the case that the user returns to // the app without having been redirected. // Note that appStateListener will NEVER be triggered before linkingListener. const appStateListener = AppState.addEventListener( 'change', (nextAppState) => { if (nextAppState !== 'active') return; appStateListener.remove(); linkingListener.remove(); reject(new Error('Operation canceled.')); } ); }); };