From 610b8dd171150a7b097ca8ce2c15fc0ab8d66de6 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Mon, 23 Mar 2026 17:51:51 -0700 Subject: [PATCH] Use secure storage for session data --- android/app/capacitor.build.gradle | 1 + android/capacitor.settings.gradle | 3 +++ ios/App/Podfile | 1 + package.json | 1 + pnpm-lock.yaml | Bin 362793 -> 364449 bytes src/app/core/storage.ts | 41 +++++++++++++++++++++++++++++ src/app/util/logout.ts | 3 ++- src/routes/+layout.svelte | 6 ++--- 8 files changed, 52 insertions(+), 4 deletions(-) diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle index b711150d..da6f2661 100644 --- a/android/app/capacitor.build.gradle +++ b/android/app/capacitor.build.gradle @@ -9,6 +9,7 @@ android { apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" dependencies { + implementation project(':aparajita-capacitor-secure-storage') implementation project(':capacitor-community-safe-area') implementation project(':capacitor-app') implementation project(':capacitor-filesystem') diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle index 4a050d9f..317412b2 100644 --- a/android/capacitor.settings.gradle +++ b/android/capacitor.settings.gradle @@ -2,6 +2,9 @@ include ':capacitor-android' project(':capacitor-android').projectDir = new File('../node_modules/.pnpm/@capacitor+android@8.0.1_@capacitor+core@8.0.1/node_modules/@capacitor/android/capacitor') +include ':aparajita-capacitor-secure-storage' +project(':aparajita-capacitor-secure-storage').projectDir = new File('../node_modules/.pnpm/@aparajita+capacitor-secure-storage@8.0.0/node_modules/@aparajita/capacitor-secure-storage/android') + include ':capacitor-community-safe-area' project(':capacitor-community-safe-area').projectDir = new File('../node_modules/.pnpm/@capacitor-community+safe-area@8.0.1_@capacitor+core@8.0.1/node_modules/@capacitor-community/safe-area/android') diff --git a/ios/App/Podfile b/ios/App/Podfile index a9cd6181..549e20cf 100644 --- a/ios/App/Podfile +++ b/ios/App/Podfile @@ -11,6 +11,7 @@ install! 'cocoapods', :disable_input_output_paths => true def capacitor_pods pod 'Capacitor', :path => '../../node_modules/.pnpm/@capacitor+ios@8.0.1_@capacitor+core@8.0.1/node_modules/@capacitor/ios' pod 'CapacitorCordova', :path => '../../node_modules/.pnpm/@capacitor+ios@8.0.1_@capacitor+core@8.0.1/node_modules/@capacitor/ios' + pod 'AparajitaCapacitorSecureStorage', :path => '../../node_modules/.pnpm/@aparajita+capacitor-secure-storage@8.0.0/node_modules/@aparajita/capacitor-secure-storage' pod 'CapacitorCommunitySafeArea', :path => '../../node_modules/.pnpm/@capacitor-community+safe-area@8.0.1_@capacitor+core@8.0.1/node_modules/@capacitor-community/safe-area' pod 'CapacitorApp', :path => '../../node_modules/.pnpm/@capacitor+app@8.0.0_@capacitor+core@8.0.1/node_modules/@capacitor/app' pod 'CapacitorFilesystem', :path => '../../node_modules/.pnpm/@capacitor+filesystem@8.1.0_@capacitor+core@8.0.1/node_modules/@capacitor/filesystem' diff --git a/package.json b/package.json index d2369b2d..391f4ef6 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ }, "type": "module", "dependencies": { + "@aparajita/capacitor-secure-storage": "^8.0.0", "@capacitor-community/safe-area": "^8.0.1", "@capacitor/android": "^8.0.1", "@capacitor/app": "^8.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4bd063e057e12862bfb615ae37157ab6ef37d64f..9a8ef707ba0ff83427c9658c259f99dc1df03ceb 100644 GIT binary patch delta 839 zcmah`O>EL&7!LaYw9AYiHBXh+2LWyG}-NW-{*aw_vd-@e0=-$_}1IY z6i=0@94k-|Ekl|WxbjSep{r$PrXpi1!-!g?>HYS>HO+~IpB`T)xTRtp&!v1>*hIxb znWoKdgY`tgU5k1lcx^e4rs_u4m(hFSChPWd;W!$I5VW;Ahc;nvJzPb6q{Znexe`{3 zr&ex8^@!CVmEeI%G5u>~SJdsVNRAE|67L=8788MjC0ro`k#r*3KpIUqZpFi?Ae!;i zNIgtj2~QxACt@&-W2roeS)9pY#mp8~2}>!H#g?+UpuKE0`^re(MP?woGqC6hVUpGj zv?BjxRC&ub3-1;-z5wyv!&8R?S2&E~LQF{T!mMvOh`8hBq>&Q1wHUg9c)WBv5Udvc z7K{wp5TVA$T@2$i(`F+B8$v`i8*J2#G`^JNOK>C(XOnu!zTj`HM(5{m4-bolfeX^B zJ)qttAH7gWnl4cPy%C1uLeN}_Krtg8G{mD85{h#IO3y`b2qQQSF_};{S4lg)q$|ZR z`bNP;@uUrBLV;q{I9K=Ug-V)StqCko`O&pBmW&;{@qVwh*=s4jIX(9(v&d#u#&a6e&FfgjH(%Gf5<%OMsAu4kKkw_9Mc z7_<2F^VgV7rq8*@JO!j%ary>H78a10^JMjY!RgN)Fh@BWOh2 diff --git a/src/app/core/storage.ts b/src/app/core/storage.ts index b05be817..32e05969 100644 --- a/src/app/core/storage.ts +++ b/src/app/core/storage.ts @@ -1,4 +1,5 @@ import {call} from "@welshman/lib" +import {SecureStorage} from "@aparajita/capacitor-secure-storage" import {Preferences} from "@capacitor/preferences" import {IDB} from "@lib/indexeddb" @@ -30,6 +31,46 @@ export const kv = call(() => { return {get, set, clear} }) +export const ss = call(() => { + let p = Promise.resolve() + + const get = async (key: string): Promise => { + let value = await SecureStorage.getItem(key) + + if (!value) { + const legacy = await Preferences.get({key}) + + if (legacy.value) { + value = legacy.value + await SecureStorage.setItem(key, legacy.value) + await Preferences.remove({key}) + } + } + + if (!value) return undefined + + try { + return JSON.parse(value) + } catch (e) { + return undefined + } + } + + const set = async (key: string, value: T): Promise => { + p = p.then(() => SecureStorage.setItem(key, JSON.stringify(value))) + + await p + } + + const clear = async () => { + p = p.then(() => SecureStorage.clear()) + + await p + } + + return {get, set, clear} +}) + export const db = new IDB({ name: "flotilla-9gl", version: 1, diff --git a/src/app/util/logout.ts b/src/app/util/logout.ts index 23a3f9ac..cef124a7 100644 --- a/src/app/util/logout.ts +++ b/src/app/util/logout.ts @@ -1,4 +1,4 @@ -import {kv, db} from "@app/core/storage" +import {db, kv, ss} from "@app/core/storage" import {Push} from "@app/util/notifications" import {deactivateCurrentPomadeSession} from "@app/util/pomade" @@ -6,6 +6,7 @@ export const logout = async () => { await deactivateCurrentPomadeSession() await Push.disable() await kv.clear() + await ss.clear() await db.clear() localStorage.clear() diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 57311b28..ea0e1e2b 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -27,7 +27,7 @@ import {setupHistory} from "@app/util/history" import {setupAnalytics} from "@app/util/analytics" import {authPolicy, blockPolicy, trustPolicy, mostlyRestrictedPolicy} from "@app/util/policies" - import {kv, db} from "@app/core/storage" + import {db, kv, ss} from "@app/core/storage" import {device, userSettingsValues, notificationSettings, pushState} from "@app/core/state" import {syncApplicationData} from "@app/core/sync" import * as commands from "@app/core/commands" @@ -96,7 +96,7 @@ const unsubscribe = call(async () => { const unsubscribers: Unsubscriber[] = [] - // Sync stuff to localstorage + // Sync stuff to storage await Promise.all([ sync({ key: "device", @@ -111,7 +111,7 @@ sync({ key: "sessions", store: sessions, - storage: kv, + storage: ss, }), sync({ key: "shouldUnwrap",