From 096a79f4f4a40f170d51d3b0429535e4974a65ab Mon Sep 17 00:00:00 2001 From: AtHeartEngineer <1675654+AtHeartEngineer@users.noreply.github.com> Date: Mon, 13 Nov 2023 22:43:09 +0300 Subject: [PATCH] encrpyted rooms work --- package-lock.json | 8 +- package.json | 4 +- .../components/Gateways/EthereumGroup.svelte | 7 +- src/lib/components/Gateways/InviteCode.svelte | 14 +- src/lib/components/Gateways/TheWord.svelte | 6 +- src/lib/crypto/rlnProver.ts | 2 +- src/lib/services/api.ts | 20 ++ src/lib/services/server.ts | 19 +- src/lib/stores/index.ts | 2 +- src/lib/utils/identity.ts | 2 +- src/lib/utils/password.ts | 28 ++- src/routes/+layout.svelte | 4 +- src/routes/admin/+page.svelte | 3 + src/routes/admin/invite/+page.svelte | 45 ++-- src/routes/admin/join/+page.svelte | 4 +- src/routes/admin/newroom/+page.svelte | 7 +- src/routes/chat/BubbleText.svelte | 3 +- src/routes/chat/ChatInputPrompt.svelte | 41 ++-- src/routes/chat/ChatRoom.svelte | 37 +++- src/routes/chat/Conversation.svelte | 30 ++- src/routes/chat/Draw.svelte | 7 +- src/routes/chat/RoomEncryption.svelte | 8 +- src/routes/chat/RoomPassword.svelte | 128 +++++++++--- src/routes/console/ConsoleInputPrompt.svelte | 4 +- src/routes/settings/debug/+page.svelte | 13 +- src/routes/signup/[invite]/+page.svelte | 2 +- static/idcNullifier/circuit.config.toml | 8 +- static/idcNullifier/final.zkey | Bin 251097 -> 251097 bytes static/idcNullifier/verification_key.json | 197 +++++++++--------- 29 files changed, 408 insertions(+), 245 deletions(-) diff --git a/package-lock.json b/package-lock.json index af0186a..3bfdbc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "date-fns": "^2.30.0", "discreetly-interfaces": "^0.1.42", "dompurify": "^3.0.5", - "idc-nullifier": "^0.0.6", + "idc-nullifier": "^0.0.8", "libsodium-wrappers": "^0.7.11", "marked": "^7.0.5", "minidenticons": "^4.2.0", @@ -7209,9 +7209,9 @@ } }, "node_modules/idc-nullifier": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/idc-nullifier/-/idc-nullifier-0.0.6.tgz", - "integrity": "sha512-jM2D9ODNnmqn/Ps/cvpxSk4JTIrMG2Ozb0Z3a99jW5cd1DS7U5YBlHJRMRJn3sGyG3YIrIHyJQYoAWPBw5UiTA==", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/idc-nullifier/-/idc-nullifier-0.0.8.tgz", + "integrity": "sha512-fNR32XHu53AoAFA7rwVs2J67U/Za1hUpAPkIohwa05lnjXrwPMoA1zBeUutkdVRgmRBMbLpfAfXsUUnjqqpQQQ==", "dependencies": { "@semaphore-protocol/identity": "^3.10.1", "circomlib": "^2.0.5", diff --git a/package.json b/package.json index 1dddc1e..0fe69cd 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "date-fns": "^2.30.0", "discreetly-interfaces": "^0.1.42", "dompurify": "^3.0.5", - "idc-nullifier": "^0.0.6", + "idc-nullifier": "^0.0.8", "libsodium-wrappers": "^0.7.11", "marked": "^7.0.5", "minidenticons": "^4.2.0", @@ -86,4 +86,4 @@ "wagmi": "^1.4.3", "zuauth": "^0.3.0" } -} +} \ No newline at end of file diff --git a/src/lib/components/Gateways/EthereumGroup.svelte b/src/lib/components/Gateways/EthereumGroup.svelte index 7e504d3..d3558dd 100644 --- a/src/lib/components/Gateways/EthereumGroup.svelte +++ b/src/lib/components/Gateways/EthereumGroup.svelte @@ -63,7 +63,6 @@ loadingRooms = true; getEthAddressRoomNames($selectedServer, address) .then((groupNames) => { - console.log(groupNames); loadingRooms = false; groups = groupNames; }) @@ -84,8 +83,7 @@

Step 1: Connect your wallet

+ class="btn variant-outline-tertiary">Connect {#if isConnected}
@@ -106,8 +104,7 @@ + class="btn variant-outline-success">Sign
{:else if loadingRooms}

Loading rooms...

diff --git a/src/lib/components/Gateways/InviteCode.svelte b/src/lib/components/Gateways/InviteCode.svelte index 56f6e63..170e6f5 100644 --- a/src/lib/components/Gateways/InviteCode.svelte +++ b/src/lib/components/Gateways/InviteCode.svelte @@ -20,7 +20,7 @@ } }) .catch((err) => { - console.log(err); + console.warn(err); alertQueue.enqueue(`Unexpected error: ${err.message}`, 'error'); }) .finally(() => { @@ -90,8 +90,7 @@ {#if !hideInput} {/if} {#if !loading} @@ -108,8 +106,7 @@ class="btn variant-ghost-success mt-3" type="button" disabled={!code} - on:click={() => addCode(code)}>{buttonText} + on:click={() => addCode(code)}>{buttonText} {:else}
Going Anon, please wait...
@@ -120,8 +117,7 @@
If you are having trouble and would like help, please message us on Discord + class="underline link">Discord
{/if} diff --git a/src/lib/components/Gateways/TheWord.svelte b/src/lib/components/Gateways/TheWord.svelte index 99abd59..048e99a 100644 --- a/src/lib/components/Gateways/TheWord.svelte +++ b/src/lib/components/Gateways/TheWord.svelte @@ -16,7 +16,7 @@ } }) .catch((err) => { - console.log(err); + console.warn(err); alertQueue.enqueue(`Unexpected error: ${err.message}`, 'error'); }) .finally(() => { @@ -55,9 +55,7 @@ class="px-2" name="the-word-proof.json" bind:files - on:change={onChangeHandler} - /> + on:change={onChangeHandler} /> {#if loading} diff --git a/src/lib/crypto/rlnProver.ts b/src/lib/crypto/rlnProver.ts index c0766f0..146cebd 100644 --- a/src/lib/crypto/rlnProver.ts +++ b/src/lib/crypto/rlnProver.ts @@ -132,7 +132,7 @@ async function genProof( ); const proof = prover.generateProof(proofInputs).then((proof: RLNFullProof) => { - console.log('Proof generated!'); + console.info('Proof generated!'); const msg: MessageI = { messageId: proof.snarkProof.publicSignals.nullifier.toString(), message: message, diff --git a/src/lib/services/api.ts b/src/lib/services/api.ts index d241e92..f4ea74d 100644 --- a/src/lib/services/api.ts +++ b/src/lib/services/api.ts @@ -128,3 +128,23 @@ export async function getAuth( throw new Error(`Failed to post to ${url}`); } } + +/** + * @description - makes a get request to the api + * @param {string[] | string} urlParts - the url parts to be joined to form the url + * @param {object} data - the data to be sent to the api + * @returns {object} - the response from the api + * @throws {Error} - if the request fails + */ +export async function postRaw(urlParts: string[] | string, data: object): Promise { + const url = cleanURL(urlParts); + const res = await fetch(url, { + method: 'POST', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(data) + }); + return res; +} diff --git a/src/lib/services/server.ts b/src/lib/services/server.ts index 3fcd00f..e83a170 100644 --- a/src/lib/services/server.ts +++ b/src/lib/services/server.ts @@ -2,7 +2,7 @@ import type { MessageI, ServerI } from 'discreetly-interfaces'; import type { IdentityStoreI, Invites, JoinResponseI, JubmojiProofI, RoomI } from '$lib/types'; import { Prover } from 'idc-nullifier'; import type { Identity } from '@semaphore-protocol/identity'; -import { get, getAuth, post, postAuth } from './api'; +import { get, getAuth, post, postAuth, postRaw } from './api'; import { getIdentity } from '$lib/utils'; import { alertQueue } from '$lib/stores'; @@ -193,6 +193,22 @@ export async function postCheckRoomPassword( return Boolean(response.success); } +export async function postDoesRoomPasswordExist( + serverUrl: string, + roomId: string +): Promise { + const response = await postRaw([serverUrl, `room/checkpasswordhash/${roomId}`], { + passwordHash: 'passwordHash' + }); + if (response.status == 200 && (response.json() as unknown as CheckResponse).success == false) { + return false; + } else if (response.status == 400) { + return true; + } else { + return false; + } +} + export async function postSetRoomPassword( serverUrl: string, roomId: string, @@ -207,7 +223,6 @@ export async function postSetRoomPassword( idForProof.nullifier = id._nullifier; idForProof.secret = id._secret; idForProof.commitment = id._commitment; - // Proves you know the identity secret with a timestamp so this proof can't be replayed prover .generateProof({ diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts index c620376..1a6224f 100644 --- a/src/lib/stores/index.ts +++ b/src/lib/stores/index.ts @@ -65,7 +65,7 @@ export const pixelStore = sessionable({} as pixelStoreI, 'pixelmaps'); /** * @description Stores the encrypted key for each room keyed by the roomId */ -export const roomPassStore = encryptable({} as roomPassStoreI, 'roomKey'); +export const roomPassStore = encryptable({} as roomPassStoreI, 'roomPasses'); /** * @description Derived Store: The messages of the currently selected room diff --git a/src/lib/utils/identity.ts b/src/lib/utils/identity.ts index dad3528..b81574f 100644 --- a/src/lib/utils/identity.ts +++ b/src/lib/utils/identity.ts @@ -32,7 +32,7 @@ export function createIdentity( alertQueue.enqueue('Identity Created! Congrats on your new journey', 'success'); return 'created'; } else { - console.log(get(identityExists)); + console.warn(get(identityExists)); alertQueue.enqueue('Error creating identity!!!', 'error'); return 'error'; } diff --git a/src/lib/utils/password.ts b/src/lib/utils/password.ts index 422d9d3..5db6936 100644 --- a/src/lib/utils/password.ts +++ b/src/lib/utils/password.ts @@ -8,7 +8,8 @@ import { identityExists, alertQueue, roomPassStore, - selectedServer + selectedServer, + roomKeyStore } from '$lib/stores'; import { encryptIdentity } from './identity'; import type { IdentityStoreI } from '$lib/types'; @@ -75,6 +76,17 @@ export async function unlockPadlock(password: string) { identityKeyStore.read(); roomPassStore.read(); updateRooms(); + console.debug('Unlocking rooms'); + setTimeout(() => { + const roomPasses = get(roomPassStore); + Object.keys(roomPasses).forEach(async (roomId) => { + const roomKey = await deriveKey(roomPasses[roomId].password); + roomKeyStore.update((roomKeys) => { + roomKeys[roomId] = roomKey; + return roomKeys; + }); + }); + }, 50); }); } else { alertQueue.enqueue('Incorrect Password', 'warning'); @@ -85,12 +97,17 @@ export async function unlockPadlock(password: string) { export async function enterRoomPassword(password: string, roomId: string): Promise { const hashedSaltedPassword = await hashPassword(password + roomId); if (hashedSaltedPassword) { - postCheckRoomPassword(get(selectedServer), roomId, hashedSaltedPassword).then((res) => { + postCheckRoomPassword(get(selectedServer), roomId, hashedSaltedPassword).then(async (res) => { if (res) { roomPassStore.update((roomPass) => { roomPass[roomId] = { password, hashedSaltedPassword }; return roomPass; }); + const key = await deriveKey(password); + roomKeyStore.update((roomKeys) => { + roomKeys[roomId] = key; + return roomKeys; + }); return true; } else { return false; @@ -103,12 +120,17 @@ export async function enterRoomPassword(password: string, roomId: string): Promi export async function setRoomPassword(password: string, roomId: string): Promise { const hashedSaltedPassword = await hashPassword(password + roomId); if (hashedSaltedPassword) { - postSetRoomPassword(get(selectedServer), roomId, hashedSaltedPassword).then((res) => { + postSetRoomPassword(get(selectedServer), roomId, hashedSaltedPassword).then(async (res) => { if (res) { roomPassStore.update((roomPass) => { roomPass[roomId] = { password, hashedSaltedPassword }; return roomPass; }); + const key = await deriveKey(password); + roomKeyStore.update((roomKeys) => { + roomKeys[roomId] = key; + return roomKeys; + }); return true; } else { return false; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 3dd1cea..38499d6 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -30,7 +30,7 @@ storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); onMount(async () => { - console.log('Starting Up Application'); + console.info('Starting Up Application'); if (getServerList().length === 0) { setDefaultServers(); } @@ -45,7 +45,7 @@ drawerStore.close(); } } else { - console.log('Input field focused, not opening console'); + console.debug('Input field focused, not opening console'); } } }); diff --git a/src/routes/admin/+page.svelte b/src/routes/admin/+page.svelte index 4ea424a..335f65f 100644 --- a/src/routes/admin/+page.svelte +++ b/src/routes/admin/+page.svelte @@ -34,6 +34,9 @@ Add Room Admin + Debug