Skip to content

Commit a04e4e0

Browse files
Merge pull request #1333 from dfinity/vetkeys-password-manager
feat: add vetkeys password manager example
2 parents 07adc55 + dfb0671 commit a04e4e0

66 files changed

Lines changed: 3068 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# VetKey Password Manager
2+
3+
| Motoko backend | [![](https://icp.ninja/assets/open.svg)](http://icp.ninja/editor?g=https://github.com/dfinity/examples/tree/master/rust/vetkeys/password_manager/motoko)|
4+
| --- | --- |
5+
| Rust backend | [![](https://icp.ninja/assets/open.svg)](http://icp.ninja/editor?g=https://github.com/dfinity/examples/tree/master/rust/vetkeys/password_manager/rust) |
6+
7+
The **VetKey Password Manager** is an example application demonstrating how to use **VetKeys** and **Encrypted Maps** to build a secure, decentralized password manager on the **Internet Computer (IC)**. This application allows users to create password vaults, store encrypted passwords, and share vaults with other users via their **Internet Identity Principal**.
8+
9+
## Features
10+
11+
- **Secure Password Storage**: Uses VetKey to encrypt passwords before storing them in Encrypted Maps.
12+
- **Vault-Based Organization**: Users can create multiple vaults, each containing multiple passwords.
13+
- **Access Control**: Vaults can be shared with other users via their **Internet Identity Principal**.
14+
15+
## Setup
16+
17+
### Prerequisites
18+
19+
- [Local Internet Computer dev environment](https://internetcomputer.org/docs/building-apps/getting-started/install)
20+
- [npm](https://www.npmjs.com/package/npm)
21+
22+
### (Optionally) Choose a Different Master Key
23+
24+
This example uses `test_key_1` by default. To use a different [available master key](https://internetcomputer.org/docs/building-apps/network-features/vetkeys/api#available-master-keys), change the `"init_arg": "(\"test_key_1\")"` line in `dfx.json` to the desired key before running `dfx deploy` in the next step.
25+
26+
### Deploy the Canisters Locally
27+
If you want to deploy this project locally with a Motoko backend, then run:
28+
```bash
29+
dfx start --background && dfx deploy
30+
```
31+
from the `motoko` folder.
32+
33+
To use the Rust backend instead of Motoko, run the same command in the `rust` folder.
34+
35+
## Running the Project
36+
37+
### Backend
38+
39+
The backend consists of an **Encrypted Maps**-enabled canister that securely stores passwords. It is automatically deployed with `dfx deploy`.
40+
41+
### Frontend
42+
43+
The frontend is a **Svelte** application providing a user-friendly interface for managing vaults and passwords.
44+
45+
To run the frontend in development mode with hot reloading:
46+
47+
```bash
48+
npm run dev
49+
```
50+
51+
## Limitations
52+
53+
This example dapp does not implement key rotation, which is strongly recommended in a production environment.
54+
Key rotation involves periodically changing encryption keys and re-encrypting data to enhance security.
55+
In a production dapp, key rotation would be useful to limit the impact of potential key compromise if a malicious party gains access to a key, or to limit access when users are added or removed from note sharing.
56+
57+
## Additional Resources
58+
59+
- **[Password Manager with Metadata](../password_manager_with_metadata/)** - If you need to store additional metadata alongside passwords.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Ignore artifacts:
2+
build
3+
coverage
4+
dist
5+
README.md
6+
**/declarations/
7+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"plugins": ["prettier-plugin-svelte"],
3+
"tabWidth": 4,
4+
"overrides": [{ "files": ["*.svelte"], "options": { "parser": "svelte" } }]
5+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# VetKD Password Manager frontend
2+
Uses the defaults provided by the devkit to implement a VetKD-based password
3+
manager. This utilizes the encrypted maps canister example to realize the
4+
password manager, i.e., there is no dedicated canister implementation, only the
5+
frontend implementation that uses all defaults from the SDK.
6+
7+
## Step 1: Deploy `encrypted_maps_example` canister and the internet identity canister.
8+
9+
## Step 2: Tell `frontend` what canisters to communicate with, so the following environment variables must be defined. For a local deployment, one can run `deploy_locally.sh` from that folder.
10+
* `CANISTER_ID_IC_VETKEYS_ENCRYPTED_MAPS_CANISTER`
11+
12+
## Step 3: Deploy frontend. This returns a link that can be used to access the frontend from the asset canister.
13+
```shell
14+
dfx deploy www
15+
```
16+
Note: if this returns a URL with the IP `0.0.0.0` and the fronetned does not
17+
work, a potential fix is to replace it with `localhost`.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// @ts-check
2+
3+
import eslint from "@eslint/js";
4+
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
5+
import globals from "globals";
6+
import tseslint from "typescript-eslint";
7+
import svelteConfig from "./svelte.config.js";
8+
import svelte from "eslint-plugin-svelte";
9+
10+
export default tseslint.config(
11+
eslint.configs.recommended,
12+
tseslint.configs.recommendedTypeChecked,
13+
...svelte.configs.recommended,
14+
eslintPluginPrettierRecommended,
15+
{
16+
languageOptions: {
17+
parserOptions: {
18+
projectService: {
19+
defaultProject: "./tsconfig.json",
20+
},
21+
tsconfigRootDir: import.meta.dirname,
22+
},
23+
globals: {
24+
...globals.browser,
25+
...globals.es2020,
26+
},
27+
},
28+
},
29+
{
30+
files: ["**/*.svelte", "**/*.svelte.ts", "**/*.svelte.js"],
31+
languageOptions: {
32+
parserOptions: {
33+
projectService: true,
34+
extraFileExtensions: [".svelte"],
35+
parser: tseslint.parser,
36+
svelteConfig,
37+
},
38+
},
39+
},
40+
{
41+
ignores: [
42+
"dist/",
43+
"src/declarations",
44+
"*.config.js",
45+
"*.config.cjs",
46+
"*.config.mjs",
47+
"*.config.ts",
48+
],
49+
},
50+
{
51+
rules: {
52+
"@typescript-eslint/no-unsafe-argument": "off",
53+
"@typescript-eslint/no-unsafe-member-access": "off",
54+
},
55+
},
56+
);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>VetKeys Password Manager</title>
8+
</head>
9+
<body>
10+
<div id="app"></div>
11+
<script type="module" src="/src/main.ts"></script>
12+
<link rel="stylesheet" href="./bundle.css" />
13+
</body>
14+
</html>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"name": "password-manager-frontend",
3+
"version": "0.1.0",
4+
"type": "module",
5+
"scripts": {
6+
"dev": "vite",
7+
"build": "vite build",
8+
"lint": "eslint",
9+
"prettier": "prettier --write .",
10+
"prettier-check": "prettier --check .",
11+
"preview": "vite preview"
12+
},
13+
"devDependencies": {
14+
"@rollup/plugin-typescript": "^12.1.2",
15+
"@tsconfig/svelte": "^5.0.4",
16+
"@typewriter/delta": "^1.2.4",
17+
"daisyui": "^4.12.23",
18+
"eslint-config-prettier": "^10.1.5",
19+
"eslint-plugin-prettier": "^5.2.6",
20+
"eslint-plugin-svelte": "^3.5.1",
21+
"globals": "^16.0.0",
22+
"prettier-plugin-svelte": "^3.4.0",
23+
"svelte": "^4.2.19",
24+
"tslib": "^2.8.1",
25+
"typescript-eslint": "^8.35.1",
26+
"vite": "^5.4.21",
27+
"vite-plugin-environment": "^1.1.3"
28+
},
29+
"dependencies": {
30+
"@dfinity/agent": "^2.3.0",
31+
"@dfinity/auth-client": "^2.3.0",
32+
"@dfinity/candid": "^2.3.0",
33+
"@dfinity/identity": "^2.3.0",
34+
"@dfinity/principal": "^2.3.0",
35+
"@dfinity/vetkeys": "^0.3.0",
36+
"@popperjs/core": "^2.11.8",
37+
"@sveltejs/vite-plugin-svelte": "^3.0.2",
38+
"@tailwindcss/postcss": "^4.0.6",
39+
"@tailwindcss/vite": "^4.0.0",
40+
"autoprefixer": "^10.4.20",
41+
"rollup-plugin-css-only": "^4.5.2",
42+
"svelte-icons": "^2.1.0",
43+
"svelte-spa-router": "^4.0.1",
44+
"tailwindcss": "^3.0.17",
45+
"typewriter-editor": "^0.9.4"
46+
}
47+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
{
3+
match: "**/*",
4+
security_policy: "hardened",
5+
headers: {
6+
"Content-Security-Policy": "default-src 'self';script-src 'self';connect-src 'self' http://localhost:* https://icp0.io https://*.icp0.io https://icp-api.io;img-src 'self' data:;style-src * 'unsafe-inline';object-src 'none';base-uri 'self';frame-ancestors 'none';form-action 'self';upgrade-insecure-requests;",
7+
},
8+
allow_raw_access: false
9+
},
10+
]
6.12 KB
Loading
7.49 KB
Loading

0 commit comments

Comments
 (0)