mirror of
https://github.com/Discreetly/frontend.git
synced 2026-01-09 12:58:03 -05:00
checkpoint: reorg lib components, saltStore, new Onboarding, sidebar/bottombar
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
import { ActionRepresentationE } from '$lib/types';
|
||||
import Shields from '$lib/components/ActionPoints/Shields.svelte';
|
||||
import { configStore } from '$lib/stores';
|
||||
import Battery from './ActionPoints/Battery.svelte';
|
||||
import Battery from './Battery.svelte';
|
||||
export let health: number;
|
||||
export let maxHealth: number;
|
||||
</script>
|
||||
@@ -2,6 +2,8 @@
|
||||
import { inviteCode } from '$lib/gateways/inviteCode';
|
||||
import { alertQueue } from '$lib/stores';
|
||||
export let code = '';
|
||||
export let buttonText = 'Submit';
|
||||
export let hideInput = false;
|
||||
|
||||
let acceptedRoomNames: string[] = [];
|
||||
let loading = false;
|
||||
@@ -79,23 +81,25 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<label class="label" for="inviteCode">
|
||||
<span class="h5">Enter Invite Code:</span>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="Invite Code"
|
||||
id="inviteCode"
|
||||
bind:value={code}
|
||||
on:keydown={(event) => inviteCodeKeyPress(event)}
|
||||
/>
|
||||
</label>
|
||||
{#if !hideInput}
|
||||
<label class="label" for="inviteCode">
|
||||
<span class="h5">Enter Invite Code:</span>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="Invite Code"
|
||||
id="inviteCode"
|
||||
bind:value={code}
|
||||
on:keydown={(event) => inviteCodeKeyPress(event)}
|
||||
/>
|
||||
</label>
|
||||
{/if}
|
||||
{#if !loading}
|
||||
<button
|
||||
class="btn variant-ghost-success mt-3"
|
||||
type="button"
|
||||
disabled={!code}
|
||||
on:click={() => addCode(code)}>Submit</button
|
||||
on:click={() => addCode(code)}>{buttonText}</button
|
||||
>
|
||||
{:else}
|
||||
<p class="italic">Loading...</p>
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
<header class="card-header">
|
||||
<h3 class="h4">Restore Your Identity</h3>
|
||||
</header>
|
||||
|
||||
<section class="px-4 pt-4">
|
||||
<label class="label w-full pb-1">
|
||||
<span class="h5"> Recover From File:</span>
|
||||
@@ -113,7 +114,7 @@
|
||||
<textarea
|
||||
name="textarea"
|
||||
id="jsonRecovery"
|
||||
class="mb-2 p-2 rounded-token"
|
||||
class="mb-2 p-2 rounded-token max-h-24"
|
||||
cols="30"
|
||||
rows="10"
|
||||
placeholder="Paste your Identity Here"
|
||||
@@ -1,9 +1,8 @@
|
||||
<script lang="ts">
|
||||
import Container from '$lib/components/Container.svelte';
|
||||
import EthereumGroupGateway from '$lib/components/Gateways/EthereumGroup.svelte';
|
||||
import InviteCodeGateway from '$lib/components/Gateways/InviteCode.svelte';
|
||||
import SelectServer from '$lib/components/SelectServer.svelte';
|
||||
import Card from '$lib/components/card.svelte';
|
||||
import SelectServer from '$lib/components/Server/SelectServer.svelte';
|
||||
import Card from '$lib/components/Utils/Card.svelte';
|
||||
import { configStore, serverStore } from '$lib/stores';
|
||||
</script>
|
||||
|
||||
@@ -19,6 +18,14 @@
|
||||
<svelte:fragment slot="description">If you were given an invite code, you can</svelte:fragment>
|
||||
<InviteCodeGateway code={$configStore.signUpStatus.inviteCode} />
|
||||
</Card>
|
||||
<Card>
|
||||
<svelte:fragment slot="header">Join the alpha testing room:</svelte:fragment>
|
||||
<InviteCodeGateway
|
||||
code={'layer-spot-gravity-fossil'}
|
||||
hideInput={true}
|
||||
buttonText="Join Alpha Testers"
|
||||
/>
|
||||
</Card>
|
||||
<Card>
|
||||
<svelte:fragment slot="header">Discord Bot</svelte:fragment>
|
||||
<svelte:fragment slot="description">Add the discord bot to your server Today!</svelte:fragment>
|
||||
@@ -34,8 +41,7 @@
|
||||
<Card>
|
||||
<svelte:fragment slot="header">Join via Ethereum Address:</svelte:fragment>
|
||||
<svelte:fragment slot="description"
|
||||
>Are you a genesis validator, daohack survivor, nouns holder? You can join using your Ethereum
|
||||
address.
|
||||
>Are you a genesis validator? You can join using your Ethereum address.
|
||||
</svelte:fragment>
|
||||
<EthereumGroupGateway />
|
||||
</Card>
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import Button from '$lib/components/button.svelte';
|
||||
import Button from '$lib/components/Utils/Button.svelte';
|
||||
import { identityExists } from '$lib/stores';
|
||||
</script>
|
||||
|
||||
18
src/lib/components/Security/SetPasswordContainer.svelte
Normal file
18
src/lib/components/Security/SetPasswordContainer.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import SetPasswordInput from './SetPasswordInput.svelte';
|
||||
import Container from '../Utils/Container.svelte';
|
||||
</script>
|
||||
|
||||
<Container heading="Set A Password">
|
||||
<p class="mt-3">
|
||||
In order to secure your identity and other sensitive data that is stored in your browser, we
|
||||
need you to set a password.
|
||||
</p>
|
||||
<p class="my-3">
|
||||
This password is only used locally, there is no username and password for your account, so don't
|
||||
forget to <a class="link" href="/settings/identity/backup" title="Backup Identity"
|
||||
>backup your identity</a
|
||||
>.
|
||||
</p>
|
||||
<SetPasswordInput />
|
||||
</Container>
|
||||
32
src/lib/components/Security/SetPasswordInput.svelte
Normal file
32
src/lib/components/Security/SetPasswordInput.svelte
Normal file
@@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
import { setPassword } from '$lib/utils';
|
||||
|
||||
const minPasswordLength = 4;
|
||||
let r = '';
|
||||
|
||||
function onSubmit() {
|
||||
if (r != '' && r != null && r != undefined && r.length >= minPasswordLength) {
|
||||
setPassword(r);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<form on:submit|preventDefault={() => onSubmit()} class="flex flex-col w-full">
|
||||
<label for="setPasswordInput" class="label" />
|
||||
<input
|
||||
id="setPasswordInput"
|
||||
type="password"
|
||||
name="password"
|
||||
inputmode="numeric"
|
||||
class="input"
|
||||
bind:value={r}
|
||||
minlength={minPasswordLength}
|
||||
required
|
||||
/>
|
||||
<small>Minimum length: {minPasswordLength}</small>
|
||||
<button
|
||||
class="btn variant-filled-primary mt-3"
|
||||
disabled={r.length < minPasswordLength}
|
||||
type="submit">Set Unlock Code</button
|
||||
>
|
||||
</form>
|
||||
@@ -1,6 +1,38 @@
|
||||
import { alertQueue, configStore } from '$lib/stores';
|
||||
import { alertQueue, configStore, saltStore } from '$lib/stores';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
/**
|
||||
* Retrieves a salt value. If a salt is not present in the store,
|
||||
* it generates a new 16-byte salt using the window.crypto API,
|
||||
* converts it to a hexadecimal string, and stores it. If a salt
|
||||
* is present in the store, it converts the stored hexadecimal
|
||||
* string back to a Uint8Array.
|
||||
*
|
||||
* @returns {Uint8Array} A 16-byte salt value.
|
||||
*/
|
||||
function getSalt(): Uint8Array {
|
||||
const salt: Uint8Array = new Uint8Array(16);
|
||||
|
||||
const saltFromStore = get(saltStore);
|
||||
|
||||
// Generate new salt if salt is not set
|
||||
if (saltFromStore === '') {
|
||||
window.crypto.getRandomValues(salt);
|
||||
|
||||
// Convert to hexadecimal string
|
||||
const saltString = Array.from(salt)
|
||||
.map((b) => b.toString(16).padStart(2, '0'))
|
||||
.join('');
|
||||
|
||||
saltStore.set(saltString);
|
||||
} else {
|
||||
for (let i = 0; i < salt.length; i++) {
|
||||
salt[i] = parseInt(saltFromStore.substring(i * 2, i * 2 + 2), 16);
|
||||
}
|
||||
}
|
||||
return salt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives an encryption key from a given password using PBKDF2.
|
||||
* The key is derived on password entry and stays in memory until page refresh
|
||||
@@ -11,8 +43,8 @@ export async function deriveKey(password: string): Promise<CryptoKey> {
|
||||
// TextEncoder will be used for converting strings to byte arrays
|
||||
const textEncoder = new TextEncoder();
|
||||
|
||||
// Salt for PBKDF2. 420+69+a bunch of randomness from my laptop
|
||||
const salt = textEncoder.encode('42069210482402528527906392650230853');
|
||||
// Salt for PBKDF2 stored in local storage
|
||||
const salt = getSalt();
|
||||
|
||||
// Importing the password as a cryptographic key
|
||||
const passwordKey = await window.crypto.subtle.importKey(
|
||||
|
||||
@@ -81,6 +81,11 @@ export const currentRoomMessages = derived(
|
||||
*/
|
||||
export const rateLimitStore = storable({} as rateLimitStoreI, 'rateLimit');
|
||||
|
||||
/**
|
||||
* @description This stores the salt used to derive the encryption key from the user's password
|
||||
*/
|
||||
export const saltStore = storable('', 'salt');
|
||||
|
||||
/* ------------------ Configuration / Misc Stores ------------------*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,8 +31,14 @@ export async function setPassword(password: string): Promise<'success' | string>
|
||||
console.error(`Error decrypting: ${e}`);
|
||||
return 'Error decrypting data while setting new password';
|
||||
}
|
||||
|
||||
/******************************
|
||||
* STAGE2: ENCRYPT EVERYTHING
|
||||
* STAGE2: Derive and set new Key
|
||||
* ******************************/
|
||||
keyStore.set(await deriveKey(password));
|
||||
|
||||
/******************************
|
||||
* STAGE3: ENCRYPT EVERYTHING
|
||||
******************************/
|
||||
try {
|
||||
if (identity) {
|
||||
@@ -43,16 +49,13 @@ export async function setPassword(password: string): Promise<'success' | string>
|
||||
return 'Error encrypting data while setting new password';
|
||||
}
|
||||
/******************************
|
||||
* STAGE3: SET PASSWORD HASH
|
||||
* STAGE4: SET PASSWORD HASH
|
||||
******************************/
|
||||
configStore.update((config) => {
|
||||
config.hashedPwd = hashedPassword;
|
||||
return config;
|
||||
});
|
||||
/******************************
|
||||
* STAGE4: Derive and set new Key
|
||||
* ******************************/
|
||||
keyStore.set(await deriveKey(password));
|
||||
|
||||
return 'success';
|
||||
}
|
||||
return 'error';
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
import '../app.postcss';
|
||||
import { onMount } from 'svelte';
|
||||
import AppHeader from './AppHeader.svelte';
|
||||
import Loading from '$lib/components/loading.svelte';
|
||||
import Loading from '$lib/components/Utils/Loading.svelte';
|
||||
import { selectedServer, alertQueue } from '$lib/stores';
|
||||
import { getServerList, isInputFieldFocused, setDefaultServers } from '$lib/utils/';
|
||||
import { updateServer } from '$lib/utils/';
|
||||
import { Drawer, getDrawerStore } from '@skeletonlabs/skeleton';
|
||||
import SelectServer from '$lib/components/SelectServer.svelte';
|
||||
import SelectRoom from '$lib/components/SelectRoom.svelte';
|
||||
import SelectServer from '$lib/components/Server/SelectServer.svelte';
|
||||
import SelectRoom from '$lib/components/Server/SelectRoom.svelte';
|
||||
import Console from './console/Console.svelte';
|
||||
import Sidebar from './Sidebar.svelte';
|
||||
import AppFooter from './Footer.svelte';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import Welcome from '$lib/components/Welcome.svelte';
|
||||
import Welcome from '$lib/components/Onboarding/Welcome.svelte';
|
||||
|
||||
console.info(
|
||||
'I see you are checking out the logs, let us know what you think on our discord: https://discord.gg/brJQ36KVxk'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script>
|
||||
import Demo from '$lib/components/Demo.svelte';
|
||||
import Introduction from '$lib/components/Introduction.svelte';
|
||||
import Demo from '$lib/components/Onboarding/Demo.svelte';
|
||||
import Introduction from '$lib/components/Onboarding/Introduction.svelte';
|
||||
</script>
|
||||
|
||||
<div class="mx-auto mt-10 max-w-[80ch]">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import AP from '$lib/components/AP.svelte';
|
||||
import Clock from '$lib/components/Clock.svelte';
|
||||
import AP from '$lib/components/ActionPoints/AP.svelte';
|
||||
import Clock from '$lib/components/Utils/Clock.svelte';
|
||||
import { currentSelectedRoom, configStore } from '$lib/stores';
|
||||
import { ProgressBar } from '@skeletonlabs/skeleton';
|
||||
import FullCircle from 'svelte-material-icons/Circle.svelte';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import SelectRoom from '$lib/components/SelectRoom.svelte';
|
||||
import SelectServer from '$lib/components/SelectServer.svelte';
|
||||
import SelectRoom from '$lib/components/Server/SelectRoom.svelte';
|
||||
import SelectServer from '$lib/components/Server/SelectServer.svelte';
|
||||
</script>
|
||||
|
||||
<div id="sidebar" class="hidden sm:grid grid-rows-[auto_1fr_auto] border-r border-surface-500/30">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Gateways from './Gateways.svelte';
|
||||
import Gateways from '$lib/components/Onboarding/Gateways.svelte';
|
||||
|
||||
import Container from '$lib/components/Container.svelte';
|
||||
import Container from '$lib/components/Utils/Container.svelte';
|
||||
</script>
|
||||
|
||||
<Container heading="Join More Communities">
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script lang="ts">
|
||||
import DeleteIdentity from './identity/DeleteIdentity.svelte';
|
||||
import BackupIdentity from './identity/BackupIdentity.svelte';
|
||||
import RestoreIdentity from './identity/RestoreIdentity.svelte';
|
||||
import DeleteIdentity from '$lib/components/Identity/DeleteIdentity.svelte';
|
||||
import BackupIdentity from './identity/BackupIdentityWrapper.svelte';
|
||||
import RestoreIdentity from '$lib/components/Identity/RestoreIdentity.svelte';
|
||||
import { createIdentity } from '$lib/utils/';
|
||||
import ActionRepresentation from './ui/ActionRepresentation.svelte';
|
||||
import IdentityIcon from 'svelte-material-icons/Account.svelte';
|
||||
import Eye from 'svelte-material-icons/Eye.svelte';
|
||||
import Container from '../../lib/components/Container.svelte';
|
||||
import Container from '$lib/components/Utils/Container.svelte';
|
||||
import { identityExists } from '$lib/stores';
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script>
|
||||
import Container from '../../../lib/components/Container.svelte';
|
||||
import BackupIdentity from './BackupIdentity.svelte';
|
||||
import DeleteIdentity from './DeleteIdentity.svelte';
|
||||
import RestoreIdentity from './RestoreIdentity.svelte';
|
||||
import Container from '$lib/components/Utils/Container.svelte';
|
||||
import BackupIdentity from './BackupIdentityWrapper.svelte';
|
||||
import DeleteIdentity from '$lib/components/Identity/DeleteIdentity.svelte';
|
||||
import RestoreIdentity from '$lib/components/Identity/RestoreIdentity.svelte';
|
||||
</script>
|
||||
|
||||
<Container heading="Manage Your Identity">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import BackupIdentity from '$lib/components/BackupIdentity.svelte';
|
||||
import BackupIdentity from '$lib/components/Identity/BackupIdentity.svelte';
|
||||
</script>
|
||||
|
||||
<div class="card variant-ghost-secondary">
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import BackupIdentity from '../BackupIdentity.svelte';
|
||||
import BackupIdentity from '../BackupIdentityWrapper.svelte';
|
||||
</script>
|
||||
|
||||
<BackupIdentity />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import RestoreIdentity from '../RestoreIdentity.svelte';
|
||||
import RestoreIdentity from '$lib/components/Identity/RestoreIdentity.svelte';
|
||||
</script>
|
||||
|
||||
<RestoreIdentity />
|
||||
|
||||
@@ -1,49 +1,12 @@
|
||||
<script lang="ts">
|
||||
import Container from '../../../lib/components/Container.svelte';
|
||||
import { setPassword } from '$lib/utils';
|
||||
import SetPassword from '$lib/components/Security/SetPasswordContainer.svelte';
|
||||
|
||||
import Container from '$lib/components/Utils/Container.svelte';
|
||||
import { passwordSet } from '$lib/stores';
|
||||
|
||||
const minPasswordLength = 4;
|
||||
let r = '';
|
||||
|
||||
function onSubmit() {
|
||||
if (r != '' && r != null && r != undefined && r.length >= minPasswordLength) {
|
||||
setPassword(r);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if !$passwordSet}
|
||||
<Container heading="Set A Password">
|
||||
<p class="mt-3">
|
||||
In order to secure your identity and other sensitive data that is stored in your browser, we
|
||||
need you to set a password.
|
||||
</p>
|
||||
<p class="my-3">
|
||||
This password is only used locally, there is no username and password for your account, so
|
||||
don't forget to <a class="link" href="/settings/identity/backup" title="Backup Identity"
|
||||
>backup your identity</a
|
||||
>.
|
||||
</p>
|
||||
<form on:submit|preventDefault={() => onSubmit()} class="flex flex-col w-full">
|
||||
<label for="setPasswordInput" class="label" />
|
||||
<input
|
||||
id="setPasswordInput"
|
||||
type="password"
|
||||
name="password"
|
||||
class="input"
|
||||
bind:value={r}
|
||||
minlength={minPasswordLength}
|
||||
required
|
||||
/>
|
||||
<small>Minimum password length: {minPasswordLength}</small>
|
||||
<button
|
||||
class="btn variant-filled-primary mt-3"
|
||||
disabled={r.length < minPasswordLength}
|
||||
type="submit">Set Password</button
|
||||
>
|
||||
</form>
|
||||
</Container>
|
||||
<SetPassword />
|
||||
{:else}
|
||||
<Container heading="Password set" />
|
||||
{/if}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import Container from '../../../lib/components/Container.svelte';
|
||||
import Container from '$lib/components/Utils/Container.svelte';
|
||||
import ActionRepresentation from './ActionRepresentation.svelte';
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import AP from '$lib/components/AP.svelte';
|
||||
import AP from '$lib/components/ActionPoints/AP.svelte';
|
||||
import { configStore } from '$lib/stores';
|
||||
import { ActionRepresentationE } from '$lib/types';
|
||||
import { RangeSlider } from '@skeletonlabs/skeleton';
|
||||
|
||||
@@ -1,11 +1,34 @@
|
||||
<script lang="ts">
|
||||
import { configStore, identityExists } from '$lib/stores';
|
||||
import { configStore, identityExists, passwordSet } from '$lib/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import ArrowRight from 'svelte-material-icons/ArrowRightBold.svelte';
|
||||
import Text from 'svelte-material-icons/TextBox.svelte';
|
||||
import Account from 'svelte-material-icons/AccountHardHat.svelte';
|
||||
import { inviteCode } from '$lib/gateways/inviteCode';
|
||||
import { addConsoleMessage } from '$lib/utils/console';
|
||||
|
||||
import { goto } from '$app/navigation';
|
||||
import { Stepper, Step, getModalStore, type ModalSettings } from '@skeletonlabs/skeleton';
|
||||
import { createIdentity, addConsoleMessage, unlockPadlock } from '$lib/utils';
|
||||
import Lock from 'svelte-material-icons/Lock.svelte';
|
||||
import Introduction from '$lib/components/Onboarding/Introduction.svelte';
|
||||
import SetPassword from '$lib/components/Security/SetPasswordInput.svelte';
|
||||
import RestoreIdentity from '$lib/components/Identity/RestoreIdentity.svelte';
|
||||
import Backup from '$lib/components/Identity/BackupIdentity.svelte';
|
||||
import Gateways from '$lib/components/Onboarding/Gateways.svelte';
|
||||
|
||||
const modalStore = getModalStore();
|
||||
|
||||
function unlock() {
|
||||
const modal: ModalSettings = {
|
||||
type: 'prompt',
|
||||
title: 'Unlock',
|
||||
body: 'Enter your password to unlock your keystores',
|
||||
value: '',
|
||||
valueAttr: { type: 'password', minlength: 4, required: true },
|
||||
response: async (r: string) => {
|
||||
if (r != 'false' && r != '' && r != null && r != undefined) {
|
||||
unlockPadlock(r);
|
||||
}
|
||||
}
|
||||
};
|
||||
modalStore.trigger(modal);
|
||||
}
|
||||
|
||||
function checkForIdentity() {
|
||||
const idStatus = $identityExists;
|
||||
@@ -20,43 +43,72 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function code() {
|
||||
if (!$configStore.signUpStatus.inviteCode) {
|
||||
addConsoleMessage(
|
||||
'No Invite Code Provided ❌ please use `/join INVITE-CODE` to join via invite code',
|
||||
'warning'
|
||||
);
|
||||
} else {
|
||||
let { acceptedRoomNames, err } = await inviteCode($configStore.signUpStatus.inviteCode);
|
||||
if (acceptedRoomNames) {
|
||||
addConsoleMessage('Invite Code Accepted 🎉');
|
||||
acceptedRoomNames.forEach((roomName) => {
|
||||
addConsoleMessage(`Joined Room: ${roomName}`);
|
||||
});
|
||||
}
|
||||
if (err) {
|
||||
addConsoleMessage(`Invite Code Error: ${err}`, 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
addConsoleMessage('👋 Welcome to Discreetly');
|
||||
checkForIdentity();
|
||||
code();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<a href="/settings" class="btn btn-sm variant-ghost-primary">
|
||||
<span>Restore Identity</span>
|
||||
<Account />
|
||||
</a>
|
||||
<a href="/about" class="btn btn-sm variant-ghost-secondary ms-2 mt-2">
|
||||
<span>Read More</span>
|
||||
<Text />
|
||||
</a>
|
||||
<a href="/chat" class="btn btn-sm variant-ghost-success ms-2 mt-2">
|
||||
<span>Continue</span>
|
||||
<ArrowRight />
|
||||
</a>
|
||||
</div>
|
||||
<Stepper
|
||||
class="max-w-sm sm:max-w-md md:max-w-3xl mx-auto mt-16"
|
||||
on:complete={() => {
|
||||
goto('/chat');
|
||||
}}
|
||||
buttonCompleteLabel="Lets Go Chat Anon"
|
||||
buttonNext="variant-filled-surface-50-900-token"
|
||||
buttonComplete="variant-filled-success"
|
||||
>
|
||||
<Step class="px-10">
|
||||
<svelte:fragment slot="header"
|
||||
><h2 class="h2 text-center">Welcome to Discreetly</h2>
|
||||
</svelte:fragment>
|
||||
<Introduction />
|
||||
</Step>
|
||||
<Step locked={!$passwordSet}>
|
||||
<svelte:fragment slot="header">
|
||||
{#if !$passwordSet}
|
||||
<h2 class="h2 text-center">Set Unlock Code</h2>
|
||||
{:else}
|
||||
<h2 class="h2 text-center">Unlock Code has been set ✅</h2>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
{#if !$passwordSet}
|
||||
<SetPassword />
|
||||
{:else}
|
||||
<p class="h4 text-center mt-5">Press next to continue, you are almost done</p>
|
||||
{/if}
|
||||
</Step>
|
||||
<Step locked={$identityExists !== 'safe'}>
|
||||
<svelte:fragment slot="header">
|
||||
{#if !$identityExists}
|
||||
<h2 class="h2 text-center">Generate or Restore an Identity</h2>
|
||||
{:else if $identityExists == 'encrypted'}
|
||||
<h2 class="h2 text-center">Identity Wallet Locked</h2>
|
||||
{:else}
|
||||
<h2 class="h2 text-center">Identity Created ✅</h2>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
{#if $identityExists == null}
|
||||
<button on:click={() => createIdentity()} class="btn variant-ghost-success" type="button">
|
||||
Generate Identity
|
||||
</button>
|
||||
<RestoreIdentity />
|
||||
{:else if $identityExists == 'encrypted'}
|
||||
<div on:click={unlock}>
|
||||
<p class="h4 text-center">Please unlock your wallet</p>
|
||||
<Lock class="h3 m-auto" />
|
||||
</div>
|
||||
{:else}
|
||||
<p class="h4 text-center mt-5">
|
||||
Backup your identity and then press next to continue, last step
|
||||
</p>
|
||||
<Backup />
|
||||
{/if}
|
||||
</Step>
|
||||
<Step>
|
||||
<svelte:fragment slot="header"
|
||||
><div class="h3 text-center">Join Communities</div></svelte:fragment
|
||||
>
|
||||
<Gateways />
|
||||
</Step>
|
||||
</Stepper>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { configStore, identityStore } from '$lib/stores';
|
||||
import { configStore, identityExists } from '$lib/stores';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
$configStore.signUpStatus.inviteCode = $page.params.invite;
|
||||
console.log(`Invited with code: ${$page.params.invite}`);
|
||||
$: identityExists = !!$identityStore._commitment;
|
||||
|
||||
onMount(() => {
|
||||
if (identityExists) {
|
||||
if ($identityExists) {
|
||||
goto('/settings#join-more');
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user