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> | ||||
|  | ||||
|             <div class="grid grid-cols-[auto_1fr] gap-x-3"> | ||||
|                 {#each $appState.currentRequest.clients as client} | ||||
|                 <p>Path: {client ? client.exe : 'Unknown'}</p> | ||||
|                 <p>PID: {client ? client.pid : 'Unknown'}</p> | ||||
|                     <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> | ||||
| @@ -64,3 +111,4 @@ | ||||
|             </Link> | ||||
|         </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,42 +11,16 @@ | ||||
|     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; | ||||
|     onMount(() => { | ||||
|         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); | ||||
|         ) | ||||
|     }) | ||||
| </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"> | ||||
| @@ -65,4 +36,3 @@ | ||||
|         {$appState.currentRequest.approval}! | ||||
|     </div> | ||||
| </div> | ||||
| {/if} | ||||
|   | ||||
| @@ -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