feat(snjs): add revisions api v2 (#2154)

* feat(snjs): add revisions api v2

* fix(snjs): reference listing and getting revisions in specs

* fix(snjs): revisions specs

* fix(web): usage of revision metadata

* fix(snjs): add specs for decryption revision

* fix(snjs): issue with building mocked specs

* fix(snjs): adjust revision creation delay
This commit is contained in:
Karol Sójko
2023-01-18 09:20:06 +01:00
committed by GitHub
parent 7d7815917b
commit 880a537774
52 changed files with 882 additions and 226 deletions

View File

@@ -0,0 +1,28 @@
import { Uuid } from '@standardnotes/domain-core'
export interface RevisionClientInterface {
listRevisions(itemUuid: Uuid): Promise<
Array<{
uuid: string
content_type: string
created_at: string
updated_at: string
required_role: string
}>
>
deleteRevision(itemUuid: Uuid, revisionUuid: Uuid): Promise<string>
getRevision(
itemUuid: Uuid,
revisionUuid: Uuid,
): Promise<{
uuid: string
item_uuid: string
content: string | null
content_type: string
items_key_id: string | null
enc_item_key: string | null
auth_hash: string | null
created_at: string
updated_at: string
} | null>
}

View File

@@ -0,0 +1,72 @@
import { RevisionApiServiceInterface } from '@standardnotes/api'
import { Uuid } from '@standardnotes/domain-core'
import { InternalEventBusInterface } from '../Internal/InternalEventBusInterface'
import { AbstractService } from '../Service/AbstractService'
import { RevisionClientInterface } from './RevisionClientInterface'
export class RevisionManager extends AbstractService implements RevisionClientInterface {
constructor(
private revisionApiService: RevisionApiServiceInterface,
protected override internalEventBus: InternalEventBusInterface,
) {
super(internalEventBus)
}
async listRevisions(
itemUuid: Uuid,
): Promise<{ uuid: string; content_type: string; created_at: string; updated_at: string; required_role: string }[]> {
try {
const result = await this.revisionApiService.listRevisions(itemUuid.value)
if (result.data.error) {
return []
}
return result.data.revisions
} catch (error) {
return []
}
}
async deleteRevision(itemUuid: Uuid, revisionUuid: Uuid): Promise<string> {
try {
const result = await this.revisionApiService.deleteRevision(itemUuid.value, revisionUuid.value)
if (result.data.error) {
return result.data.error.message
}
return result.data.message
} catch (error) {
return 'An error occurred while deleting the revision.'
}
}
async getRevision(
itemUuid: Uuid,
revisionUuid: Uuid,
): Promise<{
uuid: string
item_uuid: string
content: string | null
content_type: string
items_key_id: string | null
enc_item_key: string | null
auth_hash: string | null
created_at: string
updated_at: string
} | null> {
try {
const result = await this.revisionApiService.getRevision(itemUuid.value, revisionUuid.value)
if (result.data.error) {
return null
}
return result.data.revision
} catch (error) {
return null
}
}
}

View File

@@ -42,8 +42,6 @@ export const API_MESSAGE_FAILED_SUBSCRIPTION_INFO = "Failed to get subscription'
export const API_MESSAGE_FAILED_ACCESS_PURCHASE = 'Failed to access purchase flow.'
export const API_MESSAGE_FAILED_DELETE_REVISION = 'Failed to delete revision.'
export const API_MESSAGE_FAILED_OFFLINE_FEATURES = 'Failed to get offline features.'
export const API_MESSAGE_UNTRUSTED_EXTENSIONS_WARNING = `The extension you are attempting to install comes from an
untrusted source. Untrusted extensions may lower the security of your data. Do you want to continue?`

View File

@@ -68,6 +68,8 @@ export * from './Preferences/PreferenceServiceInterface'
export * from './Protection/MobileUnlockTiming'
export * from './Protection/ProtectionClientInterface'
export * from './Protection/TimingDisplayOption'
export * from './Revision/RevisionClientInterface'
export * from './Revision/RevisionManager'
export * from './Service/AbstractService'
export * from './Service/ServiceInterface'
export * from './Session/SessionManagerResponse'