internal: incomplete vault systems behind feature flag (#2340)

This commit is contained in:
Mo
2023-06-30 09:01:56 -05:00
committed by GitHub
parent d16e401bb9
commit b032eb9c9b
638 changed files with 20321 additions and 4813 deletions

View File

@@ -6,4 +6,9 @@ export interface ContextPayload<C extends ItemContent = ItemContent> {
content_type: ContentType
content: C | string | undefined
deleted: boolean
user_uuid?: string
key_system_identifier?: string | undefined
shared_vault_uuid?: string | undefined
last_edited_by_uuid?: string
}

View File

@@ -5,7 +5,7 @@ export interface FilteredServerItem extends ServerItemResponse {
__passed_filter__: true
}
export function CreateFilteredServerItem(item: ServerItemResponse): FilteredServerItem {
function CreateFilteredServerItem(item: ServerItemResponse): FilteredServerItem {
return {
...item,
__passed_filter__: true,

View File

@@ -19,6 +19,8 @@ export function CreateEncryptedBackupFileContextPayload(
updated_at_timestamp: fromPayload.updated_at_timestamp,
updated_at: fromPayload.updated_at,
uuid: fromPayload.uuid,
key_system_identifier: fromPayload.key_system_identifier,
shared_vault_uuid: fromPayload.shared_vault_uuid,
}
}
@@ -35,5 +37,7 @@ export function CreateDecryptedBackupFileContextPayload(
updated_at_timestamp: fromPayload.updated_at_timestamp,
updated_at: fromPayload.updated_at,
uuid: fromPayload.uuid,
key_system_identifier: fromPayload.key_system_identifier,
shared_vault_uuid: fromPayload.shared_vault_uuid,
}
}

View File

@@ -3,6 +3,7 @@ import { ItemContent } from '../Content/ItemContent'
import { DecryptedPayloadInterface, DeletedPayloadInterface, EncryptedPayloadInterface } from '../Payload'
import { useBoolean } from '@standardnotes/utils'
import { EncryptedTransferPayload, isEncryptedTransferPayload } from '../TransferPayload'
import { PersistentSignatureData } from '../../Runtime/Encryption/PersistentSignatureData'
export function isEncryptedLocalStoragePayload(
p: LocalStorageEncryptedContextualPayload | LocalStorageDecryptedContextualPayload,
@@ -25,6 +26,7 @@ export interface LocalStorageEncryptedContextualPayload extends ContextPayload {
updated_at_timestamp: number
updated_at: Date
waitingForKey: boolean
signatureData?: PersistentSignatureData
}
export interface LocalStorageDecryptedContextualPayload<C extends ItemContent = ItemContent> extends ContextPayload {
@@ -36,6 +38,7 @@ export interface LocalStorageDecryptedContextualPayload<C extends ItemContent =
duplicate_of?: string
updated_at_timestamp: number
updated_at: Date
signatureData?: PersistentSignatureData
}
export interface LocalStorageDeletedContextualPayload extends ContextPayload {
@@ -47,6 +50,7 @@ export interface LocalStorageDeletedContextualPayload extends ContextPayload {
duplicate_of?: string
updated_at_timestamp: number
updated_at: Date
signatureData?: PersistentSignatureData
}
export function CreateEncryptedLocalStorageContextPayload(
@@ -68,6 +72,11 @@ export function CreateEncryptedLocalStorageContextPayload(
updated_at: fromPayload.updated_at,
uuid: fromPayload.uuid,
waitingForKey: fromPayload.waitingForKey,
user_uuid: fromPayload.user_uuid,
key_system_identifier: fromPayload.key_system_identifier,
shared_vault_uuid: fromPayload.shared_vault_uuid,
last_edited_by_uuid: fromPayload.last_edited_by_uuid,
signatureData: fromPayload.signatureData,
}
}
@@ -85,6 +94,11 @@ export function CreateDecryptedLocalStorageContextPayload(
updated_at: fromPayload.updated_at,
uuid: fromPayload.uuid,
dirty: useBoolean(fromPayload.dirty, false),
user_uuid: fromPayload.user_uuid,
key_system_identifier: fromPayload.key_system_identifier,
shared_vault_uuid: fromPayload.shared_vault_uuid,
last_edited_by_uuid: fromPayload.last_edited_by_uuid,
signatureData: fromPayload.signatureData,
}
}
@@ -102,5 +116,10 @@ export function CreateDeletedLocalStorageContextPayload(
updated_at_timestamp: fromPayload.updated_at_timestamp,
updated_at: fromPayload.updated_at,
uuid: fromPayload.uuid,
user_uuid: fromPayload.user_uuid,
key_system_identifier: fromPayload.key_system_identifier,
shared_vault_uuid: fromPayload.shared_vault_uuid,
last_edited_by_uuid: fromPayload.last_edited_by_uuid,
signatureData: fromPayload.signatureData,
}
}

View File

@@ -29,6 +29,8 @@ export function CreateEncryptedServerSyncPushPayload(
enc_item_key: fromPayload.enc_item_key,
items_key_id: fromPayload.items_key_id,
auth_hash: fromPayload.auth_hash,
key_system_identifier: fromPayload.key_system_identifier,
shared_vault_uuid: fromPayload.shared_vault_uuid,
}
}
@@ -45,5 +47,7 @@ export function CreateDeletedServerSyncPushPayload(
updated_at: fromPayload.updated_at,
uuid: fromPayload.uuid,
content: undefined,
key_system_identifier: fromPayload.key_system_identifier,
shared_vault_uuid: fromPayload.shared_vault_uuid,
}
}

View File

@@ -16,6 +16,11 @@ export interface ServerSyncSavedContextualPayload {
updated_at_timestamp: number
updated_at: Date
uuid: string
key_system_identifier: string | undefined
shared_vault_uuid: string | undefined
user_uuid: string
duplicate_of?: string
last_edited_by_uuid?: string
}
export function CreateServerSyncSavedPayload(from: FilteredServerItem): ServerSyncSavedContextualPayload {
@@ -27,5 +32,10 @@ export function CreateServerSyncSavedPayload(from: FilteredServerItem): ServerSy
updated_at_timestamp: from.updated_at_timestamp,
updated_at: from.updated_at,
uuid: from.uuid,
key_system_identifier: from.key_system_identifier,
shared_vault_uuid: from.shared_vault_uuid,
user_uuid: from.user_uuid,
duplicate_of: from.duplicate_of,
last_edited_by_uuid: from.last_edited_by_uuid,
}
}

View File

@@ -0,0 +1,4 @@
import { ConflictParams } from '@standardnotes/responses'
import { FilteredServerItem } from './FilteredServerItem'
export type TrustedConflictParams = ConflictParams<FilteredServerItem>

View File

@@ -50,7 +50,7 @@ export class DecryptedItem<C extends ItemContent = ItemContent>
return this.payload.content.references || []
}
public isReferencingItem(item: DecryptedItemInterface): boolean {
public isReferencingItem(item: { uuid: string }): boolean {
return this.references.find((r) => r.uuid === item.uuid) != undefined
}

View File

@@ -10,6 +10,7 @@ import { SingletonStrategy } from '../Types/SingletonStrategy'
import { PayloadInterface } from '../../Payload/Interfaces/PayloadInterface'
import { HistoryEntryInterface } from '../../../Runtime/History/HistoryEntryInterface'
import { isDecryptedItem, isDeletedItem, isEncryptedErroredItem } from '../Interfaces/TypeCheck'
import { PersistentSignatureData } from '../../../Runtime/Encryption/PersistentSignatureData'
export abstract class GenericItem<P extends PayloadInterface = PayloadInterface> implements ItemInterface<P> {
payload: P
@@ -43,6 +44,26 @@ export abstract class GenericItem<P extends PayloadInterface = PayloadInterface>
return this.payload.created_at
}
get key_system_identifier(): string | undefined {
return this.payload.key_system_identifier
}
get user_uuid(): string | undefined {
return this.payload.user_uuid
}
get shared_vault_uuid(): string | undefined {
return this.payload.shared_vault_uuid
}
get last_edited_by_uuid(): string | undefined {
return this.payload.last_edited_by_uuid
}
get signatureData(): PersistentSignatureData | undefined {
return this.payload.signatureData
}
/**
* The date timestamp the server set for this item upon it being synced
* Undefined if never synced to a remote server.

View File

@@ -33,7 +33,7 @@ export interface DecryptedItemInterface<C extends ItemContent = ItemContent>
payloadRepresentation(override?: Partial<DecryptedTransferPayload<C>>): DecryptedPayloadInterface<C>
isReferencingItem(item: DecryptedItemInterface): boolean
isReferencingItem(item: { uuid: string }): boolean
getDomainData(domain: typeof ComponentDataDomain | typeof DefaultAppDomain): undefined | Record<string, unknown>

View File

@@ -5,6 +5,7 @@ import { PredicateInterface } from '../../../Runtime/Predicate/Interface'
import { HistoryEntryInterface } from '../../../Runtime/History'
import { ConflictStrategy } from '../Types/ConflictStrategy'
import { SingletonStrategy } from '../Types/SingletonStrategy'
import { PersistentSignatureData } from '../../../Runtime/Encryption/PersistentSignatureData'
export interface ItemInterface<P extends PayloadInterface = PayloadInterface> {
payload: P
@@ -14,6 +15,11 @@ export interface ItemInterface<P extends PayloadInterface = PayloadInterface> {
readonly updatedAtString?: string
uuid: string
get key_system_identifier(): string | undefined
get user_uuid(): string | undefined
get shared_vault_uuid(): string | undefined
get last_edited_by_uuid(): string | undefined
get signatureData(): PersistentSignatureData | undefined
content_type: ContentType
created_at: Date

View File

@@ -10,13 +10,13 @@ import { DecryptedPayloadInterface } from '../../Payload/Interfaces/DecryptedPay
import { ItemInterface } from '../Interfaces/ItemInterface'
import { getIncrementedDirtyIndex } from '../../../Runtime/DirtyCounter/DirtyCounter'
export class DecryptedItemMutator<C extends ItemContent = ItemContent> extends ItemMutator<
DecryptedPayloadInterface<C>,
DecryptedItemInterface<C>
> {
export class DecryptedItemMutator<
C extends ItemContent = ItemContent,
I extends DecryptedItemInterface<C> = DecryptedItemInterface<C>,
> extends ItemMutator<DecryptedPayloadInterface<C>, I> {
protected mutableContent: C
constructor(item: DecryptedItemInterface<C>, type: MutationType) {
constructor(item: I, type: MutationType) {
super(item, type)
const mutableCopy = Copy(this.immutablePayload.content)
@@ -43,6 +43,8 @@ export class DecryptedItemMutator<C extends ItemContent = ItemContent> extends I
content: this.mutableContent,
dirty: true,
dirtyIndex: getIncrementedDirtyIndex(),
signatureData: undefined,
last_edited_by_uuid: undefined,
})
return result

View File

@@ -3,6 +3,8 @@ import { PayloadInterface } from '../../Payload'
import { ItemInterface } from '../Interfaces/ItemInterface'
import { TransferPayload } from '../../TransferPayload'
import { getIncrementedDirtyIndex } from '../../../Runtime/DirtyCounter/DirtyCounter'
import { KeySystemIdentifier } from '../../../Syncable/KeySystemRootKey/KeySystemIdentifier'
import { ContentTypeUsesRootKeyEncryption } from '../../../Runtime/Encryption/ContentTypeUsesRootKeyEncryption'
/**
* An item mutator takes in an item, and an operation, and returns the resulting payload.
@@ -51,6 +53,26 @@ export class ItemMutator<
})
}
public set key_system_identifier(keySystemIdentifier: KeySystemIdentifier | undefined) {
if (ContentTypeUsesRootKeyEncryption(this.immutableItem.content_type)) {
throw new Error('Cannot set key_system_identifier on a root key encrypted item')
}
this.immutablePayload = this.immutablePayload.copy({
key_system_identifier: keySystemIdentifier,
})
}
public set shared_vault_uuid(sharedVaultUuid: string | undefined) {
if (ContentTypeUsesRootKeyEncryption(this.immutableItem.content_type)) {
throw new Error('Cannot set shared_vault_uuid on a root key encrypted item')
}
this.immutablePayload = this.immutablePayload.copy({
shared_vault_uuid: sharedVaultUuid,
})
}
public set errorDecrypting(_: boolean) {
throw Error('This method is no longer implemented')
}

View File

@@ -5,6 +5,8 @@ import { PayloadSource } from '../Types/PayloadSource'
import { TransferPayload } from '../../TransferPayload/Interfaces/TransferPayload'
import { ItemContent } from '../../Content/ItemContent'
import { SyncResolvedParams, SyncResolvedPayload } from '../../../Runtime/Deltas/Utilities/SyncResolvedPayload'
import { PersistentSignatureData } from '../../../Runtime/Encryption/PersistentSignatureData'
import { ContentTypeUsesRootKeyEncryption } from '../../../Runtime/Encryption/ContentTypeUsesRootKeyEncryption'
type RequiredKeepUndefined<T> = { [K in keyof T]-?: [T[K]] } extends infer U
? U extends Record<keyof U, [unknown]>
@@ -33,18 +35,28 @@ export abstract class PurePayload<T extends TransferPayload<C>, C extends ItemCo
readonly lastSyncEnd?: Date
readonly duplicate_of?: string
readonly user_uuid?: string
readonly key_system_identifier?: string | undefined
readonly shared_vault_uuid?: string | undefined
readonly last_edited_by_uuid?: string
readonly signatureData?: PersistentSignatureData
constructor(rawPayload: T, source = PayloadSource.Constructor) {
this.source = source
this.uuid = rawPayload.uuid
if (!this.uuid) {
if (!rawPayload.uuid) {
throw Error(
`Attempting to construct payload with null uuid
Content type: ${rawPayload.content_type}`,
)
}
if (rawPayload.key_system_identifier && ContentTypeUsesRootKeyEncryption(rawPayload.content_type)) {
throw new Error('Rootkey-encrypted payload should not have a key system identifier')
}
this.source = source
this.uuid = rawPayload.uuid
this.content = rawPayload.content
this.content_type = rawPayload.content_type
this.deleted = useBoolean(rawPayload.deleted, false)
@@ -63,6 +75,13 @@ export abstract class PurePayload<T extends TransferPayload<C>, C extends ItemCo
this.dirtyIndex = rawPayload.dirtyIndex
this.globalDirtyIndexAtLastSync = rawPayload.globalDirtyIndexAtLastSync
this.user_uuid = rawPayload.user_uuid ?? undefined
this.key_system_identifier = rawPayload.key_system_identifier ?? undefined
this.shared_vault_uuid = rawPayload.shared_vault_uuid ?? undefined
this.last_edited_by_uuid = rawPayload.last_edited_by_uuid ?? undefined
this.signatureData = rawPayload.signatureData
const timeToAllowSubclassesToFinishConstruction = 0
setTimeout(() => {
deepFreeze(this)
@@ -85,6 +104,11 @@ export abstract class PurePayload<T extends TransferPayload<C>, C extends ItemCo
globalDirtyIndexAtLastSync: this.globalDirtyIndexAtLastSync,
lastSyncBegan: this.lastSyncBegan,
lastSyncEnd: this.lastSyncEnd,
key_system_identifier: this.key_system_identifier,
user_uuid: this.user_uuid,
shared_vault_uuid: this.shared_vault_uuid,
last_edited_by_uuid: this.last_edited_by_uuid,
signatureData: this.signatureData,
}
return comprehensive

View File

@@ -3,6 +3,7 @@ import { ContentType } from '@standardnotes/common'
import { ItemContent } from '../../Content/ItemContent'
import { TransferPayload } from '../../TransferPayload/Interfaces/TransferPayload'
import { PayloadSource } from '../Types/PayloadSource'
import { PersistentSignatureData } from '../../../Runtime/Encryption/PersistentSignatureData'
export interface PayloadInterface<T extends TransferPayload = TransferPayload, C extends ItemContent = ItemContent> {
readonly source: PayloadSource
@@ -22,12 +23,18 @@ export interface PayloadInterface<T extends TransferPayload = TransferPayload, C
readonly dirtyIndex?: number
readonly globalDirtyIndexAtLastSync?: number
readonly dirty?: boolean
readonly signatureData?: PersistentSignatureData
readonly lastSyncBegan?: Date
readonly lastSyncEnd?: Date
readonly duplicate_of?: string
readonly user_uuid?: string
readonly key_system_identifier?: string | undefined
readonly shared_vault_uuid?: string | undefined
readonly last_edited_by_uuid?: string
/**
* "Ejected" means a payload for
* generic, non-contextual consumption, such as saving to a backup file or syncing

View File

@@ -0,0 +1,15 @@
import { PayloadInterface } from './../Interfaces/PayloadInterface'
import { VaultListingInterface } from '../../../Syncable/VaultListing/VaultListingInterface'
export function PayloadVaultOverrides(
vault: VaultListingInterface | undefined,
): Pick<PayloadInterface, 'key_system_identifier' | 'shared_vault_uuid'> {
if (!vault) {
return {}
}
return {
key_system_identifier: vault.systemIdentifier,
shared_vault_uuid: vault.isSharedVaultListing() ? vault.sharing.sharedVaultUuid : undefined,
}
}

View File

@@ -5,6 +5,8 @@ export enum PayloadSource {
*/
Constructor = 1,
LocalDatabaseLoaded = 2,
RemoteRetrieved,
RemoteSaved,

View File

@@ -10,4 +10,5 @@ export * from './Interfaces/TypeCheck'
export * from './Interfaces/UnionTypes'
export * from './Types/PayloadSource'
export * from './Types/EmitSource'
export * from './Types/TimestampDefaults'
export * from './Overrides/TimestampDefaults'
export * from './Overrides/VaultOverride'

View File

@@ -1,5 +1,6 @@
import { ContentType } from '@standardnotes/common'
import { ItemContent } from '../../Content/ItemContent'
import { PersistentSignatureData } from '../../../Runtime/Encryption/PersistentSignatureData'
export interface TransferPayload<C extends ItemContent = ItemContent> {
uuid: string
@@ -15,9 +16,16 @@ export interface TransferPayload<C extends ItemContent = ItemContent> {
dirtyIndex?: number
globalDirtyIndexAtLastSync?: number
dirty?: boolean
signatureData?: PersistentSignatureData
lastSyncBegan?: Date
lastSyncEnd?: Date
duplicate_of?: string
user_uuid?: string
key_system_identifier?: string | undefined
shared_vault_uuid?: string | undefined
last_edited_by_uuid?: string
}