mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-20 14:06:27 +00:00
9832d12751
The native apps show the server's own UI in a WebView, where neither SSO nor passkeys can run. They sign in through the system browser instead and need a way to carry that session back. The app keeps a random verifier and sends only its sha256 into the browser. Once signed in there, the browser trades that challenge for a one-time code (cookie session only, so an API or MCP token cannot mint itself a browser session), and the WebView redeems the code together with the verifier. The code rides through a URL scheme any app could claim, so on its own it is worthless; it is single use and good for a minute. Also: /api/health/features reports nativeApp so the apps can refuse servers that predate this, and hashed files under assets/ are served immutable, which the iOS app needs to start offline without a service worker.
31 lines
1.2 KiB
TypeScript
31 lines
1.2 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
/**
|
|
* Sign-in hand-off for the native apps, /api/auth/native.
|
|
*
|
|
* The app shows the TREK web UI inside its own WebView, but SSO and passkeys
|
|
* cannot run there, so it signs in through the system browser instead and has
|
|
* to carry that session back. The app picks a random verifier and sends only
|
|
* its sha256 (the challenge) into the browser. The browser, once signed in,
|
|
* trades the challenge for a one-time code, and the WebView redeems the code
|
|
* together with the verifier. The code travels through a URL scheme any app
|
|
* could claim, so without the verifier it is worth nothing.
|
|
*/
|
|
const hexSha256 = z.string().regex(/^[0-9a-f]{64}$/);
|
|
|
|
export const nativeHandoffRequestSchema = z.object({
|
|
challenge: hexSha256,
|
|
});
|
|
export type NativeHandoffRequest = z.infer<typeof nativeHandoffRequestSchema>;
|
|
|
|
export const nativeHandoffResponseSchema = z.object({
|
|
code: z.string(),
|
|
});
|
|
export type NativeHandoffResponse = z.infer<typeof nativeHandoffResponseSchema>;
|
|
|
|
export const nativeExchangeRequestSchema = z.object({
|
|
code: z.string().min(1).max(128),
|
|
verifier: z.string().min(43).max(128),
|
|
});
|
|
export type NativeExchangeRequest = z.infer<typeof nativeExchangeRequestSchema>;
|