2026-06-13 20:13:12 -05:00
|
|
|
import { SecureStoragePlugin } from 'capacitor-secure-storage-plugin';
|
feat(mobile): shared api/config layer, server-mode CSRF fix, robustness + update-safe DB (batch 10)
Unify the native shell and harden it:
- src/config.ts: single source for local host/port, preference keys, secure-storage
key, timeouts, and CSRF constants (dedupes LOCAL_URL etc. across App/LoadingScreen).
- src/api.ts: one HTTP client — credentials mode, AbortController timeouts, and error
normalization into user-facing messages (network/timeout/401/403/429/5xx), with typed
auth responses.
- Batch 10 CSRF fix: /api/auth/totp/challenge is not CSRF-exempt, so the native TOTP
step now fetches GET /api/auth/csrf-token and echoes it as x-csrf-token (mirrors the
web client); TOTP login no longer breaks for 2FA users.
- Error-handling / boot robustness: LoadingScreen gets a health-poll timeout and
surfaces main.js's {type:'serverError'} channel messages instead of spinning forever;
App.tsx bootstrap and the encryption-key fetch now .catch to a visible state; crypto.ts
reports secure-storage failures.
- Data safety: move the SQLite DB, backups, and tmp OUT of nodejs-project into the app's
filesDir (bt-data). nodejs-mobile re-copies nodejs-project on every app update, which was
silently wiping local-mode data. Verified on the emulator: create data -> bump versionCode
-> reinstall -> migrations skipped, no re-seed, data persists.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 10:48:23 -05:00
|
|
|
import { SECURE_KEY_NAME, ENCRYPTION_KEY_BYTES } from './config';
|
2026-06-13 20:13:12 -05:00
|
|
|
|
|
|
|
|
function generateHexKey(bytes: number): string {
|
|
|
|
|
const arr = new Uint8Array(bytes);
|
|
|
|
|
globalThis.crypto.getRandomValues(arr);
|
|
|
|
|
return Array.from(arr, b => b.toString(16).padStart(2, '0')).join('');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the device's local-mode database encryption key (TOKEN_ENCRYPTION_KEY),
|
|
|
|
|
* generating and persisting one in secure storage (Android Keystore / iOS Keychain)
|
feat(mobile): shared api/config layer, server-mode CSRF fix, robustness + update-safe DB (batch 10)
Unify the native shell and harden it:
- src/config.ts: single source for local host/port, preference keys, secure-storage
key, timeouts, and CSRF constants (dedupes LOCAL_URL etc. across App/LoadingScreen).
- src/api.ts: one HTTP client — credentials mode, AbortController timeouts, and error
normalization into user-facing messages (network/timeout/401/403/429/5xx), with typed
auth responses.
- Batch 10 CSRF fix: /api/auth/totp/challenge is not CSRF-exempt, so the native TOTP
step now fetches GET /api/auth/csrf-token and echoes it as x-csrf-token (mirrors the
web client); TOTP login no longer breaks for 2FA users.
- Error-handling / boot robustness: LoadingScreen gets a health-poll timeout and
surfaces main.js's {type:'serverError'} channel messages instead of spinning forever;
App.tsx bootstrap and the encryption-key fetch now .catch to a visible state; crypto.ts
reports secure-storage failures.
- Data safety: move the SQLite DB, backups, and tmp OUT of nodejs-project into the app's
filesDir (bt-data). nodejs-mobile re-copies nodejs-project on every app update, which was
silently wiping local-mode data. Verified on the emulator: create data -> bump versionCode
-> reinstall -> migrations skipped, no re-seed, data persists.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 10:48:23 -05:00
|
|
|
* on first launch. Throws if secure storage is unavailable — the caller
|
|
|
|
|
* (LoadingScreen) surfaces that rather than starting the server with no key.
|
2026-06-13 20:13:12 -05:00
|
|
|
*/
|
|
|
|
|
export async function getOrCreateEncryptionKey(): Promise<string> {
|
|
|
|
|
try {
|
feat(mobile): shared api/config layer, server-mode CSRF fix, robustness + update-safe DB (batch 10)
Unify the native shell and harden it:
- src/config.ts: single source for local host/port, preference keys, secure-storage
key, timeouts, and CSRF constants (dedupes LOCAL_URL etc. across App/LoadingScreen).
- src/api.ts: one HTTP client — credentials mode, AbortController timeouts, and error
normalization into user-facing messages (network/timeout/401/403/429/5xx), with typed
auth responses.
- Batch 10 CSRF fix: /api/auth/totp/challenge is not CSRF-exempt, so the native TOTP
step now fetches GET /api/auth/csrf-token and echoes it as x-csrf-token (mirrors the
web client); TOTP login no longer breaks for 2FA users.
- Error-handling / boot robustness: LoadingScreen gets a health-poll timeout and
surfaces main.js's {type:'serverError'} channel messages instead of spinning forever;
App.tsx bootstrap and the encryption-key fetch now .catch to a visible state; crypto.ts
reports secure-storage failures.
- Data safety: move the SQLite DB, backups, and tmp OUT of nodejs-project into the app's
filesDir (bt-data). nodejs-mobile re-copies nodejs-project on every app update, which was
silently wiping local-mode data. Verified on the emulator: create data -> bump versionCode
-> reinstall -> migrations skipped, no re-seed, data persists.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 10:48:23 -05:00
|
|
|
const { value } = await SecureStoragePlugin.get({ key: SECURE_KEY_NAME });
|
2026-06-13 20:13:12 -05:00
|
|
|
if (value) return value;
|
|
|
|
|
} catch {
|
|
|
|
|
// Not found — fall through to generate one.
|
|
|
|
|
}
|
|
|
|
|
|
feat(mobile): shared api/config layer, server-mode CSRF fix, robustness + update-safe DB (batch 10)
Unify the native shell and harden it:
- src/config.ts: single source for local host/port, preference keys, secure-storage
key, timeouts, and CSRF constants (dedupes LOCAL_URL etc. across App/LoadingScreen).
- src/api.ts: one HTTP client — credentials mode, AbortController timeouts, and error
normalization into user-facing messages (network/timeout/401/403/429/5xx), with typed
auth responses.
- Batch 10 CSRF fix: /api/auth/totp/challenge is not CSRF-exempt, so the native TOTP
step now fetches GET /api/auth/csrf-token and echoes it as x-csrf-token (mirrors the
web client); TOTP login no longer breaks for 2FA users.
- Error-handling / boot robustness: LoadingScreen gets a health-poll timeout and
surfaces main.js's {type:'serverError'} channel messages instead of spinning forever;
App.tsx bootstrap and the encryption-key fetch now .catch to a visible state; crypto.ts
reports secure-storage failures.
- Data safety: move the SQLite DB, backups, and tmp OUT of nodejs-project into the app's
filesDir (bt-data). nodejs-mobile re-copies nodejs-project on every app update, which was
silently wiping local-mode data. Verified on the emulator: create data -> bump versionCode
-> reinstall -> migrations skipped, no re-seed, data persists.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 10:48:23 -05:00
|
|
|
const key = generateHexKey(ENCRYPTION_KEY_BYTES);
|
|
|
|
|
try {
|
|
|
|
|
await SecureStoragePlugin.set({ key: SECURE_KEY_NAME, value: key });
|
|
|
|
|
} catch (err) {
|
|
|
|
|
throw new Error('Failed to persist the encryption key to secure storage: ' + String(err));
|
|
|
|
|
}
|
2026-06-13 20:13:12 -05:00
|
|
|
return key;
|
|
|
|
|
}
|