show approval errors in approval view
This commit is contained in:
		@@ -10,6 +10,7 @@ export let appState = writable({
 | 
			
		||||
    credentialStatus: 'locked',
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export async function acceptRequest() {
 | 
			
		||||
    let req = await get(appState).pendingRequests.get();
 | 
			
		||||
    appState.update($appState => {
 | 
			
		||||
@@ -20,6 +21,7 @@ export async function acceptRequest() {
 | 
			
		||||
    navigate('Approve');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export function completeRequest() {
 | 
			
		||||
    appState.update($appState => {
 | 
			
		||||
        $appState.currentRequest = null;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,35 @@
 | 
			
		||||
<script>
 | 
			
		||||
    import { onMount } from 'svelte';
 | 
			
		||||
    import { invoke } from '@tauri-apps/api/tauri';
 | 
			
		||||
 | 
			
		||||
    import { navigate } from '../lib/routing.js';
 | 
			
		||||
    import { appState } from '../lib/state.js';
 | 
			
		||||
    import { appState, completeRequest } from '../lib/state.js';
 | 
			
		||||
    import ErrorAlert from '../ui/ErrorAlert.svelte';
 | 
			
		||||
    import Link from '../ui/Link.svelte';
 | 
			
		||||
    import Icon from '../ui/Icon.svelte';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Send response to backend, display error if applicable
 | 
			
		||||
    let error, alert;
 | 
			
		||||
    async function respond() {
 | 
			
		||||
        let {id, approval} = $appState.currentRequest;
 | 
			
		||||
        try {
 | 
			
		||||
            await invoke('respond', {response: {id, approval}});
 | 
			
		||||
            navigate('ShowResponse');
 | 
			
		||||
        }
 | 
			
		||||
        catch (e) {
 | 
			
		||||
            if (error) {
 | 
			
		||||
                alert.shake();
 | 
			
		||||
            }
 | 
			
		||||
            error = e;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Approval has one of several outcomes depending on current credential state
 | 
			
		||||
    async function approve() {
 | 
			
		||||
        $appState.currentRequest.approval = 'Approved';
 | 
			
		||||
        let status = await invoke('get_session_status');
 | 
			
		||||
        if (status === 'unlocked') {
 | 
			
		||||
            navigate('ShowResponse');
 | 
			
		||||
            await respond();
 | 
			
		||||
        }
 | 
			
		||||
        else if (status === 'locked') {
 | 
			
		||||
            navigate('Unlock');
 | 
			
		||||
@@ -21,40 +39,69 @@
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function deny() {
 | 
			
		||||
    // Denial has only one
 | 
			
		||||
    async function deny() {
 | 
			
		||||
        $appState.currentRequest.approval = 'Denied';
 | 
			
		||||
        navigate('ShowResponse');
 | 
			
		||||
        await respond();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Extract executable name from full path
 | 
			
		||||
    let appName = null;
 | 
			
		||||
    if ($appState.currentRequest.clients.length === 1) {
 | 
			
		||||
        let path = $appState.currentRequest.clients[0].exe;
 | 
			
		||||
        // grab the filename from the path
 | 
			
		||||
        let m = path.match(/\/([^/]+?$)|\\([^\\]+?$)/);
 | 
			
		||||
        appName = m[1] || m[2];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Executable paths can be long, so ensure they only break on \ or /
 | 
			
		||||
    function breakPath(client) {
 | 
			
		||||
        return client.exe.replace(/(\\|\/)/g, '$1<wbr>');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // if the request has already been approved/denied, send response immediately
 | 
			
		||||
    onMount(async () => {
 | 
			
		||||
        if ($appState.currentRequest.approval) {
 | 
			
		||||
            await respond();
 | 
			
		||||
        }
 | 
			
		||||
    })
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div class="flex flex-col space-y-4 p-4 m-auto max-w-max h-screen justify-center">
 | 
			
		||||
    <!-- <div class="p-4 rounded-box border-2 border-neutral-content"> -->
 | 
			
		||||
<!-- Don't render at all if we're just going to immediately proceed to the next screen -->
 | 
			
		||||
{#if !$appState.currentRequest.approval}
 | 
			
		||||
    <div class="flex flex-col space-y-4 p-4 m-auto max-w-xl h-screen items-center justify-center">
 | 
			
		||||
        {#if error}
 | 
			
		||||
            <ErrorAlert bind:this={alert}>
 | 
			
		||||
                {error}
 | 
			
		||||
                <svelte:fragment slot="buttons">
 | 
			
		||||
                    <button class="btn btn-sm btn-alert-error" on:click={completeRequest}>Cancel</button>
 | 
			
		||||
                    <button class="btn btn-sm btn-alert-error" on:click={respond}>Retry</button>
 | 
			
		||||
                </svelte:fragment>
 | 
			
		||||
            </ErrorAlert>
 | 
			
		||||
        {/if}
 | 
			
		||||
 | 
			
		||||
        <div class="space-y-1 mb-4">
 | 
			
		||||
            <h2 class="text-xl font-bold">{appName ? `"${appName}"` : 'An appplication'} would like to access your AWS credentials.</h2>
 | 
			
		||||
            {#each $appState.currentRequest.clients as client}
 | 
			
		||||
                <p>Path: {client ? client.exe : 'Unknown'}</p>
 | 
			
		||||
                <p>PID: {client ? client.pid : 'Unknown'}</p>
 | 
			
		||||
            {/each}
 | 
			
		||||
 | 
			
		||||
            <div class="grid grid-cols-[auto_1fr] gap-x-3">
 | 
			
		||||
                {#each $appState.currentRequest.clients as client}
 | 
			
		||||
                    <div class="text-right">Path:</div>
 | 
			
		||||
                    <code class="">{@html client ? breakPath(client) : 'Unknown'}</code>
 | 
			
		||||
                    <div class="text-right">PID:</div>
 | 
			
		||||
                    <code>{client ? client.pid : 'Unknown'}</code>
 | 
			
		||||
                {/each}
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="grid grid-cols-2">
 | 
			
		||||
            <Link target="{deny}" hotkey="Escape">
 | 
			
		||||
        <div class="w-full flex justify-between">
 | 
			
		||||
            <Link target={deny} hotkey="Escape">
 | 
			
		||||
                <button class="btn btn-error justify-self-start">
 | 
			
		||||
                    Deny
 | 
			
		||||
                    <kbd class="ml-2 normal-case px-1 py-0.5 rounded border border-neutral">Esc</kbd>
 | 
			
		||||
                </button>
 | 
			
		||||
            </Link>
 | 
			
		||||
 | 
			
		||||
            <Link target="{approve}" hotkey="Enter" shift="{true}">
 | 
			
		||||
            <Link target={approve} hotkey="Enter" shift="{true}">
 | 
			
		||||
                <button class="btn btn-success justify-self-end">
 | 
			
		||||
                    Approve
 | 
			
		||||
                    <kbd class="ml-2 normal-case px-1 py-0.5 rounded border border-neutral">Shift</kbd>
 | 
			
		||||
@@ -63,4 +110,5 @@
 | 
			
		||||
                </button>
 | 
			
		||||
            </Link>
 | 
			
		||||
        </div>
 | 
			
		||||
</div>
 | 
			
		||||
    </div>
 | 
			
		||||
{/if}
 | 
			
		||||
@@ -29,7 +29,7 @@
 | 
			
		||||
        try {
 | 
			
		||||
            await invoke('save_credentials', {credentials, passphrase});
 | 
			
		||||
            if ($appState.currentRequest) {
 | 
			
		||||
                navigate('ShowResponse');
 | 
			
		||||
                navigate('Approve');
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                navigate('Home');
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,8 @@
 | 
			
		||||
<script>
 | 
			
		||||
    import { onMount } from 'svelte';
 | 
			
		||||
    import { draw, fade } from 'svelte/transition';
 | 
			
		||||
    import { invoke } from '@tauri-apps/api/tauri';
 | 
			
		||||
 | 
			
		||||
    import { appState, completeRequest } from '../lib/state.js';
 | 
			
		||||
    import ErrorAlert from '../ui/ErrorAlert.svelte';
 | 
			
		||||
    import Link from '../ui/Link.svelte';
 | 
			
		||||
    
 | 
			
		||||
    let success = false;
 | 
			
		||||
    let error = null;
 | 
			
		||||
@@ -14,55 +11,28 @@
 | 
			
		||||
    let fadeDuration = drawDuration * 0.6;
 | 
			
		||||
    let fadeDelay = drawDuration * 0.4;
 | 
			
		||||
 | 
			
		||||
    async function respond() {
 | 
			
		||||
        let packet = {
 | 
			
		||||
            id: $appState.currentRequest.id,
 | 
			
		||||
            approval: $appState.currentRequest.approval,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            await invoke('respond', {response: packet});
 | 
			
		||||
            success = true;
 | 
			
		||||
            window.setTimeout(
 | 
			
		||||
                completeRequest,
 | 
			
		||||
                // Extra 50ms so the window can finish disappearing before the redraw
 | 
			
		||||
                Math.min(5000, $appState.config.rehide_ms + 50),
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        catch (e) {
 | 
			
		||||
            error = e;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    onMount(respond);
 | 
			
		||||
    onMount(() => {
 | 
			
		||||
        window.setTimeout(
 | 
			
		||||
            completeRequest,
 | 
			
		||||
            // Extra 50ms so the window can finish disappearing before the redraw
 | 
			
		||||
            Math.min(5000, $appState.config.rehide_ms + 50),
 | 
			
		||||
        )
 | 
			
		||||
    })
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{#if error}
 | 
			
		||||
    <div class="flex flex-col h-screen items-center justify-center m-auto max-w-lg">
 | 
			
		||||
        <ErrorAlert>
 | 
			
		||||
            {error}
 | 
			
		||||
            <svelte:fragment slot="buttons">
 | 
			
		||||
                <Link target="Home">
 | 
			
		||||
                    <button class="btn btn-sm btn-alert-error" on:click={() => navigate('Home')}>Ok</button>
 | 
			
		||||
                </Link>
 | 
			
		||||
            </svelte:fragment>
 | 
			
		||||
        </ErrorAlert>
 | 
			
		||||
    </div>
 | 
			
		||||
{:else if success}
 | 
			
		||||
    <div class="flex flex-col h-screen items-center justify-center max-w-max m-auto">
 | 
			
		||||
        {#if $appState.currentRequest.approval === 'Approved'}
 | 
			
		||||
            <svg xmlns="http://www.w3.org/2000/svg" class="w-36 h-36" fill="none" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor">
 | 
			
		||||
              <path in:draw="{{duration: drawDuration}}" stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
 | 
			
		||||
            </svg>
 | 
			
		||||
        {:else}
 | 
			
		||||
            <svg xmlns="http://www.w3.org/2000/svg" class="w-36 h-36" fill="none" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor">
 | 
			
		||||
                <path in:draw="{{duration: 500}}" stroke-linecap="round" stroke-linejoin="round" d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
 | 
			
		||||
            </svg>
 | 
			
		||||
        {/if}
 | 
			
		||||
<div class="flex flex-col h-screen items-center justify-center max-w-max m-auto">
 | 
			
		||||
    {#if $appState.currentRequest.approval === 'Approved'}
 | 
			
		||||
        <svg xmlns="http://www.w3.org/2000/svg" class="w-36 h-36" fill="none" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor">
 | 
			
		||||
          <path in:draw="{{duration: drawDuration}}" stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
 | 
			
		||||
        </svg>
 | 
			
		||||
    {:else}
 | 
			
		||||
        <svg xmlns="http://www.w3.org/2000/svg" class="w-36 h-36" fill="none" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor">
 | 
			
		||||
            <path in:draw="{{duration: 500}}" stroke-linecap="round" stroke-linejoin="round" d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
 | 
			
		||||
        </svg>
 | 
			
		||||
    {/if}
 | 
			
		||||
 | 
			
		||||
        <div in:fade="{{duration: fadeDuration, delay: fadeDelay}}" class="text-2xl font-bold">
 | 
			
		||||
            {$appState.currentRequest.approval}!
 | 
			
		||||
        </div>
 | 
			
		||||
    <div in:fade="{{duration: fadeDuration, delay: fadeDelay}}" class="text-2xl font-bold">
 | 
			
		||||
        {$appState.currentRequest.approval}!
 | 
			
		||||
    </div>
 | 
			
		||||
{/if}
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
            let r = await invoke('unlock', {passphrase});
 | 
			
		||||
            $appState.credentialStatus = 'unlocked';
 | 
			
		||||
            if ($appState.currentRequest) {
 | 
			
		||||
                navigate('ShowResponse');
 | 
			
		||||
                navigate('Approve');
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                navigate('Home');
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user