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 4bd063e0..9a8ef707 100644 Binary files a/pnpm-lock.yaml and b/pnpm-lock.yaml differ 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",