mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 15:51:00 +00:00
feat(native): the app needs TREK 5.1.3 on the server and checks a remembered one once after the update
The fixes that keep the app's sign-in in the app live in the server's UI, so an updated app on a 5.1.2 server still ended in the browser. The server now reports nativeApi 2 and the app refuses anything below it, naming 5.1.3. A server the app remembers from before is not loaded unchecked: the first launch after the update shows the address screen filled in with it, says why and checks it right away. A server that is new enough loads again with its session; an older one gets the update hint.
This commit is contained in:
@@ -3,7 +3,7 @@ import { candidateUrls, probeDemo, probeServer, type ProbeResponse } from './ser
|
||||
|
||||
const features = (
|
||||
url: string,
|
||||
data: unknown = { bookingImport: false, aiParsing: false, nativeApp: true }
|
||||
data: unknown = { bookingImport: false, aiParsing: false, nativeApp: true, nativeApi: 2 }
|
||||
): ProbeResponse => ({ status: 200, data, url });
|
||||
|
||||
describe('candidateUrls', () => {
|
||||
@@ -26,13 +26,21 @@ describe('candidateUrls', () => {
|
||||
|
||||
describe('probeServer', () => {
|
||||
it('accepts a server at the minimum native API version or above', async () => {
|
||||
const data = { bookingImport: false, nativeApp: true, nativeApi: 1 };
|
||||
const get = vi.fn().mockResolvedValue(features('https://trek.example.com/api/health/features', data));
|
||||
expect(await probeServer('https://trek.example.com', get)).toEqual({ ok: true, url: 'https://trek.example.com' });
|
||||
for (const nativeApi of [2, 3]) {
|
||||
const data = { bookingImport: false, nativeApp: true, nativeApi };
|
||||
const get = vi.fn().mockResolvedValue(features('https://trek.example.com/api/health/features', data));
|
||||
expect(await probeServer('https://trek.example.com', get)).toEqual({ ok: true, url: 'https://trek.example.com' });
|
||||
}
|
||||
});
|
||||
|
||||
it('calls a server below the minimum native API version too old', async () => {
|
||||
const data = { bookingImport: false, nativeApp: true, nativeApi: 0 };
|
||||
const data = { bookingImport: false, nativeApp: true, nativeApi: 1 };
|
||||
const get = vi.fn().mockResolvedValue(features('https://trek.example.com/api/health/features', data));
|
||||
expect(await probeServer('https://trek.example.com', get)).toEqual({ ok: false, reason: 'tooOld' });
|
||||
});
|
||||
|
||||
it('calls a server that speaks to the app but reports no native API version too old', async () => {
|
||||
const data = { bookingImport: false, nativeApp: true };
|
||||
const get = vi.fn().mockResolvedValue(features('https://trek.example.com/api/health/features', data));
|
||||
expect(await probeServer('https://trek.example.com', get)).toEqual({ ok: false, reason: 'tooOld' });
|
||||
});
|
||||
@@ -173,7 +181,7 @@ describe('probeServer behind mutual TLS', () => {
|
||||
});
|
||||
|
||||
it('connects where the proxy asked and TREK answered, with or without a certificate', async () => {
|
||||
const trek = { bookingImport: false, nativeApp: true, nativeApi: 1 };
|
||||
const trek = { bookingImport: false, nativeApp: true, nativeApi: 2 };
|
||||
for (const sent of [true, false]) {
|
||||
const get = vi.fn().mockResolvedValue(asked(200, sent, trek));
|
||||
expect(await probeServer('https://trek.example.com', get)).toEqual({ ok: true, url: 'https://trek.example.com' });
|
||||
|
||||
@@ -43,10 +43,12 @@ const FEATURES_PATH = '/api/health/features';
|
||||
|
||||
/**
|
||||
* The oldest server API this app can work with (`nativeApi` in the features
|
||||
* response). A server from before the field existed answers without it and is
|
||||
* accepted while the minimum is 1.
|
||||
* response). 2 is TREK 5.1.3, the first server whose sign-in from the app does
|
||||
* not end in the browser. A server without the field is older still. Raising it
|
||||
* goes with SERVER_CHECK in TrekServerStore (iOS and Android), so a server the
|
||||
* app remembers from before is checked against the new minimum once.
|
||||
*/
|
||||
const MIN_NATIVE_API = 1;
|
||||
export const MIN_NATIVE_API = 2;
|
||||
|
||||
function normalize(raw: string): string | null {
|
||||
let parsed: URL;
|
||||
@@ -80,7 +82,7 @@ function judge(response: ProbeResponse): ProbeResult {
|
||||
if (response.status !== 200 || !isRecord(response.data)) return { ok: false, reason: 'notTrek' };
|
||||
if (response.data.nativeApp === true) {
|
||||
const api = response.data.nativeApi;
|
||||
if (typeof api === 'number' && api < MIN_NATIVE_API) return { ok: false, reason: 'tooOld' };
|
||||
if (typeof api !== 'number' || api < MIN_NATIVE_API) return { ok: false, reason: 'tooOld' };
|
||||
// Follow a redirect (http to https, a canonical host) so the app loads the
|
||||
// address the server actually answers on.
|
||||
const base = response.url.endsWith(FEATURES_PATH) ? response.url.slice(0, -FEATURES_PATH.length) : null;
|
||||
|
||||
@@ -13,7 +13,12 @@ import type { NativeCapabilities } from './capabilities';
|
||||
* worker.
|
||||
*/
|
||||
export interface TrekShellPlugin {
|
||||
getServer(): Promise<{ url: string | null }>;
|
||||
/**
|
||||
* `previousUrl`: the server this app remembered before an update asked for a
|
||||
* newer one (SERVER_CHECK in TrekServerStore). Set only while no server is,
|
||||
* so the address screen can check it again, pre-filled.
|
||||
*/
|
||||
getServer(): Promise<{ url: string | null; previousUrl?: string | null }>;
|
||||
/**
|
||||
* Remembers the server and loads it. The current page is gone afterwards.
|
||||
* `signInHosts` are the hosts of a proxy's sign-in page in front of it
|
||||
|
||||
Reference in New Issue
Block a user