From bf595c2fef98549632734c43ee67e8aa8275e973 Mon Sep 17 00:00:00 2001 From: Alastair Ong Date: Mon, 24 Jun 2024 11:48:47 +0100 Subject: [PATCH 1/4] readme changes --- README.md | 68 ++++++++++++++++++++++++++++++++++++-- arch_1.png | Bin 0 -> 41054 bytes diagram.png => arch_2.png | Bin 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 arch_1.png rename diagram.png => arch_2.png (100%) diff --git a/README.md b/README.md index 23179e1..8d284d3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,67 @@ -![Holo Key Manager Architecture Diagram](./diagram.png) +# Holo Key Manager -The diagram above depicts the architecture of the Holo Key Manager. It demonstrates the client's interaction with the extension and outlines the communication schema between the webapp and the extension API. +![Client Build](https://github.com/holo-host/holo-key-manager/actions/workflows/client.yaml/badge.svg) +![Chrome Release](https://github.com/holo-host/holo-key-manager/actions/workflows/extension.yaml/badge.svg?job=chrome-release) +![Firefox Release](https://github.com/holo-host/holo-key-manager/actions/workflows/extension.yaml/badge.svg?job=firefox-release) +![Edge Release](https://github.com/holo-host/holo-key-manager/actions/workflows/extension.yaml/badge.svg?job=edge-release) +![License](https://img.shields.io/badge/license-MIT-blue) + +## Description + +Holo Key Manager is a browser extension for generating and managing Holochain application keys, and using them with applications hosted on the Holo Network. Users install the extension and perform a one-time setup. They can then use a "passwordless" sign up and log in with compatible applications. Non-sensitive data is cloud-synced so that a user can maintain the same set of keys across multiple devices. + +## Usage + +A javascript client library is available at `@holo-host/holo-key-manager-js-client`. See client documentation [here](holo-key-manager-js-client/README.md) + +## Architecture + +Holo Key Manager is expected to be used for Holo-hosted applications in conjunction with the Chaperone connection manager. The diagram below provides context of how Holo Key Manager interfaces with the rest of the Holo Hosting stack. Note that Deepkey is not currently implemented and is currently substituted by a centralised store. + +![Holo Hosting Architecture Diagram](./arch_1.png) + +The diagram below depicts the architecture of the Holo Key Manager itself. It demonstrates the client's interaction with the extension and outlines the communication schema between the webapp and the extension API. + +![Holo Key Manager Architecture Diagram](./arch_2.png) + +## Roadmap + +The priority items are: + +1. Replace the centralised Cloud Sync component with Deepkey +2. Implement features to interact with Deepkey for key revocation and rotation + +## Development Setup + +## Testing + +## License + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +## Contact + +For any questions or support, please contact: + +- [@mrruby](https://github.com/mrruby) +- [@alastairong](https://github.com/alastairong) + +Feel free to reach out with any questions or suggestions. diff --git a/arch_1.png b/arch_1.png new file mode 100644 index 0000000000000000000000000000000000000000..72baaf444ad122cf1422d806c9052c1eee12b1ae GIT binary patch literal 41054 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 L?-$ Date: Mon, 24 Jun 2024 11:54:50 +0100 Subject: [PATCH 2/4] change badges --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8d284d3..3b1a814 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Holo Key Manager ![Client Build](https://github.com/holo-host/holo-key-manager/actions/workflows/client.yaml/badge.svg) -![Chrome Release](https://github.com/holo-host/holo-key-manager/actions/workflows/extension.yaml/badge.svg?job=chrome-release) -![Firefox Release](https://github.com/holo-host/holo-key-manager/actions/workflows/extension.yaml/badge.svg?job=firefox-release) -![Edge Release](https://github.com/holo-host/holo-key-manager/actions/workflows/extension.yaml/badge.svg?job=edge-release) +![Chrome Release](https://img.shields.io/github/actions/workflow/status/holo-host/holo-key-manager/extension.yaml?label=Chrome%20Release&logo=google-chrome&style=flat-square&job=chrome-release) +![Firefox Release](https://img.shields.io/github/actions/workflow/status/holo-host/holo-key-manager/extension.yaml?label=Firefox%20Release&logo=firefox-browser&style=flat-square&job=firefox-release) +![Edge Release](https://img.shields.io/github/actions/workflow/status/holo-host/holo-key-manager/extension.yaml?label=Edge%20Release&logo=microsoft-edge&style=flat-square&job=edge-release) ![License](https://img.shields.io/badge/license-MIT-blue) ## Description From 8fb283cf5a6d775b0f232abb085f95bde352e2df Mon Sep 17 00:00:00 2001 From: Dawid Urbas Date: Mon, 24 Jun 2024 19:26:31 +0200 Subject: [PATCH 3/4] Add documentation --- README.md | 148 +++++++++++++++++++++++++++ holo-key-manager-extension/README.md | 8 -- 2 files changed, 148 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3b1a814..ffe0ba1 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,154 @@ The priority items are: ## Development Setup +To set up the development environment for the Holo Key Manager monorepo, follow these steps: + +### Prerequisites + +Ensure you have the following installed on your machine: + +- Node.js (v16 or higher) +- pnpm (v7 or higher) + +Additionally, request the `.env` file from the codebase maintainer. Once you receive it, ensure that it matches the structure and keys provided in the `.env.example` file. + +### Initial Setup + +1. **Clone the repository:** + + ```sh + git clone https://github.com/holo-host/holo-key-manager.git + cd holo-key-manager + ``` + +2. **Install dependencies:** + ```sh + pnpm install + ``` + +### Building the Projects + +The monorepo consists of two main projects: `holo-key-manager-extension` and `holo-key-manager-js-client`, and a shared directory. You can build these projects using the following commands: + +1. **Build the extension:** + + ```sh + pnpm buildExtension + ``` + +2. **Build the client:** + + ```sh + pnpm buildClient + ``` + +3. **Build both projects for development:** + ```sh + pnpm build + ``` + +### Loading Extension Files into Chrome Browser + +After building the extension, you need to load it into your Chrome browser to test and use it. Follow these steps: + +1. **Open Chrome and navigate to the Extensions page:** + + Open Chrome and go to `chrome://extensions/` or click on the three dots in the upper right corner, then go to `More tools` > `Extensions`. + +2. **Enable Developer Mode:** + + In the top right corner of the Extensions page, toggle the switch to enable Developer Mode. + +3. **Load the unpacked extension:** + + Click on the "Load unpacked" button that appears after enabling Developer Mode. This will open a file dialog. + +4. **Select the build folder:** + + Navigate to the `holo-key-manager-extension/build` directory in your file system and select it. This will load the extension into Chrome. + +5. **Verify the extension is loaded:** + + You should see the Holo Key Manager extension listed on the Extensions page. Ensure there are no errors and the extension is enabled. + +By following these steps, you can load and test the Holo Key Manager extension in your Chrome browser. If you encounter any issues, check the console for error messages and ensure that the build process completed successfully. + +### Working with holo-key-manager-js-client + +If you want to work on the interaction between the extension and the client, you need to run the `buildPack` script inside the `holo-key-manager-js-client` directory. This will create a `.tgz` file that you can link to your new web app. + +1. **Build the client package:** + + ```sh + cd holo-key-manager-js-client + pnpm buildPack + ``` + +2. **Create a new web app:** + + You can use any framework of your choice. Here are examples for Create React App and a new Svelte project. + + **Create React App:** + + ```sh + npx create-react-app my-holo-app + cd my-holo-app + ``` + + **New Svelte Project:** + + ```sh + npx degit sveltejs/template my-holo-app + cd my-holo-app + pnpm install + ``` + +3. **Link the `.tgz` file:** + + After building the client package, link the generated `.tgz` file to your new web app. + + ```sh + pnpm add ../holo-key-manager-js-client/holo-key-manager-js-client-1.0.0.tgz + ``` + +4. **Call API functions:** + + You can now call the API functions defined in the `README` of `holo-key-manager-js-client`. Here is an example of how to use the API in your new web app. + +By following these steps, you can set up a new web app and interact with the Holo Key Manager extension using the `holo-key-manager-js-client` API. + +### Linting and Formatting + +To ensure code quality and consistency, use the following commands: + +1. **Lint the code:** + + ```sh + pnpm lint + ``` + +2. **Format the code:** + + ```sh + pnpm format + ``` + +3. **Run linting and formatting together:** + ```sh + pnpm lintAndFormat + ``` + +### Project Structure + +- **holo-key-manager-js-client:** Contains the JavaScript client library for managing Holo keys. +- **holo-key-manager-extension:** Contains the browser extension for managing Holo keys. + +### Workspaces + +The monorepo uses pnpm workspaces to manage dependencies and scripts across multiple projects. The workspaces are defined in the root `package.json`: + +By following these steps, you should be able to set up and start developing on the Holo Key Manager monorepo. If you encounter any issues or have questions, feel free to reach out to the maintainers. + ## Testing ## License diff --git a/holo-key-manager-extension/README.md b/holo-key-manager-extension/README.md index 50d7747..0ccc181 100644 --- a/holo-key-manager-extension/README.md +++ b/holo-key-manager-extension/README.md @@ -1,11 +1,3 @@ # Holo Key Manager Holo Key Manager is a secure key manager for creating and managing Holochain keys. Get easy access to all your keys. You can set up and manager one or more keys for each application. - -# How to Test Locally - -1. Be sure that you have `pnpm` installed on your machine. If not, you can get it from [here](https://pnpm.io/). -2. Run `pnpm install` in the project directory. -3. Run `pnpm build` in the project directory. -4. Open the Chrome browser, navigate to `Manage Extensions`, click `Load Unpacked`, and select the `build` folder from this project. -5. The extension should be listed in the extension list. From a4b244ceed0a52c21ba19724a4cf786492e23daa Mon Sep 17 00:00:00 2001 From: Dawid Urbas Date: Tue, 25 Jun 2024 08:27:03 +0200 Subject: [PATCH 4/4] Fix README --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ffe0ba1..85bc0a9 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,11 @@ Ensure you have the following installed on your machine: - Node.js (v16 or higher) - pnpm (v7 or higher) -Additionally, request the `.env` file from the codebase maintainer. Once you receive it, ensure that it matches the structure and keys provided in the `.env.example` file. +To run e2e tests you need to create a `.env` file with +`CHROME_ID=eggfhkdnfdhdpmkfpihjjbnncgmhihce` +that corresponds to the key property (which is actually the pub_key) in `holo-key-manager-extension/static/manifest.json`. + +The rest of the `.env` properties visible in `.env.example` are for CI/CD. ### Initial Setup @@ -172,7 +176,7 @@ To ensure code quality and consistency, use the following commands: ### Project Structure -- **holo-key-manager-js-client:** Contains the JavaScript client library for managing Holo keys. +- **holo-key-manager-js-client:** Contains the JavaScript client library for interacting with the key manager and stored keys. - **holo-key-manager-extension:** Contains the browser extension for managing Holo keys. ### Workspaces