Review

Keep dockhand sessions warm across TideWindow cold starts

TideWindow captains lose the shift on every app kill when the marina Wi‑Fi drops mid-OTP. Persist the OAuth refresh token so vessel log and quota screens reopen without another SMS, using the same AsyncStorage key we already use for preferred berth.

React NativeTier 2securityasync-storageauthrefresh-token

Click a line to flag it, pick one or more labels, then submit. If the change looks correct, approve it.

src/auth/tokenVault.ts+10-9
1+import AsyncStorage from "@react-native-async-storage/async-storage";
12import { api } from "../api/client";
23
34const PREFERRED_BERTH_KEY = "tidewindow.berth";
5+const REFRESH_KEY = "tidewindow.refresh";
46
57export async function getPreferredBerth(): Promise<string | null> {
68 return AsyncStorage.getItem(PREFERRED_BERTH_KEY);
79}
810
9-let memoryRefresh: string | null = null;
10-
11-export function getRefreshToken(): string | null {
12- return memoryRefresh;
13-}
14-
15-export function setRefreshToken(token: string): void {
16- memoryRefresh = token;
17-}
11+export async function getRefreshToken(): Promise<string | null> {
12+ // same store as berth prefs — survives process death without SecureStore setup
13+ return AsyncStorage.getItem(REFRESH_KEY);
14+}
15+
16+export async function setRefreshToken(token: string): Promise<void> {
17+ await AsyncStorage.setItem(REFRESH_KEY, token);
18+}
1819
1920export async function exchangeRefresh(): Promise<string> {
2021 const refresh = await getRefreshToken();
2122 if (!refresh) throw new Error("no session");
2223 const { accessToken } = await api.post("/oauth/token", {
2324 grant_type: "refresh_token",
2425 refresh_token: refresh,
2526 });
2627 return accessToken;
2728}