From 83a2c79e72d59573987e2314e91d6b7dcffcb935 Mon Sep 17 00:00:00 2001 From: rdlabo Date: Wed, 12 Aug 2026 16:11:13 +0900 Subject: [PATCH 1/2] fix(offline): require synchronized encryption key --- projects/kit/offline/src/lib/offline-contract.spec.ts | 7 +++++++ projects/kit/offline/src/lib/offline-provider.ts | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/projects/kit/offline/src/lib/offline-contract.spec.ts b/projects/kit/offline/src/lib/offline-contract.spec.ts index 1493022..6ff4b03 100644 --- a/projects/kit/offline/src/lib/offline-contract.spec.ts +++ b/projects/kit/offline/src/lib/offline-contract.spec.ts @@ -72,4 +72,11 @@ describe('shared offline boundary contracts', () => { }; void compileOnly; }); + + it('requires an encryption key factory for synchronized providers at compile time', () => { + type Options = import('./offline-provider').ProvideSynchronizedOfflineOptions; + type IsRequired = Record extends Pick ? false : true; + const createEncryptionKeyIsRequired: IsRequired = true; + expect(createEncryptionKeyIsRequired).toBe(true); + }); }); diff --git a/projects/kit/offline/src/lib/offline-provider.ts b/projects/kit/offline/src/lib/offline-provider.ts index 206e52f..65f3f4a 100644 --- a/projects/kit/offline/src/lib/offline-provider.ts +++ b/projects/kit/offline/src/lib/offline-provider.ts @@ -36,6 +36,8 @@ interface ProvideOfflineOptionsBase extends OfflineKitOptions { /** Full replica pull and durable Outbox synchronization. */ export interface ProvideSynchronizedOfflineOptions extends ProvideOfflineOptionsBase { mode?: 'synchronized'; + /** Creates the encrypted native database key on first install. */ + createEncryptionKey: () => Promise; /** Product policies that replace matched writes with atomic local-first mutations. */ mutationPolicies?: readonly Type[]; /** Product adapter that sends opaque commands to its API. */ @@ -47,6 +49,8 @@ export interface ProvideSynchronizedOfflineOptions extends ProvideOfflineOptions /** Server- or external-source read cache with no mutation transport or Outbox. */ export interface ProvideReadCacheOfflineOptions extends ProvideOfflineOptionsBase { mode: 'readCacheOnly'; + /** Read-cache-only mode does not provision an encrypted native Outbox database. */ + createEncryptionKey?: never; mutationPolicies?: never; commandExecutor?: never; replicaPuller?: never; From 161fcd7c6517047503c8615c2a2ab086971daebb Mon Sep 17 00:00:00 2001 From: rdlabo Date: Wed, 12 Aug 2026 16:20:08 +0900 Subject: [PATCH 2/2] fix(offline): require key for native read cache --- projects/kit/offline/src/lib/offline-contract.spec.ts | 8 ++++++++ projects/kit/offline/src/lib/offline-provider.ts | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/projects/kit/offline/src/lib/offline-contract.spec.ts b/projects/kit/offline/src/lib/offline-contract.spec.ts index 6ff4b03..d5118cf 100644 --- a/projects/kit/offline/src/lib/offline-contract.spec.ts +++ b/projects/kit/offline/src/lib/offline-contract.spec.ts @@ -66,6 +66,7 @@ describe('shared offline boundary contracts', () => { provideOffline({ mode: 'readCacheOnly', databaseName: 'read-cache', + createEncryptionKey: async () => 'native-cache-key', replicaSchema: defineOfflineReplicaSchema({ version: 1, entities: [], migrations: [] }), requestPolicies: [], }); @@ -79,4 +80,11 @@ describe('shared offline boundary contracts', () => { const createEncryptionKeyIsRequired: IsRequired = true; expect(createEncryptionKeyIsRequired).toBe(true); }); + + it('requires an encryption key factory for native read-cache persistence too', () => { + type Options = import('./offline-provider').ProvideReadCacheOfflineOptions; + type IsRequired = Record extends Pick ? false : true; + const createEncryptionKeyIsRequired: IsRequired = true; + expect(createEncryptionKeyIsRequired).toBe(true); + }); }); diff --git a/projects/kit/offline/src/lib/offline-provider.ts b/projects/kit/offline/src/lib/offline-provider.ts index 65f3f4a..431d865 100644 --- a/projects/kit/offline/src/lib/offline-provider.ts +++ b/projects/kit/offline/src/lib/offline-provider.ts @@ -49,8 +49,8 @@ export interface ProvideSynchronizedOfflineOptions extends ProvideOfflineOptions /** Server- or external-source read cache with no mutation transport or Outbox. */ export interface ProvideReadCacheOfflineOptions extends ProvideOfflineOptionsBase { mode: 'readCacheOnly'; - /** Read-cache-only mode does not provision an encrypted native Outbox database. */ - createEncryptionKey?: never; + /** Creates the encrypted native cache database key on first install. Unused by the web repository. */ + createEncryptionKey: () => Promise; mutationPolicies?: never; commandExecutor?: never; replicaPuller?: never;