Skip to content

Commit

Permalink
Add passphrase page
Browse files Browse the repository at this point in the history
  • Loading branch information
mrruby committed Oct 25, 2023
1 parent a2e78e4 commit cd2d166
Show file tree
Hide file tree
Showing 25 changed files with 260 additions and 48 deletions.
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@
"postcss": "^8.4.31",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.10.1",
"svelte": "^4.0.5",
"svelte-check": "^3.4.3",
"tailwindcss": "^3.3.3",
"tiny-glob": "^0.2.9",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^4.4.2"
},
"type": "module"
"type": "module",
"dependencies": {
"clsx": "^2.0.0",
"svelte": "^4.0.5",
"tailwindcss": "^3.3.3",
"tiny-glob": "^0.2.9"
}
}
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/lib/components/AppParagraph.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<script lang="ts">
export let text: string;
export let textColor = 'text-secondary';
export let extraProps = '';
</script>

<p class="text-base text-gray font-normal max-w-xs {extraProps}">
<p class="{textColor} text-base font-normal {extraProps}">
{text}
</p>
20 changes: 15 additions & 5 deletions src/lib/components/Button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@
export let onClick: () => void;
export let color: 'primary' | 'secondary' = 'primary';
export let arrow = false;
export let extraBottomMargin = false;
export let disabled = false;
import clsx from 'clsx';
</script>

<button
class="max-w-xs p-2 my-2 rounded-2xl w-full text-base font-bold relative flex justify-center
items-center {color === 'primary'
? 'bg-primary text-white'
: 'bg-white text-gray border border-gray'}"
class={clsx(
'max-w-xs p-2 my-2 rounded-2xl text-base font-bold relative flex justify-center w-full',
{
'bg-primary-disabled text-white': color === 'primary' && disabled,
'bg-primary text-white': color === 'primary' && !disabled,
'bg-white text-secondary border border-secondary': color !== 'primary',
'mb-4': extraBottomMargin
}
)}
on:click={onClick}
{disabled}
>
<span>{label}</span>
{#if arrow}
<img src="/img/arrow.svg" alt="Arrow" class="absolute right-4" />
<img src="/img/arrow-right.svg" alt="Arrow" class="absolute right-4" />
{/if}
</button>
8 changes: 8 additions & 0 deletions src/lib/components/Tooltip.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="relative cursor-pointer group">
<slot name="content" />
<div
class="absolute invisible group-hover:visible z-10 bottom-full left-1/2 transform -translate-x-1/2 bg-white px-4 py-2 text-secondary text-sm rounded-md transition-opacity opacity-0 group-hover:opacity-100 shadow-lg w-96"
>
<slot name="body" />
</div>
</div>
1 change: 1 addition & 0 deletions src/lib/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './navigation';
3 changes: 3 additions & 0 deletions src/lib/helpers/navigation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function dismissExtensionWindow() {
return window.close();
}
1 change: 1 addition & 0 deletions src/lib/stores/const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const passphrase = 'passphrase';
2 changes: 2 additions & 0 deletions src/lib/stores/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './passphraseStore';
export * from './const';
5 changes: 5 additions & 0 deletions src/lib/stores/passphraseStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { writable } from 'svelte/store';

const passphraseStore = writable('');

export { passphraseStore };
1 change: 1 addition & 0 deletions src/lib/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './password';
1 change: 1 addition & 0 deletions src/lib/types/password.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type SetPassphrase = 'set' | 'confirm';
11 changes: 4 additions & 7 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
<script>
import Button from '$components/Button.svelte';
import AppParagraph from '$components/AppParagraph.svelte';
import { dismissExtensionWindow } from '$lib/helpers';
function redirectToSetup() {
window.open('setup.html', '_blank');
}
function dismissExtensionWindow() {
return window.close();
window.open('setup/start.html', '_blank');
}
</script>

Expand All @@ -22,11 +19,11 @@
<img src="/img/setup.svg" alt="Close" class="max-w-[48px]" />
<p class="font-bold text-2xl mt-4">Setup Required</p>
<AppParagraph
extraProps="my-4 text-center"
extraProps="my-4 text-center max-w-xs"
text="You are yet to setup Holo Key Manager. Click “start setup” to begin."
/>
</div>

<Button label="Start setup" onClick={redirectToSetup} />
<Button label="Start setup" onClick={redirectToSetup} extraBottomMargin />
<Button label="Cancel" onClick={dismissExtensionWindow} color="secondary" />
</div>
23 changes: 23 additions & 0 deletions src/routes/setup/+layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script>
import { page } from '$app/stores';
import { setContext } from 'svelte';
import { passphrase, passphraseStore } from '$stores';
function dismissExtensionWindow() {
window.history.back();
}
setContext(passphrase, passphraseStore);
</script>

<div
class="flex flex-col items-center mt-20 w-[576px] border border-light-gray rounded-xl mx-auto py-8"
>
{#if !$page.url.pathname.includes('start')}
<button class="self-start ml-6 mb-4 flex items-center" on:click={dismissExtensionWindow}>
<img src="/img/arrow-left.svg" alt="Arrow" />
<span class="ml-2 text-base">Back</span></button
>
{/if}
<slot />
</div>
28 changes: 0 additions & 28 deletions src/routes/setup/+page.svelte

This file was deleted.

45 changes: 45 additions & 0 deletions src/routes/setup/enter-passphrase/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script lang="ts">
import PopupDialog from './PopupDialog.svelte';
import { getContext } from 'svelte';
import { passphrase } from '$stores';
import EnterPassphraseComponent from './EnterPassphraseComponent.svelte';
import type { SetPassphrase } from '$lib/types';
import type { Writable } from 'svelte/store';
const passphraseStore = getContext<Writable<string>>(passphrase);
let passphraseState: SetPassphrase = 'set';
let confirmPassphrase = '';
let showDialog = false;
$: charCount = $passphraseStore.length;
</script>

{#if passphraseState === 'set'}
<EnterPassphraseComponent
bind:inputValue={$passphraseStore}
isRed={charCount < 20}
title="Enter Passphrase"
description="Enter your desired passphrase and remind to keep it safe."
nextLabel="Set Passphrase"
inputState={charCount < 20
? 'Please enter a minimum of 20 Characters'
: `${charCount} characters`}
next={() => (showDialog = true)}
/>
{#if showDialog}
<PopupDialog next={() => (passphraseState = 'confirm')} dismiss={() => (showDialog = false)} />
{/if}
{/if}

{#if passphraseState === 'confirm'}
<EnterPassphraseComponent
bind:inputValue={confirmPassphrase}
isRed={confirmPassphrase !== $passphraseStore}
title="Confirm Passphrase"
description="Tying loose ends, please enter your passphrase again."
nextLabel="Next"
inputState={confirmPassphrase !== $passphraseStore ? 'Passphrases do not match' : ``}
next={() => null}
/>
{/if}
55 changes: 55 additions & 0 deletions src/routes/setup/enter-passphrase/EnterPassphraseComponent.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<script lang="ts">
import AppParagraph from '$components/AppParagraph.svelte';
import Button from '$components/Button.svelte';
import Tooltip from '$components/Tooltip.svelte';
import { dismissExtensionWindow } from '$lib/helpers';
import clsx from 'clsx';
export let inputValue: string;
export let isRed: boolean;
export let title: string;
export let description: string;
export let nextLabel: string;
export let inputState: string;
export let next: () => void;
</script>

<h1 class="text-4xl font-bold text-center mb-2">{title}</h1>
<AppParagraph extraProps="mx-auto text-center" text={description} />
<div class="p-6 w-full">
<textarea
bind:value={inputValue}
class="w-full h-44 rounded border border-secondary resize-none py-1 px-2 text-sm"
placeholder={title}
/>
<div class="flex justify-between items-center">
<AppParagraph textColor={clsx(isRed && 'text-alert')} text={inputState} />
<Tooltip>
<div slot="content">
<div class="flex items-center text-primary text-base">
<p>What is passphrase</p>
<img src="/img/question.svg" alt="Question icon" class="ml-2" />
</div>
</div>
<div slot="body">
<strong class="text-sm text-black">Passphrase</strong>
<p>
This is can be a word or sentence of your choice. E.g Manager (word) or The quick brown
fox jumps over the lazy dog (sentence). Make your passphrase as strong as possible. It
should be long, include a mix of many different types of characters, and be hard to guess.
</p>
<p class="pt-2">
You can optionally turn off your internet while doing this for added security.
</p>
<div class="pt-2">
<strong>Tip:</strong> Write down or store your passphrase in a password manager.
</div>
</div>
</Tooltip>
</div>
</div>

<div class="grid grid-cols-2 gap-5 w-full p-6">
<Button label="Cancel" onClick={dismissExtensionWindow} color="secondary" />
<Button disabled={inputValue.length < 20} label={nextLabel} onClick={next} />
</div>
22 changes: 22 additions & 0 deletions src/routes/setup/enter-passphrase/PopupDialog.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script lang="ts">
export let dismiss: () => void;
export let next: () => void;
</script>

<div class="fixed inset-0 flex items-center justify-center z-50 bg-gray-500 bg-opacity-70">
<div class="bg-white p-10 rounded-md shadow-lg flex flex-col items-center">
<img src="/img/noun.svg" alt="Noun" />
<div class="my-4">
<h2 class="text-xl font-semibold">Important</h2>
</div>
<p>Did you remember to write down your passphrase?</p>
<div class="mt-4 flex flex-col justify-center w-36 mx-auto">
<button class="bg-tertiary text-white font-bold py-2 px-4 rounded-full m-2" on:click={next}>
Yes
</button>
<button class="underline text-quaternary font-bold py-2 px-4 m-2 bg-white" on:click={dismiss}>
Go back
</button>
</div>
</div>
</div>
25 changes: 25 additions & 0 deletions src/routes/setup/start/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script>
import Button from '$components/Button.svelte';
import AppParagraph from '$components/AppParagraph.svelte';
import { goto } from '$app/navigation';
</script>

<img src="/img/holo_logo.svg" alt="Holo Key Manager Logo" class="w-12 my-4" />
<h1 class="text-4xl font-bold text-center">Holo Key Manager</h1>
<div class="border-b-[0.5px] my-4 border-light-gray w-full">
<AppParagraph extraProps="mx-auto text-center max-w-xs" text="Welcome to Holo Key Manager." />
<AppParagraph
extraProps="mx-auto text-center max-w-xs mb-4"
text="Let’s setup up your hApps key manager."
/>
</div>
<AppParagraph
extraProps="my-4 max-w-xs"
text="Holo Key Manager is a secure key manager for creating and managing Holochain keys. Get easy access to all your keys. You can set up and manager one or more keys for each application"
/>
<AppParagraph
extraProps="my-4 max-w-xs"
text="First time user? Select “first time setup” below. If you have already setup the key manager in the past you can select “Import existing keys"
/>
<Button arrow label="First time setup" onClick={() => goto('/setup/enter-passphrase')} />
<Button label="Import existing keys" onClick={() => null} color="secondary" />
3 changes: 3 additions & 0 deletions static/img/arrow-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
5 changes: 5 additions & 0 deletions static/img/noun.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions static/img/question.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion svelte.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ const config = {
adapter: adapter(),
appDir: 'app',
alias: {
$components: path.resolve('./src/lib/components')
$components: path.resolve('./src/lib/components'),
$helpers: path.resolve('./src/lib/helpers'),
$stores: path.resolve('./src/lib/stores'),
$types: path.resolve('./src/lib/types')
}
}
};
Expand Down
Loading

0 comments on commit cd2d166

Please sign in to comment.