Use same lock values as mobile clients
[ProtonMail-WebClient.git] / packages / docs-core / lib / UseCase / SeedInitialCommit.ts
blob3fb05a3fe466307448b1d2bf3df62d67355d3013
1 import { CommitVersion, DocumentUpdateVersion, CreateDocumentUpdate, CreateCommit } from '@proton/docs-proto'
2 import type { UseCaseInterface } from '../Domain/UseCase/UseCaseInterface'
3 import { Result } from '../Domain/Result/Result'
4 import type { DocsApi } from '../Api/DocsApi'
5 import type { EncryptMessage } from './EncryptMessage'
6 import type { DocumentKeys } from '@proton/drive-store'
7 import type { DocumentMetaInterface } from '@proton/docs-shared'
8 import { GenerateUUID } from '../Util/GenerateUuid'
10 type SeedInitialCommitResult = { commitId: string; linkId: string; volumeId: string }
12 /**
13  * Allows the client to create an initial commit. This used by the Duplicate function to allow us to seed the document
14  * with an initial commit value equaling the source document's.
15  */
16 export class SeedInitialCommit implements UseCaseInterface<SeedInitialCommitResult> {
17   constructor(
18     private docsApi: DocsApi,
19     private encryptMessage: EncryptMessage,
20   ) {}
22   async execute(
23     docMeta: Pick<DocumentMetaInterface, 'volumeId' | 'linkId'>,
24     state: Uint8Array,
25     keys: DocumentKeys,
26   ): Promise<Result<SeedInitialCommitResult>> {
27     const metadata = {
28       version: DocumentUpdateVersion.V1,
29       authorAddress: keys.userOwnAddress,
30       timestamp: Date.now(),
31     }
32     const encryptedUpdate = await this.encryptMessage.execute(state, metadata, keys)
33     if (encryptedUpdate.isFailed()) {
34       return Result.fail<SeedInitialCommitResult>(encryptedUpdate.getError())
35     }
37     const update = CreateDocumentUpdate({
38       content: encryptedUpdate.getValue(),
39       authorAddress: metadata.authorAddress,
40       timestamp: metadata.timestamp,
41       version: metadata.version,
42       uuid: GenerateUUID(),
43     })
45     const commit = CreateCommit({
46       updates: [update],
47       version: CommitVersion.V1,
48       lockId: '',
49     })
51     const commitResult = await this.docsApi.seedInitialCommit(docMeta, commit)
53     if (commitResult.isFailed()) {
54       return Result.fail(commitResult.getError())
55     }
57     const { CommitID: commitId, VolumeID: volumeId, LinkID: linkId } = commitResult.getValue()
59     return Result.ok<SeedInitialCommitResult>({ commitId, volumeId, linkId })
60   }