feat(api): add keyshare initiation for workspaces

This commit is contained in:
Karol Sójko
2022-10-12 14:05:11 +02:00
parent 3fbbacfc25
commit fabce1f7ac
15 changed files with 179 additions and 0 deletions

View File

@@ -4,4 +4,5 @@ export enum WorkspaceApiOperations {
Accepting,
ListingWorkspaces,
ListingWorkspaceUsers,
InitiatingKeyshare,
}

View File

@@ -1,4 +1,5 @@
import { WorkspaceAccessLevel, WorkspaceType } from '@standardnotes/common'
import { HttpStatusCode } from '../../Http'
import { WorkspaceCreationResponse } from '../../Response/Workspace/WorkspaceCreationResponse'
import { WorkspaceInvitationAcceptingResponse } from '../../Response/Workspace/WorkspaceInvitationAcceptingResponse'
@@ -6,6 +7,7 @@ import { WorkspaceInvitationResponse } from '../../Response/Workspace/WorkspaceI
import { WorkspaceListResponse } from '../../Response/Workspace/WorkspaceListResponse'
import { WorkspaceUserListResponse } from '../../Response/Workspace/WorkspaceUserListResponse'
import { WorkspaceServerInterface } from '../../Server/Workspace/WorkspaceServerInterface'
import { WorkspaceKeyshareInitiatingResponse } from '../../Response/Workspace/WorkspaceKeyshareInitiatingResponse'
import { WorkspaceApiOperations } from './WorkspaceApiOperations'
import { WorkspaceApiService } from './WorkspaceApiService'
@@ -34,6 +36,10 @@ describe('WorkspaceApiService', () => {
status: HttpStatusCode.Success,
data: { users: [] },
} as jest.Mocked<WorkspaceUserListResponse>)
workspaceServer.initiateKeyshare = jest.fn().mockReturnValue({
status: HttpStatusCode.Success,
data: { success: true },
} as jest.Mocked<WorkspaceKeyshareInitiatingResponse>)
})
it('should create a workspace', async () => {
@@ -304,4 +310,59 @@ describe('WorkspaceApiService', () => {
expect(error).not.toBeNull()
})
it('should initiate keyshare in workspace for user', async () => {
const response = await createService().initiateKeyshare({
workspaceUuid: 'w-1-2-3',
userUuid: 'u-1-2-3',
encryptedWorkspaceKey: 'foobar',
})
expect(response).toEqual({
status: 200,
data: {
success: true,
},
})
expect(workspaceServer.initiateKeyshare).toHaveBeenCalledWith({
workspaceUuid: 'w-1-2-3',
userUuid: 'u-1-2-3',
encryptedWorkspaceKey: 'foobar',
})
})
it('should not initiate keyshare in workspace if it is already initiating', async () => {
const service = createService()
Object.defineProperty(service, 'operationsInProgress', {
get: () => new Map([[WorkspaceApiOperations.InitiatingKeyshare, true]]),
})
let error = null
try {
await service.initiateKeyshare({ workspaceUuid: 'w-1-2-3', userUuid: 'u-1-2-3', encryptedWorkspaceKey: 'foobar' })
} catch (caughtError) {
error = caughtError
}
expect(error).not.toBeNull()
})
it('should not initiate keyshare in workspace if the server fails', async () => {
workspaceServer.initiateKeyshare = jest.fn().mockImplementation(() => {
throw new Error('Oops')
})
let error = null
try {
await createService().initiateKeyshare({
workspaceUuid: 'w-1-2-3',
userUuid: 'u-1-2-3',
encryptedWorkspaceKey: 'foobar',
})
} catch (caughtError) {
error = caughtError
}
expect(error).not.toBeNull()
})
})

View File

@@ -8,6 +8,7 @@ import { WorkspaceInvitationResponse } from '../../Response/Workspace/WorkspaceI
import { WorkspaceServerInterface } from '../../Server/Workspace/WorkspaceServerInterface'
import { WorkspaceListResponse } from '../../Response/Workspace/WorkspaceListResponse'
import { WorkspaceUserListResponse } from '../../Response/Workspace/WorkspaceUserListResponse'
import { WorkspaceKeyshareInitiatingResponse } from '../../Response/Workspace/WorkspaceKeyshareInitiatingResponse'
import { WorkspaceApiServiceInterface } from './WorkspaceApiServiceInterface'
import { WorkspaceApiOperations } from './WorkspaceApiOperations'
@@ -19,6 +20,28 @@ export class WorkspaceApiService implements WorkspaceApiServiceInterface {
this.operationsInProgress = new Map()
}
async initiateKeyshare(dto: {
workspaceUuid: string
userUuid: string
encryptedWorkspaceKey: string
}): Promise<WorkspaceKeyshareInitiatingResponse> {
this.lockOperation(WorkspaceApiOperations.InitiatingKeyshare)
try {
const response = await this.workspaceServer.initiateKeyshare({
workspaceUuid: dto.workspaceUuid,
userUuid: dto.userUuid,
encryptedWorkspaceKey: dto.encryptedWorkspaceKey,
})
this.unlockOperation(WorkspaceApiOperations.InitiatingKeyshare)
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
}
}
async listWorkspaceUsers(dto: { workspaceUuid: string }): Promise<WorkspaceUserListResponse> {
this.lockOperation(WorkspaceApiOperations.ListingWorkspaceUsers)

View File

@@ -1,5 +1,6 @@
import { Uuid, WorkspaceAccessLevel, WorkspaceType } from '@standardnotes/common'
import { WorkspaceKeyshareInitiatingResponse } from '../../Response/Workspace/WorkspaceKeyshareInitiatingResponse'
import { WorkspaceCreationResponse } from '../../Response/Workspace/WorkspaceCreationResponse'
import { WorkspaceInvitationAcceptingResponse } from '../../Response/Workspace/WorkspaceInvitationAcceptingResponse'
import { WorkspaceInvitationResponse } from '../../Response/Workspace/WorkspaceInvitationResponse'
@@ -27,4 +28,9 @@ export interface WorkspaceApiServiceInterface {
}): Promise<WorkspaceInvitationAcceptingResponse>
listWorkspaces(): Promise<WorkspaceListResponse>
listWorkspaceUsers(dto: { workspaceUuid: Uuid }): Promise<WorkspaceUserListResponse>
initiateKeyshare(dto: {
workspaceUuid: Uuid
userUuid: Uuid
encryptedWorkspaceKey: string
}): Promise<WorkspaceKeyshareInitiatingResponse>
}