mirror of
https://github.com/Discreetly/frontend.git
synced 2026-01-08 20:38:04 -05:00
encrpyted rooms work
This commit is contained in:
8
package-lock.json
generated
8
package-lock.json
generated
@@ -22,7 +22,7 @@
|
|||||||
"date-fns": "^2.30.0",
|
"date-fns": "^2.30.0",
|
||||||
"discreetly-interfaces": "^0.1.42",
|
"discreetly-interfaces": "^0.1.42",
|
||||||
"dompurify": "^3.0.5",
|
"dompurify": "^3.0.5",
|
||||||
"idc-nullifier": "^0.0.6",
|
"idc-nullifier": "^0.0.8",
|
||||||
"libsodium-wrappers": "^0.7.11",
|
"libsodium-wrappers": "^0.7.11",
|
||||||
"marked": "^7.0.5",
|
"marked": "^7.0.5",
|
||||||
"minidenticons": "^4.2.0",
|
"minidenticons": "^4.2.0",
|
||||||
@@ -7209,9 +7209,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/idc-nullifier": {
|
"node_modules/idc-nullifier": {
|
||||||
"version": "0.0.6",
|
"version": "0.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/idc-nullifier/-/idc-nullifier-0.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/idc-nullifier/-/idc-nullifier-0.0.8.tgz",
|
||||||
"integrity": "sha512-jM2D9ODNnmqn/Ps/cvpxSk4JTIrMG2Ozb0Z3a99jW5cd1DS7U5YBlHJRMRJn3sGyG3YIrIHyJQYoAWPBw5UiTA==",
|
"integrity": "sha512-fNR32XHu53AoAFA7rwVs2J67U/Za1hUpAPkIohwa05lnjXrwPMoA1zBeUutkdVRgmRBMbLpfAfXsUUnjqqpQQQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@semaphore-protocol/identity": "^3.10.1",
|
"@semaphore-protocol/identity": "^3.10.1",
|
||||||
"circomlib": "^2.0.5",
|
"circomlib": "^2.0.5",
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
"date-fns": "^2.30.0",
|
"date-fns": "^2.30.0",
|
||||||
"discreetly-interfaces": "^0.1.42",
|
"discreetly-interfaces": "^0.1.42",
|
||||||
"dompurify": "^3.0.5",
|
"dompurify": "^3.0.5",
|
||||||
"idc-nullifier": "^0.0.6",
|
"idc-nullifier": "^0.0.8",
|
||||||
"libsodium-wrappers": "^0.7.11",
|
"libsodium-wrappers": "^0.7.11",
|
||||||
"marked": "^7.0.5",
|
"marked": "^7.0.5",
|
||||||
"minidenticons": "^4.2.0",
|
"minidenticons": "^4.2.0",
|
||||||
@@ -86,4 +86,4 @@
|
|||||||
"wagmi": "^1.4.3",
|
"wagmi": "^1.4.3",
|
||||||
"zuauth": "^0.3.0"
|
"zuauth": "^0.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,6 @@
|
|||||||
loadingRooms = true;
|
loadingRooms = true;
|
||||||
getEthAddressRoomNames($selectedServer, address)
|
getEthAddressRoomNames($selectedServer, address)
|
||||||
.then((groupNames) => {
|
.then((groupNames) => {
|
||||||
console.log(groupNames);
|
|
||||||
loadingRooms = false;
|
loadingRooms = false;
|
||||||
groups = groupNames;
|
groups = groupNames;
|
||||||
})
|
})
|
||||||
@@ -84,8 +83,7 @@
|
|||||||
<h3 class="h4 mb-2"><span class="text-success-500">Step 1:</span> Connect your wallet</h3>
|
<h3 class="h4 mb-2"><span class="text-success-500">Step 1:</span> Connect your wallet</h3>
|
||||||
<button
|
<button
|
||||||
bind:this={btnEl}
|
bind:this={btnEl}
|
||||||
class="btn variant-outline-tertiary">Connect</button
|
class="btn variant-outline-tertiary">Connect</button>
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
{#if isConnected}
|
{#if isConnected}
|
||||||
<div>
|
<div>
|
||||||
@@ -106,8 +104,7 @@
|
|||||||
<button
|
<button
|
||||||
on:click={proveOwnership}
|
on:click={proveOwnership}
|
||||||
id="btn"
|
id="btn"
|
||||||
class="btn variant-outline-success">Sign</button
|
class="btn variant-outline-success">Sign</button>
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
{:else if loadingRooms}
|
{:else if loadingRooms}
|
||||||
<p>Loading rooms...</p>
|
<p>Loading rooms...</p>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
console.warn(err);
|
||||||
alertQueue.enqueue(`Unexpected error: ${err.message}`, 'error');
|
alertQueue.enqueue(`Unexpected error: ${err.message}`, 'error');
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
@@ -90,8 +90,7 @@
|
|||||||
{#if !hideInput}
|
{#if !hideInput}
|
||||||
<label
|
<label
|
||||||
class="label"
|
class="label"
|
||||||
for="inviteCode"
|
for="inviteCode">
|
||||||
>
|
|
||||||
<span class="h5">Enter Invite Code:</span>
|
<span class="h5">Enter Invite Code:</span>
|
||||||
<input
|
<input
|
||||||
class="input"
|
class="input"
|
||||||
@@ -99,8 +98,7 @@
|
|||||||
placeholder="Invite Code"
|
placeholder="Invite Code"
|
||||||
id="inviteCode"
|
id="inviteCode"
|
||||||
bind:value={code}
|
bind:value={code}
|
||||||
on:keydown={(event) => inviteCodeKeyPress(event)}
|
on:keydown={(event) => inviteCodeKeyPress(event)} />
|
||||||
/>
|
|
||||||
</label>
|
</label>
|
||||||
{/if}
|
{/if}
|
||||||
{#if !loading}
|
{#if !loading}
|
||||||
@@ -108,8 +106,7 @@
|
|||||||
class="btn variant-ghost-success mt-3"
|
class="btn variant-ghost-success mt-3"
|
||||||
type="button"
|
type="button"
|
||||||
disabled={!code}
|
disabled={!code}
|
||||||
on:click={() => addCode(code)}>{buttonText}</button
|
on:click={() => addCode(code)}>{buttonText}</button>
|
||||||
>
|
|
||||||
{:else}
|
{:else}
|
||||||
<div class="text-primary">Going Anon, please wait...</div>
|
<div class="text-primary">Going Anon, please wait...</div>
|
||||||
<Loading />
|
<Loading />
|
||||||
@@ -120,8 +117,7 @@
|
|||||||
<div>
|
<div>
|
||||||
If you are having trouble and would like help, please message us on <a
|
If you are having trouble and would like help, please message us on <a
|
||||||
href="https://discord.gg/brJQ36KVxk"
|
href="https://discord.gg/brJQ36KVxk"
|
||||||
class="underline link">Discord</a
|
class="underline link">Discord</a>
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
console.warn(err);
|
||||||
alertQueue.enqueue(`Unexpected error: ${err.message}`, 'error');
|
alertQueue.enqueue(`Unexpected error: ${err.message}`, 'error');
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
@@ -55,9 +55,7 @@
|
|||||||
class="px-2"
|
class="px-2"
|
||||||
name="the-word-proof.json"
|
name="the-word-proof.json"
|
||||||
bind:files
|
bind:files
|
||||||
on:change={onChangeHandler}
|
on:change={onChangeHandler} /></label>
|
||||||
/></label
|
|
||||||
>
|
|
||||||
</section>
|
</section>
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<Loading />
|
<Loading />
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ async function genProof(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const proof = prover.generateProof(proofInputs).then((proof: RLNFullProof) => {
|
const proof = prover.generateProof(proofInputs).then((proof: RLNFullProof) => {
|
||||||
console.log('Proof generated!');
|
console.info('Proof generated!');
|
||||||
const msg: MessageI = {
|
const msg: MessageI = {
|
||||||
messageId: proof.snarkProof.publicSignals.nullifier.toString(),
|
messageId: proof.snarkProof.publicSignals.nullifier.toString(),
|
||||||
message: message,
|
message: message,
|
||||||
|
|||||||
@@ -128,3 +128,23 @@ export async function getAuth(
|
|||||||
throw new Error(`Failed to post to ${url}`);
|
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<Response> {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import type { MessageI, ServerI } from 'discreetly-interfaces';
|
|||||||
import type { IdentityStoreI, Invites, JoinResponseI, JubmojiProofI, RoomI } from '$lib/types';
|
import type { IdentityStoreI, Invites, JoinResponseI, JubmojiProofI, RoomI } from '$lib/types';
|
||||||
import { Prover } from 'idc-nullifier';
|
import { Prover } from 'idc-nullifier';
|
||||||
import type { Identity } from '@semaphore-protocol/identity';
|
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 { getIdentity } from '$lib/utils';
|
||||||
import { alertQueue } from '$lib/stores';
|
import { alertQueue } from '$lib/stores';
|
||||||
|
|
||||||
@@ -193,6 +193,22 @@ export async function postCheckRoomPassword(
|
|||||||
return Boolean(response.success);
|
return Boolean(response.success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function postDoesRoomPasswordExist(
|
||||||
|
serverUrl: string,
|
||||||
|
roomId: string
|
||||||
|
): Promise<boolean> {
|
||||||
|
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(
|
export async function postSetRoomPassword(
|
||||||
serverUrl: string,
|
serverUrl: string,
|
||||||
roomId: string,
|
roomId: string,
|
||||||
@@ -207,7 +223,6 @@ export async function postSetRoomPassword(
|
|||||||
idForProof.nullifier = id._nullifier;
|
idForProof.nullifier = id._nullifier;
|
||||||
idForProof.secret = id._secret;
|
idForProof.secret = id._secret;
|
||||||
idForProof.commitment = id._commitment;
|
idForProof.commitment = id._commitment;
|
||||||
|
|
||||||
// Proves you know the identity secret with a timestamp so this proof can't be replayed
|
// Proves you know the identity secret with a timestamp so this proof can't be replayed
|
||||||
prover
|
prover
|
||||||
.generateProof({
|
.generateProof({
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export const pixelStore = sessionable({} as pixelStoreI, 'pixelmaps');
|
|||||||
/**
|
/**
|
||||||
* @description Stores the encrypted key for each room keyed by the roomId
|
* @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
|
* @description Derived Store: The messages of the currently selected room
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export function createIdentity(
|
|||||||
alertQueue.enqueue('Identity Created! Congrats on your new journey', 'success');
|
alertQueue.enqueue('Identity Created! Congrats on your new journey', 'success');
|
||||||
return 'created';
|
return 'created';
|
||||||
} else {
|
} else {
|
||||||
console.log(get(identityExists));
|
console.warn(get(identityExists));
|
||||||
alertQueue.enqueue('Error creating identity!!!', 'error');
|
alertQueue.enqueue('Error creating identity!!!', 'error');
|
||||||
return 'error';
|
return 'error';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import {
|
|||||||
identityExists,
|
identityExists,
|
||||||
alertQueue,
|
alertQueue,
|
||||||
roomPassStore,
|
roomPassStore,
|
||||||
selectedServer
|
selectedServer,
|
||||||
|
roomKeyStore
|
||||||
} from '$lib/stores';
|
} from '$lib/stores';
|
||||||
import { encryptIdentity } from './identity';
|
import { encryptIdentity } from './identity';
|
||||||
import type { IdentityStoreI } from '$lib/types';
|
import type { IdentityStoreI } from '$lib/types';
|
||||||
@@ -75,6 +76,17 @@ export async function unlockPadlock(password: string) {
|
|||||||
identityKeyStore.read();
|
identityKeyStore.read();
|
||||||
roomPassStore.read();
|
roomPassStore.read();
|
||||||
updateRooms();
|
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 {
|
} else {
|
||||||
alertQueue.enqueue('Incorrect Password', 'warning');
|
alertQueue.enqueue('Incorrect Password', 'warning');
|
||||||
@@ -85,12 +97,17 @@ export async function unlockPadlock(password: string) {
|
|||||||
export async function enterRoomPassword(password: string, roomId: string): Promise<boolean> {
|
export async function enterRoomPassword(password: string, roomId: string): Promise<boolean> {
|
||||||
const hashedSaltedPassword = await hashPassword(password + roomId);
|
const hashedSaltedPassword = await hashPassword(password + roomId);
|
||||||
if (hashedSaltedPassword) {
|
if (hashedSaltedPassword) {
|
||||||
postCheckRoomPassword(get(selectedServer), roomId, hashedSaltedPassword).then((res) => {
|
postCheckRoomPassword(get(selectedServer), roomId, hashedSaltedPassword).then(async (res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
roomPassStore.update((roomPass) => {
|
roomPassStore.update((roomPass) => {
|
||||||
roomPass[roomId] = { password, hashedSaltedPassword };
|
roomPass[roomId] = { password, hashedSaltedPassword };
|
||||||
return roomPass;
|
return roomPass;
|
||||||
});
|
});
|
||||||
|
const key = await deriveKey(password);
|
||||||
|
roomKeyStore.update((roomKeys) => {
|
||||||
|
roomKeys[roomId] = key;
|
||||||
|
return roomKeys;
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -103,12 +120,17 @@ export async function enterRoomPassword(password: string, roomId: string): Promi
|
|||||||
export async function setRoomPassword(password: string, roomId: string): Promise<boolean> {
|
export async function setRoomPassword(password: string, roomId: string): Promise<boolean> {
|
||||||
const hashedSaltedPassword = await hashPassword(password + roomId);
|
const hashedSaltedPassword = await hashPassword(password + roomId);
|
||||||
if (hashedSaltedPassword) {
|
if (hashedSaltedPassword) {
|
||||||
postSetRoomPassword(get(selectedServer), roomId, hashedSaltedPassword).then((res) => {
|
postSetRoomPassword(get(selectedServer), roomId, hashedSaltedPassword).then(async (res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
roomPassStore.update((roomPass) => {
|
roomPassStore.update((roomPass) => {
|
||||||
roomPass[roomId] = { password, hashedSaltedPassword };
|
roomPass[roomId] = { password, hashedSaltedPassword };
|
||||||
return roomPass;
|
return roomPass;
|
||||||
});
|
});
|
||||||
|
const key = await deriveKey(password);
|
||||||
|
roomKeyStore.update((roomKeys) => {
|
||||||
|
roomKeys[roomId] = key;
|
||||||
|
return roomKeys;
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow });
|
storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow });
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
console.log('Starting Up Application');
|
console.info('Starting Up Application');
|
||||||
if (getServerList().length === 0) {
|
if (getServerList().length === 0) {
|
||||||
setDefaultServers();
|
setDefaultServers();
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
drawerStore.close();
|
drawerStore.close();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('Input field focused, not opening console');
|
console.debug('Input field focused, not opening console');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -34,6 +34,9 @@
|
|||||||
<a
|
<a
|
||||||
class="btn variant-filled-primary"
|
class="btn variant-filled-primary"
|
||||||
href="/admin/addAdmin">Add Room Admin</a>
|
href="/admin/addAdmin">Add Room Admin</a>
|
||||||
|
<a
|
||||||
|
class="btn variant-filled-warning"
|
||||||
|
href="/settings/debug">Debug</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function newCodes(numCodes: number) {
|
async function newCodes(numCodes: number) {
|
||||||
console.log(`Requesting ${numCodes} codes`);
|
console.debug(`Requesting ${numCodes} codes`);
|
||||||
const canvasContainer = document.getElementById('qr');
|
const canvasContainer = document.getElementById('qr');
|
||||||
canvasContainer?.replaceChildren();
|
canvasContainer?.replaceChildren();
|
||||||
if (usesLeft == 0) {
|
if (usesLeft == 0) {
|
||||||
@@ -44,7 +44,6 @@
|
|||||||
expiresAt,
|
expiresAt,
|
||||||
usesLeft
|
usesLeft
|
||||||
);
|
);
|
||||||
console.log(resp);
|
|
||||||
const codes = resp.codes;
|
const codes = resp.codes;
|
||||||
codes.forEach((code) => {
|
codes.forEach((code) => {
|
||||||
makeInviteQRCode(code.claimcode);
|
makeInviteQRCode(code.claimcode);
|
||||||
@@ -68,14 +67,12 @@
|
|||||||
<div class="flex flex-col place-content-center max-w-sm m-auto pt-5">
|
<div class="flex flex-col place-content-center max-w-sm m-auto pt-5">
|
||||||
<div
|
<div
|
||||||
id="qr"
|
id="qr"
|
||||||
class="flex flex-col gap-12 place-content-center"
|
class="flex flex-col gap-12 place-content-center">
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<canvas
|
<canvas
|
||||||
class="variant-soft-secondary"
|
class="variant-soft-secondary"
|
||||||
width="250"
|
width="250"
|
||||||
height="250"
|
height="250" />
|
||||||
/>
|
|
||||||
<p>no code generated yet</p>
|
<p>no code generated yet</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,8 +80,7 @@
|
|||||||
class="btn my-12 variant-soft-primary text-center items-center"
|
class="btn my-12 variant-soft-primary text-center items-center"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
newCodes(numCodes);
|
newCodes(numCodes);
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
{#if numCodes > 1}
|
{#if numCodes > 1}
|
||||||
Generate New Codes
|
Generate New Codes
|
||||||
{:else}
|
{:else}
|
||||||
@@ -109,10 +105,8 @@
|
|||||||
type="range"
|
type="range"
|
||||||
min="1"
|
min="1"
|
||||||
max="5"
|
max="5"
|
||||||
bind:value={numCodes}
|
bind:value={numCodes} />
|
||||||
/>
|
</label></svelte:fragment>
|
||||||
</label></svelte:fragment
|
|
||||||
>
|
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
<AccordionItem>
|
<AccordionItem>
|
||||||
<svelte:fragment slot="summary">Number of Uses Per Code</svelte:fragment>
|
<svelte:fragment slot="summary">Number of Uses Per Code</svelte:fragment>
|
||||||
@@ -123,10 +117,8 @@
|
|||||||
type="range"
|
type="range"
|
||||||
min="0"
|
min="0"
|
||||||
max="50"
|
max="50"
|
||||||
bind:value={usesLeft}
|
bind:value={usesLeft} />
|
||||||
/>
|
</label></svelte:fragment>
|
||||||
</label></svelte:fragment
|
|
||||||
>
|
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
<AccordionItem>
|
<AccordionItem>
|
||||||
<svelte:fragment slot="summary">Expiration</svelte:fragment>
|
<svelte:fragment slot="summary">Expiration</svelte:fragment>
|
||||||
@@ -137,10 +129,8 @@
|
|||||||
type="range"
|
type="range"
|
||||||
min="1"
|
min="1"
|
||||||
max="14"
|
max="14"
|
||||||
bind:value={daysFromNow}
|
bind:value={daysFromNow} />
|
||||||
/>
|
</label></svelte:fragment>
|
||||||
</label></svelte:fragment
|
|
||||||
>
|
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
<AccordionItem>
|
<AccordionItem>
|
||||||
<svelte:fragment slot="summary">Rooms</svelte:fragment>
|
<svelte:fragment slot="summary">Rooms</svelte:fragment>
|
||||||
@@ -152,13 +142,11 @@
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
value={room.roomId}
|
value={room.roomId}
|
||||||
on:change={updateRoomList}
|
on:change={updateRoomList}
|
||||||
checked={roomIds.includes(String(room.roomId))}
|
checked={roomIds.includes(String(room.roomId))} />
|
||||||
/>
|
|
||||||
<span title={String(room.roomId)}>{room.name}</span>
|
<span title={String(room.roomId)}>{room.name}</span>
|
||||||
</label>
|
</label>
|
||||||
{/each}
|
{/each}
|
||||||
</div></svelte:fragment
|
</div></svelte:fragment>
|
||||||
>
|
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
<AccordionItem>
|
<AccordionItem>
|
||||||
<svelte:fragment slot="summary">API</svelte:fragment>
|
<svelte:fragment slot="summary">API</svelte:fragment>
|
||||||
@@ -168,18 +156,15 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="input"
|
class="input"
|
||||||
bind:value={$configStore.apiUsername}
|
bind:value={$configStore.apiUsername} />
|
||||||
/>
|
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span>Api Password</span>
|
<span>Api Password</span>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
class="input"
|
class="input"
|
||||||
bind:value={$configStore.apiPassword}
|
bind:value={$configStore.apiPassword} />
|
||||||
/>
|
</label></svelte:fragment>
|
||||||
</label></svelte:fragment
|
|
||||||
>
|
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
async function getRooms() {
|
async function getRooms() {
|
||||||
if (username && password) {
|
if (username && password) {
|
||||||
console.log('getting rooms');
|
console.debug('getting rooms');
|
||||||
rooms = await getAllRooms($selectedServer, username, password);
|
rooms = await getAllRooms($selectedServer, username, password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
} else {
|
} else {
|
||||||
selectedRoomIds = selectedRoomIds.filter((id) => id !== roomId);
|
selectedRoomIds = selectedRoomIds.filter((id) => id !== roomId);
|
||||||
}
|
}
|
||||||
console.log(selectedRoomIds);
|
console.debug('selectedRoomIds', selectedRoomIds);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,10 @@
|
|||||||
formData.bandadaGroupId,
|
formData.bandadaGroupId,
|
||||||
formData.bandadaApiKey
|
formData.bandadaApiKey
|
||||||
).then((res) => {
|
).then((res) => {
|
||||||
console.log(res);
|
console.debug(res);
|
||||||
submitted = true;
|
submitted = true;
|
||||||
createdCodes = res.claimCodes;
|
createdCodes = res.claimCodes;
|
||||||
console.log(createdCodes);
|
console.info(createdCodes);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
alertQueue.enqueue('You must create an identity before creating a room', 'error');
|
alertQueue.enqueue('You must create an identity before creating a room', 'error');
|
||||||
@@ -62,8 +62,7 @@
|
|||||||
handleSubmit();
|
handleSubmit();
|
||||||
}}
|
}}
|
||||||
buttonNext="variant-filled-surface-50-900-token"
|
buttonNext="variant-filled-surface-50-900-token"
|
||||||
buttonComplete="variant-filled-success"
|
buttonComplete="variant-filled-success">
|
||||||
>
|
|
||||||
<RoomName {formData} />
|
<RoomName {formData} />
|
||||||
<MembershipType {formData} />
|
<MembershipType {formData} />
|
||||||
<RateLimit {formData} />
|
<RateLimit {formData} />
|
||||||
|
|||||||
@@ -6,9 +6,10 @@
|
|||||||
import * as emoji from 'node-emoji';
|
import * as emoji from 'node-emoji';
|
||||||
|
|
||||||
export let bubbleText: string;
|
export let bubbleText: string;
|
||||||
|
|
||||||
let formattedText = '';
|
let formattedText = '';
|
||||||
|
|
||||||
onMount(() => {
|
onMount(async () => {
|
||||||
// Only render text on the frontend because DOMPurify
|
// Only render text on the frontend because DOMPurify
|
||||||
// needs access to the DOM.
|
// needs access to the DOM.
|
||||||
formattedText = formatText(bubbleText);
|
formattedText = formatText(bubbleText);
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
import {
|
||||||
currentSelectedRoom,
|
currentSelectedRoom,
|
||||||
keyStore,
|
|
||||||
rateLimitStore,
|
rateLimitStore,
|
||||||
roomKeyStore,
|
|
||||||
alertQueue,
|
alertQueue,
|
||||||
identityExists,
|
identityExists,
|
||||||
configStore
|
configStore
|
||||||
@@ -12,13 +10,16 @@
|
|||||||
import type { Socket } from 'socket.io-client';
|
import type { Socket } from 'socket.io-client';
|
||||||
import { getIdentity, clearMessageHistory } from '$lib/utils';
|
import { getIdentity, clearMessageHistory } from '$lib/utils';
|
||||||
import Send from 'svelte-material-icons/Send.svelte';
|
import Send from 'svelte-material-icons/Send.svelte';
|
||||||
import { decrypt, encrypt } from '$lib/crypto/crypto';
|
import { encrypt } from '$lib/crypto/crypto';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
export let socket: Socket;
|
export let socket: Socket;
|
||||||
export let connected: boolean;
|
export let connected: boolean;
|
||||||
export let currentEpoch: number;
|
export let currentEpoch: number;
|
||||||
export let userMessageLimit: number;
|
export let userMessageLimit: number;
|
||||||
export let roomId: string;
|
export let roomId: string;
|
||||||
|
export let getKey: () => Promise<CryptoKey>;
|
||||||
|
let key: CryptoKey;
|
||||||
|
|
||||||
let scrollChatEvent = new CustomEvent('scrollChat', {
|
let scrollChatEvent = new CustomEvent('scrollChat', {
|
||||||
detail: { behavior: 'smooth', delay: 20 }
|
detail: { behavior: 'smooth', delay: 20 }
|
||||||
@@ -111,27 +112,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to handle encrypted room messages
|
// Helper function to handle encrypted room messages
|
||||||
async function handleEncryptedMessage(
|
async function handleEncryptedMessage(messageText: string, roomId: string): Promise<string> {
|
||||||
messageText: string,
|
const encryptedMessage = await encrypt(messageText, key);
|
||||||
roomId: string,
|
|
||||||
keyStore: any,
|
|
||||||
roomKeyStore: any
|
|
||||||
): Promise<string> {
|
|
||||||
if ($currentSelectedRoom.encrypted == 'AES' && !roomKeyStore[roomId]) {
|
|
||||||
throw new Error('ROOM IS ENCRYPTED BUT NO PASSWORD WAS FOUND');
|
|
||||||
}
|
|
||||||
if (!keyStore) {
|
|
||||||
throw new Error('NO KEYSTORE FOUND');
|
|
||||||
}
|
|
||||||
|
|
||||||
const key = await decrypt(roomKeyStore[roomId], keyStore);
|
|
||||||
if (!key) {
|
|
||||||
throw new Error('NO KEY FOUND');
|
|
||||||
}
|
|
||||||
const encryptedMessage = await encrypt(messageText, key as unknown as CryptoKey);
|
|
||||||
if (encryptedMessage == null) {
|
if (encryptedMessage == null) {
|
||||||
throw new Error('ENCRYPTION FAILED');
|
throw new Error('ENCRYPTION FAILED');
|
||||||
} else {
|
} else {
|
||||||
|
console.debug(encryptedMessage);
|
||||||
return encryptedMessage;
|
return encryptedMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,12 +150,7 @@
|
|||||||
let messageToSend: string = messageText;
|
let messageToSend: string = messageText;
|
||||||
|
|
||||||
if (room.encrypted === 'AES') {
|
if (room.encrypted === 'AES') {
|
||||||
messageToSend = await handleEncryptedMessage(
|
messageToSend = await handleEncryptedMessage(messageText, room.roomId!.toString());
|
||||||
messageText,
|
|
||||||
room.roomId!.toString(),
|
|
||||||
$keyStore,
|
|
||||||
$roomKeyStore
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const msg = await genProof(
|
const msg = await genProof(
|
||||||
@@ -215,6 +196,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
getKey().then((k) => {
|
||||||
|
key = k;
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="border-t border-surface-500/30 p-2 md:p-4 !border-dashed">
|
<section class="border-t border-surface-500/30 p-2 md:p-4 !border-dashed">
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
selectedServer,
|
selectedServer,
|
||||||
configStore,
|
configStore,
|
||||||
currentRoomsStore,
|
currentRoomsStore,
|
||||||
roomPasswordSet
|
roomPasswordSet,
|
||||||
|
identityExists,
|
||||||
|
roomKeyStore,
|
||||||
|
roomPassStore
|
||||||
} from '$lib/stores';
|
} from '$lib/stores';
|
||||||
import RoomPassword from './RoomPassword.svelte';
|
import RoomPassword from './RoomPassword.svelte';
|
||||||
import { Experiences } from '$lib/types';
|
import { Experiences } from '$lib/types';
|
||||||
@@ -19,6 +22,7 @@
|
|||||||
import Conversation from './Conversation.svelte';
|
import Conversation from './Conversation.svelte';
|
||||||
import Draw from './Draw.svelte';
|
import Draw from './Draw.svelte';
|
||||||
import InputPrompt from './ChatInputPrompt.svelte';
|
import InputPrompt from './ChatInputPrompt.svelte';
|
||||||
|
import { deriveKey } from '$lib/crypto/crypto';
|
||||||
|
|
||||||
const toastStore = getToastStore();
|
const toastStore = getToastStore();
|
||||||
|
|
||||||
@@ -59,6 +63,20 @@
|
|||||||
|
|
||||||
$: updateRooms($selectedServer, [roomId]);
|
$: updateRooms($selectedServer, [roomId]);
|
||||||
|
|
||||||
|
async function getKey(): Promise<CryptoKey> {
|
||||||
|
let key: CryptoKey;
|
||||||
|
if (!$roomPassStore[roomId]) {
|
||||||
|
throw new Error('ROOM IS ENCRYPTED BUT NO PASSWORD WAS FOUND');
|
||||||
|
}
|
||||||
|
if (!$roomKeyStore[roomId]) {
|
||||||
|
key = await deriveKey($roomPassStore[roomId].password);
|
||||||
|
$roomKeyStore[roomId] = key;
|
||||||
|
} else {
|
||||||
|
key = $roomKeyStore[roomId];
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
function updateEpoch() {
|
function updateEpoch() {
|
||||||
if ($currentSelectedRoom === undefined) {
|
if ($currentSelectedRoom === undefined) {
|
||||||
if ($currentRoomsStore[0] === undefined) {
|
if ($currentRoomsStore[0] === undefined) {
|
||||||
@@ -143,6 +161,7 @@
|
|||||||
updateEpoch();
|
updateEpoch();
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
unsubscribeStore();
|
unsubscribeStore();
|
||||||
socket.emit('leavingRoom', $currentSelectedRoom?.roomId);
|
socket.emit('leavingRoom', $currentSelectedRoom?.roomId);
|
||||||
@@ -164,31 +183,39 @@
|
|||||||
{onlineMembers} />
|
{onlineMembers} />
|
||||||
{#if $configStore.experience == Experiences.Chat}
|
{#if $configStore.experience == Experiences.Chat}
|
||||||
{#key $currentSelectedRoom.roomId}
|
{#key $currentSelectedRoom.roomId}
|
||||||
<Conversation {roomRateLimit} />
|
<Conversation
|
||||||
|
{roomRateLimit}
|
||||||
|
{getKey} />
|
||||||
{/key}
|
{/key}
|
||||||
<InputPrompt
|
<InputPrompt
|
||||||
{socket}
|
{socket}
|
||||||
{connected}
|
{connected}
|
||||||
{currentEpoch}
|
{currentEpoch}
|
||||||
{userMessageLimit}
|
{userMessageLimit}
|
||||||
{roomId} />
|
{roomId}
|
||||||
|
{getKey} />
|
||||||
{:else if $configStore.experience == Experiences.Draw}
|
{:else if $configStore.experience == Experiences.Draw}
|
||||||
<Draw />
|
<Draw />
|
||||||
{:else}
|
{:else}
|
||||||
{#key $currentSelectedRoom.roomId}
|
{#key $currentSelectedRoom.roomId}
|
||||||
<Conversation {roomRateLimit} />
|
<Conversation
|
||||||
|
{roomRateLimit}
|
||||||
|
{getKey} />
|
||||||
{/key}
|
{/key}
|
||||||
<InputPrompt
|
<InputPrompt
|
||||||
{socket}
|
{socket}
|
||||||
{connected}
|
{connected}
|
||||||
{currentEpoch}
|
{currentEpoch}
|
||||||
{userMessageLimit}
|
{userMessageLimit}
|
||||||
{roomId} />
|
{roomId}
|
||||||
|
{getKey} />
|
||||||
{/if}
|
{/if}
|
||||||
<!-- Conversation -->
|
<!-- Conversation -->
|
||||||
|
|
||||||
<!-- Prompt -->
|
<!-- Prompt -->
|
||||||
</div>
|
</div>
|
||||||
|
{:else if $identityExists == 'encrypted'}
|
||||||
|
<h3 class="h3 my-5 text-center text-primary-500">Unlock your credentials to see this room.</h3>
|
||||||
{:else}
|
{:else}
|
||||||
<div><RoomPassword {roomId} /></div>
|
<div><RoomPassword {roomId} /></div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -6,8 +6,11 @@
|
|||||||
import BubbleText from './BubbleText.svelte';
|
import BubbleText from './BubbleText.svelte';
|
||||||
import { minidenticon } from 'minidenticons';
|
import { minidenticon } from 'minidenticons';
|
||||||
import { bubbleBgFromSessionId } from '$lib/utils/color';
|
import { bubbleBgFromSessionId } from '$lib/utils/color';
|
||||||
|
import { decrypt } from '$lib/crypto/crypto';
|
||||||
|
|
||||||
export let roomRateLimit: number;
|
export let roomRateLimit: number;
|
||||||
|
export let getKey: () => Promise<CryptoKey>;
|
||||||
|
let key: CryptoKey;
|
||||||
|
|
||||||
let elemChat: HTMLElement;
|
let elemChat: HTMLElement;
|
||||||
|
|
||||||
@@ -21,6 +24,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function decryptText(text: string): Promise<string> {
|
||||||
|
if (!key) {
|
||||||
|
return getKey().then(async (k) => {
|
||||||
|
key = k;
|
||||||
|
const result = await decrypt(text, key);
|
||||||
|
return result ? result : text;
|
||||||
|
});
|
||||||
|
} else if (key) {
|
||||||
|
const result = await decrypt(text, key);
|
||||||
|
return result ? result : text;
|
||||||
|
} else {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function scrollChatBottom(behavior: ScrollBehavior = 'smooth', delay = 20, count = 0): void {
|
function scrollChatBottom(behavior: ScrollBehavior = 'smooth', delay = 20, count = 0): void {
|
||||||
if (count > 10) {
|
if (count > 10) {
|
||||||
console.warn('scrollChatBottom: elemChat is not defined after multiple attempts, giving up');
|
console.warn('scrollChatBottom: elemChat is not defined after multiple attempts, giving up');
|
||||||
@@ -56,6 +74,9 @@
|
|||||||
const delay = customEvent.detail.delay ? customEvent.detail.delay : 20;
|
const delay = customEvent.detail.delay ? customEvent.detail.delay : 20;
|
||||||
scrollChatBottom(behavior, delay);
|
scrollChatBottom(behavior, delay);
|
||||||
});
|
});
|
||||||
|
getKey().then((k) => {
|
||||||
|
key = k;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -78,7 +99,14 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#key msg}
|
{#key msg}
|
||||||
<BubbleText bubbleText={String(msg.message)} />
|
{#await decryptText(String(msg.message))}
|
||||||
|
<p>Decrypting...</p>
|
||||||
|
{:then decryptedText}
|
||||||
|
<BubbleText bubbleText={decryptedText} />
|
||||||
|
{:catch error}
|
||||||
|
<BubbleText bubbleText={String(msg.message)} />
|
||||||
|
<!-- You can customize this error state -->
|
||||||
|
{/await}
|
||||||
{/key}
|
{/key}
|
||||||
</div>
|
</div>
|
||||||
<footer class="flex justify-between items-center text-xs md:text-sm pb-1">
|
<footer class="flex justify-between items-center text-xs md:text-sm pb-1">
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
const parent = canvas.parentElement;
|
const parent = canvas.parentElement;
|
||||||
const parentWidth = parent!.clientWidth;
|
const parentWidth = parent!.clientWidth;
|
||||||
const parentHeight = parent!.clientHeight - 150;
|
const parentHeight = parent!.clientHeight - 150;
|
||||||
console.log(parentWidth, parentHeight);
|
console.debug(parentWidth, parentHeight);
|
||||||
let height, width;
|
let height, width;
|
||||||
|
|
||||||
if (parentHeight < parentWidth / aspectRatio) {
|
if (parentHeight < parentWidth / aspectRatio) {
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
canvas.width = width;
|
canvas.width = width;
|
||||||
canvas.height = height;
|
canvas.height = height;
|
||||||
console.log(canvas.height, canvas.width);
|
console.debug(canvas.height, canvas.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
@@ -53,5 +53,4 @@
|
|||||||
id="drawing-canvas"
|
id="drawing-canvas"
|
||||||
width="250"
|
width="250"
|
||||||
height="250"
|
height="250"
|
||||||
class="border border-surface-300-600-token m-1 sm:m-3"
|
class="border border-surface-300-600-token m-1 sm:m-3" />
|
||||||
/>
|
|
||||||
|
|||||||
@@ -6,12 +6,12 @@
|
|||||||
|
|
||||||
$: if (room.encrypted) {
|
$: if (room.encrypted) {
|
||||||
if ($roomPassStore[room.roomId.toString()] && $keyStore) {
|
if ($roomPassStore[room.roomId.toString()] && $keyStore) {
|
||||||
console.log('Room is encrypted and encrypted password is stored');
|
console.debug('Room is encrypted and encrypted password is stored');
|
||||||
decrypt($roomPassStore[room.roomId.toString()], $keyStore);
|
decrypt($roomPassStore[room.roomId.toString()].password, $keyStore);
|
||||||
} else {
|
} else {
|
||||||
console.log('Room is encrypted and password is not stored');
|
console.debug('Room is encrypted and password is not stored');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('Room is not encrypted');
|
console.debug('Room is not encrypted');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,35 +1,113 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { enterRoomPassword } from '$lib/utils';
|
import { enterRoomPassword, getCommitment } from '$lib/utils';
|
||||||
import Container from '$lib/components/Utils/Container.svelte';
|
import Container from '$lib/components/Utils/Container.svelte';
|
||||||
|
import { postDoesRoomPasswordExist, postSetRoomPassword } from '$lib/services/server';
|
||||||
|
import { roomPassStore, selectedServer, roomsStore } from '$lib/stores';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import { hashPassword } from '$lib/crypto/crypto';
|
||||||
|
import Loading from '$lib/components/Utils/Loading.svelte';
|
||||||
|
|
||||||
export let roomId: string;
|
export let roomId: string;
|
||||||
|
let _passwordSet: boolean;
|
||||||
const minPasswordLength = 4;
|
|
||||||
let r = '';
|
let r = '';
|
||||||
|
let admin = false;
|
||||||
|
let loaded = false;
|
||||||
|
|
||||||
function onSubmit() {
|
function enterPassword() {
|
||||||
if (r != '' && r != null && r != undefined && r.length >= minPasswordLength) {
|
enterRoomPassword(r, roomId);
|
||||||
enterRoomPassword(r, roomId);
|
}
|
||||||
|
|
||||||
|
async function setRoomPassword() {
|
||||||
|
const hashedSaltedPassword = await hashPassword(r + roomId);
|
||||||
|
if (hashedSaltedPassword) {
|
||||||
|
postSetRoomPassword($selectedServer, roomId, hashedSaltedPassword).then((answer) => {
|
||||||
|
if (answer) {
|
||||||
|
roomPassStore.update((roomPass) => {
|
||||||
|
roomPass[roomId] = { password: r, hashedSaltedPassword };
|
||||||
|
return roomPass;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error('Failed to hash password');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPasswordSet() {
|
||||||
|
try {
|
||||||
|
postDoesRoomPasswordExist($selectedServer, roomId).then((answer) => {
|
||||||
|
_passwordSet = answer;
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAdmin() {
|
||||||
|
const idc = getCommitment();
|
||||||
|
$roomsStore[roomId].adminIdentities?.forEach((id) => {
|
||||||
|
if (id === idc) {
|
||||||
|
admin = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
isPasswordSet();
|
||||||
|
isAdmin();
|
||||||
|
loaded = true;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Container heading="Enter Room Password">
|
{#if loaded}
|
||||||
<form
|
{#if _passwordSet}
|
||||||
on:submit|preventDefault={() => onSubmit()}
|
<Container heading="Enter Room Password">
|
||||||
class="flex flex-col w-full">
|
<form
|
||||||
<label
|
on:submit|preventDefault={() => enterPassword()}
|
||||||
for="enterRoomPassword"
|
class="flex flex-col w-full">
|
||||||
class="label" />
|
<label
|
||||||
<input
|
for="enterRoomPassword"
|
||||||
id="enterRoomPassword"
|
class="label" />
|
||||||
type="password"
|
<input
|
||||||
name="password"
|
id="enterRoomPassword"
|
||||||
class="input"
|
type="password"
|
||||||
bind:value={r}
|
name="password"
|
||||||
required />
|
class="input"
|
||||||
<button
|
bind:value={r}
|
||||||
class="btn variant-filled-primary mt-3"
|
required />
|
||||||
type="submit">Enter Room Password</button>
|
<button
|
||||||
</form>
|
class="btn variant-filled-primary mt-3"
|
||||||
</Container>
|
type="submit">Enter Room Password</button>
|
||||||
|
</form>
|
||||||
|
</Container>
|
||||||
|
{:else if admin}
|
||||||
|
<Container heading="Set Room Password">
|
||||||
|
<form
|
||||||
|
on:submit|preventDefault={() => setRoomPassword()}
|
||||||
|
class="flex flex-col w-full">
|
||||||
|
<label
|
||||||
|
for="setRoomPassword"
|
||||||
|
class="label" />
|
||||||
|
<input
|
||||||
|
id="setRoomPassword"
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
class="input"
|
||||||
|
bind:value={r}
|
||||||
|
required />
|
||||||
|
<button
|
||||||
|
class="btn variant-filled-primary mt-3"
|
||||||
|
type="submit">Set Room Password</button>
|
||||||
|
</form>
|
||||||
|
</Container>
|
||||||
|
{:else}
|
||||||
|
<Container heading="Password Not Set">
|
||||||
|
<p class="text-center">
|
||||||
|
The room you are trying to enter requires a password, but the password has not been set yet.
|
||||||
|
Annoy the administrators who created this room!
|
||||||
|
</p>
|
||||||
|
</Container>
|
||||||
|
{/if}
|
||||||
|
{:else}
|
||||||
|
<Loading />
|
||||||
|
{/if}
|
||||||
|
|||||||
@@ -54,7 +54,6 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
|
||||||
addConsoleMessage(err, 'error');
|
addConsoleMessage(err, 'error');
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -161,5 +160,4 @@
|
|||||||
class="input py-1 px-2"
|
class="input py-1 px-2"
|
||||||
type="text"
|
type="text"
|
||||||
{placeholder}
|
{placeholder}
|
||||||
on:keypress={handleInput}
|
on:keypress={handleInput} />
|
||||||
/>
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
identityExists,
|
identityExists,
|
||||||
identityKeyStore,
|
identityKeyStore,
|
||||||
identityStore,
|
identityStore,
|
||||||
|
roomPassStore,
|
||||||
lockStateStore,
|
lockStateStore,
|
||||||
passwordSet,
|
passwordSet,
|
||||||
roomsStore,
|
roomsStore,
|
||||||
@@ -49,8 +50,7 @@
|
|||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<div
|
<div
|
||||||
id="status"
|
id="status"
|
||||||
class="flex flex-col gap-5"
|
class="flex flex-col gap-5">
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<h2 class="h3">configStore</h2>
|
<h2 class="h3">configStore</h2>
|
||||||
<div>Completed Signup: {JSON.stringify($configStore.signUpStatus.completedSignup)}</div>
|
<div>Completed Signup: {JSON.stringify($configStore.signUpStatus.completedSignup)}</div>
|
||||||
@@ -103,19 +103,20 @@
|
|||||||
<div class="ms-4">membershipType: {membershipType}</div>
|
<div class="ms-4">membershipType: {membershipType}</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
roomPassStore: {JSON.stringify($roomPassStore)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="border-t py-2 my-5">
|
<div class="border-t py-2 my-5">
|
||||||
<button
|
<button
|
||||||
class="btn variant-outline-primary m-4"
|
class="btn variant-outline-primary m-4"
|
||||||
on:click={triggerAlert}>Test Alert</button
|
on:click={triggerAlert}>Test Alert</button>
|
||||||
>
|
|
||||||
<select
|
<select
|
||||||
class="select"
|
class="select"
|
||||||
name="alertType"
|
name="alertType"
|
||||||
id="alertType"
|
id="alertType"
|
||||||
bind:value={t}
|
bind:value={t}>
|
||||||
>
|
|
||||||
{#each c as choice}
|
{#each c as choice}
|
||||||
<option value={choice}>{choice}</option>
|
<option value={choice}>{choice}</option>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
$configStore.signUpStatus.inviteCode = $page.params.invite;
|
$configStore.signUpStatus.inviteCode = $page.params.invite;
|
||||||
console.log(`Invited with code: ${$page.params.invite}`);
|
console.info(`Invited with code: ${$page.params.invite}`);
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if ($identityExists) {
|
if ($identityExists) {
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ Circuit_Type = "idcNullifier"
|
|||||||
[Circuit_Build]
|
[Circuit_Build]
|
||||||
Circom_Version = "circom compiler 2.1.5"
|
Circom_Version = "circom compiler 2.1.5"
|
||||||
GitHub_URL = "https://github.com/Discreetly/IdentityCommitmentNullifierCircuit.git"
|
GitHub_URL = "https://github.com/Discreetly/IdentityCommitmentNullifierCircuit.git"
|
||||||
Git_Commit = "b940865"
|
Git_Commit = "a0d6415"
|
||||||
Compilation_Time = 1698174365
|
Compilation_Time = 1699876330
|
||||||
|
|
||||||
[Files]
|
[Files]
|
||||||
Wasm = "circuit.wasm"
|
Wasm = "circuit.wasm"
|
||||||
Wasm_SHA256SUM = "410da93349f51f96dfb1bbb2d6578617a3de2494cf46d1ca6c1910a0098c82b8"
|
Wasm_SHA256SUM = "410da93349f51f96dfb1bbb2d6578617a3de2494cf46d1ca6c1910a0098c82b8"
|
||||||
Zkey = "final.zkey"
|
Zkey = "final.zkey"
|
||||||
Zkey_SHA256SUM = "7a626d709b4f6dc1150b554b3e643bd22099eaad1b5ed8d3b0202a8756004248"
|
Zkey_SHA256SUM = "6a375f8c6066abd38535bcadfc03c0616bdd80c2fca96bb6c1e4d4aa41f9662b"
|
||||||
Verification_Key = "verification_key.json"
|
Verification_Key = "verification_key.json"
|
||||||
Verification_Key_SHA256SUM = "1406f9e05c4bbbef93c9053cf0fa10a47881c5e8e3f1ada67e1ef3c5260fce91"
|
Verification_Key_SHA256SUM = "cc7b95eb8adedbdbfe0ff150bca89597d888230a9c11901b7d0a81ad92b9b36d"
|
||||||
|
|||||||
Binary file not shown.
@@ -1,95 +1,104 @@
|
|||||||
{
|
{
|
||||||
"protocol": "groth16",
|
"protocol": "groth16",
|
||||||
"curve": "bn128",
|
"curve": "bn128",
|
||||||
"nPublic": 3,
|
"nPublic": 3,
|
||||||
"vk_alpha_1": [
|
"vk_alpha_1": [
|
||||||
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
|
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
|
||||||
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
|
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
"vk_beta_2": [
|
"vk_beta_2": [
|
||||||
[
|
[
|
||||||
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
|
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
|
||||||
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
|
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
|
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
|
||||||
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
|
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
|
||||||
],
|
],
|
||||||
["1", "0"]
|
[
|
||||||
],
|
"1",
|
||||||
"vk_gamma_2": [
|
"0"
|
||||||
[
|
]
|
||||||
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
|
],
|
||||||
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
|
"vk_gamma_2": [
|
||||||
],
|
[
|
||||||
[
|
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
|
||||||
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
|
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
|
||||||
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
|
],
|
||||||
],
|
[
|
||||||
["1", "0"]
|
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
|
||||||
],
|
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
|
||||||
"vk_delta_2": [
|
],
|
||||||
[
|
[
|
||||||
"17133313670231667487736004097020484843226717741134543071681595192213542404569",
|
"1",
|
||||||
"18673817425770621231905673683883346893405144776326422608131560048409738195792"
|
"0"
|
||||||
],
|
]
|
||||||
[
|
],
|
||||||
"11821370524809748218863201748748705728394144148925669901234409589641087093424",
|
"vk_delta_2": [
|
||||||
"18513628196399124885663344181867643312766015533146283344455531540544551221665"
|
[
|
||||||
],
|
"2263054764437434763570286704031806516721917814051603656052135584430600195849",
|
||||||
["1", "0"]
|
"332267239743604505067953832758848322829862699821984128892005653857113955614"
|
||||||
],
|
],
|
||||||
"vk_alphabeta_12": [
|
[
|
||||||
[
|
"8107422899773313798194038382837705724842762783652811880556511721860229797648",
|
||||||
[
|
"5609865441509880240754758422778809019695266789051834830754116541635728659997"
|
||||||
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
|
],
|
||||||
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
|
[
|
||||||
],
|
"1",
|
||||||
[
|
"0"
|
||||||
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
|
]
|
||||||
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
|
],
|
||||||
],
|
"vk_alphabeta_12": [
|
||||||
[
|
[
|
||||||
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
|
[
|
||||||
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
|
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
|
||||||
]
|
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[
|
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
|
||||||
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
|
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
|
||||||
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
|
],
|
||||||
],
|
[
|
||||||
[
|
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
|
||||||
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
|
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
|
||||||
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
|
[
|
||||||
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
|
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
|
||||||
]
|
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
|
||||||
]
|
],
|
||||||
],
|
[
|
||||||
"IC": [
|
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
|
||||||
[
|
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
|
||||||
"10540353245037691655240058832465935071147222378795512774896416883563614389198",
|
],
|
||||||
"20042286059857913285646233979306226083538103143380748863555356103197961213823",
|
[
|
||||||
"1"
|
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
|
||||||
],
|
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
|
||||||
[
|
]
|
||||||
"5831260214145524146501320942030802135386415386731869532840770699430145685903",
|
]
|
||||||
"10936406497477698856797103676487112559914492317404578945377836522823774186039",
|
],
|
||||||
"1"
|
"IC": [
|
||||||
],
|
[
|
||||||
[
|
"10540353245037691655240058832465935071147222378795512774896416883563614389198",
|
||||||
"1295407852409244811850984901965423450287105807829809873962419792828349329577",
|
"20042286059857913285646233979306226083538103143380748863555356103197961213823",
|
||||||
"11301654800484264796111478656697951131719015244071014736702281514571505462297",
|
"1"
|
||||||
"1"
|
],
|
||||||
],
|
[
|
||||||
[
|
"5831260214145524146501320942030802135386415386731869532840770699430145685903",
|
||||||
"6823739927950557742246913693052072220213742766782370219666937126411380340633",
|
"10936406497477698856797103676487112559914492317404578945377836522823774186039",
|
||||||
"19878777316727584245579797737044924949420447706770682437221414501064053790692",
|
"1"
|
||||||
"1"
|
],
|
||||||
]
|
[
|
||||||
]
|
"1295407852409244811850984901965423450287105807829809873962419792828349329577",
|
||||||
}
|
"11301654800484264796111478656697951131719015244071014736702281514571505462297",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"6823739927950557742246913693052072220213742766782370219666937126411380340633",
|
||||||
|
"19878777316727584245579797737044924949420447706770682437221414501064053790692",
|
||||||
|
"1"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user