mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 13:23:34 +00:00
[PM-686] [CLI] Add proxy support for file downloads (#7345)
* Add proxy support for file downloads Instead of using node's native fetch we extend ApiService with NodeApiService to add support for proxies using `node-fetch` * Add comments to the DownloadCommand --------- Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
99008267e6
commit
065725df7a
@@ -1,7 +1,6 @@
|
|||||||
// FIXME: Update this file to be type safe and remove this and next line
|
// FIXME: Update this file to be type safe and remove this and next line
|
||||||
// @ts-strict-ignore
|
// @ts-strict-ignore
|
||||||
import * as fet from "node-fetch";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
|
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer";
|
import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer";
|
||||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||||
@@ -10,16 +9,36 @@ import { Response } from "../models/response";
|
|||||||
import { FileResponse } from "../models/response/file.response";
|
import { FileResponse } from "../models/response/file.response";
|
||||||
import { CliUtils } from "../utils";
|
import { CliUtils } from "../utils";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to download and save attachments
|
||||||
|
*/
|
||||||
export abstract class DownloadCommand {
|
export abstract class DownloadCommand {
|
||||||
constructor(protected encryptService: EncryptService) {}
|
/**
|
||||||
|
* @param encryptService - Needed for decryption of the retrieved attachment
|
||||||
|
* @param apiService - Needed to override the existing nativeFetch which is available as of Node 18, to support proxies
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
protected encryptService: EncryptService,
|
||||||
|
protected apiService: ApiService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches an attachment via the url, decrypts it's content and saves it to a file
|
||||||
|
* @param url - url used to retrieve the attachment
|
||||||
|
* @param key - SymmetricCryptoKey to decrypt the file contents
|
||||||
|
* @param fileName - filename used when written to disk
|
||||||
|
* @param output - If output is empty or `--raw` was passed to the initial command the content is output onto stdout
|
||||||
|
* @returns Promise<FileResponse>
|
||||||
|
*/
|
||||||
protected async saveAttachmentToFile(
|
protected async saveAttachmentToFile(
|
||||||
url: string,
|
url: string,
|
||||||
key: SymmetricCryptoKey,
|
key: SymmetricCryptoKey,
|
||||||
fileName: string,
|
fileName: string,
|
||||||
output?: string,
|
output?: string,
|
||||||
) {
|
) {
|
||||||
const response = await fet.default(new fet.Request(url, { headers: { cache: "no-cache" } }));
|
const response = await this.apiService.nativeFetch(
|
||||||
|
new Request(url, { headers: { cache: "no-cache" } }),
|
||||||
|
);
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
return Response.error(
|
return Response.error(
|
||||||
"A " + response.status + " error occurred while downloading the attachment.",
|
"A " + response.status + " error occurred while downloading the attachment.",
|
||||||
|
|||||||
@@ -60,13 +60,13 @@ export class GetCommand extends DownloadCommand {
|
|||||||
private keyService: KeyService,
|
private keyService: KeyService,
|
||||||
encryptService: EncryptService,
|
encryptService: EncryptService,
|
||||||
private searchService: SearchService,
|
private searchService: SearchService,
|
||||||
private apiService: ApiService,
|
protected apiService: ApiService,
|
||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
private eventCollectionService: EventCollectionService,
|
private eventCollectionService: EventCollectionService,
|
||||||
private accountProfileService: BillingAccountProfileStateService,
|
private accountProfileService: BillingAccountProfileStateService,
|
||||||
private accountService: AccountService,
|
private accountService: AccountService,
|
||||||
) {
|
) {
|
||||||
super(encryptService);
|
super(encryptService, apiService);
|
||||||
}
|
}
|
||||||
|
|
||||||
async run(object: string, id: string, cmdOptions: Record<string, any>): Promise<Response> {
|
async run(object: string, id: string, cmdOptions: Record<string, any>): Promise<Response> {
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ export class OssServeConfigurator {
|
|||||||
this.serviceContainer.environmentService,
|
this.serviceContainer.environmentService,
|
||||||
this.serviceContainer.searchService,
|
this.serviceContainer.searchService,
|
||||||
this.serviceContainer.encryptService,
|
this.serviceContainer.encryptService,
|
||||||
|
this.serviceContainer.apiService,
|
||||||
);
|
);
|
||||||
this.sendEditCommand = new SendEditCommand(
|
this.sendEditCommand = new SendEditCommand(
|
||||||
this.serviceContainer.sendService,
|
this.serviceContainer.sendService,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { OptionValues } from "commander";
|
import { OptionValues } from "commander";
|
||||||
import { firstValueFrom } from "rxjs";
|
import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { SearchService } from "@bitwarden/common/abstractions/search.service";
|
import { SearchService } from "@bitwarden/common/abstractions/search.service";
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
@@ -20,8 +21,9 @@ export class SendGetCommand extends DownloadCommand {
|
|||||||
private environmentService: EnvironmentService,
|
private environmentService: EnvironmentService,
|
||||||
private searchService: SearchService,
|
private searchService: SearchService,
|
||||||
encryptService: EncryptService,
|
encryptService: EncryptService,
|
||||||
|
apiService: ApiService,
|
||||||
) {
|
) {
|
||||||
super(encryptService);
|
super(encryptService, apiService);
|
||||||
}
|
}
|
||||||
|
|
||||||
async run(id: string, options: OptionValues) {
|
async run(id: string, options: OptionValues) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { OptionValues } from "commander";
|
|||||||
import * as inquirer from "inquirer";
|
import * as inquirer from "inquirer";
|
||||||
import { firstValueFrom } from "rxjs";
|
import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
@@ -35,8 +36,9 @@ export class SendReceiveCommand extends DownloadCommand {
|
|||||||
private platformUtilsService: PlatformUtilsService,
|
private platformUtilsService: PlatformUtilsService,
|
||||||
private environmentService: EnvironmentService,
|
private environmentService: EnvironmentService,
|
||||||
private sendApiService: SendApiService,
|
private sendApiService: SendApiService,
|
||||||
|
apiService: ApiService,
|
||||||
) {
|
) {
|
||||||
super(encryptService);
|
super(encryptService, apiService);
|
||||||
}
|
}
|
||||||
|
|
||||||
async run(url: string, options: OptionValues): Promise<Response> {
|
async run(url: string, options: OptionValues): Promise<Response> {
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ export class SendProgram extends BaseProgram {
|
|||||||
this.serviceContainer.platformUtilsService,
|
this.serviceContainer.platformUtilsService,
|
||||||
this.serviceContainer.environmentService,
|
this.serviceContainer.environmentService,
|
||||||
this.serviceContainer.sendApiService,
|
this.serviceContainer.sendApiService,
|
||||||
|
this.serviceContainer.apiService,
|
||||||
);
|
);
|
||||||
const response = await cmd.run(url, options);
|
const response = await cmd.run(url, options);
|
||||||
this.processResponse(response);
|
this.processResponse(response);
|
||||||
@@ -190,6 +191,7 @@ export class SendProgram extends BaseProgram {
|
|||||||
this.serviceContainer.environmentService,
|
this.serviceContainer.environmentService,
|
||||||
this.serviceContainer.searchService,
|
this.serviceContainer.searchService,
|
||||||
this.serviceContainer.encryptService,
|
this.serviceContainer.encryptService,
|
||||||
|
this.serviceContainer.apiService,
|
||||||
);
|
);
|
||||||
const response = await cmd.run(id, options);
|
const response = await cmd.run(id, options);
|
||||||
this.processResponse(response);
|
this.processResponse(response);
|
||||||
@@ -249,6 +251,7 @@ export class SendProgram extends BaseProgram {
|
|||||||
this.serviceContainer.environmentService,
|
this.serviceContainer.environmentService,
|
||||||
this.serviceContainer.searchService,
|
this.serviceContainer.searchService,
|
||||||
this.serviceContainer.encryptService,
|
this.serviceContainer.encryptService,
|
||||||
|
this.serviceContainer.apiService,
|
||||||
);
|
);
|
||||||
const cmd = new SendEditCommand(
|
const cmd = new SendEditCommand(
|
||||||
this.serviceContainer.sendService,
|
this.serviceContainer.sendService,
|
||||||
|
|||||||
Reference in New Issue
Block a user