Skip to content

Commit

Permalink
[SG-534] and [SG-535] Implement Credential Create and Update commands (
Browse files Browse the repository at this point in the history
…#3342)

* Status command start

* Refactor ipc test service and add status command

* fixed linter errors

* Move types into a model file

* Cleanup and comments

* Fix auth status condition

* Remove .vscode settings file. Fix this in a separate work item

* Implement bw-credential-retrieval

* Add active field to status response

* Add bw-credential-create

* Better response handling in test runner

* Extract native messaging types into their own files

* Remove experimental decorators

* Turn off no console lint rule for the test runner

* Casing fix

* Models import casing fixes

* bw-cipher-create move type into its own file

* Use LogUtils for all logging

* Implement bw-credential-update

* Give naming conventions for types

* Rename file correctly
  • Loading branch information
differsthecat committed Aug 24, 2022
1 parent 98dc690 commit 83a32e3
Show file tree
Hide file tree
Showing 12 changed files with 293 additions and 18 deletions.
4 changes: 3 additions & 1 deletion apps/desktop/native-messaging-test-runner/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
"scripts": {
"handshake": "tsc && node dist/apps/desktop/native-messaging-test-runner/src/bw-handshake.js",
"status": "tsc && node dist/apps/desktop/native-messaging-test-runner/src/bw-status.js",
"retrieve": "tsc && node dist/apps/desktop/native-messaging-test-runner/src/bw-credential-retrieval.js"
"retrieve": "tsc && node dist/apps/desktop/native-messaging-test-runner/src/bw-credential-retrieval.js",
"create": "tsc && node dist/apps/desktop/native-messaging-test-runner/src/bw-credential-create.js",
"update": "tsc && node dist/apps/desktop/native-messaging-test-runner/src/bw-credential-update.js"
},
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
"license": "GPL-3.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import "module-alias/register";

import yargs from "yargs";
import { hideBin } from "yargs/helpers";

import { LogUtils } from "./logUtils";
import NativeMessageService from "./nativeMessageService";
import * as config from "./variables";

const argv: any = yargs(hideBin(process.argv)).option("name", {
alias: "n",
demand: true,
describe: "Name that the created login will be given",
type: "string",
}).argv;

const { name } = argv;

(async () => {
const nativeMessageService = new NativeMessageService(1.0);
// Handshake
LogUtils.logWarning("Sending Handshake");
const handshakeResponse = await nativeMessageService.sendHandshake(config.testRsaPublicKey);

if (handshakeResponse.status !== "success") {
LogUtils.logError(" Handshake failed. Status was:", handshakeResponse.status);
nativeMessageService.disconnect();
return;
}

LogUtils.logSuccess("Handshake success response");
const response = await nativeMessageService.credentialCreation(handshakeResponse.sharedKey, name);

if (response.payload.status === "failure") {
LogUtils.logError("Failure response returned ");
} else if (response.payload.status === "success") {
LogUtils.logSuccess("Success response returned ");
} else if (response.payload.error === "locked") {
LogUtils.logError("Error: vault is locked");
} else {
LogUtils.logWarning("Other response: ", response);
}

nativeMessageService.disconnect();
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import "module-alias/register";

import yargs from "yargs";
import { hideBin } from "yargs/helpers";

import { LogUtils } from "./logUtils";
import NativeMessageService from "./nativeMessageService";
import * as config from "./variables";

// Command line arguments
const argv: any = yargs(hideBin(process.argv))
.option("name", {
alias: "n",
demand: true,
describe: "Name that the updated login will be given",
type: "string",
})
.option("username", {
alias: "u",
demand: true,
describe: "Username that the login will be given",
type: "string",
})
.option("password", {
alias: "p",
demand: true,
describe: "Password that the login will be given",
type: "string",
})
.option("uri", {
demand: true,
describe: "Uri that the login will be given",
type: "string",
}).argv;

const { name, username, password, uri } = argv;

(async () => {
const nativeMessageService = new NativeMessageService(1.0);
// Handshake
LogUtils.logWarning("Sending Handshake");
const handshakeResponse = await nativeMessageService.sendHandshake(config.testRsaPublicKey);

if (handshakeResponse.status !== "success") {
LogUtils.logError(" Handshake failed. Status was:", handshakeResponse.status);
nativeMessageService.disconnect();
return;
}
LogUtils.logSuccess("Handshake success response");

// Get active account userId
const status = await nativeMessageService.checkStatus(handshakeResponse.sharedKey);

const activeUser = status.payload.filter((a) => a.active === true && a.status === "unlocked")[0];
if (activeUser === undefined) {
LogUtils.logError("No active or unlocked user");
}
LogUtils.logWarning("Active userId: " + activeUser.id);

const response = await nativeMessageService.credentialUpdate(
handshakeResponse.sharedKey,
name,
password,
username,
uri,
activeUser.id,
// Replace with credentialId you want to update
"2a08b546-fa9d-48cc-ae8e-ae7601207da9"
);

if (response.payload.status === "failure") {
LogUtils.logError("Failure response returned ");
} else if (response.payload.status === "success") {
LogUtils.logSuccess("Success response returned ");
} else {
LogUtils.logWarning("Other response: ", response);
}

nativeMessageService.disconnect();
})();
7 changes: 4 additions & 3 deletions apps/desktop/native-messaging-test-runner/src/bw-handshake.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { LogUtils } from "./logUtils";
import NativeMessageService from "./nativeMessageService";
import * as config from "./variables";

(async () => {
const nativeMessageService = new NativeMessageService(1.0);

const response = await nativeMessageService.sendHandshake(config.testRsaPublicKey);
console.log("[Handshake Command]\x1b[32m Received response to handshake request \x1b[0m");
LogUtils.logSuccess("Received response to handshake request");
if (response.status === "success") {
console.log("[Handshake Command]\x1b[32m Handshake success response \x1b[0m");
LogUtils.logSuccess("Handshake success response");
} else {
console.log("[Handshake Command]\x1b[31m Handshake failure response \x1b[0m");
LogUtils.logError("Handshake failure response");
}
nativeMessageService.disconnect();
})();
15 changes: 7 additions & 8 deletions apps/desktop/native-messaging-test-runner/src/bw-status.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import "module-alias/register";
import { LogUtils } from "./logUtils";
import NativeMessageService from "./nativeMessageService";
import * as config from "./variables";

(async () => {
const nativeMessageService = new NativeMessageService(1.0);

console.log("[Status Command]\x1b[32m Sending Handshake \x1b[0m");
LogUtils.logWarning("Sending Handshake");
const handshakeResponse = await nativeMessageService.sendHandshake(config.testRsaPublicKey);
console.log("[Status Command]\x1b[32m Received response to handshake request \x1b[0m");
LogUtils.logSuccess("Received response to handshake request");

if (handshakeResponse.status !== "success") {
console.log(
`[Status Command]\x1b[31m Handshake failed \x1b[0m Status was: ${handshakeResponse.status}`
);
LogUtils.logError(" Handshake failed. Status was:", handshakeResponse.status);
nativeMessageService.disconnect();
return;
}
console.log("[Status Command]\x1b[32m Handshake success response \x1b[0m");
LogUtils.logSuccess("Handshake success response");
const status = await nativeMessageService.checkStatus(handshakeResponse.sharedKey);

console.log(`[Status Command] Status output is: `, status);

LogUtils.logSuccess("Status output is: ", status);
nativeMessageService.disconnect();
})();
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { ConsoleLogService } from "@bitwarden/common/services/consoleLog.service
import { EncryptService } from "@bitwarden/common/services/encrypt.service";
import { NodeCryptoFunctionService } from "@bitwarden/node/services/nodeCryptoFunction.service";

import { CredentialCreatePayload } from "../../src/models/nativeMessaging/credentialCreatePayload";
import { CredentialUpdatePayload } from "../../src/models/nativeMessaging/credentialUpdatePayload";
import { DecryptedCommandData } from "../../src/models/nativeMessaging/decryptedCommandData";
import { EncryptedMessage } from "../../src/models/nativeMessaging/encryptedMessage";
import { EncryptedMessageResponse } from "../../src/models/nativeMessaging/encryptedMessageResponse";
Expand Down Expand Up @@ -87,6 +89,56 @@ export default class NativeMessageService {
return this.decryptResponsePayload(response.encryptedPayload, key);
}

async credentialCreation(key: string, name: string): Promise<DecryptedCommandData> {
const encryptedCommand = await this.encryptCommandData(
{
command: "bw-credential-create",
payload: {
name: name,
userName: "SuperAwesomeUser",
password: "dolhpin",
uri: "google.com",
} as CredentialCreatePayload,
},
key
);
const response = await this.sendEncryptedMessage({
encryptedCommand,
});

return this.decryptResponsePayload(response.encryptedPayload, key);
}

async credentialUpdate(
key: string,
name: string,
password: string,
username: string,
uri: string,
userId: string,
credentialId: string
): Promise<DecryptedCommandData> {
const encryptedCommand = await this.encryptCommandData(
{
command: "bw-credential-update",
payload: {
userId: userId,
credentialId: credentialId,
userName: username,
uri: uri,
password: password,
name: name,
} as CredentialUpdatePayload,
},
key
);
const response = await this.sendEncryptedMessage({
encryptedCommand,
});

return this.decryptResponsePayload(response.encryptedPayload, key);
}

// Private message sending

private async sendEncryptedMessage(
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/app/services/services.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
import { MessagingService as MessagingServiceAbstraction } from "@bitwarden/common/abstractions/messaging.service";
import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from "@bitwarden/common/abstractions/passwordReprompt.service";
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/abstractions/platformUtils.service";
import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction";
import { StateService as StateServiceAbstraction } from "@bitwarden/common/abstractions/state.service";
import { StateMigrationService as StateMigrationServiceAbstraction } from "@bitwarden/common/abstractions/stateMigration.service";
import { AbstractStorageService } from "@bitwarden/common/abstractions/storage.service";
Expand Down Expand Up @@ -158,6 +159,7 @@ const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK");
CryptoServiceAbstraction,
CryptoFunctionServiceAbstraction,
CipherService,
PolicyService,
],
},
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type CiphersResponse = {
export type CipherResponse = {
userId: string;
credentialId: string;
userName: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type CredentialCreatePayload = {
userId: string;
userName: string;
password: string;
name: string;
uri: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export type CredentialUpdatePayload = {
userId: string;
userName: string;
password: string;
name: string;
uri: string;
credentialId: string;
};
4 changes: 3 additions & 1 deletion apps/desktop/src/models/nativeMessaging/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export * from "./ciphersResponse";
export * from "./cipherResponse";
export * from "./credentialCreatePayload";
export * from "./credentialUpdatePayload";
export * from "./decryptedCommandData";
export * from "./encryptedCommand";
export * from "./encryptedMessage";
Expand Down

0 comments on commit 83a32e3

Please sign in to comment.