diff options
author | Paul Frazee <pfrazee@gmail.com> | 2022-06-15 20:26:41 -0500 |
---|---|---|
committer | Paul Frazee <pfrazee@gmail.com> | 2022-06-15 20:26:41 -0500 |
commit | 07b92a2180ca6600f09e03a85c8ca7a06d24cbfc (patch) | |
tree | 1f7fd65f7cbaf59ff93c92595dc04a22b0a079a7 /src | |
parent | 81441c3c265ae6e733365dcba01f7da650f5b1f9 (diff) | |
download | voidsky-07b92a2180ca6600f09e03a85c8ca7a06d24cbfc.tar.zst |
Implement full auth flow in iOS
Diffstat (limited to 'src')
-rw-r--r-- | src/platform/urls.tsx | 27 | ||||
-rw-r--r-- | src/state/auth.ts | 54 | ||||
-rw-r--r-- | src/state/index.ts | 7 |
3 files changed, 65 insertions, 23 deletions
diff --git a/src/platform/urls.tsx b/src/platform/urls.tsx index 958b5232d..048c92f2e 100644 --- a/src/platform/urls.tsx +++ b/src/platform/urls.tsx @@ -1,4 +1,5 @@ -import {isIOS, isAndroid} from './detection' +import {Linking} from 'react-native' +import {isIOS, isAndroid, isNative, isWeb} from './detection' export function makeAppUrl(path = '') { if (isIOS) { @@ -10,3 +11,27 @@ export function makeAppUrl(path = '') { return `${window.location.origin}${path}` } } + +export function extractHashFragment(url: string): string { + return url.split('#')[1] || '' +} + +export async function getInitialURL(): Promise<string> { + if (isNative) { + const url = await Linking.getInitialURL() + if (url) { + return url + } + return makeAppUrl() + } else { + // @ts-ignore window exists -prf + return window.location.toString() + } +} + +export function clearHash() { + if (isWeb) { + // @ts-ignore window exists -prf + window.location.hash = '' + } +} diff --git a/src/state/auth.ts b/src/state/auth.ts index b49a11d90..ee0fe981d 100644 --- a/src/state/auth.ts +++ b/src/state/auth.ts @@ -3,7 +3,12 @@ import * as auth from '@adxp/auth' import * as ucan from 'ucans' import {InAppBrowser} from 'react-native-inappbrowser-reborn' import {isWeb} from '../platform/detection' -import {makeAppUrl} from '../platform/urls' +import { + getInitialURL, + extractHashFragment, + clearHash, + makeAppUrl, +} from '../platform/urls' import * as storage from './storage' import * as env from '../env' @@ -20,24 +25,26 @@ export async function logout(authStore: ReactNativeStore) { await authStore.reset() } -export async function parseUrlForUcan() { - if (isWeb) { - // @ts-ignore window is defined -prf - const fragment = window.location.hash - if (fragment.length < 1) { - return undefined - } - try { - const ucan = await auth.parseLobbyResponseHashFragment(fragment) - // @ts-ignore window is defined -prf - window.location.hash = '' - return ucan - } catch (err) { - return undefined +export async function parseUrlForUcan(fragment: string) { + try { + return await auth.parseLobbyResponseHashFragment(fragment) + } catch (err) { + return undefined + } +} + +export async function initialLoadUcanCheck(authStore: ReactNativeStore) { + let wasAuthed = false + const fragment = extractHashFragment(await getInitialURL()) + if (fragment) { + const ucan = await parseUrlForUcan(fragment) + if (ucan) { + await authStore.addUcan(ucan) + wasAuthed = true + clearHash() } - } else { - // TODO } + return wasAuthed } export async function requestAppUcan(authStore: ReactNativeStore) { @@ -53,6 +60,7 @@ export async function requestAppUcan(authStore: ReactNativeStore) { } if (await InAppBrowser.isAvailable()) { + // use in-app browser const res = await InAppBrowser.openAuth(url, returnUrl, { // iOS Properties ephemeralWebSession: false, @@ -62,12 +70,20 @@ export async function requestAppUcan(authStore: ReactNativeStore) { enableDefaultShare: false, }) if (res.type === 'success' && res.url) { - Linking.openURL(res.url) + const fragment = extractHashFragment(res.url) + if (fragment) { + const ucan = await parseUrlForUcan(fragment) + if (ucan) { + await authStore.addUcan(ucan) + return true + } + } } else { - console.error('Bad response', res) + console.log('Not completed', res) return false } } else { + // use system browser Linking.openURL(url) } return true diff --git a/src/state/index.ts b/src/state/index.ts index fa7c9518d..460815d13 100644 --- a/src/state/index.ts +++ b/src/state/index.ts @@ -7,6 +7,7 @@ import { import {Environment} from './env' import * as storage from './storage' import * as auth from './auth' +import * as urls from '../platform/urls' const ROOT_STATE_STORAGE_KEY = 'root' @@ -32,9 +33,9 @@ export async function setupState() { if (env.authStore) { const isAuthed = await auth.isAuthed(env.authStore) rootStore.session.setAuthed(isAuthed) - const ucan = await auth.parseUrlForUcan() - if (ucan) { - await env.authStore.addUcan(ucan) + + // handle redirect from auth + if (await auth.initialLoadUcanCheck(env.authStore)) { rootStore.session.setAuthed(true) } } |