chore: remove phased out storage encryption policy (#2323)
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<PureCryptoInterface>
|
||||
crypto.initialize = jest.fn()
|
||||
|
||||
device = {} as jest.Mocked<DeviceInterface>
|
||||
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<AlertService>,
|
||||
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: [] },
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -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<void> {
|
||||
this.diskStorageService.setEncryptionPolicy(encryptionPolicy)
|
||||
return this.protocolService.repersistAllItems()
|
||||
}
|
||||
|
||||
public enableEphemeralPersistencePolicy(): Promise<void> {
|
||||
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)
|
||||
|
||||
@@ -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<InternalEventBus>
|
||||
device = {} as jest.Mocked<DeviceInterface>
|
||||
|
||||
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 () => {
|
||||
|
||||
@@ -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<Services.StorageValuesObject>
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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": {
|
||||
|
||||
Reference in New Issue
Block a user