Skip to content

Commit

Permalink
Improve TS bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
dani-garcia committed Dec 4, 2023
1 parent 7fc3b84 commit 98e2c07
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 99 deletions.
190 changes: 117 additions & 73 deletions languages/js_webassembly/bitwarden_client/index.ts
Original file line number Diff line number Diff line change
@@ -1,71 +1,54 @@
import * as rust from "../pkg/bitwarden_wasm";
import { LoggingLevel } from "./logging_level";
import {
AccessTokenLoginResponse,
ClientSettings,
Convert,
ResponseForPasswordLoginResponse,
ResponseForSecretIdentifiersResponse,
ResponseForSecretResponse,
ResponseForSecretsDeleteResponse,
ResponseForSyncResponse,
ResponseForUserAPIKeyResponse,
ProjectResponse,
ProjectsDeleteResponse,
ProjectsResponse,
SecretIdentifiersResponse,
SecretResponse,
SecretsDeleteResponse,
} from "./schemas";

export class BitwardenClient {
client: rust.BitwardenClient;
export type LogLevel = rust.LogLevel;
export const LogLevel = rust.LogLevel;

constructor(settings?: ClientSettings, logging_level?: LoggingLevel) {
const settings_json = settings == null ? null : Convert.clientSettingsToJson(settings);
this.client = new rust.BitwardenClient(settings_json, logging_level ?? LoggingLevel.Info);
function handleResponse<T>(response: { success: boolean; errorMessage?: string; data?: T }): T {
if (!response.success) {
throw new Error(response.errorMessage);
}

async login(email: string, password: string): Promise<ResponseForPasswordLoginResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
passwordLogin: {
email: email,
password: password,
},
})
);

return Convert.toResponseForPasswordLoginResponse(response);
}
return response.data as T;
}

async getUserApiKey(
secret: string,
isOtp: boolean = false
): Promise<ResponseForUserAPIKeyResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
getUserApiKey: {
masterPassword: isOtp ? null : secret,
otp: isOtp ? secret : null,
},
})
);
export class BitwardenClient {
client: rust.BitwardenClient;

return Convert.toResponseForUserAPIKeyResponse(response);
constructor(settings?: ClientSettings, log_level?: rust.LogLevel) {
const settings_json = settings == null ? null : Convert.clientSettingsToJson(settings);
this.client = new rust.BitwardenClient(settings_json, log_level ?? rust.LogLevel.Info);
}


async sync(
excludeSubdomains: boolean = false
): Promise<ResponseForSyncResponse> {
async accessTokenLogin(accessToken: string): Promise<AccessTokenLoginResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
sync: {
excludeSubdomains
accessTokenLogin: {
accessToken,
},
})
}),
);

return Convert.toResponseForSyncResponse(response);
return handleResponse(Convert.toResponseForAccessTokenLoginResponse(response));
}

secrets(): SecretsClient {
return new SecretsClient(this.client);
}

projects(): ProjectsClient {
return new ProjectsClient(this.client);
}
}

export class SecretsClient {
Expand All @@ -75,81 +58,142 @@ export class SecretsClient {
this.client = client;
}

async get(
id: string
): Promise<ResponseForSecretResponse> {
async get(id: string): Promise<SecretResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
secrets: {
get: { id }
get: { id },
},
})
}),
);

return Convert.toResponseForSecretResponse(response);
return handleResponse(Convert.toResponseForSecretResponse(response));
}

async create(
key: string,
value: string,
note: string,
organizationId: string,
value: string,
): Promise<ResponseForSecretResponse> {
): Promise<SecretResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
secrets: {
create: { key, note, organizationId, value }
create: { key, value, note, organizationId },
},
})
}),
);

return Convert.toResponseForSecretResponse(response);
return handleResponse(Convert.toResponseForSecretResponse(response));
}

async list(
organizationId: string
): Promise<ResponseForSecretIdentifiersResponse> {
async list(organizationId: string): Promise<SecretIdentifiersResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
secrets: {
list: { organizationId }
list: { organizationId },
},
})
}),
);

return Convert.toResponseForSecretIdentifiersResponse(response);
return handleResponse(Convert.toResponseForSecretIdentifiersResponse(response));
}

async update(
id: string,
key: string,
value: string,
note: string,
organizationId: string,
value: string,
): Promise<ResponseForSecretResponse> {
): Promise<SecretResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
secrets: {
update: { id, key, note, organizationId, value }
update: { id, key, value, note, organizationId },
},
})
}),
);

return Convert.toResponseForSecretResponse(response);
return handleResponse(Convert.toResponseForSecretResponse(response));
}

async delete(
ids: string[]
): Promise<ResponseForSecretsDeleteResponse> {
async delete(ids: string[]): Promise<SecretsDeleteResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
secrets: {
delete: { ids }
delete: { ids },
},
})
}),
);

return Convert.toResponseForSecretsDeleteResponse(response);
return handleResponse(Convert.toResponseForSecretsDeleteResponse(response));
}
}

export class ProjectsClient {
client: rust.BitwardenClient;

constructor(client: rust.BitwardenClient) {
this.client = client;
}

async get(id: string): Promise<ProjectResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
projects: {
get: { id },
},
}),
);

return handleResponse(Convert.toResponseForProjectResponse(response));
}

async create(name: string, organizationId: string): Promise<ProjectResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
projects: {
create: { name, organizationId },
},
}),
);

return handleResponse(Convert.toResponseForProjectResponse(response));
}

async list(organizationId: string): Promise<ProjectsResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
projects: {
list: { organizationId },
},
}),
);

return handleResponse(Convert.toResponseForProjectsResponse(response));
}

async update(id: string, name: string, organizationId: string): Promise<ProjectResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
projects: {
update: { id, name, organizationId },
},
}),
);

return handleResponse(Convert.toResponseForProjectResponse(response));
}

async delete(ids: string[]): Promise<ProjectsDeleteResponse> {
const response = await this.client.run_command(
Convert.commandToJson({
projects: {
delete: { ids },
},
}),
);

return handleResponse(Convert.toResponseForProjectsDeleteResponse(response));
}
}
7 changes: 0 additions & 7 deletions languages/js_webassembly/bitwarden_client/logging_level.ts

This file was deleted.

2 changes: 1 addition & 1 deletion languages/js_webassembly/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>

<html>
<head>
Expand Down
35 changes: 17 additions & 18 deletions languages/js_webassembly/index.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
import { LoggingLevel } from "./bitwarden_client/logging_level";
import { DeviceType } from "./bitwarden_client/schemas";

import("./bitwarden_client").then(async (module) => {
const client = new module.BitwardenClient({
apiUrl: "http://localhost:8081/api",
identityUrl: "http://localhost:8081/identity",
deviceType: DeviceType.SDK,
userAgent: "Bitwarden JS SDK",
}, LoggingLevel.Debug);
const result = await client.login("[email protected]", "asdfasdf");
console.log(`auth result success: ${result.success}`);
const client = new module.BitwardenClient(
{
apiUrl: "http://localhost:8081/api",
identityUrl: "http://localhost:8081/identity",
deviceType: DeviceType.SDK,
userAgent: "Bitwarden JS SDK",
},
module.LogLevel.Debug,
);

const apikeyResponse = await client.getUserApiKey("asdfasdf");
console.log(`user API key: ${apikeyResponse.data.apiKey}`);
const accessToken = "insert your access token here";
const organizationId = "insert your organization id here";

const sync = await client.sync();
console.log("Sync result", sync);
await client.accessTokenLogin(accessToken);

const org_id = sync.data.profile.organizations[0].id;
const secret = await client
.secrets()
.create("TEST_KEY", "Secret1234!", "This is a test secret", organizationId);
console.log("New secret: ", secret);

const secret = await client.secrets().create("TEST_KEY", "This is a test secret", org_id, "Secret1234!");
console.log("New secret: ", secret.data);

await client.secrets().delete([secret.data.id]);
await client.secrets().delete([secret.id]);
});

0 comments on commit 98e2c07

Please sign in to comment.