mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-20 16:07:45 +01:00
4a30782939
* Added inputs to the view and edit component to disable or remove the delete button when a user does not have manage rights * Refactored editByCipherId to receive cipherview object * Fixed issue where adding an item on the individual vault throws a null reference * Fixed issue where adding an item on the AC vault throws a null reference * Allow delete in unassigned collection * created reusable service to check if a user has delete permission on an item * Registered service * Used authorizationservice on the browser and desktop Only display the delete button when a user has delete permission * Added comments to the service * Passed active collectionId to add edit component renamed constructor parameter * restored input property used by the web * Fixed dependency issue * Fixed dependency issue * Fixed dependency issue * Modified service to cater for org vault * Updated to include new dependency * Updated components to use the observable * Added check on the cli to know if user has rights to delete an item * Renamed abstraction and renamed implementation to include Default Fixed permission issues * Fixed test to reflect changes in implementation * Modified base classes to use new naming Passed new parameters for the canDeleteCipher * Modified base classes to use new naming Made changes from base class * Desktop changes Updated reference naming * cli changes Updated reference naming Passed new parameters for the canDeleteCipher$ * Updated references * browser changes Updated reference naming Passed new parameters for the canDeleteCipher$ * Modified cipher form dialog to take in active collection id used canDeleteCipher$ on the vault item dialog to disable the delete button when user does not have the required permissions * Fix number of arguments issue * Added active collection id * Updated canDeleteCipher$ arguments * Updated to pass the cipher object * Fixed up refrences and comments * Updated dependency * updated check to canEditUnassignedCiphers * Fixed unit tests * Removed activeCollectionId from cipher form * Fixed issue where bulk delete option shows for can edit users * Fix null reference when checking if a cipher belongs to the unassigned collection * Fixed bug where allowedCollection passed is undefined * Modified cipher by adding a isAdminConsoleAction argument to tell when a reuqest comes from the admin console * Passed isAdminConsoleAction as true when request is from the admin console
409 lines
14 KiB
TypeScript
409 lines
14 KiB
TypeScript
import * as koaMulter from "@koa/multer";
|
|
import * as koaRouter from "@koa/router";
|
|
import * as koa from "koa";
|
|
|
|
import { ConfirmCommand } from "./admin-console/commands/confirm.command";
|
|
import { ShareCommand } from "./admin-console/commands/share.command";
|
|
import { LockCommand } from "./auth/commands/lock.command";
|
|
import { UnlockCommand } from "./auth/commands/unlock.command";
|
|
import { EditCommand } from "./commands/edit.command";
|
|
import { GetCommand } from "./commands/get.command";
|
|
import { ListCommand } from "./commands/list.command";
|
|
import { RestoreCommand } from "./commands/restore.command";
|
|
import { StatusCommand } from "./commands/status.command";
|
|
import { Response } from "./models/response";
|
|
import { FileResponse } from "./models/response/file.response";
|
|
import { ServiceContainer } from "./service-container/service-container";
|
|
import { GenerateCommand } from "./tools/generate.command";
|
|
import {
|
|
SendEditCommand,
|
|
SendCreateCommand,
|
|
SendDeleteCommand,
|
|
SendGetCommand,
|
|
SendListCommand,
|
|
SendRemovePasswordCommand,
|
|
} from "./tools/send";
|
|
import { CreateCommand } from "./vault/create.command";
|
|
import { DeleteCommand } from "./vault/delete.command";
|
|
import { SyncCommand } from "./vault/sync.command";
|
|
|
|
export class OssServeConfigurator {
|
|
private listCommand: ListCommand;
|
|
private getCommand: GetCommand;
|
|
private createCommand: CreateCommand;
|
|
private editCommand: EditCommand;
|
|
private generateCommand: GenerateCommand;
|
|
private shareCommand: ShareCommand;
|
|
private statusCommand: StatusCommand;
|
|
private syncCommand: SyncCommand;
|
|
private deleteCommand: DeleteCommand;
|
|
private confirmCommand: ConfirmCommand;
|
|
private restoreCommand: RestoreCommand;
|
|
private lockCommand: LockCommand;
|
|
private unlockCommand: UnlockCommand;
|
|
|
|
private sendCreateCommand: SendCreateCommand;
|
|
private sendDeleteCommand: SendDeleteCommand;
|
|
private sendEditCommand: SendEditCommand;
|
|
private sendGetCommand: SendGetCommand;
|
|
private sendListCommand: SendListCommand;
|
|
private sendRemovePasswordCommand: SendRemovePasswordCommand;
|
|
|
|
constructor(protected serviceContainer: ServiceContainer) {
|
|
this.getCommand = new GetCommand(
|
|
this.serviceContainer.cipherService,
|
|
this.serviceContainer.folderService,
|
|
this.serviceContainer.collectionService,
|
|
this.serviceContainer.totpService,
|
|
this.serviceContainer.auditService,
|
|
this.serviceContainer.cryptoService,
|
|
this.serviceContainer.encryptService,
|
|
this.serviceContainer.stateService,
|
|
this.serviceContainer.searchService,
|
|
this.serviceContainer.apiService,
|
|
this.serviceContainer.organizationService,
|
|
this.serviceContainer.eventCollectionService,
|
|
this.serviceContainer.billingAccountProfileStateService,
|
|
this.serviceContainer.accountService,
|
|
);
|
|
this.listCommand = new ListCommand(
|
|
this.serviceContainer.cipherService,
|
|
this.serviceContainer.folderService,
|
|
this.serviceContainer.collectionService,
|
|
this.serviceContainer.organizationService,
|
|
this.serviceContainer.searchService,
|
|
this.serviceContainer.organizationUserApiService,
|
|
this.serviceContainer.apiService,
|
|
this.serviceContainer.eventCollectionService,
|
|
);
|
|
this.createCommand = new CreateCommand(
|
|
this.serviceContainer.cipherService,
|
|
this.serviceContainer.folderService,
|
|
this.serviceContainer.cryptoService,
|
|
this.serviceContainer.encryptService,
|
|
this.serviceContainer.apiService,
|
|
this.serviceContainer.folderApiService,
|
|
this.serviceContainer.billingAccountProfileStateService,
|
|
this.serviceContainer.organizationService,
|
|
this.serviceContainer.accountService,
|
|
);
|
|
this.editCommand = new EditCommand(
|
|
this.serviceContainer.cipherService,
|
|
this.serviceContainer.folderService,
|
|
this.serviceContainer.cryptoService,
|
|
this.serviceContainer.encryptService,
|
|
this.serviceContainer.apiService,
|
|
this.serviceContainer.folderApiService,
|
|
this.serviceContainer.accountService,
|
|
);
|
|
this.generateCommand = new GenerateCommand(
|
|
this.serviceContainer.passwordGenerationService,
|
|
this.serviceContainer.stateService,
|
|
);
|
|
this.syncCommand = new SyncCommand(this.serviceContainer.syncService);
|
|
this.statusCommand = new StatusCommand(
|
|
this.serviceContainer.environmentService,
|
|
this.serviceContainer.syncService,
|
|
this.serviceContainer.accountService,
|
|
this.serviceContainer.authService,
|
|
);
|
|
this.deleteCommand = new DeleteCommand(
|
|
this.serviceContainer.cipherService,
|
|
this.serviceContainer.folderService,
|
|
this.serviceContainer.apiService,
|
|
this.serviceContainer.folderApiService,
|
|
this.serviceContainer.billingAccountProfileStateService,
|
|
this.serviceContainer.cipherAuthorizationService,
|
|
);
|
|
this.confirmCommand = new ConfirmCommand(
|
|
this.serviceContainer.apiService,
|
|
this.serviceContainer.cryptoService,
|
|
this.serviceContainer.encryptService,
|
|
this.serviceContainer.organizationUserApiService,
|
|
);
|
|
this.restoreCommand = new RestoreCommand(this.serviceContainer.cipherService);
|
|
this.shareCommand = new ShareCommand(
|
|
this.serviceContainer.cipherService,
|
|
this.serviceContainer.accountService,
|
|
);
|
|
this.lockCommand = new LockCommand(this.serviceContainer.vaultTimeoutService);
|
|
this.unlockCommand = new UnlockCommand(
|
|
this.serviceContainer.accountService,
|
|
this.serviceContainer.masterPasswordService,
|
|
this.serviceContainer.cryptoService,
|
|
this.serviceContainer.userVerificationService,
|
|
this.serviceContainer.cryptoFunctionService,
|
|
this.serviceContainer.logService,
|
|
this.serviceContainer.keyConnectorService,
|
|
this.serviceContainer.environmentService,
|
|
this.serviceContainer.syncService,
|
|
this.serviceContainer.organizationApiService,
|
|
async () => await this.serviceContainer.logout(),
|
|
);
|
|
|
|
this.sendCreateCommand = new SendCreateCommand(
|
|
this.serviceContainer.sendService,
|
|
this.serviceContainer.environmentService,
|
|
this.serviceContainer.sendApiService,
|
|
this.serviceContainer.billingAccountProfileStateService,
|
|
);
|
|
this.sendDeleteCommand = new SendDeleteCommand(
|
|
this.serviceContainer.sendService,
|
|
this.serviceContainer.sendApiService,
|
|
);
|
|
this.sendGetCommand = new SendGetCommand(
|
|
this.serviceContainer.sendService,
|
|
this.serviceContainer.environmentService,
|
|
this.serviceContainer.searchService,
|
|
this.serviceContainer.encryptService,
|
|
);
|
|
this.sendEditCommand = new SendEditCommand(
|
|
this.serviceContainer.sendService,
|
|
this.sendGetCommand,
|
|
this.serviceContainer.sendApiService,
|
|
this.serviceContainer.billingAccountProfileStateService,
|
|
);
|
|
this.sendListCommand = new SendListCommand(
|
|
this.serviceContainer.sendService,
|
|
this.serviceContainer.environmentService,
|
|
this.serviceContainer.searchService,
|
|
);
|
|
this.sendRemovePasswordCommand = new SendRemovePasswordCommand(
|
|
this.serviceContainer.sendService,
|
|
this.serviceContainer.sendApiService,
|
|
this.serviceContainer.environmentService,
|
|
);
|
|
}
|
|
|
|
configureRouter(router: koaRouter) {
|
|
router.get("/generate", async (ctx, next) => {
|
|
const response = await this.generateCommand.run(ctx.request.query);
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.get("/status", async (ctx, next) => {
|
|
const response = await this.statusCommand.run();
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.get("/list/object/:object", async (ctx, next) => {
|
|
if (await this.errorIfLocked(ctx.response)) {
|
|
await next();
|
|
return;
|
|
}
|
|
let response: Response = null;
|
|
if (ctx.params.object === "send") {
|
|
response = await this.sendListCommand.run(ctx.request.query);
|
|
} else {
|
|
response = await this.listCommand.run(ctx.params.object, ctx.request.query);
|
|
}
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.get("/send/list", async (ctx, next) => {
|
|
if (await this.errorIfLocked(ctx.response)) {
|
|
await next();
|
|
return;
|
|
}
|
|
const response = await this.sendListCommand.run(ctx.request.query);
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.post("/sync", async (ctx, next) => {
|
|
const response = await this.syncCommand.run(ctx.request.query);
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.post("/lock", async (ctx, next) => {
|
|
const response = await this.lockCommand.run();
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.post("/unlock", async (ctx, next) => {
|
|
// Do not allow guessing password location through serve command
|
|
delete ctx.request.query.passwordFile;
|
|
delete ctx.request.query.passwordEnv;
|
|
|
|
const response = await this.unlockCommand.run(
|
|
ctx.request.body.password == null ? null : (ctx.request.body.password as string),
|
|
ctx.request.query,
|
|
);
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.post("/confirm/:object/:id", async (ctx, next) => {
|
|
if (await this.errorIfLocked(ctx.response)) {
|
|
await next();
|
|
return;
|
|
}
|
|
const response = await this.confirmCommand.run(
|
|
ctx.params.object,
|
|
ctx.params.id,
|
|
ctx.request.query,
|
|
);
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.post("/restore/:object/:id", async (ctx, next) => {
|
|
if (await this.errorIfLocked(ctx.response)) {
|
|
await next();
|
|
return;
|
|
}
|
|
const response = await this.restoreCommand.run(ctx.params.object, ctx.params.id);
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.post("/move/:id/:organizationId", async (ctx, next) => {
|
|
if (await this.errorIfLocked(ctx.response)) {
|
|
await next();
|
|
return;
|
|
}
|
|
const response = await this.shareCommand.run(
|
|
ctx.params.id,
|
|
ctx.params.organizationId,
|
|
ctx.request.body, // TODO: Check the format of this body for an array of collection ids
|
|
);
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.post("/attachment", koaMulter().single("file"), async (ctx, next) => {
|
|
if (await this.errorIfLocked(ctx.response)) {
|
|
await next();
|
|
return;
|
|
}
|
|
const response = await this.createCommand.run(
|
|
"attachment",
|
|
ctx.request.body,
|
|
ctx.request.query,
|
|
{
|
|
fileBuffer: ctx.request.file.buffer,
|
|
fileName: ctx.request.file.originalname,
|
|
},
|
|
);
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.post("/send/:id/remove-password", async (ctx, next) => {
|
|
if (await this.errorIfLocked(ctx.response)) {
|
|
await next();
|
|
return;
|
|
}
|
|
const response = await this.sendRemovePasswordCommand.run(ctx.params.id);
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.post("/object/:object", async (ctx, next) => {
|
|
if (await this.errorIfLocked(ctx.response)) {
|
|
await next();
|
|
return;
|
|
}
|
|
let response: Response = null;
|
|
if (ctx.params.object === "send") {
|
|
response = await this.sendCreateCommand.run(ctx.request.body, ctx.request.query);
|
|
} else {
|
|
response = await this.createCommand.run(
|
|
ctx.params.object,
|
|
ctx.request.body,
|
|
ctx.request.query,
|
|
);
|
|
}
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.put("/object/:object/:id", async (ctx, next) => {
|
|
if (await this.errorIfLocked(ctx.response)) {
|
|
await next();
|
|
return;
|
|
}
|
|
let response: Response = null;
|
|
if (ctx.params.object === "send") {
|
|
ctx.request.body.id = ctx.params.id;
|
|
response = await this.sendEditCommand.run(ctx.request.body, ctx.request.query);
|
|
} else {
|
|
response = await this.editCommand.run(
|
|
ctx.params.object,
|
|
ctx.params.id,
|
|
ctx.request.body,
|
|
ctx.request.query,
|
|
);
|
|
}
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.get("/object/:object/:id", async (ctx, next) => {
|
|
if (await this.errorIfLocked(ctx.response)) {
|
|
await next();
|
|
return;
|
|
}
|
|
let response: Response = null;
|
|
if (ctx.params.object === "send") {
|
|
response = await this.sendGetCommand.run(ctx.params.id, null);
|
|
} else {
|
|
response = await this.getCommand.run(ctx.params.object, ctx.params.id, ctx.request.query);
|
|
}
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
|
|
router.delete("/object/:object/:id", async (ctx, next) => {
|
|
if (await this.errorIfLocked(ctx.response)) {
|
|
await next();
|
|
return;
|
|
}
|
|
let response: Response = null;
|
|
if (ctx.params.object === "send") {
|
|
response = await this.sendDeleteCommand.run(ctx.params.id);
|
|
} else {
|
|
response = await this.deleteCommand.run(
|
|
ctx.params.object,
|
|
ctx.params.id,
|
|
ctx.request.query,
|
|
);
|
|
}
|
|
this.processResponse(ctx.response, response);
|
|
await next();
|
|
});
|
|
}
|
|
|
|
protected processResponse(res: koa.Response, commandResponse: Response) {
|
|
if (!commandResponse.success) {
|
|
res.status = 400;
|
|
}
|
|
if (commandResponse.data instanceof FileResponse) {
|
|
res.body = commandResponse.data.data;
|
|
res.attachment(commandResponse.data.fileName);
|
|
res.set("Content-Type", "application/octet-stream");
|
|
res.set("Content-Length", commandResponse.data.data.length.toString());
|
|
} else {
|
|
res.body = commandResponse;
|
|
}
|
|
}
|
|
|
|
protected async errorIfLocked(res: koa.Response) {
|
|
const authed = await this.serviceContainer.stateService.getIsAuthenticated();
|
|
if (!authed) {
|
|
this.processResponse(res, Response.error("You are not logged in."));
|
|
return true;
|
|
}
|
|
if (await this.serviceContainer.cryptoService.hasUserKey()) {
|
|
return false;
|
|
}
|
|
this.processResponse(res, Response.error("Vault is locked."));
|
|
return true;
|
|
}
|
|
}
|