mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 05:26:47 +00:00
ae0d4e4520
Everything the server's UI does differently inside the iOS and Android app lives under src/native and is inert in a browser. Sign-in: SSO and the passkey button go through the system browser (signInThroughBrowser), because identity providers refuse embedded browsers and WebAuthn needs a domain association no build can have for every server. The browser end is the new /native-handoff page: it signs the user in if needed and hands the session over only after an explicit tap, so a link carrying somebody else's challenge cannot pass a session on silently. The verifier is hashed with @noble/hashes because crypto.subtle is missing on the plain-http servers many home networks use. An OIDC-only install no longer bounces to the IdP inside the WebView, and passkey management is hidden in the app. Downloads: the WebView cannot save a blob, so downloadBlob, downloadFile and openFile write to the app cache and open the share sheet. The eight places that built their own download anchor now use downloadBlob, which they should have anyway. The rest: "Change server" on the login page and in the account settings, the splash hides after the first frame, Android's back button walks history before it leaves the app, the status bar follows the scheme, and on iOS the start page is refreshed and every chunk of the build (listed in the new asset-manifest.json) is pulled into WebKit's cache so the app can start without network.
13 lines
691 B
TypeScript
13 lines
691 B
TypeScript
import type { NativeExchangeRequest, NativeHandoffResponse } from '@trek/shared'
|
|
import { apiClient } from './client'
|
|
|
|
/** The two halves of the sign-in hand-off between system browser and app. */
|
|
export const nativeAuthApi = {
|
|
/** Browser side: trade a signed-in session for a one-time code bound to `challenge`. */
|
|
handoff: (challenge: string): Promise<NativeHandoffResponse> =>
|
|
apiClient.post('/auth/native/handoff', { challenge }).then((r) => r.data),
|
|
/** App side: redeem the code with the verifier; the response sets the session cookie. */
|
|
exchange: (body: NativeExchangeRequest): Promise<void> =>
|
|
apiClient.post('/auth/native/exchange', body).then(() => undefined),
|
|
}
|