import { VaultUser } from '../Domain/VaultUser/Model/VaultUser' import { VaultServiceInterface } from '../Domain/Vault/Service/VaultServiceInterface' import { Request, Response } from 'express' import { BaseHttpController, controller, httpPost, results, httpDelete, httpPatch, httpGet, } from 'inversify-express-utils' import TYPES from '../Bootstrap/Types' import { inject } from 'inversify' import { ProjectorInterface } from '../Projection/ProjectorInterface' import { Vault } from '../Domain/Vault/Model/Vault' import { VaultProjection } from '../Projection/VaultProjection' import { VaultUserProjection } from '../Projection/VaultUserProjection' import { VaultUserServiceInterface } from '../Domain/VaultUser/Service/VaultUserServiceInterface' import { CreateVaultFileValetToken } from '../Domain/UseCase/CreateVaultFileValetToken/CreateVaultFileValetToken' @controller('/vaults') export class VaultsController extends BaseHttpController { constructor( @inject(TYPES.VaultService) private vaultService: VaultServiceInterface, @inject(TYPES.VaultUserService) private vaultUserService: VaultUserServiceInterface, @inject(TYPES.VaultProjector) private vaultProjector: ProjectorInterface, @inject(TYPES.VaultUserProjector) private vaultUserProjector: ProjectorInterface, @inject(TYPES.CreateVaultFileReadValetToken) private createVaultFileReadValetToken: CreateVaultFileValetToken, ) { super() } @httpGet('/', TYPES.AuthMiddleware) public async getVaults(_request: Request, response: Response): Promise { const vaults = await this.vaultService.getVaults({ userUuid: response.locals.user.uuid, }) return this.json({ vaults: vaults.map((vault) => this.vaultProjector.projectFull(vault)), }) } @httpPost('/:vaultUuid/valet-tokens', TYPES.AuthMiddleware) public async getValetTokenForVaultFile( request: Request, response: Response, ): Promise { const valetTokenResult = await this.createVaultFileReadValetToken.execute({ userUuid: response.locals.user.uuid, vaultUuid: request.params.vaultUuid, fileUuid: request.body.file_uuid, remoteIdentifier: request.body.remote_identifier, moveOperationType: request.body.move_operation_type, operation: request.body.operation, }) if (valetTokenResult.success === false) { return this.errorResponse(400, `Failed to create vault valet token: ${valetTokenResult.reason}`) } return this.json({ valetToken: valetTokenResult.valetToken, }) } @httpPost('/', TYPES.AuthMiddleware) public async createVault(request: Request, response: Response): Promise { const result = await this.vaultService.createVault({ userUuid: response.locals.user.uuid, vaultUuid: request.body.vault_uuid, vaultKeyTimestamp: request.body.vault_key_timestamp, specifiedItemsKeyUuid: request.body.specified_items_key_uuid, }) if (!result) { return this.errorResponse(400, 'Could not create vault') } const vaultUser = await this.vaultUserService.addVaultUser({ vaultUuid: result.uuid, userUuid: response.locals.user.uuid, permissions: 'admin', }) if (!vaultUser) { return this.errorResponse(400, 'Could not add user to vault') } return this.json({ vault: this.vaultProjector.projectFull(result), vaultUser: this.vaultUserProjector.projectFull(vaultUser), }) } @httpPatch('/:vaultUuid', TYPES.AuthMiddleware) public async updateVault(request: Request, response: Response): Promise { const result = await this.vaultService.updateVault({ vaultUuid: request.params.vaultUuid, originatorUuid: response.locals.user.uuid, vaultKeyTimestamp: request.body.vault_key_timestamp, specifiedItemsKeyUuid: request.body.specified_items_key_uuid, }) if (!result) { return this.errorResponse(400, 'Could not update vault') } return this.json({ vault: this.vaultProjector.projectFull(result), }) } @httpDelete('/:vaultUuid', TYPES.AuthMiddleware) public async deleteVault(request: Request, response: Response): Promise { const result = await this.vaultService.deleteVault({ vaultUuid: request.params.vaultUuid, originatorUuid: response.locals.user.uuid, }) if (!result) { return this.errorResponse(400, 'Could not delete vault') } return this.json({ success: true }) } private errorResponse(status: number, message?: string, tag?: string) { return this.json( { error: { message, tag }, }, status, ) } }