From 9f937f217b0ae4d10b8041a5142c7f0fab97059f Mon Sep 17 00:00:00 2001 From: Mo Date: Wed, 3 May 2023 07:56:01 -0500 Subject: [PATCH] chore: remove phased out storage encryption policy (#2323) --- .../src/Domain/Storage/StorageKeys.ts | 1 - .../src/Domain/Storage/StorageTypes.ts | 7 +- .../snjs/lib/Application/Application.spec.ts | 145 ------------------ packages/snjs/lib/Application/Application.ts | 10 -- .../Storage/DiskStorageService.spec.ts | 4 +- .../Services/Storage/DiskStorageService.ts | 58 ++----- packages/snjs/mocha/storage.test.js | 22 --- packages/snjs/package.json | 2 +- 8 files changed, 14 insertions(+), 235 deletions(-) delete mode 100644 packages/snjs/lib/Application/Application.spec.ts diff --git a/packages/services/src/Domain/Storage/StorageKeys.ts b/packages/services/src/Domain/Storage/StorageKeys.ts index 5413906dd..2af95426c 100644 --- a/packages/services/src/Domain/Storage/StorageKeys.ts +++ b/packages/services/src/Domain/Storage/StorageKeys.ts @@ -31,7 +31,6 @@ export enum StorageKey { ProtectionExpirey = 'SessionExpiresAtKey', ProtectionSessionLength = 'SessionLengthKey', KeyRecoveryUndecryptableItems = 'key_recovery_undecryptable', - StorageEncryptionPolicy = 'storage_policy', WebSocketUrl = 'webSocket_url', UserRoles = 'user_roles', OfflineUserRoles = 'offline_user_roles', diff --git a/packages/services/src/Domain/Storage/StorageTypes.ts b/packages/services/src/Domain/Storage/StorageTypes.ts index a28807144..f221ecd3c 100644 --- a/packages/services/src/Domain/Storage/StorageTypes.ts +++ b/packages/services/src/Domain/Storage/StorageTypes.ts @@ -7,13 +7,8 @@ export enum StoragePersistencePolicies { Ephemeral = 2, } -export enum StorageEncryptionPolicy { - Default = 1, - Disabled = 2, -} - export enum StorageValueModes { - /** Stored inside wrapped encrpyed storage object */ + /** Stored inside wrapped encrypted storage object */ Default = 1, /** Stored outside storage object, unencrypted */ Nonwrapped = 2, diff --git a/packages/snjs/lib/Application/Application.spec.ts b/packages/snjs/lib/Application/Application.spec.ts deleted file mode 100644 index 192d9902c..000000000 --- a/packages/snjs/lib/Application/Application.spec.ts +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @jest-environment jsdom - */ - -import { SNLog } from './../Log' -import { PureCryptoInterface } from '@standardnotes/sncrypto-common' -import { AlertService, DeviceInterface, namespacedKey, RawStorageKey } from '@standardnotes/services' -import { Environment, Platform } from '@standardnotes/models' -import { SNApplication } from './Application' - -describe('application', () => { - // eslint-disable-next-line no-console - SNLog.onLog = console.log - SNLog.onError = console.error - - let application: SNApplication - let device: DeviceInterface - let crypto: PureCryptoInterface - - beforeEach(async () => { - const identifier = '123' - - crypto = {} as jest.Mocked - crypto.initialize = jest.fn() - - device = {} as jest.Mocked - device.openDatabase = jest.fn().mockResolvedValue(true) - device.getAllDatabaseEntries = jest.fn().mockReturnValue([]) - device.setRawStorageValue = jest.fn() - device.getRawStorageValue = jest.fn().mockImplementation((key) => { - if (key === namespacedKey(identifier, RawStorageKey.SnjsVersion)) { - return '10.0.0' - } - return undefined - }) - - application = new SNApplication({ - environment: Environment.Mobile, - platform: Platform.Ios, - deviceInterface: device, - crypto: crypto, - alertService: {} as jest.Mocked, - identifier: identifier, - defaultHost: 'localhost', - appVersion: '1.0', - }) - - await application.prepareForLaunch({ receiveChallenge: jest.fn() }) - }) - - it('diagnostics', async () => { - const diagnostics = await application.getDiagnostics() - - expect(diagnostics).toEqual( - expect.objectContaining({ - application: expect.objectContaining({ - appVersion: '1.0', - environment: 3, - platform: 1, - }), - payloads: { - integrityPayloads: [], - nonDeletedItemCount: 0, - invalidPayloadsCount: 0, - }, - items: { allIds: [] }, - storage: { - storagePersistable: false, - persistencePolicy: 'Default', - encryptionPolicy: 'Default', - needsPersist: false, - currentPersistPromise: false, - isStorageWrapped: false, - allRawPayloadsCount: 0, - }, - encryption: expect.objectContaining({ - getLatestVersion: '004', - hasAccount: false, - getUserVersion: undefined, - upgradeAvailable: false, - accountUpgradeAvailable: false, - passcodeUpgradeAvailable: false, - hasPasscode: false, - isPasscodeLocked: false, - itemsEncryption: expect.objectContaining({ - itemsKeysIds: [], - }), - rootKeyEncryption: expect.objectContaining({ - hasRootKey: false, - keyMode: 'RootKeyNone', - hasRootKeyWrapper: false, - hasAccount: false, - hasPasscode: false, - }), - }), - api: { - hasSession: false, - user: undefined, - registering: false, - authenticating: false, - changing: false, - refreshingSession: false, - filesHost: undefined, - host: 'localhost', - }, - session: { - isSessionRenewChallengePresented: false, - online: false, - offline: true, - isSignedIn: false, - isSignedIntoFirstPartyServer: false, - }, - sync: { - syncToken: undefined, - cursorToken: undefined, - lastSyncDate: undefined, - outOfSync: false, - completedOnlineDownloadFirstSync: false, - clientLocked: false, - databaseLoaded: false, - syncLock: false, - dealloced: false, - itemsNeedingSync: [], - itemsNeedingSyncCount: 0, - pendingRequestCount: 0, - }, - protections: expect.objectContaining({ - getLastSessionLength: undefined, - hasProtectionSources: false, - hasUnprotectedAccessSession: true, - hasBiometricsEnabled: false, - }), - keyRecovery: { queueLength: 0, isProcessingQueue: false }, - features: { - roles: [], - features: [], - enabledExperimentalFeatures: [], - needsInitialFeaturesUpdate: true, - completedSuccessfulFeaturesRetrieval: false, - }, - migrations: { activeMigrations: [] }, - }), - ) - }) -}) diff --git a/packages/snjs/lib/Application/Application.ts b/packages/snjs/lib/Application/Application.ts index c2d698eaf..b57f2c4e2 100644 --- a/packages/snjs/lib/Application/Application.ts +++ b/packages/snjs/lib/Application/Application.ts @@ -1079,15 +1079,6 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli return this.userService.changePasscode(newPasscode, origination) } - public getStorageEncryptionPolicy(): ExternalServices.StorageEncryptionPolicy { - return this.diskStorageService.getStorageEncryptionPolicy() - } - - public setStorageEncryptionPolicy(encryptionPolicy: ExternalServices.StorageEncryptionPolicy): Promise { - this.diskStorageService.setEncryptionPolicy(encryptionPolicy) - return this.protocolService.repersistAllItems() - } - public enableEphemeralPersistencePolicy(): Promise { return this.diskStorageService.setPersistencePolicy(ExternalServices.StoragePersistencePolicies.Ephemeral) } @@ -1527,7 +1518,6 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli this.diskStorageService = new InternalServices.DiskStorageService( this.deviceInterface, this.identifier, - this.environment, this.internalEventBus, ) this.services.push(this.diskStorageService) diff --git a/packages/snjs/lib/Services/Storage/DiskStorageService.spec.ts b/packages/snjs/lib/Services/Storage/DiskStorageService.spec.ts index 8ed72ac2c..e5a9da605 100644 --- a/packages/snjs/lib/Services/Storage/DiskStorageService.spec.ts +++ b/packages/snjs/lib/Services/Storage/DiskStorageService.spec.ts @@ -1,7 +1,5 @@ import { DiskStorageService } from './DiskStorageService' - import { InternalEventBus, DeviceInterface, InternalEventBusInterface } from '@standardnotes/services' -import { Environment } from '@standardnotes/models' describe('diskStorageService', () => { let storageService: DiskStorageService @@ -12,7 +10,7 @@ describe('diskStorageService', () => { internalEventBus = {} as jest.Mocked device = {} as jest.Mocked - storageService = new DiskStorageService(device, 'test', Environment.Desktop, internalEventBus) + storageService = new DiskStorageService(device, 'test', internalEventBus) }) it('setInitialValues should set unwrapped values as wrapped value if wrapped value is not encrypted', async () => { diff --git a/packages/snjs/lib/Services/Storage/DiskStorageService.ts b/packages/snjs/lib/Services/Storage/DiskStorageService.ts index 25bb88581..e7e77b771 100644 --- a/packages/snjs/lib/Services/Storage/DiskStorageService.ts +++ b/packages/snjs/lib/Services/Storage/DiskStorageService.ts @@ -19,7 +19,6 @@ import { DeletedPayloadInterface, PayloadTimestampDefaults, LocalStorageEncryptedContextualPayload, - Environment, FullyFormedTransferPayload, } from '@standardnotes/models' @@ -37,7 +36,6 @@ export class DiskStorageService extends Services.AbstractService implements Serv private encryptionProvider!: Encryption.EncryptionProviderInterface private storagePersistable = false private persistencePolicy!: Services.StoragePersistencePolicies - private encryptionPolicy!: Services.StorageEncryptionPolicy private needsPersist = false private currentPersistPromise?: Promise @@ -46,12 +44,10 @@ export class DiskStorageService extends Services.AbstractService implements Serv constructor( private deviceInterface: Services.DeviceInterface, private identifier: string, - private environment: Environment, protected override internalEventBus: Services.InternalEventBusInterface, ) { super(internalEventBus) void this.setPersistencePolicy(Services.StoragePersistencePolicies.Default) - void this.setEncryptionPolicy(Services.StorageEncryptionPolicy.Default, false) } public provideEncryptionProvider(provider: Encryption.EncryptionProviderInterface): void { @@ -73,11 +69,6 @@ export class DiskStorageService extends Services.AbstractService implements Serv if (this.needsPersist) { void this.persistValuesToDisk() } - } else if (stage === Services.ApplicationStage.StorageDecrypted_09) { - const persistedPolicy = await this.getValue(Services.StorageKey.StorageEncryptionPolicy) - if (persistedPolicy) { - void this.setEncryptionPolicy(persistedPolicy as Services.StorageEncryptionPolicy, false) - } } } @@ -90,21 +81,6 @@ export class DiskStorageService extends Services.AbstractService implements Serv } } - public setEncryptionPolicy(encryptionPolicy: Services.StorageEncryptionPolicy, persist = true): void { - if ( - encryptionPolicy === Services.StorageEncryptionPolicy.Disabled && - ![Environment.Mobile].includes(this.environment) - ) { - throw Error('Disabling storage encryption is only available on mobile.') - } - - this.encryptionPolicy = encryptionPolicy - - if (persist) { - this.setValue(Services.StorageKey.StorageEncryptionPolicy, encryptionPolicy) - } - } - public isEphemeralSession() { return this.persistencePolicy === Services.StoragePersistencePolicies.Ephemeral } @@ -329,10 +305,6 @@ export class DiskStorageService extends Services.AbstractService implements Serv } } - public getStorageEncryptionPolicy() { - return this.encryptionPolicy - } - /** * Default persistence key. Platforms can override as needed. */ @@ -393,36 +365,29 @@ export class DiskStorageService extends Services.AbstractService implements Serv const { encrypted, decrypted, deleted, discardable } = CreatePayloadSplitWithDiscardables(payloads) - const encryptionEnabled = this.encryptionPolicy === Services.StorageEncryptionPolicy.Default const rootKeyEncryptionAvailable = this.encryptionProvider.hasRootKeyEncryptionSource() const encryptable: DecryptedPayloadInterface[] = [] const unencryptable: DecryptedPayloadInterface[] = [] - if (encryptionEnabled) { - const split = Encryption.SplitPayloadsByEncryptionType(decrypted) + const split = Encryption.SplitPayloadsByEncryptionType(decrypted) + if (split.itemsKeyEncryption) { + extendArray(encryptable, split.itemsKeyEncryption) + } - if (split.itemsKeyEncryption) { - extendArray(encryptable, split.itemsKeyEncryption) + if (split.rootKeyEncryption) { + if (!rootKeyEncryptionAvailable) { + extendArray(unencryptable, split.rootKeyEncryption) + } else { + extendArray(encryptable, split.rootKeyEncryption) } - - if (split.rootKeyEncryption) { - if (!rootKeyEncryptionAvailable) { - extendArray(unencryptable, split.rootKeyEncryption) - } else { - extendArray(encryptable, split.rootKeyEncryption) - } - } - } else { - extendArray(unencryptable, encryptable) - extendArray(unencryptable, decrypted) } await this.deletePayloads(discardable) - const split = Encryption.SplitPayloadsByEncryptionType(encryptable) + const encryptableSplit = Encryption.SplitPayloadsByEncryptionType(encryptable) - const keyLookupSplit = Encryption.CreateEncryptionSplitWithKeyLookup(split) + const keyLookupSplit = Encryption.CreateEncryptionSplitWithKeyLookup(encryptableSplit) const encryptedResults = await this.encryptionProvider.encryptSplit(keyLookupSplit) @@ -478,7 +443,6 @@ export class DiskStorageService extends Services.AbstractService implements Serv storage: { storagePersistable: this.storagePersistable, persistencePolicy: Services.StoragePersistencePolicies[this.persistencePolicy], - encryptionPolicy: Services.StorageEncryptionPolicy[this.encryptionPolicy], needsPersist: this.needsPersist, currentPersistPromise: this.currentPersistPromise != undefined, isStorageWrapped: this.isStorageWrapped(), diff --git a/packages/snjs/mocha/storage.test.js b/packages/snjs/mocha/storage.test.js index 38fb680f7..1a3a39bc6 100644 --- a/packages/snjs/mocha/storage.test.js +++ b/packages/snjs/mocha/storage.test.js @@ -223,28 +223,6 @@ describe('storage manager', function () { expect(decrypted.content).to.be.an.instanceof(Object) }) - /** @TODO: Storage encryption disable is no longer available, remove tests and associated functionality */ - it.skip('disabling storage encryption should store items without encryption', async function () { - await Factory.registerUserToApplication({ - application: this.application, - email: this.email, - password: this.password, - ephemeral: false, - }) - - await this.application.setStorageEncryptionPolicy(StorageEncryptionPolicy.Disabled) - - const payloads = await this.application.diskStorageService.getAllRawPayloads() - const payload = payloads[0] - expect(typeof payload.content).to.not.equal('string') - expect(payload.content.references).to.be.ok - - const identifier = this.application.identifier - - const app = await Factory.createAndInitializeApplication(identifier, Environment.Mobile) - expect(app.diskStorageService.encryptionPolicy).to.equal(StorageEncryptionPolicy.Disabled) - }) - it('stored payloads should not contain metadata fields', async function () { await this.application.addPasscode('123') await Factory.createSyncedNote(this.application) diff --git a/packages/snjs/package.json b/packages/snjs/package.json index 3d4430d57..d60b3d7d8 100644 --- a/packages/snjs/package.json +++ b/packages/snjs/package.json @@ -29,7 +29,7 @@ "lint:eslint": "eslint --ext .ts lib/", "lint:fix": "eslint --fix --ext .ts lib/", "lint:tsc": "tsc --noEmit --emitDeclarationOnly false --project lib/tsconfig.json", - "test": "jest --coverage", + "test": "jest", "test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand" }, "devDependencies": {