Skip to content

Commit

Permalink
Add new automation
Browse files Browse the repository at this point in the history
  • Loading branch information
mrruby committed Apr 16, 2024
1 parent 039b7a4 commit 99044b1
Show file tree
Hide file tree
Showing 18 changed files with 161 additions and 166 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ EDGE_ACCESS_TOKEN_URL=your_edge_access_token_url
FF_ID=your_firefox_id
FF_JWT_ISSUER=your_firefox_jwt_issuer
FF_JWT_SECRET=your_firefox_jwt_secret
NPM_TOKEN=your_npm_token


31 changes: 31 additions & 0 deletions .github/workflows/client.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: 'client'
on:
push:
branches: [main]
paths:
- 'holo-key-manager-js-client/package.json'

jobs:
build:
runs-on: ubuntu-latest

environment:
name: Client

steps:
- uses: actions/checkout@v4
- name: Setup Node.js environment
uses: actions/setup-node@v4
- name: Install pnpm
run: npm install -g pnpm
- name: Install dependencies
run: pnpm install
working-directory: holo-key-manager-js-client
- name: Build and pack
run: pnpm buildPack
working-directory: holo-key-manager-js-client
- name: Publish to npm
run: npm publish
working-directory: holo-key-manager-js-client
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 'test'
name: 'extension'
on:
push:
branches: [main]
Expand All @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest

environment:
name: test
name: Extension

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -51,7 +51,7 @@ jobs:
run: npm install -g pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile=false
run: pnpm install

- name: Build extension
run: pnpm build
Expand Down
2 changes: 1 addition & 1 deletion holo-key-manager-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@tanstack/svelte-query": "^5.28.6",
"clsx": "^2.1.0",
"file-saver": "^2.0.5",
"hcSeedBundle": "github:mrruby/hcSeedBundle#v0.0.4",
"hcSeedBundle": "github:mrruby/hcSeedBundle#v0.0.5",
"jszip": "^3.10.1",
"svelte": "^4.2.12",
"tailwindcss": "^3.4.1",
Expand Down
10 changes: 4 additions & 6 deletions holo-key-manager-extension/src/lib/helpers/queries.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { encodeHashToBase64 } from '@holochain/client';
import type { QueryClient } from '@tanstack/svelte-query';

import { unlockKey } from '$services';
Expand All @@ -11,7 +10,7 @@ import {
SESSION,
SESSION_STORAGE_KEY
} from '$shared/const';
import { parseMessageSchema } from '$shared/helpers';
import { parseMessageSchema, uint8ArrayToBase64 } from '$shared/helpers';
import { sendMessage, storageService } from '$shared/services';
import {
AppsListSchema,
Expand Down Expand Up @@ -91,10 +90,11 @@ export const deriveSignPubKey = async (newIndex: number) => {

const keyUnlocked = await unlockKey(sessionKey.data, SESSION);
const { signPubKey } = keyUnlocked.derive(newIndex);

keyUnlocked.zero();

const validatedSchema = PubKeySchema.safeParse({
pubKey: signPubKey
pubKey: uint8ArrayToBase64(signPubKey)
});

if (!validatedSchema.success) {
Expand All @@ -119,10 +119,8 @@ export const signMessage = async (message: string, index: number) => {
keyUnlocked.zero();
appKey.zero();

const encodedMessage = encodeHashToBase64(signedMessage);

const validatedSchema = SuccessMessageSignedSchema.safeParse({
message: encodedMessage
message: uint8ArrayToBase64(signedMessage)
});

if (!validatedSchema.success) {
Expand Down
8 changes: 4 additions & 4 deletions holo-key-manager-extension/src/lib/services/generate-keys.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// eslint-disable-next-line
// @ts-nocheck
import { decodeHashFromBase64, encodeHashToBase64 } from '@holochain/client';
import * as hcSeedBundle from 'hcSeedBundle';

import { base64ToUint8Array, uint8ArrayToBase64 } from '$shared/helpers';
import type { GeneratedKeys } from '$types';

const lock = (root: never, password: string) =>
Expand Down Expand Up @@ -57,7 +57,7 @@ export async function generateKeys(

return {
encodedMaster: encodedMasterBytes,
encodedDeviceWithExtensionPassword: encodeHashToBase64(encodedDeviceBytesWithExtensionPassword),
encodedDeviceWithExtensionPassword: uint8ArrayToBase64(encodedDeviceBytesWithExtensionPassword),
encodedDevice: encodedDeviceBytes,
encodedRevocation: encodedRevocationBytes
};
Expand All @@ -73,14 +73,14 @@ export const lockKey = async (key: unknown, password: string) => {

key.zero();

return encodeHashToBase64(encodedBytes);
return uint8ArrayToBase64(encodedBytes);
};

export const unlockKey = async (encodedBytesString: string, password: string) => {
await hcSeedBundle.seedBundleReady;

const cipherList = hcSeedBundle.UnlockedSeedBundle.fromLocked(
decodeHashFromBase64(encodedBytesString)
base64ToUint8Array(encodedBytesString)
);

if (!(cipherList[0] instanceof hcSeedBundle.LockedSeedCipherPwHash)) {
Expand Down
2 changes: 1 addition & 1 deletion holo-key-manager-extension/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
const requestPermission = async () => {
if (isChromePermissionsSafe()) {
const granted = await chrome.permissions.request({ origins: ['*://localhost/*'] });
const granted = await chrome.permissions.request({ origins: ['<all_urls>'] });
permissionGranted = granted;
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script lang="ts">
import { encodeHashToBase64 } from '@holochain/client';
import fileSaver from 'file-saver';
import JSZip from 'jszip';
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
import { AppParagraph, Button, Title } from '$components';
import { uint8ArrayToBase64 } from '$shared/helpers';
import { keysStore } from '$stores';
onMount(() => {
Expand All @@ -25,15 +25,15 @@
const files = [
{
name: 'master.txt',
data: encodeHashToBase64(keys.encodedMaster)
data: uint8ArrayToBase64(keys.encodedMaster)
},
{
name: 'device.txt',
data: encodeHashToBase64(keys.encodedDevice)
data: uint8ArrayToBase64(keys.encodedDevice)
},
{
name: 'revocation.txt',
data: encodeHashToBase64(keys.encodedRevocation)
data: uint8ArrayToBase64(keys.encodedRevocation)
}
];
const zip = new JSZip();
Expand Down
4 changes: 2 additions & 2 deletions holo-key-manager-extension/static/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "Holo key manager",
"description": "A browser extension to manage holo keys",
"version": "0.0.45",
"version": "0.0.46",
"manifest_version": 3,
"action": {
"default_title": "Holo key manager",
Expand All @@ -18,7 +18,7 @@
"permissions": ["activeTab", "storage", "tabs", "nativeMessaging"],
"content_scripts": [
{
"matches": ["*://localhost/*"],
"matches": ["<all_urls>"],
"js": ["scripts/content.js"],
"all_frames": true
}
Expand Down
5 changes: 3 additions & 2 deletions holo-key-manager-js-client/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "holo-key-manager-js-client",
"version": "1.0.0",
"version": "0.0.1",
"description": "A JavaScript client API for managing Holo keys",
"main": "lib/index.js",
"types": "lib/holo-key-manager-js-client/src/index.d.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"buildPack": "rm -rf lib/* && rollup -c && npm pack"
"build": "rm -rf lib/* && rollup -c",
"buildPack": "npm run build && npm pack"
},
"keywords": [
"holo",
Expand Down
26 changes: 26 additions & 0 deletions holo-key-manager-js-client/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,37 @@
import { HOLO_KEY_MANAGER_EXTENSION_MARKER_ID, SENDER_WEBAPP } from '@shared/const';
import { parseMessageSchema } from '@shared/helpers';
import { createMessageWithId } from '@shared/services';
import { type Message, type MessageWithId, MessageWithIdSchema } from '@shared/types';

let timeoutId: number | null = null;

const isWindowDefined = () => typeof window !== 'undefined';

const isExpectedPayload = <T>(payload: unknown): payload is T => {
return typeof payload === 'object' && payload !== null;
};

export const parseMessageAndCheckAction = (response: MessageWithId, expectedAction: string) => {
const parsedMessageSchema = parseMessageSchema(response);
const { action } = parsedMessageSchema.data;

if (action !== expectedAction) {
throw new Error(parsedMessageSchema.data.action);
}

return parsedMessageSchema.data;
};

export const parseMessagePayload = <T>(response: MessageWithId, expectedAction: string): T => {
const data = parseMessageAndCheckAction(response, expectedAction);

if ('payload' in data && isExpectedPayload<T>(data.payload)) {
return data.payload;
}

throw new Error(data.action);
};

export const sendMessage = (message: Message): Promise<MessageWithId> =>
new Promise((resolve, reject) => {
if (!isWindowDefined()) {
Expand Down
71 changes: 39 additions & 32 deletions holo-key-manager-js-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ import {
SIGN_UP,
SIGN_UP_SUCCESS
} from '@shared/const';
import { parseMessageSchema } from '@shared/helpers';
import { type MessageWithId, type SignUpSuccessPayload } from '@shared/types';
import { base64ToUint8Array, uint8ArrayToBase64 } from '@shared/helpers';
import { type PubKey, type SignUpSuccessPayload, type SuccessMessageSigned } from '@shared/types';

import { checkContentScriptAndBrowser, sendMessage } from './helpers';
import {
checkContentScriptAndBrowser,
parseMessageAndCheckAction,
parseMessagePayload,
sendMessage
} from './helpers';
import type { HoloKeyManagerConfig, IHoloKeyManager } from './types';

const createHoloKeyManager = ({
Expand All @@ -23,25 +28,7 @@ const createHoloKeyManager = ({
requireRegistrationCode,
requireEmail
}: HoloKeyManagerConfig): IHoloKeyManager => {
const handleResponseWithData = <T>(response: MessageWithId, action: string): T => {
const parsedMessageSchema = parseMessageSchema(response);

if ('payload' in parsedMessageSchema.data && parsedMessageSchema.data.action === action) {
return parsedMessageSchema.data.payload as T;
} else {
throw new Error(parsedMessageSchema.data.action);
}
};

const handleResponse = (response: MessageWithId, expectedAction: string): void => {
const parsedMessageSchema = parseMessageSchema(response);

if (parsedMessageSchema.data.action !== expectedAction) {
throw new Error(parsedMessageSchema.data.action);
}
};

const performSignUpAction = async (): Promise<SignUpSuccessPayload> => {
const performSignUpAction = async () => {
checkContentScriptAndBrowser();
const response = await sendMessage({
action: SIGN_UP,
Expand All @@ -55,10 +42,18 @@ const createHoloKeyManager = ({
},
sender: SENDER_WEBAPP
});
return handleResponseWithData(response, SIGN_UP_SUCCESS);
const { pubKey, email, registrationCode } = parseMessagePayload<SignUpSuccessPayload>(
response,
SIGN_UP_SUCCESS
);
return {
pubKey: base64ToUint8Array(pubKey),
email,
registrationCode
};
};

const performSignInAction = async (): Promise<SignUpSuccessPayload> => {
const performSignInAction = async () => {
checkContentScriptAndBrowser();
const response = await sendMessage({
action: SIGN_IN,
Expand All @@ -67,32 +62,44 @@ const createHoloKeyManager = ({
},
sender: SENDER_WEBAPP
});
return handleResponseWithData(response, SIGN_IN_SUCCESS);

const { pubKey } = parseMessagePayload<PubKey>(response, SIGN_IN_SUCCESS);

return {
pubKey: base64ToUint8Array(pubKey)
};
};

const performSignOutAction = async (): Promise<void> => {
const performSignMessageAction = async (messageToSign: Uint8Array) => {
checkContentScriptAndBrowser();
const encodedMessage = uint8ArrayToBase64(messageToSign);
const response = await sendMessage({
action: SIGN_OUT,
action: SIGN_MESSAGE,
payload: {
message: encodedMessage,
happId
},
sender: SENDER_WEBAPP
});
return handleResponse(response, SIGN_OUT_SUCCESS);

const { message } = parseMessagePayload<SuccessMessageSigned>(response, SIGN_MESSAGE_SUCCESS);

return {
message: base64ToUint8Array(message)
};
};

const performSignMessageAction = async (message: string): Promise<string> => {
const performSignOutAction = async () => {
checkContentScriptAndBrowser();
const response = await sendMessage({
action: SIGN_MESSAGE,
action: SIGN_OUT,
payload: {
message,
happId
},
sender: SENDER_WEBAPP
});
return handleResponseWithData(response, SIGN_MESSAGE_SUCCESS);

parseMessageAndCheckAction(response, SIGN_OUT_SUCCESS);
};

return {
Expand Down
Loading

0 comments on commit 99044b1

Please sign in to comment.