Skip to content

Commit

Permalink
Add auto sign
Browse files Browse the repository at this point in the history
  • Loading branch information
mrruby committed Apr 20, 2024
1 parent 5ceea60 commit 9e54a9a
Show file tree
Hide file tree
Showing 22 changed files with 172 additions and 130 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-disable @typescript-eslint/no-var-requires */
// replaceForFirefox.cjs
const fs = require('fs');
const path = require('path');
const backgroundScriptPath = path.resolve(__dirname, '../build/scripts/background.js');

fs.readFile(backgroundScriptPath, 'utf8', (err, data) => {
if (err) {
console.error('Error reading the background script file:', err);
return;
}

let modifiedData = data.replace(/global\./g, 'self.');

modifiedData = modifiedData.replace(
/var normalize = bufferUtil\.normalize;/g,
`var normalize = function (buffer) {
if (Buffer.isBuffer(buffer)) return buffer;
return Buffer.from(buffer.buffer, buffer.byteOffset, buffer.byteLength);
};`
);

fs.writeFile(backgroundScriptPath, modifiedData, 'utf8', (err) => {
if (err) {
console.error('Error writing the modified background script file:', err);
return;
}

console.log('Background script file modified successfully.');
});
});
6 changes: 4 additions & 2 deletions holo-key-manager-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
"version": "0.0.3",
"private": true,
"scripts": {
"build": "pnpm build:vite && pnpm build:script && pnpm build:removeInline",
"buildDev": "pnpm build:vite && pnpm build:script && pnpm build:removeInline && pnpm build:buildForFirefoxDev",
"buildCommon": "pnpm build:vite && pnpm build:script && pnpm build:fixBackgroundScriptForSigning && pnpm build:removeInline",
"build": "pnpm buildCommon",
"buildDev": "pnpm buildCommon && pnpm build:buildForFirefoxDev",
"build:vite": "vite build",
"build:script": "cd scripts && pnpm build && cd ..",
"build:removeInline": "node build-scripts/removeInlineScript.cjs",
"build:replaceForFirefox": "node build-scripts/replaceForFirefox.cjs",
"build:buildForFirefoxDev": "node build-scripts/devFirefox.cjs",
"build:fixBackgroundScriptForSigning": "node build-scripts/fixBackgroundScriptForSigning.cjs",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
Expand Down
21 changes: 15 additions & 6 deletions holo-key-manager-extension/scripts/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
SENDER_EXTENSION,
SIGN_IN,
SIGN_MESSAGE,
SIGN_MESSAGE_SUCCESS,
SIGN_OUT,
SIGN_OUT_SUCCESS,
SIGN_UP,
Expand All @@ -22,6 +23,12 @@ import {
type WindowProperties
} from '@shared/types';

import { signMessageLogic } from './helpers';

// Important: This script is modified by a
// post-build script (build-scripts/fixBackgroundScriptForSigning.cjs)
// which may alter some of its intended behavior.

let windowId: number | undefined;

type SendResponse = (response?: Message) => void;
Expand Down Expand Up @@ -149,12 +156,14 @@ const processMessage = async (message: Message, sendResponse: SendResponse) => {
})
: sendResponseWithSender({ action: NO_KEY_FOR_HAPP });
case SIGN_MESSAGE:
return (await isAuthenticated(parsedMessage.data.payload.happId))
? createOrUpdateDataResponseWindow(sendResponseWithSender, {
action: parsedMessage.data.action,
payload: parsedMessage.data.payload
})
: sendResponseWithSender({ action: NOT_AUTHENTICATED });
if (await isAuthenticated(parsedMessage.data.payload.happId)) {
const signedMessage = await signMessageLogic(parsedMessage.data.payload);
return sendResponseWithSender({
action: SIGN_MESSAGE_SUCCESS,
payload: signedMessage
});
}
return sendResponseWithSender({ action: NOT_AUTHENTICATED });
case SIGN_OUT:
signOut(parsedMessage.data.payload.happId);
return sendResponseWithSender({ action: SIGN_OUT_SUCCESS });
Expand Down
61 changes: 61 additions & 0 deletions holo-key-manager-extension/scripts/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { AUTHENTICATED_APPS_LIST, SESSION } from '@shared/const';
import { base64ToUint8Array, uint8ArrayToBase64 } from '@shared/helpers';
import { getSessionKey, storageService } from '@shared/services';
import {
AuthenticatedAppsListSchema,
type MessageToSign,
SuccessMessageSignedSchema
} from '@shared/types';
// @ts-expect-error no types for hcSeedBundle
import * as hcSeedBundle from 'hcSeedBundle';

export const signMessageLogic = async ({ message, happId }: MessageToSign) => {
const authenticatedAppsListData = await storageService.getWithoutCallback({
key: AUTHENTICATED_APPS_LIST,
area: SESSION
});

const parsedAuthenticatedAppsListData =
AuthenticatedAppsListSchema.safeParse(authenticatedAppsListData);

if (!parsedAuthenticatedAppsListData.success) {
throw new Error('Failed to parse authenticated apps list data');
}

const index = parsedAuthenticatedAppsListData.data[happId];
const sessionKey = await getSessionKey();

if (!sessionKey.success) {
throw new Error('Session data not found');
}

await hcSeedBundle.seedBundleReady;

const cipherList = hcSeedBundle.UnlockedSeedBundle.fromLocked(
base64ToUint8Array(sessionKey.data)
);

if (!(cipherList[0] instanceof hcSeedBundle.LockedSeedCipherPwHash)) {
throw new Error('Expecting PwHash');
}

const pw = new TextEncoder().encode(SESSION);
const keyUnlocked = cipherList[0].unlock(hcSeedBundle.parseSecret(pw));

const appKey = keyUnlocked.derive(index);

const signedMessage = appKey.sign(message);

keyUnlocked.zero();
appKey.zero();

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

if (!validatedSchema.success) {
throw new Error('Invalid message');
}

return validatedSchema.data;
};
8 changes: 8 additions & 0 deletions holo-key-manager-extension/scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,13 @@
"type": "module",
"scripts": {
"build": "rollup -c"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-inject": "^5.0.5",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.5",
"buffer": "^6.0.3",
"rollup-plugin-node-polyfills": "^0.2.1"
}
}
21 changes: 19 additions & 2 deletions holo-key-manager-extension/scripts/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import inject from '@rollup/plugin-inject';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import nodePolyfills from 'rollup-plugin-node-polyfills';
import tscAlias from 'rollup-plugin-tsc-alias';
import typescript from 'rollup-plugin-typescript2';

Expand All @@ -8,7 +12,20 @@ const createConfig = (input, file) => ({
file,
format: 'esm'
},
plugins: [tscAlias(), typescript(), resolve()]
plugins: [
tscAlias(),
nodePolyfills(),
nodeResolve({ preferBuiltins: true }),
commonjs(),
inject({
Buffer: ['buffer', 'Buffer']
}),
replace({
preventAssignment: true,
global: 'self'
}),
typescript()
]
});

export default [
Expand Down
2 changes: 1 addition & 1 deletion holo-key-manager-extension/scripts/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
"compilerOptions": {
"outDir": "../build"
},
"include": ["background.ts", "content.ts"]
"include": ["background.ts", "content.ts", "helpers.ts"]
}
43 changes: 3 additions & 40 deletions holo-key-manager-extension/src/lib/helpers/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,16 @@ import {
BACKGROUND_SCRIPT_RECEIVED_DATA,
LOCAL,
PASSWORD,
SESSION,
SESSION_STORAGE_KEY
SESSION
} from '$shared/const';
import { parseMessageSchema, uint8ArrayToBase64 } from '$shared/helpers';
import { sendMessage, storageService } from '$shared/services';
import { getSessionKey, sendMessage, storageService } from '$shared/services';
import {
AppsListSchema,
AuthenticatedAppsListSchema,
HashSaltSchema,
type Message,
PubKeySchema,
SessionStateSchema,
SuccessMessageSignedSchema
PubKeySchema
} from '$shared/types';

export const handleSuccess = (queryClient: QueryClient, queryKey: string[]) => () =>
Expand All @@ -33,14 +30,6 @@ export const getPassword = async () => {
return HashSaltSchema.safeParse(data);
};

export const getSessionKey = async () => {
const data = await storageService.getWithoutCallback({
key: SESSION_STORAGE_KEY,
area: SESSION
});
return SessionStateSchema.safeParse(data);
};

export const fetchAndParseAppsList = async () => {
const appsListData = await storageService.getWithoutCallback({
key: APPS_LIST,
Expand Down Expand Up @@ -103,29 +92,3 @@ export const deriveSignPubKey = async (newIndex: number) => {

return validatedSchema.data;
};

export const signMessage = async (message: string, index: number) => {
const sessionKey = await getSessionKey();

if (!sessionKey.success) {
throw new Error('Session data not found');
}

const keyUnlocked = await unlockKey(sessionKey.data, SESSION);
const appKey = keyUnlocked.derive(index);

const signedMessage = appKey.sign(message);

keyUnlocked.zero();
appKey.zero();

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

if (!validatedSchema.success) {
throw new Error('Invalid message');
}

return validatedSchema.data;
};
24 changes: 1 addition & 23 deletions holo-key-manager-extension/src/lib/queries/applicationQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {
fetchAndParseAppsList,
fetchAuthenticatedAppsList,
handleSuccess,
sendMessageAndHandleResponse,
signMessage
sendMessageAndHandleResponse
} from '$helpers';
import {
APPLICATION_KEYS,
Expand All @@ -17,7 +16,6 @@ import {
SENDER_EXTENSION,
SESSION,
SIGN_IN_SUCCESS,
SIGN_MESSAGE_SUCCESS,
SIGN_UP_SUCCESS
} from '$shared/const';
import { storageService } from '$shared/services';
Expand Down Expand Up @@ -121,26 +119,6 @@ export function createSignInWithKeyMutation(queryClient: QueryClient) {
});
}

export function createMessageMutation() {
return createMutation({
mutationFn: async (signMessageData: { happId: string; message: string }) => {
const { happId, message } = signMessageData;

const currentAuthenticatedAppsList = await fetchAuthenticatedAppsList(happId);

const index = currentAuthenticatedAppsList[happId];

const signedMessage = await signMessage(message, index);

await sendMessageAndHandleResponse({
sender: SENDER_EXTENSION,
action: SIGN_MESSAGE_SUCCESS,
payload: signedMessage
});
}
});
}

export function createSignedInApplicationKeysIndexQuery() {
return (happId: string) => {
return createQuery({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { createMutation, createQuery, QueryClient } from '@tanstack/svelte-query';

import { getSessionKey, handleSuccess } from '$helpers';
import { handleSuccess } from '$helpers';
import { unlockKey } from '$services';
import { DEVICE_KEY, LOCAL, PASSWORD, SESSION_DATA_KEY, SETUP_KEY } from '$shared/const';
import { isSetupComplete, storageService } from '$shared/services';
import { getSessionKey, isSetupComplete, storageService } from '$shared/services';
import { EncryptedDeviceKeySchema, HashSaltSchema } from '$shared/types';
import { deviceKeyContentStore, passphraseStore } from '$stores';

Expand Down
5 changes: 1 addition & 4 deletions holo-key-manager-extension/src/lib/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useQueryClient } from '@tanstack/svelte-query';
import {
createApplicationKeyMutation,
createApplicationKeysQuery,
createMessageMutation,
createSignInWithKeyMutation
} from './applicationQueries';
import {
Expand Down Expand Up @@ -31,7 +30,6 @@ export function appQueries() {
const setupPasswordQuery = createSetupPasswordQuery();
const applicationKeysQueryFunction = createApplicationKeysQuery();
const signInMutation = createSignInMutation(queryClient);
const messageMutation = createMessageMutation();
const storeDeviceKey = createStoreDeviceKey(queryClient);
const recoverDeviceKeyMutation = createRecoverDeviceKeyMutation();
const applicationKeyMutation = createApplicationKeyMutation(queryClient);
Expand All @@ -49,7 +47,6 @@ export function appQueries() {
recoverDeviceKeyMutation,
passwordAndStoreDeviceKeyMutation,
applicationKeysQueryFunction,
signInWithKeyMutation,
messageMutation
signInWithKeyMutation
};
}
2 changes: 1 addition & 1 deletion holo-key-manager-extension/src/lib/services/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './generate-keys';
export * from './manage-keys';
3 changes: 1 addition & 2 deletions holo-key-manager-extension/src/lib/stores/keys-store.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { writable } from 'svelte/store';

import { generateKeys } from '$services';
import type { KeysState } from '$types';

import { generateKeys } from '../services/generate-keys';

const initKeysStore = () => {
const initialState: KeysState = {
keys: {
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 @@ -19,7 +19,7 @@
onMount(async () => {
if (isChromePermissionsSafe()) {
const permissions = await chrome.permissions.getAll();
permissionGranted = permissions.origins?.includes('*://localhost/*') ?? false;
permissionGranted = permissions.origins?.includes('<all_urls>') ?? false;
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { goto } from '$app/navigation';
import { ActionPage } from '$components';
import { extractDetailsFromUrl } from '$helpers';
import { SIGN_IN, SIGN_MESSAGE } from '$shared/const';
import { SIGN_IN } from '$shared/const';
const submitFormData = () => {
goto(`create-key?${new URLSearchParams(window.location.search)}`);
Expand All @@ -14,9 +14,6 @@
if ($extractDetailsFromUrl.action === SIGN_IN) {
goto(`select-key-to-login?${new URLSearchParams(window.location.search)}`);
}
if ($extractDetailsFromUrl.action === SIGN_MESSAGE) {
goto(`sign-message?${new URLSearchParams(window.location.search)}`);
}
});
</script>

Expand Down
Loading

0 comments on commit 9e54a9a

Please sign in to comment.