From 2cbc1b073813863e08e6d76e3039b6a1f7ee0d56 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Tue, 5 Jul 2022 17:54:05 -0400 Subject: [PATCH 01/40] super basic picker with logging --- .../teleport/src/DesktopSession/DesktopSession.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index f759e16c3..4456f3bc0 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -164,6 +164,11 @@ function Session(props: PropsWithChildren) { isSharingDirectory={isSharingDirectory} onShareDirectory={() => { setIsSharingDirectory(true); + const sharedDirHandle = window + .showDirectoryPicker() + .then(sharedDirHandle => { + console.log(sharedDirHandle); + }); }} /> @@ -218,3 +223,9 @@ const DesktopSessionAlert = styled(Alert)` align-self: center; min-width: 450px; `; + +declare global { + interface Window { + showDirectoryPicker: () => Promise; + } +} From bc51777773c543f752942c632f2b40e7689fba8d Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Wed, 6 Jul 2022 17:19:05 -0400 Subject: [PATCH 02/40] Adds SharedDirectoryAnnounce --- .../src/DesktopSession/DesktopSession.tsx | 10 ++++-- .../src/DesktopSession/useClipboard.ts | 2 +- .../src/DesktopSession/useDesktopSession.tsx | 3 ++ .../src/DesktopSession/useTdpClientCanvas.tsx | 25 ++++++++++++-- packages/teleport/src/lib/tdp/client.ts | 28 ++++++++++++++++ packages/teleport/src/lib/tdp/codec.ts | 33 +++++++++++++++++++ 6 files changed, 94 insertions(+), 7 deletions(-) diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index 4456f3bc0..c6f393ff8 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -163,11 +163,15 @@ function Session(props: PropsWithChildren) { canShareDirectory={canShareDirectory} isSharingDirectory={isSharingDirectory} onShareDirectory={() => { - setIsSharingDirectory(true); - const sharedDirHandle = window + window .showDirectoryPicker() .then(sharedDirHandle => { - console.log(sharedDirHandle); + setIsSharingDirectory(true); + tdpClient.sharedDirectory = sharedDirHandle; + tdpClient.sendSharedDirectoryAnnounce(); + }) + .catch(() => { + setIsSharingDirectory(false); }); }} /> diff --git a/packages/teleport/src/DesktopSession/useClipboard.ts b/packages/teleport/src/DesktopSession/useClipboard.ts index 00b86fe3f..5f8ec7a5c 100644 --- a/packages/teleport/src/DesktopSession/useClipboard.ts +++ b/packages/teleport/src/DesktopSession/useClipboard.ts @@ -113,7 +113,7 @@ enum ClipboardPermissionType { Write = 'clipboard-write', } -type ClipboardPermissionStatus = { +export type ClipboardPermissionStatus = { state: PermissionState | 'error' | ''; errorText?: string; }; diff --git a/packages/teleport/src/DesktopSession/useDesktopSession.tsx b/packages/teleport/src/DesktopSession/useDesktopSession.tsx index f0eb718f9..42e1fc297 100644 --- a/packages/teleport/src/DesktopSession/useDesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/useDesktopSession.tsx @@ -140,6 +140,9 @@ export default function useDesktopSession() { clusterId, setTdpConnection, setWsConnection, + setIsRecording, + setClipboardState, + setIsSharingDirectory, enableClipboardSharing: clipboardState.enabled && clipboardState.permission.state === 'granted' && diff --git a/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx b/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx index f9b143347..666c10735 100644 --- a/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx +++ b/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx @@ -15,12 +15,13 @@ limitations under the License. */ import { useState, useEffect, useRef, Dispatch, SetStateAction } from 'react'; +import { Attempt } from 'shared/hooks/useAttemptNext'; import { TdpClient, ButtonState, ScrollAxis } from 'teleport/lib/tdp'; import { ClipboardData, PngFrame } from 'teleport/lib/tdp/codec'; -import { TopBarHeight } from './TopBar'; -import cfg from 'teleport/config'; import { getAccessToken, getHostName } from 'teleport/services/api'; -import { Attempt } from 'shared/hooks/useAttemptNext'; +import cfg from 'teleport/config'; +import { TopBarHeight } from './TopBar'; +import { ClipboardPermissionStatus } from './useClipboard'; export default function useTdpClientCanvas(props: Props) { const { @@ -29,6 +30,9 @@ export default function useTdpClientCanvas(props: Props) { clusterId, setTdpConnection, setWsConnection, + setIsRecording, + setClipboardState, + setIsSharingDirectory, enableClipboardSharing, } = props; const [tdpClient, setTdpClient] = useState(null); @@ -76,6 +80,12 @@ export default function useTdpClientCanvas(props: Props) { // Default TdpClientEvent.TDP_ERROR handler const onTdpError = (err: Error) => { + setIsSharingDirectory(false); + setIsRecording(false); + setClipboardState(prevState => ({ + ...prevState, + enabled: false, + })); setTdpConnection({ status: 'failed', statusText: err.message }); }; @@ -200,5 +210,14 @@ type Props = { clusterId: string; setTdpConnection: Dispatch>; setWsConnection: Dispatch>; + setIsRecording: Dispatch>; + setClipboardState: Dispatch< + SetStateAction<{ + enabled: boolean; + permission: ClipboardPermissionStatus; + errorText: string; + }> + >; + setIsSharingDirectory: Dispatch>; enableClipboardSharing: boolean; }; diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index b7596baa6..12deae320 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -42,6 +42,8 @@ export default class Client extends EventEmitterWebAuthnSender { protected codec: Codec; protected socket: WebSocket | undefined; private socketAddr: string; + sharedDirectory: FileSystemDirectoryHandle | undefined; + private logger = Logger.create('TDPClient'); constructor(socketAddr: string) { @@ -223,6 +225,32 @@ export default class Client extends EventEmitterWebAuthnSender { this.send(msg); } + private sharedDirectoryReady() { + if (!this.sharedDirectory) { + this.handleError( + new Error( + 'attempted to use a shared directory before one was initialized' + ) + ); + return false; + } + + return true; + } + + sendSharedDirectoryAnnounce() { + if (!this.sharedDirectoryReady()) return; + this.socket.send( + this.codec.encodeSharedDirectoryAnnounce({ + completionId: 0, // This is always the first request. + // Hardcode directoryId for now since we only support sharing 1 directory. + // We're using 2 because the smartcard device is hardcoded to 1 in the backend. + directoryId: 2, + name: this.sharedDirectory.name, + }) + ); + } + resize(spec: ClientScreenSpec) { this.send(this.codec.encodeClientScreenSpec(spec)); } diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index da94af558..8217f12ed 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -37,6 +37,7 @@ export enum MessageType { MOUSE_WHEEL_SCROLL = 8, ERROR = 9, MFA_JSON = 10, + SHARED_DIRECTORY_ANNOUNCE = 11, } // 0 is left button, 1 is middle button, 2 is right button @@ -84,6 +85,13 @@ export type MfaJson = { jsonString: string; }; +// | message type (11) | completion_id uint32 | directory_id uint32 | name_length uint32 | name []byte | +export type SharedDirectoryAnnounce = { + completionId: number; + directoryId: number; + name: string; +}; + // TdaCodec provides an api for encoding and decoding teleport desktop access protocol messages [1] // Buffers in TdaCodec are manipulated as DataView's [2] in order to give us low level control // of endianness (defaults to big endian, which is what we want), as opposed to using *Array @@ -389,6 +397,31 @@ export default class Codec { return buffer; } + // | message type (11) | completion_id uint32 | directory_id uint32 | name_length uint32 | name []byte | + encodeSharedDirectoryAnnounce( + sharedDirAnnounce: SharedDirectoryAnnounce + ): Message { + const dataUtf8array = this.encoder.encode(sharedDirAnnounce.name); + + const bufLen = byteLength + 3 * uint32Length + dataUtf8array.length; + const buffer = new ArrayBuffer(bufLen); + const view = new DataView(buffer); + let offset = 0; + + view.setUint8(offset++, MessageType.SHARED_DIRECTORY_ANNOUNCE); + view.setUint32(offset, sharedDirAnnounce.completionId); + offset += uint32Length; + view.setUint32(offset, sharedDirAnnounce.directoryId); + offset += uint32Length; + view.setUint32(offset, dataUtf8array.length); + offset += uint32Length; + dataUtf8array.forEach(byte => { + view.setUint8(offset++, byte); + }); + + return buffer; + } + // decodeClipboardData decodes clipboard data decodeClipboardData(buffer: ArrayBuffer): ClipboardData { return { From bc6586b32cc8eb7ec6ae25e1d125d6b5d907bfb4 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Wed, 6 Jul 2022 17:39:41 -0400 Subject: [PATCH 03/40] Removes recording icon --- .../src/DesktopSession/DesktopSession.tsx | 4 ---- .../teleport/src/DesktopSession/TopBar.tsx | 23 ------------------- .../src/DesktopSession/useDesktopSession.tsx | 7 ------ .../src/DesktopSession/useTdpClientCanvas.tsx | 3 --- packages/teleport/src/config.ts | 2 +- 5 files changed, 1 insertion(+), 38 deletions(-) diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index c6f393ff8..442c1a880 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -108,8 +108,6 @@ function Session(props: PropsWithChildren) { hostname, clipboardState, setClipboardState, - isRecording, - setIsRecording, canShareDirectory, isSharingDirectory, setIsSharingDirectory, @@ -153,13 +151,11 @@ function Session(props: PropsWithChildren) { ...prevState, enabled: false, })); - setIsRecording(false); setIsSharingDirectory(false); tdpClient.nuke(); }} userHost={`${username}@${hostname}`} clipboardSharingEnabled={clipboardSharingActive} - isRecording={isRecording} canShareDirectory={canShareDirectory} isSharingDirectory={isSharingDirectory} onShareDirectory={() => { diff --git a/packages/teleport/src/DesktopSession/TopBar.tsx b/packages/teleport/src/DesktopSession/TopBar.tsx index 3d485a1bb..6d5ac2aa7 100644 --- a/packages/teleport/src/DesktopSession/TopBar.tsx +++ b/packages/teleport/src/DesktopSession/TopBar.tsx @@ -24,7 +24,6 @@ export default function TopBar(props: Props) { const { userHost, clipboardSharingEnabled, - isRecording, onDisconnect, canShareDirectory, isSharingDirectory, @@ -70,19 +69,6 @@ export default function TopBar(props: Props) { : 'Clipboard Sharing Disabled' } /> - - - Recording - setHostname(desktop.name)), userService.fetchUserContext().then(user => { setHasClipboardSharingEnabled(user.acl.clipboardSharingEnabled); - setIsRecording(user.acl.desktopSessionRecordingEnabled); setCanShareDirectory(user.acl.directorySharingEnabled); }), ]) @@ -140,7 +136,6 @@ export default function useDesktopSession() { clusterId, setTdpConnection, setWsConnection, - setIsRecording, setClipboardState, setIsSharingDirectory, enableClipboardSharing: @@ -156,8 +151,6 @@ export default function useDesktopSession() { username, clipboardState, setClipboardState, - isRecording, - setIsRecording, canShareDirectory, isSharingDirectory, setIsSharingDirectory, diff --git a/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx b/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx index 666c10735..975110a9e 100644 --- a/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx +++ b/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx @@ -30,7 +30,6 @@ export default function useTdpClientCanvas(props: Props) { clusterId, setTdpConnection, setWsConnection, - setIsRecording, setClipboardState, setIsSharingDirectory, enableClipboardSharing, @@ -81,7 +80,6 @@ export default function useTdpClientCanvas(props: Props) { // Default TdpClientEvent.TDP_ERROR handler const onTdpError = (err: Error) => { setIsSharingDirectory(false); - setIsRecording(false); setClipboardState(prevState => ({ ...prevState, enabled: false, @@ -210,7 +208,6 @@ type Props = { clusterId: string; setTdpConnection: Dispatch>; setWsConnection: Dispatch>; - setIsRecording: Dispatch>; setClipboardState: Dispatch< SetStateAction<{ enabled: boolean; diff --git a/packages/teleport/src/config.ts b/packages/teleport/src/config.ts index 4f359fd18..59dfb5a12 100644 --- a/packages/teleport/src/config.ts +++ b/packages/teleport/src/config.ts @@ -29,7 +29,7 @@ import generateResourcePath from './generateResourcePath'; const cfg = { // TODO(isaiah): remove after feature is finished. - enableDirectorySharing: false, // note to reviewers: should be false in any PRs. + enableDirectorySharing: true, // note to reviewers: should be false in any PRs. isEnterprise: false, isCloud: false, tunnelPublicAddress: '', From fa09ec31a174ab2582954c411c6985a260feaddb Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Wed, 6 Jul 2022 19:29:26 -0400 Subject: [PATCH 04/40] reverting config to its rightful checkin state --- packages/teleport/src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/teleport/src/config.ts b/packages/teleport/src/config.ts index 59dfb5a12..4f359fd18 100644 --- a/packages/teleport/src/config.ts +++ b/packages/teleport/src/config.ts @@ -29,7 +29,7 @@ import generateResourcePath from './generateResourcePath'; const cfg = { // TODO(isaiah): remove after feature is finished. - enableDirectorySharing: true, // note to reviewers: should be false in any PRs. + enableDirectorySharing: false, // note to reviewers: should be false in any PRs. isEnterprise: false, isCloud: false, tunnelPublicAddress: '', From becfad38776a68e0d8be634476f24cead7890ffc Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 11:02:30 -0400 Subject: [PATCH 05/40] updates storybook and storybook test snapshot --- .../DesktopSession/DesktopSession.story.tsx | 4 - .../DesktopSession.story.test.tsx.snap | 406 ++++-------------- 2 files changed, 90 insertions(+), 320 deletions(-) diff --git a/packages/teleport/src/DesktopSession/DesktopSession.story.tsx b/packages/teleport/src/DesktopSession/DesktopSession.story.tsx index 779daab61..2dbd461f6 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.story.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.story.tsx @@ -46,7 +46,6 @@ const props: State = { permission: { state: '' }, errorText: '', }, - isRecording: false, tdpClient: fakeClient(), username: 'user', onWsOpen: () => {}, @@ -55,7 +54,6 @@ const props: State = { disconnected: false, setDisconnected: () => {}, setClipboardState: () => {}, - setIsRecording: () => {}, canShareDirectory: true, isSharingDirectory: false, setIsSharingDirectory: () => {}, @@ -113,7 +111,6 @@ export const ConnectedSettingsFalse = () => { permission: { state: '' }, errorText: '', }} - isRecording={false} onPngFrame={(ctx: CanvasRenderingContext2D) => { fillGray(ctx.canvas); }} @@ -140,7 +137,6 @@ export const ConnectedSettingsTrue = () => { permission: { state: 'granted' }, errorText: '', }} - isRecording={true} isSharingDirectory={true} onPngFrame={(ctx: CanvasRenderingContext2D) => { fillGray(ctx.canvas); diff --git a/packages/teleport/src/DesktopSession/__snapshots__/DesktopSession.story.test.tsx.snap b/packages/teleport/src/DesktopSession/__snapshots__/DesktopSession.story.test.tsx.snap index 29239d02b..c6191c76c 100644 --- a/packages/teleport/src/DesktopSession/__snapshots__/DesktopSession.story.test.tsx.snap +++ b/packages/teleport/src/DesktopSession/__snapshots__/DesktopSession.story.test.tsx.snap @@ -8,13 +8,13 @@ exports[`clipboard error 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -36,20 +36,20 @@ exports[`clipboard error 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -61,12 +61,6 @@ exports[`clipboard error 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -108,15 +102,7 @@ exports[`clipboard error 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} - -.c13 { +.c11 { display: flex; align-items: center; justify-content: center; @@ -139,7 +125,7 @@ exports[`clipboard error 1`] = ` min-width: 450px; } -.c13 a { +.c11 a { color: #FFFFFF; } @@ -176,33 +162,18 @@ exports[`clipboard error 1`] = ` style="color: rgba(255, 255, 255, 0.56);" title="Clipboard Sharing Disabled" /> -
-
-
- Recording -
-
@@ -210,7 +181,7 @@ exports[`clipboard error 1`] = `
clipboard error @@ -230,13 +201,13 @@ exports[`connected settings false 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -258,20 +229,20 @@ exports[`connected settings false 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -283,12 +254,6 @@ exports[`connected settings false 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -330,14 +295,6 @@ exports[`connected settings false 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} -
-
-
-
- Recording -
-
@@ -419,13 +361,13 @@ exports[`connected settings true 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -447,20 +389,20 @@ exports[`connected settings true 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -472,12 +414,6 @@ exports[`connected settings true 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -519,14 +455,6 @@ exports[`connected settings true 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} -
-
-
-
- Recording -
-
@@ -608,13 +521,13 @@ exports[`connection error 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -636,20 +549,20 @@ exports[`connection error 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -661,12 +574,6 @@ exports[`connection error 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -708,15 +615,7 @@ exports[`connection error 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} - -.c13 { +.c11 { display: flex; align-items: center; justify-content: center; @@ -739,7 +638,7 @@ exports[`connection error 1`] = ` min-width: 450px; } -.c13 a { +.c11 a { color: #FFFFFF; } @@ -776,33 +675,18 @@ exports[`connection error 1`] = ` style="color: rgba(255, 255, 255, 0.56);" title="Clipboard Sharing Disabled" /> -
-
-
- Recording -
-
@@ -810,7 +694,7 @@ exports[`connection error 1`] = `
some connection error @@ -823,7 +707,7 @@ exports[`connection error 1`] = ` `; exports[`disconnected 1`] = ` -.c13 { +.c11 { box-sizing: border-box; margin: 72px; text-align: center; @@ -836,13 +720,13 @@ exports[`disconnected 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -864,20 +748,20 @@ exports[`disconnected 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -889,7 +773,7 @@ exports[`disconnected 1`] = ` padding-right: 16px; } -.c10 { +.c12 { overflow: hidden; text-overflow: ellipsis; margin: 0px; @@ -936,14 +820,6 @@ exports[`disconnected 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} -
-
-
-
- Recording -
-
@@ -1011,10 +872,10 @@ exports[`disconnected 1`] = `
Session successfully disconnected
@@ -1034,13 +895,13 @@ exports[`fetch error 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -1062,20 +923,20 @@ exports[`fetch error 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -1087,12 +948,6 @@ exports[`fetch error 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -1134,15 +989,7 @@ exports[`fetch error 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} - -.c13 { +.c11 { display: flex; align-items: center; justify-content: center; @@ -1165,7 +1012,7 @@ exports[`fetch error 1`] = ` min-width: 450px; } -.c13 a { +.c11 a { color: #FFFFFF; } @@ -1202,33 +1049,18 @@ exports[`fetch error 1`] = ` style="color: rgba(255, 255, 255, 0.56);" title="Clipboard Sharing Disabled" /> -
-
-
- Recording -
-
@@ -1236,7 +1068,7 @@ exports[`fetch error 1`] = `
some fetch error @@ -1256,13 +1088,13 @@ exports[`unintended disconnect 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -1284,20 +1116,20 @@ exports[`unintended disconnect 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -1309,12 +1141,6 @@ exports[`unintended disconnect 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -1356,15 +1182,7 @@ exports[`unintended disconnect 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} - -.c13 { +.c11 { display: flex; align-items: center; justify-content: center; @@ -1387,7 +1205,7 @@ exports[`unintended disconnect 1`] = ` min-width: 450px; } -.c13 a { +.c11 a { color: #FFFFFF; } @@ -1424,33 +1242,18 @@ exports[`unintended disconnect 1`] = ` style="color: rgba(255, 255, 255, 0.56);" title="Clipboard Sharing Disabled" /> -
-
-
- Recording -
-
@@ -1458,7 +1261,7 @@ exports[`unintended disconnect 1`] = `
Session disconnected for an unknown reason @@ -1471,7 +1274,7 @@ exports[`unintended disconnect 1`] = ` `; exports[`webauthn prompt 1`] = ` -.c13 { +.c11 { box-sizing: border-box; margin: 72px; text-align: center; @@ -1484,13 +1287,13 @@ exports[`webauthn prompt 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -1512,20 +1315,20 @@ exports[`webauthn prompt 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -1537,12 +1340,6 @@ exports[`webauthn prompt 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -1584,14 +1381,6 @@ exports[`webauthn prompt 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} -
-
-
-
- Recording -
-
@@ -1659,7 +1433,7 @@ exports[`webauthn prompt 1`] = `
Date: Thu, 7 Jul 2022 11:18:50 -0400 Subject: [PATCH 06/40] Adds types for File System Access API --- packages/teleport/package.json | 1 + .../src/DesktopSession/DesktopSession.tsx | 8 +- yarn.lock | 227 ++---------------- 3 files changed, 27 insertions(+), 209 deletions(-) diff --git a/packages/teleport/package.json b/packages/teleport/package.json index 859ac922b..c1c931f35 100644 --- a/packages/teleport/package.json +++ b/packages/teleport/package.json @@ -24,6 +24,7 @@ }, "devDependencies": { "@gravitational/build": "^1.0.0", + "@types/wicg-native-file-system": "^2020.6.0", "jest-canvas-mock": "^2.3.1" } } diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index 442c1a880..b5f55431f 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -222,10 +222,4 @@ function Session(props: PropsWithChildren) { const DesktopSessionAlert = styled(Alert)` align-self: center; min-width: 450px; -`; - -declare global { - interface Window { - showDirectoryPicker: () => Promise; - } -} +`; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index b9e1c754c..a791dfdb6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3029,6 +3029,11 @@ tapable "^2.2.0" webpack "^5" +"@types/wicg-native-file-system@^2020.6.0": + version "2020.6.0" + resolved "https://registry.yarnpkg.com/@types/wicg-native-file-system/-/wicg-native-file-system-2020.6.0.tgz#63cbb7bac47bdb9eae4b0d66e63134b33e47e05d" + integrity sha512-M7n6jvHfUzUXDtf6UGpL6rVIddV7UzEYrvwZPORApeHvDGQnZJ79fXorLlDj8xJKyUemnEBohRd8yx09k9NBUw== + "@types/yargs-parser@*": version "20.2.1" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" @@ -3416,11 +3421,6 @@ abab@^2.0.3, abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -3482,22 +3482,13 @@ address@1.1.2, address@^1.0.1: resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== -agent-base@6, agent-base@^6.0.2: +agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" -agentkeepalive@^4.1.3: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" - integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA== - dependencies: - debug "^4.1.0" - depd "^1.1.2" - humanize-ms "^1.2.1" - aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -3723,14 +3714,6 @@ are-we-there-yet@^2.0.0: delegates "^1.0.0" readable-stream "^3.6.0" -are-we-there-yet@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz#ba20bd6b553e31d62fc8c31bd23d22b95734390d" - integrity sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -4564,7 +4547,7 @@ cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^15.0.5, cacache@^15.2.0: +cacache@^15.0.5: version "15.3.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== @@ -4943,7 +4926,7 @@ color-string@^1.6.0: color-name "^1.0.0" simple-swizzle "^0.2.2" -color-support@^1.1.2, color-support@^1.1.3: +color-support@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== @@ -5543,13 +5526,6 @@ debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: dependencies: ms "2.1.2" -debug@^4.3.3: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - decimal.js@^10.2.1: version "10.3.1" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" @@ -5687,7 +5663,7 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -depd@^1.1.2, depd@~1.1.2: +depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== @@ -6145,13 +6121,6 @@ encodeurl@^1.0.2, encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.12: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -6216,11 +6185,6 @@ envinfo@^7.7.3: resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== -err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== - errno@^0.1.3, errno@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" @@ -7246,20 +7210,6 @@ gauge@^3.0.0: strip-ansi "^3.0.1 || ^4.0.0" wide-align "^1.1.2" -gauge@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" - integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -7877,7 +7827,7 @@ htmlparser2@^6.1.0: domutils "^2.5.2" entities "^2.0.0" -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: +http-cache-semantics@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== @@ -7980,13 +7930,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - iconv-corefoundation@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/iconv-corefoundation/-/iconv-corefoundation-1.1.6.tgz#27c135470237f6f8d13462fa1f5eaf250523c29a" @@ -8389,11 +8332,6 @@ is-installed-globally@^0.4.0: global-dirs "^3.0.0" is-path-inside "^3.0.2" -is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" - integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== - is-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" @@ -9629,28 +9567,6 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: dependencies: semver "^6.0.0" -make-fetch-happen@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" - integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== - dependencies: - agentkeepalive "^4.1.3" - cacache "^15.2.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^6.0.0" - minipass "^3.1.3" - minipass-collect "^1.0.2" - minipass-fetch "^1.3.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.2" - promise-retry "^2.0.1" - socks-proxy-agent "^6.0.0" - ssri "^8.0.0" - makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -9928,11 +9844,16 @@ minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.5, minimist@~0.0.1: +minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw== + minipass-collect@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" @@ -9940,17 +9861,6 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" -minipass-fetch@^1.3.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" - integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== - dependencies: - minipass "^3.1.0" - minipass-sized "^1.0.3" - minizlib "^2.0.0" - optionalDependencies: - encoding "^0.1.12" - minipass-flush@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" @@ -9958,20 +9868,13 @@ minipass-flush@^1.0.5: dependencies: minipass "^3.0.0" -minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: +minipass-pipeline@^1.2.2: version "1.2.4" resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== dependencies: minipass "^3.0.0" -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== - dependencies: - minipass "^3.0.0" - minipass@^3.0.0, minipass@^3.1.1: version "3.1.5" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.5.tgz#71f6251b0a33a49c01b3cf97ff77eda030dff732" @@ -9979,14 +9882,7 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" -minipass@^3.1.0, minipass@^3.1.3: - version "3.1.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" - integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== - dependencies: - yallist "^4.0.0" - -minizlib@^2.0.0, minizlib@^2.1.1: +minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -10064,7 +9960,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.0.0, ms@^2.1.1: +ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -10119,11 +10015,6 @@ negotiator@0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -negotiator@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" @@ -10171,22 +10062,6 @@ node-forge@^0.10.0: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== -node-gyp@8.4.1: - version "8.4.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" - integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^9.1.0" - nopt "^5.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -10243,13 +10118,6 @@ node-releases@^2.0.1: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -10307,16 +10175,6 @@ npmlog@^5.0.1: gauge "^3.0.0" set-blocking "^2.0.0" -npmlog@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" - integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.3" - set-blocking "^2.0.0" - nth-check@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" @@ -11193,14 +11051,6 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= -promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" - integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - promise.allsettled@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.5.tgz#2443f3d4b2aa8dfa560f6ac2aa6c4ea999d75f53" @@ -12088,11 +11938,6 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - retry@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" @@ -12489,11 +12334,6 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== -signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -12532,7 +12372,7 @@ slice-ansi@^1.0.0: dependencies: is-fullwidth-code-point "^2.0.0" -smart-buffer@^4.0.2, smart-buffer@^4.2.0: +smart-buffer@^4.0.2: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== @@ -12576,23 +12416,6 @@ sockjs@^0.3.21: uuid "^3.4.0" websocket-driver "^0.7.4" -socks-proxy-agent@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz#f6b5229cc0cbd6f2f202d9695f09d871e951c85e" - integrity sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - -socks@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.2.tgz#ec042d7960073d40d94268ff3bb727dc685f111a" - integrity sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA== - dependencies: - ip "^1.1.5" - smart-buffer "^4.2.0" - source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -12733,7 +12556,7 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" -ssri@^8.0.0, ssri@^8.0.1: +ssri@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== @@ -12838,7 +12661,7 @@ string-length@^4.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -13107,7 +12930,7 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar@^6.0.2, tar@^6.1.2: +tar@^6.0.2: version "6.1.11" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== @@ -14253,14 +14076,14 @@ which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" -which@^2.0.1, which@^2.0.2: +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@^1.1.2, wide-align@^1.1.5: +wide-align@^1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== From edfe30d1a38f64ed9ea27f0961054af6c8717c10 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 11:46:23 -0400 Subject: [PATCH 07/40] prettier --- packages/teleport/src/DesktopSession/DesktopSession.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index b5f55431f..49ec82d1b 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -222,4 +222,4 @@ function Session(props: PropsWithChildren) { const DesktopSessionAlert = styled(Alert)` align-self: center; min-width: 450px; -`; \ No newline at end of file +`; From b9f0690f28326eced0df49d2ac172d89136e1ee1 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 14:44:20 -0400 Subject: [PATCH 08/40] Adds SharedDirectoryAcknowledge, SharedDirectoryErrCode, updates some previously janky validity checks --- packages/teleport/src/lib/tdp/client.ts | 30 +++++++++++-- packages/teleport/src/lib/tdp/codec.test.ts | 8 +++- packages/teleport/src/lib/tdp/codec.ts | 49 ++++++++++++++++++--- 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index 12deae320..55e04b555 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -23,6 +23,7 @@ import Codec, { ClientScreenSpec, PngFrame, ClipboardData, + SharedDirectoryErrCode, } from './codec'; export enum TdpClientEvent { @@ -108,6 +109,9 @@ export default class Client extends EventEmitterWebAuthnSender { case MessageType.MFA_JSON: this.handleMfaChallenge(buffer); break; + case MessageType.SHARED_DIRECTORY_ACKNOWLEDGE: + this.handleSharedDirectoryAcknowledge(buffer); + break; default: this.logger.warn(`received unsupported message type ${messageType}`); } @@ -165,8 +169,7 @@ export default class Client extends EventEmitterWebAuthnSender { this.emit(TermEventEnum.WEBAUTHN_CHALLENGE, mfaJson.jsonString); } else { // mfaJson.mfaType === 'u', or else decodeMfaJson would have thrown an error. - this.emit( - TdpClientEvent.TDP_ERROR, + this.handleError( new Error( 'Multifactor authentication is required for accessing this desktop, \ however the U2F API for hardware keys is not supported for desktop sessions. \ @@ -176,10 +179,31 @@ export default class Client extends EventEmitterWebAuthnSender { ); } } catch (err) { - this.emit(TdpClientEvent.TDP_ERROR, err); + this.handleError(err); } } + private wasSuccessful(errCode: SharedDirectoryErrCode) { + if (errCode === SharedDirectoryErrCode.Nil) { + return true; + } + + this.handleError( + new Error(`Encountered shared directory error: ${errCode}`) + ); + return false; + } + + handleSharedDirectoryAcknowledge(buffer: ArrayBuffer) { + const ack = this.codec.decodeSharedDirectoryAcknowledge(buffer); + + if (!this.wasSuccessful(ack.errCode)) { + return; + } + + this.logger.info('Started sharing directory: ' + this.sharedDirectory.name); + } + protected send( data: string | ArrayBufferLike | Blob | ArrayBufferView ): void { diff --git a/packages/teleport/src/lib/tdp/codec.test.ts b/packages/teleport/src/lib/tdp/codec.test.ts index ae0085464..7b9a53d4f 100644 --- a/packages/teleport/src/lib/tdp/codec.test.ts +++ b/packages/teleport/src/lib/tdp/codec.test.ts @@ -104,7 +104,9 @@ test('decodes message types', () => { const { buffer: pngFrameBuf } = makeBuf(MessageType.PNG_FRAME); const { buffer: clipboardBuf } = makeBuf(MessageType.CLIPBOARD_DATA); const { buffer: errorBuf } = makeBuf(MessageType.ERROR); - const { buffer: invalidBuf } = makeBuf(MessageType.MFA_JSON + 1); + const { buffer: invalidBuf } = makeBuf( + MessageType.SHARED_DIRECTORY_ACKNOWLEDGE + 1 + ); expect(codec.decodeMessageType(pngFrameBuf)).toEqual(MessageType.PNG_FRAME); expect(codec.decodeMessageType(clipboardBuf)).toEqual( @@ -113,7 +115,9 @@ test('decodes message types', () => { expect(codec.decodeMessageType(errorBuf)).toEqual(MessageType.ERROR); expect(() => { codec.decodeMessageType(invalidBuf); - }).toThrow(`invalid message type: ${MessageType.MFA_JSON + 1}`); + }).toThrow( + `invalid message type: ${MessageType.SHARED_DIRECTORY_ACKNOWLEDGE + 1}` + ); }); test('decodes errors', () => { diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index 8217f12ed..229390193 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -38,6 +38,7 @@ export enum MessageType { ERROR = 9, MFA_JSON = 10, SHARED_DIRECTORY_ANNOUNCE = 11, + SHARED_DIRECTORY_ACKNOWLEDGE = 12, } // 0 is left button, 1 is middle button, 2 is right button @@ -92,6 +93,31 @@ export type SharedDirectoryAnnounce = { name: string; }; +// | message type (12) | err error | directory_id uint32 | +export type SharedDirectoryAcknowledge = { + errCode: SharedDirectoryErrCode; + directoryId: number; +}; + +export enum SharedDirectoryErrCode { + // nil (no error, operation succeeded) + Nil = 0, + // operation failed + Failed = 1, + // resource does not exist + DoesNotExist = 2, + // resource already exists + AlreadyExists = 3, +} + +function toSharedDirectoryErrCode(errCode: number): SharedDirectoryErrCode { + if (!(errCode in SharedDirectoryErrCode)) { + throw new Error(`attempted to convert invalid error code ${errCode}`); + } + + return errCode as SharedDirectoryErrCode; +} + // TdaCodec provides an api for encoding and decoding teleport desktop access protocol messages [1] // Buffers in TdaCodec are manipulated as DataView's [2] in order to give us low level control // of endianness (defaults to big endian, which is what we want), as opposed to using *Array @@ -434,8 +460,7 @@ export default class Codec { // Throws an error on an invalid or unexpected MessageType value. decodeMessageType(buffer: ArrayBuffer): MessageType { const messageType = new DataView(buffer).getUint8(0); - // TODO(isaiah): this is fragile, instead switch all possibilities here. - if (messageType > MessageType.MFA_JSON) { + if (!(messageType in MessageType)) { throw new Error(`invalid message type: ${messageType}`); } return messageType; @@ -480,13 +505,27 @@ export default class Codec { data: image, }; pngFrame.data.onload = onload(pngFrame); - pngFrame.data.src = this._asBase64Url(buffer); + pngFrame.data.src = this.asBase64Url(buffer); return pngFrame; } - // _asBase64Url creates a data:image uri from the png data part of a PNG_FRAME tdp message. - _asBase64Url(buffer: ArrayBuffer): string { + // | message type (12) | directory_id uint32 | succeeded byte | + decodeSharedDirectoryAcknowledge( + buffer: ArrayBuffer + ): SharedDirectoryAcknowledge { + let dv = new DataView(buffer); + let errCode = toSharedDirectoryErrCode(dv.getUint32(1)); + let directoryId = dv.getUint32(5); + + return { + errCode, + directoryId, + }; + } + + // asBase64Url creates a data:image uri from the png data part of a PNG_FRAME tdp message. + private asBase64Url(buffer: ArrayBuffer): string { return `data:image/png;base64,${arrayBufferToBase64(buffer.slice(17))}`; } } From b3bf95c50bb4e07173a548b8995616bf649a2093 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 15:51:12 -0400 Subject: [PATCH 09/40] Adds debug to logger --- packages/shared/libs/logger.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/shared/libs/logger.js b/packages/shared/libs/logger.js index 972c97d54..8a10659c2 100644 --- a/packages/shared/libs/logger.js +++ b/packages/shared/libs/logger.js @@ -35,6 +35,10 @@ export class Logger { this.log('info', ...args); } + debug(...args) { + this.log('debug', ...args); + } + error(...args) { this.log('error', ...args); } From d69f16d464b9d66cd313104968eea43236c04836 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 15:51:33 -0400 Subject: [PATCH 10/40] Adds SharedDirectoryInfoRequest --- packages/teleport/src/lib/tdp/client.ts | 11 ++++++++++ packages/teleport/src/lib/tdp/codec.ts | 28 +++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index 55e04b555..997177a9c 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -112,6 +112,9 @@ export default class Client extends EventEmitterWebAuthnSender { case MessageType.SHARED_DIRECTORY_ACKNOWLEDGE: this.handleSharedDirectoryAcknowledge(buffer); break; + case MessageType.SHARED_DIRECTORY_INFO_REQUEST: + this.handleSharedDirectoryInfoRequest(buffer); + break; default: this.logger.warn(`received unsupported message type ${messageType}`); } @@ -204,6 +207,14 @@ export default class Client extends EventEmitterWebAuthnSender { this.logger.info('Started sharing directory: ' + this.sharedDirectory.name); } + handleSharedDirectoryInfoRequest(buffer: ArrayBuffer) { + const req = this.codec.decodeSharedDirectoryInfoRequest(buffer); + this.logger.debug( + 'Received SharedDirectoryInfoRequest: ' + JSON.stringify(req) + ); + // TODO(isaiah): here's where we'll respond with SharedDirectoryInfoResponse + } + protected send( data: string | ArrayBufferLike | Blob | ArrayBufferView ): void { diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index 229390193..81753fbc8 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -39,6 +39,7 @@ export enum MessageType { MFA_JSON = 10, SHARED_DIRECTORY_ANNOUNCE = 11, SHARED_DIRECTORY_ACKNOWLEDGE = 12, + SHARED_DIRECTORY_INFO_REQUEST = 13, } // 0 is left button, 1 is middle button, 2 is right button @@ -93,12 +94,19 @@ export type SharedDirectoryAnnounce = { name: string; }; -// | message type (12) | err error | directory_id uint32 | +// | message type (12) | errCode error | directory_id uint32 | export type SharedDirectoryAcknowledge = { errCode: SharedDirectoryErrCode; directoryId: number; }; +// | message type (13) | completion_id uint32 | directory_id uint32 | path_length uint32 | path []byte | +export type SharedDirectoryInfoRequest = { + completionId: number; + directoryId: number; + path: string; +}; + export enum SharedDirectoryErrCode { // nil (no error, operation succeeded) Nil = 0, @@ -510,7 +518,7 @@ export default class Codec { return pngFrame; } - // | message type (12) | directory_id uint32 | succeeded byte | + // | message type (12) | errCode error | directory_id uint32 | decodeSharedDirectoryAcknowledge( buffer: ArrayBuffer ): SharedDirectoryAcknowledge { @@ -524,6 +532,22 @@ export default class Codec { }; } + // | message type (13) | completion_id uint32 | directory_id uint32 | path_length uint32 | path []byte | + decodeSharedDirectoryInfoRequest( + buffer: ArrayBuffer + ): SharedDirectoryInfoRequest { + let dv = new DataView(buffer); + let completionId = dv.getUint32(1); + let directoryId = dv.getUint32(5); + let path = this.decoder.decode(new Uint8Array(buffer.slice(13))); + + return { + completionId, + directoryId, + path, + }; + } + // asBase64Url creates a data:image uri from the png data part of a PNG_FRAME tdp message. private asBase64Url(buffer: ArrayBuffer): string { return `data:image/png;base64,${arrayBufferToBase64(buffer.slice(17))}`; From 3474fedbe301818828892153bb9fe406f4dd08aa Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 15:52:09 -0400 Subject: [PATCH 11/40] Updates test with some ts-fu to get the maximum value of a numerical enum --- packages/teleport/src/lib/tdp/codec.test.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/teleport/src/lib/tdp/codec.test.ts b/packages/teleport/src/lib/tdp/codec.test.ts index 7b9a53d4f..9635f2249 100644 --- a/packages/teleport/src/lib/tdp/codec.test.ts +++ b/packages/teleport/src/lib/tdp/codec.test.ts @@ -104,9 +104,13 @@ test('decodes message types', () => { const { buffer: pngFrameBuf } = makeBuf(MessageType.PNG_FRAME); const { buffer: clipboardBuf } = makeBuf(MessageType.CLIPBOARD_DATA); const { buffer: errorBuf } = makeBuf(MessageType.ERROR); - const { buffer: invalidBuf } = makeBuf( - MessageType.SHARED_DIRECTORY_ACKNOWLEDGE + 1 - ); + let invalid = + Math.max( + ...(Object.values(MessageType).filter( + mt => !isNaN(Number(mt)) + ) as number[]) + ) + 1; + const { buffer: invalidBuf } = makeBuf(invalid); expect(codec.decodeMessageType(pngFrameBuf)).toEqual(MessageType.PNG_FRAME); expect(codec.decodeMessageType(clipboardBuf)).toEqual( @@ -115,9 +119,7 @@ test('decodes message types', () => { expect(codec.decodeMessageType(errorBuf)).toEqual(MessageType.ERROR); expect(() => { codec.decodeMessageType(invalidBuf); - }).toThrow( - `invalid message type: ${MessageType.SHARED_DIRECTORY_ACKNOWLEDGE + 1}` - ); + }).toThrow(`invalid message type: ${invalid}`); }); test('decodes errors', () => { From a0c6e9d12a625f245c2b12486d466fc69b9d7996 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Wed, 13 Jul 2022 13:28:53 -0400 Subject: [PATCH 12/40] Updates babel targets to the latest 2 versions of primary browsers --- README.md | 26 ++++++++++++++++++++++++++ packages/build/.babelrc.js | 11 ++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f4b74eee7..6b6209116 100644 --- a/README.md +++ b/README.md @@ -169,3 +169,29 @@ proxy_service: ``` Then start the dev server like `yarn start-teleport --target=https://proxy.127.0.0.1.nip.io:3080` and access it at https://proxy.127.0.0.1.nip.io:8080. + +### Adding Packages with `yarn` + +We use [Yarn Workspaces](https://classic.yarnpkg.com/blog/2017/08/02/introducing-workspaces/) to manage dependencies. +Typically you will want to add packages to the lowest level necessary, by running + +``` +yarn workspace add +``` + +The `` of a given workspace is defined by its `"name"`. For example, if you wanted to add the package +`caniuse-lite` to the workspace `packages/build`, you would run + +``` +yarn workspace @gravitational/build add caniuse-lite +``` + +After adding a package to a workspace, you should expect to find a new lockfile in the workspace's directory. In this +example, the file `packages/build/yarn.lock` will have been created. This appears to be a bug in yarn workspaces, as +we want to track all dependencies in a single lockfile at the workspace root (`yarn.lock` in the root of this repo). To +fix this, you need to run the following: + +``` +rm packages/build/yarn.lock +yarn install +``` diff --git a/packages/build/.babelrc.js b/packages/build/.babelrc.js index 5db9da5bd..e25199625 100644 --- a/packages/build/.babelrc.js +++ b/packages/build/.babelrc.js @@ -31,7 +31,16 @@ function makePresents(test = false) { ]; } - return ['@babel/preset-env', ...presents]; + return [ + [ + '@babel/preset-env', + { + targets: + 'last 2 chrome version, last 2 edge version, last 2 firefox version, last 2 safari version', + }, + ], + ...presents, + ]; } module.exports = { From 1cd81310b8eed24aa4a8d1fbab096085fc26a805 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 14 Jul 2022 10:59:52 -0400 Subject: [PATCH 13/40] Updates Adding Packages section with better instructions --- README.md | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 6b6209116..77e7d33dc 100644 --- a/README.md +++ b/README.md @@ -170,28 +170,12 @@ proxy_service: Then start the dev server like `yarn start-teleport --target=https://proxy.127.0.0.1.nip.io:3080` and access it at https://proxy.127.0.0.1.nip.io:8080. -### Adding Packages with `yarn` +### Adding Packages/Dependencies We use [Yarn Workspaces](https://classic.yarnpkg.com/blog/2017/08/02/introducing-workspaces/) to manage dependencies. -Typically you will want to add packages to the lowest level necessary, by running -``` -yarn workspace add -``` - -The `` of a given workspace is defined by its `"name"`. For example, if you wanted to add the package -`caniuse-lite` to the workspace `packages/build`, you would run +The easiest way to add a package is to add a line to the workspace's `package.json` file and then run `yarn install` from +the root of this repository. -``` -yarn workspace @gravitational/build add caniuse-lite -``` - -After adding a package to a workspace, you should expect to find a new lockfile in the workspace's directory. In this -example, the file `packages/build/yarn.lock` will have been created. This appears to be a bug in yarn workspaces, as -we want to track all dependencies in a single lockfile at the workspace root (`yarn.lock` in the root of this repo). To -fix this, you need to run the following: - -``` -rm packages/build/yarn.lock -yarn install -``` +Keep in mind that there should only be a single `yarn.lock` in this repository, here at the top level. If you add packages +via `yarn workspace add `, it will create a `packages//yarn.lock` file, which should not be checked in. From f2970db3e4bc5bbbe4449671c5ee55ca2275e406 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Tue, 5 Jul 2022 17:54:05 -0400 Subject: [PATCH 14/40] super basic picker with logging --- .../teleport/src/DesktopSession/DesktopSession.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index f759e16c3..4456f3bc0 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -164,6 +164,11 @@ function Session(props: PropsWithChildren) { isSharingDirectory={isSharingDirectory} onShareDirectory={() => { setIsSharingDirectory(true); + const sharedDirHandle = window + .showDirectoryPicker() + .then(sharedDirHandle => { + console.log(sharedDirHandle); + }); }} /> @@ -218,3 +223,9 @@ const DesktopSessionAlert = styled(Alert)` align-self: center; min-width: 450px; `; + +declare global { + interface Window { + showDirectoryPicker: () => Promise; + } +} From 8150accd0f07e2c5bac493768ab8fc87cb3bf757 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Wed, 6 Jul 2022 17:19:05 -0400 Subject: [PATCH 15/40] Adds SharedDirectoryAnnounce --- .../src/DesktopSession/DesktopSession.tsx | 10 ++++-- .../src/DesktopSession/useClipboard.ts | 2 +- .../src/DesktopSession/useDesktopSession.tsx | 3 ++ .../src/DesktopSession/useTdpClientCanvas.tsx | 25 ++++++++++++-- packages/teleport/src/lib/tdp/client.ts | 28 ++++++++++++++++ packages/teleport/src/lib/tdp/codec.ts | 33 +++++++++++++++++++ 6 files changed, 94 insertions(+), 7 deletions(-) diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index 4456f3bc0..c6f393ff8 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -163,11 +163,15 @@ function Session(props: PropsWithChildren) { canShareDirectory={canShareDirectory} isSharingDirectory={isSharingDirectory} onShareDirectory={() => { - setIsSharingDirectory(true); - const sharedDirHandle = window + window .showDirectoryPicker() .then(sharedDirHandle => { - console.log(sharedDirHandle); + setIsSharingDirectory(true); + tdpClient.sharedDirectory = sharedDirHandle; + tdpClient.sendSharedDirectoryAnnounce(); + }) + .catch(() => { + setIsSharingDirectory(false); }); }} /> diff --git a/packages/teleport/src/DesktopSession/useClipboard.ts b/packages/teleport/src/DesktopSession/useClipboard.ts index 00b86fe3f..5f8ec7a5c 100644 --- a/packages/teleport/src/DesktopSession/useClipboard.ts +++ b/packages/teleport/src/DesktopSession/useClipboard.ts @@ -113,7 +113,7 @@ enum ClipboardPermissionType { Write = 'clipboard-write', } -type ClipboardPermissionStatus = { +export type ClipboardPermissionStatus = { state: PermissionState | 'error' | ''; errorText?: string; }; diff --git a/packages/teleport/src/DesktopSession/useDesktopSession.tsx b/packages/teleport/src/DesktopSession/useDesktopSession.tsx index f0eb718f9..42e1fc297 100644 --- a/packages/teleport/src/DesktopSession/useDesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/useDesktopSession.tsx @@ -140,6 +140,9 @@ export default function useDesktopSession() { clusterId, setTdpConnection, setWsConnection, + setIsRecording, + setClipboardState, + setIsSharingDirectory, enableClipboardSharing: clipboardState.enabled && clipboardState.permission.state === 'granted' && diff --git a/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx b/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx index f9b143347..666c10735 100644 --- a/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx +++ b/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx @@ -15,12 +15,13 @@ limitations under the License. */ import { useState, useEffect, useRef, Dispatch, SetStateAction } from 'react'; +import { Attempt } from 'shared/hooks/useAttemptNext'; import { TdpClient, ButtonState, ScrollAxis } from 'teleport/lib/tdp'; import { ClipboardData, PngFrame } from 'teleport/lib/tdp/codec'; -import { TopBarHeight } from './TopBar'; -import cfg from 'teleport/config'; import { getAccessToken, getHostName } from 'teleport/services/api'; -import { Attempt } from 'shared/hooks/useAttemptNext'; +import cfg from 'teleport/config'; +import { TopBarHeight } from './TopBar'; +import { ClipboardPermissionStatus } from './useClipboard'; export default function useTdpClientCanvas(props: Props) { const { @@ -29,6 +30,9 @@ export default function useTdpClientCanvas(props: Props) { clusterId, setTdpConnection, setWsConnection, + setIsRecording, + setClipboardState, + setIsSharingDirectory, enableClipboardSharing, } = props; const [tdpClient, setTdpClient] = useState(null); @@ -76,6 +80,12 @@ export default function useTdpClientCanvas(props: Props) { // Default TdpClientEvent.TDP_ERROR handler const onTdpError = (err: Error) => { + setIsSharingDirectory(false); + setIsRecording(false); + setClipboardState(prevState => ({ + ...prevState, + enabled: false, + })); setTdpConnection({ status: 'failed', statusText: err.message }); }; @@ -200,5 +210,14 @@ type Props = { clusterId: string; setTdpConnection: Dispatch>; setWsConnection: Dispatch>; + setIsRecording: Dispatch>; + setClipboardState: Dispatch< + SetStateAction<{ + enabled: boolean; + permission: ClipboardPermissionStatus; + errorText: string; + }> + >; + setIsSharingDirectory: Dispatch>; enableClipboardSharing: boolean; }; diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index b7596baa6..12deae320 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -42,6 +42,8 @@ export default class Client extends EventEmitterWebAuthnSender { protected codec: Codec; protected socket: WebSocket | undefined; private socketAddr: string; + sharedDirectory: FileSystemDirectoryHandle | undefined; + private logger = Logger.create('TDPClient'); constructor(socketAddr: string) { @@ -223,6 +225,32 @@ export default class Client extends EventEmitterWebAuthnSender { this.send(msg); } + private sharedDirectoryReady() { + if (!this.sharedDirectory) { + this.handleError( + new Error( + 'attempted to use a shared directory before one was initialized' + ) + ); + return false; + } + + return true; + } + + sendSharedDirectoryAnnounce() { + if (!this.sharedDirectoryReady()) return; + this.socket.send( + this.codec.encodeSharedDirectoryAnnounce({ + completionId: 0, // This is always the first request. + // Hardcode directoryId for now since we only support sharing 1 directory. + // We're using 2 because the smartcard device is hardcoded to 1 in the backend. + directoryId: 2, + name: this.sharedDirectory.name, + }) + ); + } + resize(spec: ClientScreenSpec) { this.send(this.codec.encodeClientScreenSpec(spec)); } diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index da94af558..8217f12ed 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -37,6 +37,7 @@ export enum MessageType { MOUSE_WHEEL_SCROLL = 8, ERROR = 9, MFA_JSON = 10, + SHARED_DIRECTORY_ANNOUNCE = 11, } // 0 is left button, 1 is middle button, 2 is right button @@ -84,6 +85,13 @@ export type MfaJson = { jsonString: string; }; +// | message type (11) | completion_id uint32 | directory_id uint32 | name_length uint32 | name []byte | +export type SharedDirectoryAnnounce = { + completionId: number; + directoryId: number; + name: string; +}; + // TdaCodec provides an api for encoding and decoding teleport desktop access protocol messages [1] // Buffers in TdaCodec are manipulated as DataView's [2] in order to give us low level control // of endianness (defaults to big endian, which is what we want), as opposed to using *Array @@ -389,6 +397,31 @@ export default class Codec { return buffer; } + // | message type (11) | completion_id uint32 | directory_id uint32 | name_length uint32 | name []byte | + encodeSharedDirectoryAnnounce( + sharedDirAnnounce: SharedDirectoryAnnounce + ): Message { + const dataUtf8array = this.encoder.encode(sharedDirAnnounce.name); + + const bufLen = byteLength + 3 * uint32Length + dataUtf8array.length; + const buffer = new ArrayBuffer(bufLen); + const view = new DataView(buffer); + let offset = 0; + + view.setUint8(offset++, MessageType.SHARED_DIRECTORY_ANNOUNCE); + view.setUint32(offset, sharedDirAnnounce.completionId); + offset += uint32Length; + view.setUint32(offset, sharedDirAnnounce.directoryId); + offset += uint32Length; + view.setUint32(offset, dataUtf8array.length); + offset += uint32Length; + dataUtf8array.forEach(byte => { + view.setUint8(offset++, byte); + }); + + return buffer; + } + // decodeClipboardData decodes clipboard data decodeClipboardData(buffer: ArrayBuffer): ClipboardData { return { From d3f9cac2fb21b51f6de31bd3c9d827790f6e06ed Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Wed, 6 Jul 2022 17:39:41 -0400 Subject: [PATCH 16/40] Removes recording icon --- .../src/DesktopSession/DesktopSession.tsx | 4 ---- .../teleport/src/DesktopSession/TopBar.tsx | 23 ------------------- .../src/DesktopSession/useDesktopSession.tsx | 7 ------ .../src/DesktopSession/useTdpClientCanvas.tsx | 3 --- packages/webapps.e | 2 +- 5 files changed, 1 insertion(+), 38 deletions(-) diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index c6f393ff8..442c1a880 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -108,8 +108,6 @@ function Session(props: PropsWithChildren) { hostname, clipboardState, setClipboardState, - isRecording, - setIsRecording, canShareDirectory, isSharingDirectory, setIsSharingDirectory, @@ -153,13 +151,11 @@ function Session(props: PropsWithChildren) { ...prevState, enabled: false, })); - setIsRecording(false); setIsSharingDirectory(false); tdpClient.nuke(); }} userHost={`${username}@${hostname}`} clipboardSharingEnabled={clipboardSharingActive} - isRecording={isRecording} canShareDirectory={canShareDirectory} isSharingDirectory={isSharingDirectory} onShareDirectory={() => { diff --git a/packages/teleport/src/DesktopSession/TopBar.tsx b/packages/teleport/src/DesktopSession/TopBar.tsx index 3d485a1bb..6d5ac2aa7 100644 --- a/packages/teleport/src/DesktopSession/TopBar.tsx +++ b/packages/teleport/src/DesktopSession/TopBar.tsx @@ -24,7 +24,6 @@ export default function TopBar(props: Props) { const { userHost, clipboardSharingEnabled, - isRecording, onDisconnect, canShareDirectory, isSharingDirectory, @@ -70,19 +69,6 @@ export default function TopBar(props: Props) { : 'Clipboard Sharing Disabled' } /> - - - Recording - setHostname(desktop.name)), userService.fetchUserContext().then(user => { setHasClipboardSharingEnabled(user.acl.clipboardSharingEnabled); - setIsRecording(user.acl.desktopSessionRecordingEnabled); setCanShareDirectory(user.acl.directorySharingEnabled); }), ]) @@ -140,7 +136,6 @@ export default function useDesktopSession() { clusterId, setTdpConnection, setWsConnection, - setIsRecording, setClipboardState, setIsSharingDirectory, enableClipboardSharing: @@ -156,8 +151,6 @@ export default function useDesktopSession() { username, clipboardState, setClipboardState, - isRecording, - setIsRecording, canShareDirectory, isSharingDirectory, setIsSharingDirectory, diff --git a/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx b/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx index 666c10735..975110a9e 100644 --- a/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx +++ b/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx @@ -30,7 +30,6 @@ export default function useTdpClientCanvas(props: Props) { clusterId, setTdpConnection, setWsConnection, - setIsRecording, setClipboardState, setIsSharingDirectory, enableClipboardSharing, @@ -81,7 +80,6 @@ export default function useTdpClientCanvas(props: Props) { // Default TdpClientEvent.TDP_ERROR handler const onTdpError = (err: Error) => { setIsSharingDirectory(false); - setIsRecording(false); setClipboardState(prevState => ({ ...prevState, enabled: false, @@ -210,7 +208,6 @@ type Props = { clusterId: string; setTdpConnection: Dispatch>; setWsConnection: Dispatch>; - setIsRecording: Dispatch>; setClipboardState: Dispatch< SetStateAction<{ enabled: boolean; diff --git a/packages/webapps.e b/packages/webapps.e index 0355d7e1a..406ec5075 160000 --- a/packages/webapps.e +++ b/packages/webapps.e @@ -1 +1 @@ -Subproject commit 0355d7e1a895a43c35d7933f297cad390127a3a3 +Subproject commit 406ec5075f92ec78244febec18dd2d66b3bf63ec From 9b5f4c6a10526b162911bc9566497fc15b83130d Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 11:02:30 -0400 Subject: [PATCH 17/40] updates storybook and storybook test snapshot --- .../DesktopSession/DesktopSession.story.tsx | 4 - .../DesktopSession.story.test.tsx.snap | 406 ++++-------------- 2 files changed, 90 insertions(+), 320 deletions(-) diff --git a/packages/teleport/src/DesktopSession/DesktopSession.story.tsx b/packages/teleport/src/DesktopSession/DesktopSession.story.tsx index 779daab61..2dbd461f6 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.story.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.story.tsx @@ -46,7 +46,6 @@ const props: State = { permission: { state: '' }, errorText: '', }, - isRecording: false, tdpClient: fakeClient(), username: 'user', onWsOpen: () => {}, @@ -55,7 +54,6 @@ const props: State = { disconnected: false, setDisconnected: () => {}, setClipboardState: () => {}, - setIsRecording: () => {}, canShareDirectory: true, isSharingDirectory: false, setIsSharingDirectory: () => {}, @@ -113,7 +111,6 @@ export const ConnectedSettingsFalse = () => { permission: { state: '' }, errorText: '', }} - isRecording={false} onPngFrame={(ctx: CanvasRenderingContext2D) => { fillGray(ctx.canvas); }} @@ -140,7 +137,6 @@ export const ConnectedSettingsTrue = () => { permission: { state: 'granted' }, errorText: '', }} - isRecording={true} isSharingDirectory={true} onPngFrame={(ctx: CanvasRenderingContext2D) => { fillGray(ctx.canvas); diff --git a/packages/teleport/src/DesktopSession/__snapshots__/DesktopSession.story.test.tsx.snap b/packages/teleport/src/DesktopSession/__snapshots__/DesktopSession.story.test.tsx.snap index 29239d02b..c6191c76c 100644 --- a/packages/teleport/src/DesktopSession/__snapshots__/DesktopSession.story.test.tsx.snap +++ b/packages/teleport/src/DesktopSession/__snapshots__/DesktopSession.story.test.tsx.snap @@ -8,13 +8,13 @@ exports[`clipboard error 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -36,20 +36,20 @@ exports[`clipboard error 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -61,12 +61,6 @@ exports[`clipboard error 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -108,15 +102,7 @@ exports[`clipboard error 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} - -.c13 { +.c11 { display: flex; align-items: center; justify-content: center; @@ -139,7 +125,7 @@ exports[`clipboard error 1`] = ` min-width: 450px; } -.c13 a { +.c11 a { color: #FFFFFF; } @@ -176,33 +162,18 @@ exports[`clipboard error 1`] = ` style="color: rgba(255, 255, 255, 0.56);" title="Clipboard Sharing Disabled" /> -
-
-
- Recording -
-
@@ -210,7 +181,7 @@ exports[`clipboard error 1`] = `
clipboard error @@ -230,13 +201,13 @@ exports[`connected settings false 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -258,20 +229,20 @@ exports[`connected settings false 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -283,12 +254,6 @@ exports[`connected settings false 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -330,14 +295,6 @@ exports[`connected settings false 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} -
-
-
-
- Recording -
-
@@ -419,13 +361,13 @@ exports[`connected settings true 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -447,20 +389,20 @@ exports[`connected settings true 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -472,12 +414,6 @@ exports[`connected settings true 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -519,14 +455,6 @@ exports[`connected settings true 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} -
-
-
-
- Recording -
-
@@ -608,13 +521,13 @@ exports[`connection error 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -636,20 +549,20 @@ exports[`connection error 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -661,12 +574,6 @@ exports[`connection error 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -708,15 +615,7 @@ exports[`connection error 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} - -.c13 { +.c11 { display: flex; align-items: center; justify-content: center; @@ -739,7 +638,7 @@ exports[`connection error 1`] = ` min-width: 450px; } -.c13 a { +.c11 a { color: #FFFFFF; } @@ -776,33 +675,18 @@ exports[`connection error 1`] = ` style="color: rgba(255, 255, 255, 0.56);" title="Clipboard Sharing Disabled" /> -
-
-
- Recording -
-
@@ -810,7 +694,7 @@ exports[`connection error 1`] = `
some connection error @@ -823,7 +707,7 @@ exports[`connection error 1`] = ` `; exports[`disconnected 1`] = ` -.c13 { +.c11 { box-sizing: border-box; margin: 72px; text-align: center; @@ -836,13 +720,13 @@ exports[`disconnected 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -864,20 +748,20 @@ exports[`disconnected 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -889,7 +773,7 @@ exports[`disconnected 1`] = ` padding-right: 16px; } -.c10 { +.c12 { overflow: hidden; text-overflow: ellipsis; margin: 0px; @@ -936,14 +820,6 @@ exports[`disconnected 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} -
-
-
-
- Recording -
-
@@ -1011,10 +872,10 @@ exports[`disconnected 1`] = `
Session successfully disconnected
@@ -1034,13 +895,13 @@ exports[`fetch error 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -1062,20 +923,20 @@ exports[`fetch error 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -1087,12 +948,6 @@ exports[`fetch error 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -1134,15 +989,7 @@ exports[`fetch error 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} - -.c13 { +.c11 { display: flex; align-items: center; justify-content: center; @@ -1165,7 +1012,7 @@ exports[`fetch error 1`] = ` min-width: 450px; } -.c13 a { +.c11 a { color: #FFFFFF; } @@ -1202,33 +1049,18 @@ exports[`fetch error 1`] = ` style="color: rgba(255, 255, 255, 0.56);" title="Clipboard Sharing Disabled" /> -
-
-
- Recording -
-
@@ -1236,7 +1068,7 @@ exports[`fetch error 1`] = `
some fetch error @@ -1256,13 +1088,13 @@ exports[`unintended disconnect 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -1284,20 +1116,20 @@ exports[`unintended disconnect 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -1309,12 +1141,6 @@ exports[`unintended disconnect 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -1356,15 +1182,7 @@ exports[`unintended disconnect 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} - -.c13 { +.c11 { display: flex; align-items: center; justify-content: center; @@ -1387,7 +1205,7 @@ exports[`unintended disconnect 1`] = ` min-width: 450px; } -.c13 a { +.c11 a { color: #FFFFFF; } @@ -1424,33 +1242,18 @@ exports[`unintended disconnect 1`] = ` style="color: rgba(255, 255, 255, 0.56);" title="Clipboard Sharing Disabled" /> -
-
-
- Recording -
-
@@ -1458,7 +1261,7 @@ exports[`unintended disconnect 1`] = `
Session disconnected for an unknown reason @@ -1471,7 +1274,7 @@ exports[`unintended disconnect 1`] = ` `; exports[`webauthn prompt 1`] = ` -.c13 { +.c11 { box-sizing: border-box; margin: 72px; text-align: center; @@ -1484,13 +1287,13 @@ exports[`webauthn prompt 1`] = ` color: #FFFFFF; } -.c12 { +.c10 { display: inline-block; transition: color 0.3s; color: #FFFFFF; } -.c11 { +.c9 { align-items: center; border: none; cursor: pointer; @@ -1512,20 +1315,20 @@ exports[`webauthn prompt 1`] = ` color: rgba(255,255,255,0.56); } -.c11 .c5 { +.c9 .c5 { color: inherit; } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:disabled { +.c9:disabled { color: rgba(255,255,255,0.3); } -.c11:hover, -.c11:focus { +.c9:hover, +.c9:focus { background: rgba(255,255,255,0.1); } @@ -1537,12 +1340,6 @@ exports[`webauthn prompt 1`] = ` padding-right: 16px; } -.c10 { - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - .c0 { box-sizing: border-box; display: flex; @@ -1584,14 +1381,6 @@ exports[`webauthn prompt 1`] = ` align-self: 'center'; } -.c9 { - width: 10px; - height: 10px; - border-radius: 10px; - margin-right: 6px; - vertical-align: text-bottom; -} -
-
-
-
- Recording -
-
@@ -1659,7 +1433,7 @@ exports[`webauthn prompt 1`] = `
Date: Thu, 7 Jul 2022 11:18:50 -0400 Subject: [PATCH 18/40] Adds types for File System Access API --- packages/teleport/package.json | 1 + .../src/DesktopSession/DesktopSession.tsx | 8 +- yarn.lock | 227 ++---------------- 3 files changed, 27 insertions(+), 209 deletions(-) diff --git a/packages/teleport/package.json b/packages/teleport/package.json index 859ac922b..c1c931f35 100644 --- a/packages/teleport/package.json +++ b/packages/teleport/package.json @@ -24,6 +24,7 @@ }, "devDependencies": { "@gravitational/build": "^1.0.0", + "@types/wicg-native-file-system": "^2020.6.0", "jest-canvas-mock": "^2.3.1" } } diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index 442c1a880..b5f55431f 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -222,10 +222,4 @@ function Session(props: PropsWithChildren) { const DesktopSessionAlert = styled(Alert)` align-self: center; min-width: 450px; -`; - -declare global { - interface Window { - showDirectoryPicker: () => Promise; - } -} +`; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 9f4d01106..f6cdca28a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3029,6 +3029,11 @@ tapable "^2.2.0" webpack "^5" +"@types/wicg-native-file-system@^2020.6.0": + version "2020.6.0" + resolved "https://registry.yarnpkg.com/@types/wicg-native-file-system/-/wicg-native-file-system-2020.6.0.tgz#63cbb7bac47bdb9eae4b0d66e63134b33e47e05d" + integrity sha512-M7n6jvHfUzUXDtf6UGpL6rVIddV7UzEYrvwZPORApeHvDGQnZJ79fXorLlDj8xJKyUemnEBohRd8yx09k9NBUw== + "@types/yargs-parser@*": version "20.2.1" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" @@ -3416,11 +3421,6 @@ abab@^2.0.3, abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -3482,22 +3482,13 @@ address@1.1.2, address@^1.0.1: resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== -agent-base@6, agent-base@^6.0.2: +agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" -agentkeepalive@^4.1.3: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" - integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA== - dependencies: - debug "^4.1.0" - depd "^1.1.2" - humanize-ms "^1.2.1" - aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -3723,14 +3714,6 @@ are-we-there-yet@^2.0.0: delegates "^1.0.0" readable-stream "^3.6.0" -are-we-there-yet@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz#ba20bd6b553e31d62fc8c31bd23d22b95734390d" - integrity sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -4564,7 +4547,7 @@ cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^15.0.5, cacache@^15.2.0: +cacache@^15.0.5: version "15.3.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== @@ -4943,7 +4926,7 @@ color-string@^1.6.0: color-name "^1.0.0" simple-swizzle "^0.2.2" -color-support@^1.1.2, color-support@^1.1.3: +color-support@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== @@ -5543,13 +5526,6 @@ debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: dependencies: ms "2.1.2" -debug@^4.3.3: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - decimal.js@^10.2.1: version "10.3.1" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" @@ -5687,7 +5663,7 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -depd@^1.1.2, depd@~1.1.2: +depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== @@ -6145,13 +6121,6 @@ encodeurl@^1.0.2, encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.12: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -6216,11 +6185,6 @@ envinfo@^7.7.3: resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== -err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== - errno@^0.1.3, errno@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" @@ -7246,20 +7210,6 @@ gauge@^3.0.0: strip-ansi "^3.0.1 || ^4.0.0" wide-align "^1.1.2" -gauge@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" - integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -7877,7 +7827,7 @@ htmlparser2@^6.1.0: domutils "^2.5.2" entities "^2.0.0" -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: +http-cache-semantics@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== @@ -7980,13 +7930,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - iconv-corefoundation@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/iconv-corefoundation/-/iconv-corefoundation-1.1.6.tgz#27c135470237f6f8d13462fa1f5eaf250523c29a" @@ -8389,11 +8332,6 @@ is-installed-globally@^0.4.0: global-dirs "^3.0.0" is-path-inside "^3.0.2" -is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" - integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== - is-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" @@ -9629,28 +9567,6 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: dependencies: semver "^6.0.0" -make-fetch-happen@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" - integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== - dependencies: - agentkeepalive "^4.1.3" - cacache "^15.2.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^6.0.0" - minipass "^3.1.3" - minipass-collect "^1.0.2" - minipass-fetch "^1.3.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.2" - promise-retry "^2.0.1" - socks-proxy-agent "^6.0.0" - ssri "^8.0.0" - makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -9928,11 +9844,16 @@ minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.5, minimist@~0.0.1: +minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw== + minipass-collect@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" @@ -9940,17 +9861,6 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" -minipass-fetch@^1.3.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" - integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== - dependencies: - minipass "^3.1.0" - minipass-sized "^1.0.3" - minizlib "^2.0.0" - optionalDependencies: - encoding "^0.1.12" - minipass-flush@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" @@ -9958,20 +9868,13 @@ minipass-flush@^1.0.5: dependencies: minipass "^3.0.0" -minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: +minipass-pipeline@^1.2.2: version "1.2.4" resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== dependencies: minipass "^3.0.0" -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== - dependencies: - minipass "^3.0.0" - minipass@^3.0.0, minipass@^3.1.1: version "3.1.5" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.5.tgz#71f6251b0a33a49c01b3cf97ff77eda030dff732" @@ -9979,14 +9882,7 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" -minipass@^3.1.0, minipass@^3.1.3: - version "3.1.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" - integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== - dependencies: - yallist "^4.0.0" - -minizlib@^2.0.0, minizlib@^2.1.1: +minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -10064,7 +9960,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.0.0, ms@^2.1.1: +ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -10119,11 +10015,6 @@ negotiator@0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -negotiator@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" @@ -10171,22 +10062,6 @@ node-forge@^0.10.0: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== -node-gyp@8.4.1: - version "8.4.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" - integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^9.1.0" - nopt "^5.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -10243,13 +10118,6 @@ node-releases@^2.0.1: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -10307,16 +10175,6 @@ npmlog@^5.0.1: gauge "^3.0.0" set-blocking "^2.0.0" -npmlog@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" - integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.3" - set-blocking "^2.0.0" - nth-check@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" @@ -11193,14 +11051,6 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= -promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" - integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - promise.allsettled@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.5.tgz#2443f3d4b2aa8dfa560f6ac2aa6c4ea999d75f53" @@ -12088,11 +11938,6 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - retry@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" @@ -12489,11 +12334,6 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== -signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -12532,7 +12372,7 @@ slice-ansi@^1.0.0: dependencies: is-fullwidth-code-point "^2.0.0" -smart-buffer@^4.0.2, smart-buffer@^4.2.0: +smart-buffer@^4.0.2: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== @@ -12576,23 +12416,6 @@ sockjs@^0.3.21: uuid "^3.4.0" websocket-driver "^0.7.4" -socks-proxy-agent@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz#f6b5229cc0cbd6f2f202d9695f09d871e951c85e" - integrity sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - -socks@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.2.tgz#ec042d7960073d40d94268ff3bb727dc685f111a" - integrity sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA== - dependencies: - ip "^1.1.5" - smart-buffer "^4.2.0" - source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -12733,7 +12556,7 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" -ssri@^8.0.0, ssri@^8.0.1: +ssri@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== @@ -12838,7 +12661,7 @@ string-length@^4.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -13107,7 +12930,7 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar@^6.0.2, tar@^6.1.2: +tar@^6.0.2: version "6.1.11" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== @@ -14253,14 +14076,14 @@ which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" -which@^2.0.1, which@^2.0.2: +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@^1.1.2, wide-align@^1.1.5: +wide-align@^1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== From ca592665643a994834e92753ee9791f778546bc3 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 11:46:23 -0400 Subject: [PATCH 19/40] prettier --- packages/teleport/src/DesktopSession/DesktopSession.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index b5f55431f..49ec82d1b 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -222,4 +222,4 @@ function Session(props: PropsWithChildren) { const DesktopSessionAlert = styled(Alert)` align-self: center; min-width: 450px; -`; \ No newline at end of file +`; From 20c14ff2022abcd963a611e2a9bba86d7561ee26 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 14:44:20 -0400 Subject: [PATCH 20/40] Adds SharedDirectoryAcknowledge, SharedDirectoryErrCode, updates some previously janky validity checks --- packages/teleport/src/lib/tdp/client.ts | 30 +++++++++++-- packages/teleport/src/lib/tdp/codec.test.ts | 8 +++- packages/teleport/src/lib/tdp/codec.ts | 49 ++++++++++++++++++--- 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index 12deae320..55e04b555 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -23,6 +23,7 @@ import Codec, { ClientScreenSpec, PngFrame, ClipboardData, + SharedDirectoryErrCode, } from './codec'; export enum TdpClientEvent { @@ -108,6 +109,9 @@ export default class Client extends EventEmitterWebAuthnSender { case MessageType.MFA_JSON: this.handleMfaChallenge(buffer); break; + case MessageType.SHARED_DIRECTORY_ACKNOWLEDGE: + this.handleSharedDirectoryAcknowledge(buffer); + break; default: this.logger.warn(`received unsupported message type ${messageType}`); } @@ -165,8 +169,7 @@ export default class Client extends EventEmitterWebAuthnSender { this.emit(TermEventEnum.WEBAUTHN_CHALLENGE, mfaJson.jsonString); } else { // mfaJson.mfaType === 'u', or else decodeMfaJson would have thrown an error. - this.emit( - TdpClientEvent.TDP_ERROR, + this.handleError( new Error( 'Multifactor authentication is required for accessing this desktop, \ however the U2F API for hardware keys is not supported for desktop sessions. \ @@ -176,10 +179,31 @@ export default class Client extends EventEmitterWebAuthnSender { ); } } catch (err) { - this.emit(TdpClientEvent.TDP_ERROR, err); + this.handleError(err); } } + private wasSuccessful(errCode: SharedDirectoryErrCode) { + if (errCode === SharedDirectoryErrCode.Nil) { + return true; + } + + this.handleError( + new Error(`Encountered shared directory error: ${errCode}`) + ); + return false; + } + + handleSharedDirectoryAcknowledge(buffer: ArrayBuffer) { + const ack = this.codec.decodeSharedDirectoryAcknowledge(buffer); + + if (!this.wasSuccessful(ack.errCode)) { + return; + } + + this.logger.info('Started sharing directory: ' + this.sharedDirectory.name); + } + protected send( data: string | ArrayBufferLike | Blob | ArrayBufferView ): void { diff --git a/packages/teleport/src/lib/tdp/codec.test.ts b/packages/teleport/src/lib/tdp/codec.test.ts index ae0085464..7b9a53d4f 100644 --- a/packages/teleport/src/lib/tdp/codec.test.ts +++ b/packages/teleport/src/lib/tdp/codec.test.ts @@ -104,7 +104,9 @@ test('decodes message types', () => { const { buffer: pngFrameBuf } = makeBuf(MessageType.PNG_FRAME); const { buffer: clipboardBuf } = makeBuf(MessageType.CLIPBOARD_DATA); const { buffer: errorBuf } = makeBuf(MessageType.ERROR); - const { buffer: invalidBuf } = makeBuf(MessageType.MFA_JSON + 1); + const { buffer: invalidBuf } = makeBuf( + MessageType.SHARED_DIRECTORY_ACKNOWLEDGE + 1 + ); expect(codec.decodeMessageType(pngFrameBuf)).toEqual(MessageType.PNG_FRAME); expect(codec.decodeMessageType(clipboardBuf)).toEqual( @@ -113,7 +115,9 @@ test('decodes message types', () => { expect(codec.decodeMessageType(errorBuf)).toEqual(MessageType.ERROR); expect(() => { codec.decodeMessageType(invalidBuf); - }).toThrow(`invalid message type: ${MessageType.MFA_JSON + 1}`); + }).toThrow( + `invalid message type: ${MessageType.SHARED_DIRECTORY_ACKNOWLEDGE + 1}` + ); }); test('decodes errors', () => { diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index 8217f12ed..229390193 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -38,6 +38,7 @@ export enum MessageType { ERROR = 9, MFA_JSON = 10, SHARED_DIRECTORY_ANNOUNCE = 11, + SHARED_DIRECTORY_ACKNOWLEDGE = 12, } // 0 is left button, 1 is middle button, 2 is right button @@ -92,6 +93,31 @@ export type SharedDirectoryAnnounce = { name: string; }; +// | message type (12) | err error | directory_id uint32 | +export type SharedDirectoryAcknowledge = { + errCode: SharedDirectoryErrCode; + directoryId: number; +}; + +export enum SharedDirectoryErrCode { + // nil (no error, operation succeeded) + Nil = 0, + // operation failed + Failed = 1, + // resource does not exist + DoesNotExist = 2, + // resource already exists + AlreadyExists = 3, +} + +function toSharedDirectoryErrCode(errCode: number): SharedDirectoryErrCode { + if (!(errCode in SharedDirectoryErrCode)) { + throw new Error(`attempted to convert invalid error code ${errCode}`); + } + + return errCode as SharedDirectoryErrCode; +} + // TdaCodec provides an api for encoding and decoding teleport desktop access protocol messages [1] // Buffers in TdaCodec are manipulated as DataView's [2] in order to give us low level control // of endianness (defaults to big endian, which is what we want), as opposed to using *Array @@ -434,8 +460,7 @@ export default class Codec { // Throws an error on an invalid or unexpected MessageType value. decodeMessageType(buffer: ArrayBuffer): MessageType { const messageType = new DataView(buffer).getUint8(0); - // TODO(isaiah): this is fragile, instead switch all possibilities here. - if (messageType > MessageType.MFA_JSON) { + if (!(messageType in MessageType)) { throw new Error(`invalid message type: ${messageType}`); } return messageType; @@ -480,13 +505,27 @@ export default class Codec { data: image, }; pngFrame.data.onload = onload(pngFrame); - pngFrame.data.src = this._asBase64Url(buffer); + pngFrame.data.src = this.asBase64Url(buffer); return pngFrame; } - // _asBase64Url creates a data:image uri from the png data part of a PNG_FRAME tdp message. - _asBase64Url(buffer: ArrayBuffer): string { + // | message type (12) | directory_id uint32 | succeeded byte | + decodeSharedDirectoryAcknowledge( + buffer: ArrayBuffer + ): SharedDirectoryAcknowledge { + let dv = new DataView(buffer); + let errCode = toSharedDirectoryErrCode(dv.getUint32(1)); + let directoryId = dv.getUint32(5); + + return { + errCode, + directoryId, + }; + } + + // asBase64Url creates a data:image uri from the png data part of a PNG_FRAME tdp message. + private asBase64Url(buffer: ArrayBuffer): string { return `data:image/png;base64,${arrayBufferToBase64(buffer.slice(17))}`; } } From 43f921f2dbb90b78bc60982a268b6960cf63673f Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 15:51:12 -0400 Subject: [PATCH 21/40] Adds debug to logger --- packages/shared/libs/logger.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/shared/libs/logger.js b/packages/shared/libs/logger.js index 972c97d54..8a10659c2 100644 --- a/packages/shared/libs/logger.js +++ b/packages/shared/libs/logger.js @@ -35,6 +35,10 @@ export class Logger { this.log('info', ...args); } + debug(...args) { + this.log('debug', ...args); + } + error(...args) { this.log('error', ...args); } From e779785d8235234ac725f62ac7e255a159d8a276 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 15:51:33 -0400 Subject: [PATCH 22/40] Adds SharedDirectoryInfoRequest --- packages/teleport/src/lib/tdp/client.ts | 11 ++++++++++ packages/teleport/src/lib/tdp/codec.ts | 28 +++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index 55e04b555..997177a9c 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -112,6 +112,9 @@ export default class Client extends EventEmitterWebAuthnSender { case MessageType.SHARED_DIRECTORY_ACKNOWLEDGE: this.handleSharedDirectoryAcknowledge(buffer); break; + case MessageType.SHARED_DIRECTORY_INFO_REQUEST: + this.handleSharedDirectoryInfoRequest(buffer); + break; default: this.logger.warn(`received unsupported message type ${messageType}`); } @@ -204,6 +207,14 @@ export default class Client extends EventEmitterWebAuthnSender { this.logger.info('Started sharing directory: ' + this.sharedDirectory.name); } + handleSharedDirectoryInfoRequest(buffer: ArrayBuffer) { + const req = this.codec.decodeSharedDirectoryInfoRequest(buffer); + this.logger.debug( + 'Received SharedDirectoryInfoRequest: ' + JSON.stringify(req) + ); + // TODO(isaiah): here's where we'll respond with SharedDirectoryInfoResponse + } + protected send( data: string | ArrayBufferLike | Blob | ArrayBufferView ): void { diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index 229390193..81753fbc8 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -39,6 +39,7 @@ export enum MessageType { MFA_JSON = 10, SHARED_DIRECTORY_ANNOUNCE = 11, SHARED_DIRECTORY_ACKNOWLEDGE = 12, + SHARED_DIRECTORY_INFO_REQUEST = 13, } // 0 is left button, 1 is middle button, 2 is right button @@ -93,12 +94,19 @@ export type SharedDirectoryAnnounce = { name: string; }; -// | message type (12) | err error | directory_id uint32 | +// | message type (12) | errCode error | directory_id uint32 | export type SharedDirectoryAcknowledge = { errCode: SharedDirectoryErrCode; directoryId: number; }; +// | message type (13) | completion_id uint32 | directory_id uint32 | path_length uint32 | path []byte | +export type SharedDirectoryInfoRequest = { + completionId: number; + directoryId: number; + path: string; +}; + export enum SharedDirectoryErrCode { // nil (no error, operation succeeded) Nil = 0, @@ -510,7 +518,7 @@ export default class Codec { return pngFrame; } - // | message type (12) | directory_id uint32 | succeeded byte | + // | message type (12) | errCode error | directory_id uint32 | decodeSharedDirectoryAcknowledge( buffer: ArrayBuffer ): SharedDirectoryAcknowledge { @@ -524,6 +532,22 @@ export default class Codec { }; } + // | message type (13) | completion_id uint32 | directory_id uint32 | path_length uint32 | path []byte | + decodeSharedDirectoryInfoRequest( + buffer: ArrayBuffer + ): SharedDirectoryInfoRequest { + let dv = new DataView(buffer); + let completionId = dv.getUint32(1); + let directoryId = dv.getUint32(5); + let path = this.decoder.decode(new Uint8Array(buffer.slice(13))); + + return { + completionId, + directoryId, + path, + }; + } + // asBase64Url creates a data:image uri from the png data part of a PNG_FRAME tdp message. private asBase64Url(buffer: ArrayBuffer): string { return `data:image/png;base64,${arrayBufferToBase64(buffer.slice(17))}`; From 265564f363eafa9120027e0578a178a52ec623a1 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Thu, 7 Jul 2022 15:52:09 -0400 Subject: [PATCH 23/40] Updates test with some ts-fu to get the maximum value of a numerical enum --- packages/teleport/src/lib/tdp/codec.test.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/teleport/src/lib/tdp/codec.test.ts b/packages/teleport/src/lib/tdp/codec.test.ts index 7b9a53d4f..9635f2249 100644 --- a/packages/teleport/src/lib/tdp/codec.test.ts +++ b/packages/teleport/src/lib/tdp/codec.test.ts @@ -104,9 +104,13 @@ test('decodes message types', () => { const { buffer: pngFrameBuf } = makeBuf(MessageType.PNG_FRAME); const { buffer: clipboardBuf } = makeBuf(MessageType.CLIPBOARD_DATA); const { buffer: errorBuf } = makeBuf(MessageType.ERROR); - const { buffer: invalidBuf } = makeBuf( - MessageType.SHARED_DIRECTORY_ACKNOWLEDGE + 1 - ); + let invalid = + Math.max( + ...(Object.values(MessageType).filter( + mt => !isNaN(Number(mt)) + ) as number[]) + ) + 1; + const { buffer: invalidBuf } = makeBuf(invalid); expect(codec.decodeMessageType(pngFrameBuf)).toEqual(MessageType.PNG_FRAME); expect(codec.decodeMessageType(clipboardBuf)).toEqual( @@ -115,9 +119,7 @@ test('decodes message types', () => { expect(codec.decodeMessageType(errorBuf)).toEqual(MessageType.ERROR); expect(() => { codec.decodeMessageType(invalidBuf); - }).toThrow( - `invalid message type: ${MessageType.SHARED_DIRECTORY_ACKNOWLEDGE + 1}` - ); + }).toThrow(`invalid message type: ${invalid}`); }); test('decodes errors', () => { From 14a61661208b66d3f48d2574dd896223d7a7f0b7 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Tue, 12 Jul 2022 13:50:37 -0400 Subject: [PATCH 24/40] swaps out wicg-native-file-system for apparently more up to date wicg-file-system-access --- packages/teleport/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/teleport/package.json b/packages/teleport/package.json index c1c931f35..0b739c00e 100644 --- a/packages/teleport/package.json +++ b/packages/teleport/package.json @@ -24,7 +24,7 @@ }, "devDependencies": { "@gravitational/build": "^1.0.0", - "@types/wicg-native-file-system": "^2020.6.0", + "@types/wicg-file-system-access": "^2020.9.5", "jest-canvas-mock": "^2.3.1" } } diff --git a/yarn.lock b/yarn.lock index f6cdca28a..47ef921e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3029,10 +3029,10 @@ tapable "^2.2.0" webpack "^5" -"@types/wicg-native-file-system@^2020.6.0": - version "2020.6.0" - resolved "https://registry.yarnpkg.com/@types/wicg-native-file-system/-/wicg-native-file-system-2020.6.0.tgz#63cbb7bac47bdb9eae4b0d66e63134b33e47e05d" - integrity sha512-M7n6jvHfUzUXDtf6UGpL6rVIddV7UzEYrvwZPORApeHvDGQnZJ79fXorLlDj8xJKyUemnEBohRd8yx09k9NBUw== +"@types/wicg-file-system-access@^2020.9.5": + version "2020.9.5" + resolved "https://registry.yarnpkg.com/@types/wicg-file-system-access/-/wicg-file-system-access-2020.9.5.tgz#4a0c8f3d1ed101525f329e86c978f7735404474f" + integrity sha512-UYK244awtmcUYQfs7FR8710MJcefL2WvkyHMjA8yJzxd1mo0Gfn88sRZ1Bls7hiUhA2w7ne1gpJ9T5g3G0wOyA== "@types/yargs-parser@*": version "20.2.1" From 317d0d8f9b942e1b838e31033f7ba5c18f31c21d Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Tue, 12 Jul 2022 17:26:11 -0400 Subject: [PATCH 25/40] adds SharedDirectoryInfoResponse and FileSystemObject to the codec --- packages/teleport/src/lib/tdp/codec.ts | 71 +++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index 81753fbc8..b684ffc22 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -40,6 +40,7 @@ export enum MessageType { SHARED_DIRECTORY_ANNOUNCE = 11, SHARED_DIRECTORY_ACKNOWLEDGE = 12, SHARED_DIRECTORY_INFO_REQUEST = 13, + SHARED_DIRECTORY_INFO_RESPONSE = 14, } // 0 is left button, 1 is middle button, 2 is right button @@ -94,7 +95,7 @@ export type SharedDirectoryAnnounce = { name: string; }; -// | message type (12) | errCode error | directory_id uint32 | +// | message type (12) | err_code error | directory_id uint32 | export type SharedDirectoryAcknowledge = { errCode: SharedDirectoryErrCode; directoryId: number; @@ -107,6 +108,21 @@ export type SharedDirectoryInfoRequest = { path: string; }; +// | message type (14) | completion_id uint32 | err_code uint32 | file_system_object fso | +export type SharedDirectoryInfoResponse = { + completionId: number; + errCode: SharedDirectoryErrCode; + fso: FileSystemObject; +}; + +// | last_modified uint64 | size uint64 | file_type uint32 | path_length uint32 | path byte[] | +export type FileSystemObject = { + lastModified: bigint; + size: bigint; + fileType: FileType; + path: string; +}; + export enum SharedDirectoryErrCode { // nil (no error, operation succeeded) Nil = 0, @@ -118,6 +134,11 @@ export enum SharedDirectoryErrCode { AlreadyExists = 3, } +export enum FileType { + File = 0, + Directory = 1, +} + function toSharedDirectoryErrCode(errCode: number): SharedDirectoryErrCode { if (!(errCode in SharedDirectoryErrCode)) { throw new Error(`attempted to convert invalid error code ${errCode}`); @@ -456,6 +477,51 @@ export default class Codec { return buffer; } + // | message type (14) | completion_id uint32 | err_code uint32 | file_system_object fso | + encodeSharedDirectoryInfoResponse(res: SharedDirectoryInfoResponse): Message { + const bufLenSansFso = byteLength + 2 * uint32Length; + const bufferSansFso = new ArrayBuffer(bufLenSansFso); + const view = new DataView(bufferSansFso); + let offset = 0; + + view.setUint8(offset++, MessageType.SHARED_DIRECTORY_INFO_RESPONSE); + view.setUint32(offset, res.completionId); + offset += uint32Length; + view.setUint32(offset, res.errCode); + offset += uint32Length; + + const fsoBuffer = this.encodeFileSystemObject(res.fso); + + // https://gist.github.com/72lions/4528834?permalink_comment_id=2395442#gistcomment-2395442 + return new Uint8Array([ + ...new Uint8Array(bufferSansFso), + ...new Uint8Array(fsoBuffer), + ]).buffer; + } + + // | last_modified uint64 | size uint64 | file_type uint32 | path_length uint32 | path byte[] | + encodeFileSystemObject(fso: FileSystemObject): Message { + const dataUtf8array = this.encoder.encode(fso.path); + + const bufLen = 2 * uint64Length + 2 * uint32Length + dataUtf8array.length; + const buffer = new ArrayBuffer(bufLen); + const view = new DataView(buffer); + let offset = 0; + view.setBigUint64(offset, fso.lastModified); + offset += uint64Length; + view.setBigUint64(offset, fso.size); + offset += uint64Length; + view.setUint32(offset, fso.fileType); + offset += uint32Length; + view.setUint32(offset, dataUtf8array.length); + offset += uint32Length; + dataUtf8array.forEach(byte => { + view.setUint8(offset++, byte); + }); + + return buffer; + } + // decodeClipboardData decodes clipboard data decodeClipboardData(buffer: ArrayBuffer): ClipboardData { return { @@ -518,7 +584,7 @@ export default class Codec { return pngFrame; } - // | message type (12) | errCode error | directory_id uint32 | + // | message type (12) | err_code error | directory_id uint32 | decodeSharedDirectoryAcknowledge( buffer: ArrayBuffer ): SharedDirectoryAcknowledge { @@ -556,3 +622,4 @@ export default class Codec { const byteLength = 1; const uint32Length = 4; +const uint64Length = uint32Length * 2; From 6c258adf8ce77c2afdcad3f3f537bb1fca77dc75 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Tue, 12 Jul 2022 17:53:32 -0400 Subject: [PATCH 26/40] Retains existing functionality, substituting in a new sharedDirectoryManager --- .../src/DesktopSession/DesktopSession.tsx | 2 +- packages/teleport/src/lib/tdp/client.ts | 45 ++++++++++--------- .../src/lib/tdp/sharedDirectoryManager.ts | 38 ++++++++++++++++ 3 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 packages/teleport/src/lib/tdp/sharedDirectoryManager.ts diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index 49ec82d1b..2ebc8bd18 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -163,7 +163,7 @@ function Session(props: PropsWithChildren) { .showDirectoryPicker() .then(sharedDirHandle => { setIsSharingDirectory(true); - tdpClient.sharedDirectory = sharedDirHandle; + tdpClient.addSharedDirectory(sharedDirHandle); tdpClient.sendSharedDirectoryAnnounce(); }) .catch(() => { diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index 997177a9c..e3cb58b4f 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -24,7 +24,9 @@ import Codec, { PngFrame, ClipboardData, SharedDirectoryErrCode, + SharedDirectoryInfoResponse, } from './codec'; +import { SharedDirectoryManager } from './sharedDirectoryManager'; export enum TdpClientEvent { TDP_CLIENT_SCREEN_SPEC = 'tdp client screen spec', @@ -43,7 +45,7 @@ export default class Client extends EventEmitterWebAuthnSender { protected codec: Codec; protected socket: WebSocket | undefined; private socketAddr: string; - sharedDirectory: FileSystemDirectoryHandle | undefined; + private sdManager: SharedDirectoryManager; private logger = Logger.create('TDPClient'); @@ -51,6 +53,7 @@ export default class Client extends EventEmitterWebAuthnSender { super(); this.socketAddr = socketAddr; this.codec = new Codec(); + this.sdManager = new SharedDirectoryManager(); } // Connect to the websocket and register websocket event handlers. @@ -204,7 +207,7 @@ export default class Client extends EventEmitterWebAuthnSender { return; } - this.logger.info('Started sharing directory: ' + this.sharedDirectory.name); + this.logger.info('Started sharing directory: ' + this.sdManager.getName()); } handleSharedDirectoryInfoRequest(buffer: ArrayBuffer) { @@ -260,30 +263,28 @@ export default class Client extends EventEmitterWebAuthnSender { this.send(msg); } - private sharedDirectoryReady() { - if (!this.sharedDirectory) { - this.handleError( - new Error( - 'attempted to use a shared directory before one was initialized' - ) - ); - return false; + addSharedDirectory(sharedDirectory: FileSystemDirectoryHandle) { + try { + this.sdManager.add(sharedDirectory); + } catch (err) { + this.handleError(err); } - - return true; } sendSharedDirectoryAnnounce() { - if (!this.sharedDirectoryReady()) return; - this.socket.send( - this.codec.encodeSharedDirectoryAnnounce({ - completionId: 0, // This is always the first request. - // Hardcode directoryId for now since we only support sharing 1 directory. - // We're using 2 because the smartcard device is hardcoded to 1 in the backend. - directoryId: 2, - name: this.sharedDirectory.name, - }) - ); + try { + this.socket.send( + this.codec.encodeSharedDirectoryAnnounce({ + completionId: 0, // This is always the first request. + // Hardcode directoryId for now since we only support sharing 1 directory. + // We're using 2 because the smartcard device is hardcoded to 1 in the backend. + directoryId: 2, + name: this.sdManager.getName(), + }) + ); + } catch (err) { + this.handleError(err); + } } resize(spec: ClientScreenSpec) { diff --git a/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts b/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts new file mode 100644 index 000000000..0c4d5b5d6 --- /dev/null +++ b/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts @@ -0,0 +1,38 @@ +// Copyright 2022 Gravitational, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +export class SharedDirectoryManager { + private dir: FileSystemDirectoryHandle | undefined; + + add(sharedDirectory: FileSystemDirectoryHandle) { + if (this.dir) { + throw new Error( + 'SharedDirectoryManager currently only supports sharing a single directory' + ); + } + this.dir = sharedDirectory; + } + + getName(): string { + this.checkReady(); + return this.dir.name; + } + + private checkReady() { + if (!this.dir) { + throw new Error( + 'attempted to use a shared directory before one was initialized' + ); + } + } +} From ece73c749f040f016837ad1fa2bd5d6136cf21c2 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Sun, 17 Jul 2022 19:59:57 -0700 Subject: [PATCH 27/40] Adds untested walkPath --- packages/teleport/src/lib/tdp/client.ts | 13 ++- .../src/lib/tdp/sharedDirectoryManager.ts | 82 +++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index e3cb58b4f..f20a24001 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -210,11 +210,22 @@ export default class Client extends EventEmitterWebAuthnSender { this.logger.info('Started sharing directory: ' + this.sdManager.getName()); } - handleSharedDirectoryInfoRequest(buffer: ArrayBuffer) { + async handleSharedDirectoryInfoRequest(buffer: ArrayBuffer) { const req = this.codec.decodeSharedDirectoryInfoRequest(buffer); this.logger.debug( 'Received SharedDirectoryInfoRequest: ' + JSON.stringify(req) ); + try { + const size = await this.sdManager.getSize(req.path); + console.log('size = ' + size); + const lastModified = await this.sdManager.getLastModified(req.path); + console.log('lastModified = ' + lastModified); + } catch (e) { + // TODO(isaiah) I think sometimes we want to just pass this back, + // since windows defaults to look for certain files like desktop.ini + this.handleError(e); + } + // TODO(isaiah): here's where we'll respond with SharedDirectoryInfoResponse } diff --git a/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts b/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts index 0c4d5b5d6..cfe607dc3 100644 --- a/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts +++ b/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts @@ -11,6 +11,10 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. + +// SharedDirectoryManager manages a FileSystemDirectoryHandle for use +// by the TDP client. Most of it's methods can potentially throw errors +// and so should be wrapped in try/catch blocks. export class SharedDirectoryManager { private dir: FileSystemDirectoryHandle | undefined; @@ -28,6 +32,84 @@ export class SharedDirectoryManager { return this.dir.name; } + // gets the size of item at path, where + // path is the relative path from the root + // directory. Size returned is in bytes. + async getSize(path: string): Promise { + this.checkReady(); + + const fileOrDir = await this.walkPath(path); + + if (fileOrDir.kind === 'directory') { + // Magic value for directories per the TDP spec. + return 4096; + } + let file = await fileOrDir.getFile(); + return file.size; + } + + // gets the last modified date at path, where + // path is the relative path from the root directory. + // The number returned is the last modified date in + // milliseconds since the unix epoch. + async getLastModified(path: string): Promise { + this.checkReady(); + + const fileOrDir = await this.walkPath(path); + + if (fileOrDir.kind === 'directory') { + // Magic value for directories per the TDP spec. + return 0; + } + let file = await fileOrDir.getFile(); + return file.lastModified; + } + + // walkPath walks a pathstr (assumed to be in the qualified Unix format specified + // in the TDP spec), returning the FileSystemDirectoryHandle | FileSystemFileHandle + // it finds at its end. If the pathstr isn't a valid path in the shared directory, + // it throws an error. + private async walkPath( + pathstr: string + ): Promise { + if (pathstr === '') { + return this.dir; + } + + let path = pathstr.split('/'); + + let walkIt = async ( + dir: FileSystemDirectoryHandle, + path: string[] + ): Promise => { + // Pop the next path element off the stack + let nextPathElem = path.shift(); + + // Iterate through the items in the directory + for await (const entry of dir.values()) { + // If we find the entry we're looking for + if (entry.name === nextPathElem) { + if (path.length === 0) { + // We're at the end of the path, so this + // is the end element we've been walking towards. + return entry; + } else if (entry.kind === 'directory') { + // We're not at the end of the path and + // have encountered a directory, recurse + // further. + return walkIt(entry, path); + } else { + break; + } + } + } + + throw new Error('Invalid path'); + }; + + return walkIt(this.dir, path); + } + private checkReady() { if (!this.dir) { throw new Error( From fe6ea5b910bb68aa8fc6b0827031c3fc616d6a41 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Mon, 18 Jul 2022 15:36:32 -0700 Subject: [PATCH 28/40] uses consts in decodeSharedDirectoryAcknowledge --- packages/teleport/src/lib/tdp/codec.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index 229390193..29c347905 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -93,7 +93,7 @@ export type SharedDirectoryAnnounce = { name: string; }; -// | message type (12) | err error | directory_id uint32 | +// | message type (12) | errCode error | directory_id uint32 | export type SharedDirectoryAcknowledge = { errCode: SharedDirectoryErrCode; directoryId: number; @@ -510,13 +510,16 @@ export default class Codec { return pngFrame; } - // | message type (12) | directory_id uint32 | succeeded byte | + // | message type (12) | errCode error | directory_id uint32 | decodeSharedDirectoryAcknowledge( buffer: ArrayBuffer ): SharedDirectoryAcknowledge { - let dv = new DataView(buffer); - let errCode = toSharedDirectoryErrCode(dv.getUint32(1)); - let directoryId = dv.getUint32(5); + const dv = new DataView(buffer); + let offset = 0; + offset += byteLength; // eat message type + const errCode = toSharedDirectoryErrCode(dv.getUint32(offset)); + offset += uint32Length; // eat errCode + const directoryId = dv.getUint32(5); return { errCode, From e54f2510209b9e8e6480b9e7fcc36e3bc7d6d369 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Mon, 18 Jul 2022 15:47:20 -0700 Subject: [PATCH 29/40] uses consts in decodeSharedDirectoryInfoRequest --- packages/teleport/src/lib/tdp/codec.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index 9e0b8b935..44c6671de 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -540,9 +540,14 @@ export default class Codec { buffer: ArrayBuffer ): SharedDirectoryInfoRequest { let dv = new DataView(buffer); - let completionId = dv.getUint32(1); - let directoryId = dv.getUint32(5); - let path = this.decoder.decode(new Uint8Array(buffer.slice(13))); + let offset = 0; + offset += byteLength; // eat message type + let completionId = dv.getUint32(offset); + offset += uint32Length; // eat completion_id + let directoryId = dv.getUint32(offset); + offset += uint32Length; // eat directory_id + offset += uint32Length; // eat path_length + let path = this.decoder.decode(new Uint8Array(buffer.slice(offset))); return { completionId, From 1c2ec0ecfb58b735f510feda6e660b115297e6ba Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Mon, 18 Jul 2022 15:47:20 -0700 Subject: [PATCH 30/40] uses consts in decodeSharedDirectoryInfoRequest --- packages/teleport/src/lib/tdp/codec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index 44c6671de..ce35c4c3e 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -539,15 +539,15 @@ export default class Codec { decodeSharedDirectoryInfoRequest( buffer: ArrayBuffer ): SharedDirectoryInfoRequest { - let dv = new DataView(buffer); + const dv = new DataView(buffer); let offset = 0; offset += byteLength; // eat message type - let completionId = dv.getUint32(offset); + const completionId = dv.getUint32(offset); offset += uint32Length; // eat completion_id - let directoryId = dv.getUint32(offset); + const directoryId = dv.getUint32(offset); offset += uint32Length; // eat directory_id offset += uint32Length; // eat path_length - let path = this.decoder.decode(new Uint8Array(buffer.slice(offset))); + const path = this.decoder.decode(new Uint8Array(buffer.slice(offset))); return { completionId, From d86c2ee03d8b66217bc96728c06428eeb1bdec7d Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Mon, 18 Jul 2022 15:57:39 -0700 Subject: [PATCH 31/40] uses consts in decodePngFrame --- packages/teleport/src/lib/tdp/codec.ts | 31 ++++++++++++++++---------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index ce35c4c3e..b0604f48a 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -502,18 +502,25 @@ export default class Codec { // decodePngFrame decodes a raw tdp PNG frame message and returns it as a PngFrame // | message type (2) | left uint32 | top uint32 | right uint32 | bottom uint32 | data []byte | // https://github.com/gravitational/teleport/blob/master/rfd/0037-desktop-access-protocol.md#2---png-frame - decodePngFrame(buffer: ArrayBuffer, onload: (PngFrame) => any): PngFrame { - let dv = new DataView(buffer); + decodePngFrame( + buffer: ArrayBuffer, + onload: (pngFrame: PngFrame) => any + ): PngFrame { + const dv = new DataView(buffer); const image = new Image(); - const pngFrame = { - left: dv.getUint32(1), - top: dv.getUint32(5), - right: dv.getUint32(9), - bottom: dv.getUint32(13), - data: image, - }; + let offset = 0; + offset += byteLength; // eat message type + const left = dv.getUint32(offset); + offset += uint32Length; // eat left + const top = dv.getUint32(offset); + offset += uint32Length; // eat top + const right = dv.getUint32(offset); + offset += uint32Length; // eat right + const bottom = dv.getUint32(offset); + offset += uint32Length; // eat bottom + const pngFrame = { left, top, right, bottom, data: image }; pngFrame.data.onload = onload(pngFrame); - pngFrame.data.src = this.asBase64Url(buffer); + pngFrame.data.src = this.asBase64Url(buffer, offset); return pngFrame; } @@ -557,8 +564,8 @@ export default class Codec { } // asBase64Url creates a data:image uri from the png data part of a PNG_FRAME tdp message. - private asBase64Url(buffer: ArrayBuffer): string { - return `data:image/png;base64,${arrayBufferToBase64(buffer.slice(17))}`; + private asBase64Url(buffer: ArrayBuffer, offset: number): string { + return `data:image/png;base64,${arrayBufferToBase64(buffer.slice(offset))}`; } } From 85f87e5362dbbb562ace4556bc1795ea5e4fc3e9 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Mon, 18 Jul 2022 16:01:47 -0700 Subject: [PATCH 32/40] uses consts in decodeStringMessage --- packages/teleport/src/lib/tdp/codec.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index b0604f48a..09205fac8 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -459,7 +459,7 @@ export default class Codec { // decodeClipboardData decodes clipboard data decodeClipboardData(buffer: ArrayBuffer): ClipboardData { return { - data: this._decodeStringMessage(buffer), + data: this.decodeStringMessage(buffer), }; } @@ -477,7 +477,7 @@ export default class Codec { // decodeError decodes a raw tdp ERROR message and returns it as a string // | message type (9) | message_length uint32 | message []byte decodeErrorMessage(buffer: ArrayBuffer): string { - return this._decodeStringMessage(buffer); + return this.decodeStringMessage(buffer); } // decodeMfaChallenge decodes a raw tdp MFA challenge message and returns it as a string (of a json). @@ -492,11 +492,12 @@ export default class Codec { return { mfaType, jsonString }; } - // _decodeStringMessage decodes a tdp message of the form + // decodeStringMessage decodes a tdp message of the form // | message type (N) | message_length uint32 | message []byte - _decodeStringMessage(buffer: ArrayBuffer): string { + private decodeStringMessage(buffer: ArrayBuffer): string { // slice(5) ensures we skip the message type and message_length - return this.decoder.decode(new Uint8Array(buffer.slice(5))); + const offset = 0 + byteLength + uint32Length; // eat message type and message_length + return this.decoder.decode(new Uint8Array(buffer.slice(offset))); } // decodePngFrame decodes a raw tdp PNG frame message and returns it as a PngFrame From f09ec07001b9cc643060438b77d0ce586bcd869b Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Mon, 18 Jul 2022 16:09:48 -0700 Subject: [PATCH 33/40] uses consts in decodeMfaJson --- packages/teleport/src/lib/tdp/codec.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index 09205fac8..a777de5f1 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -484,11 +484,17 @@ export default class Codec { // | message type (10) | mfa_type byte | message_length uint32 | json []byte decodeMfaJson(buffer: ArrayBuffer): MfaJson { let dv = new DataView(buffer); - const mfaType = String.fromCharCode(dv.getUint8(1)); + let offset = 0; + offset += byteLength; // eat message type + const mfaType = String.fromCharCode(dv.getUint8(offset)); + offset += byteLength; // eat mfa_type if (mfaType !== 'n' && mfaType !== 'u') { throw new Error(`invalid mfa type ${mfaType}, should be "n" or "u"`); } - const jsonString = this.decoder.decode(new Uint8Array(buffer.slice(6))); + offset += uint32Length; // eat message_length + const jsonString = this.decoder.decode( + new Uint8Array(buffer.slice(offset)) + ); return { mfaType, jsonString }; } From 868f9d0099d8d7108d53559157a9aacb2d6365d5 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Mon, 18 Jul 2022 16:35:51 -0700 Subject: [PATCH 34/40] Adds __LAST to MessageType enum --- packages/teleport/src/lib/tdp/client.ts | 1 + packages/teleport/src/lib/tdp/codec.test.ts | 7 +------ packages/teleport/src/lib/tdp/codec.ts | 3 ++- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index 997177a9c..077ee6234 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -209,6 +209,7 @@ export default class Client extends EventEmitterWebAuthnSender { handleSharedDirectoryInfoRequest(buffer: ArrayBuffer) { const req = this.codec.decodeSharedDirectoryInfoRequest(buffer); + // TODO(isaiah): remove debug once message is handled. this.logger.debug( 'Received SharedDirectoryInfoRequest: ' + JSON.stringify(req) ); diff --git a/packages/teleport/src/lib/tdp/codec.test.ts b/packages/teleport/src/lib/tdp/codec.test.ts index 9635f2249..d0ac2ce56 100644 --- a/packages/teleport/src/lib/tdp/codec.test.ts +++ b/packages/teleport/src/lib/tdp/codec.test.ts @@ -104,12 +104,7 @@ test('decodes message types', () => { const { buffer: pngFrameBuf } = makeBuf(MessageType.PNG_FRAME); const { buffer: clipboardBuf } = makeBuf(MessageType.CLIPBOARD_DATA); const { buffer: errorBuf } = makeBuf(MessageType.ERROR); - let invalid = - Math.max( - ...(Object.values(MessageType).filter( - mt => !isNaN(Number(mt)) - ) as number[]) - ) + 1; + let invalid = MessageType.__LAST; const { buffer: invalidBuf } = makeBuf(invalid); expect(codec.decodeMessageType(pngFrameBuf)).toEqual(MessageType.PNG_FRAME); diff --git a/packages/teleport/src/lib/tdp/codec.ts b/packages/teleport/src/lib/tdp/codec.ts index a777de5f1..ccc1e848d 100644 --- a/packages/teleport/src/lib/tdp/codec.ts +++ b/packages/teleport/src/lib/tdp/codec.ts @@ -40,6 +40,7 @@ export enum MessageType { SHARED_DIRECTORY_ANNOUNCE = 11, SHARED_DIRECTORY_ACKNOWLEDGE = 12, SHARED_DIRECTORY_INFO_REQUEST = 13, + __LAST, // utility value } // 0 is left button, 1 is middle button, 2 is right button @@ -468,7 +469,7 @@ export default class Codec { // Throws an error on an invalid or unexpected MessageType value. decodeMessageType(buffer: ArrayBuffer): MessageType { const messageType = new DataView(buffer).getUint8(0); - if (!(messageType in MessageType)) { + if (!(messageType in MessageType) || messageType === MessageType.__LAST) { throw new Error(`invalid message type: ${messageType}`); } return messageType; From 634ad6a373d468f82e8fbff5c42098d8ac5f18f3 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Mon, 18 Jul 2022 17:38:46 -0700 Subject: [PATCH 35/40] reverting webapps.e change --- packages/webapps.e | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webapps.e b/packages/webapps.e index 406ec5075..8734fb5af 160000 --- a/packages/webapps.e +++ b/packages/webapps.e @@ -1 +1 @@ -Subproject commit 406ec5075f92ec78244febec18dd2d66b3bf63ec +Subproject commit 8734fb5af2c7c14e4a7f306e2e22f8092bf64be3 From e51e4e528a5010dfdb339c0a764387d0f839034f Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Mon, 18 Jul 2022 17:43:41 -0700 Subject: [PATCH 36/40] fixes broken merge --- .../src/DesktopSession/DesktopSession.tsx | 2 +- yarn.lock | 227 ++++++++++++++++-- 2 files changed, 208 insertions(+), 21 deletions(-) diff --git a/packages/teleport/src/DesktopSession/DesktopSession.tsx b/packages/teleport/src/DesktopSession/DesktopSession.tsx index 14bd4c747..dd268bd41 100644 --- a/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -147,7 +147,7 @@ function Session(props: PropsWithChildren) { .showDirectoryPicker() .then(sharedDirHandle => { setIsSharingDirectory(true); - tdpClient.sharedDirectory = sharedDirHandle; + tdpClient.addSharedDirectory(sharedDirHandle); tdpClient.sendSharedDirectoryAnnounce(); }) .catch(() => { diff --git a/yarn.lock b/yarn.lock index 47ef921e8..34c0a97dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3421,6 +3421,11 @@ abab@^2.0.3, abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -3482,13 +3487,22 @@ address@1.1.2, address@^1.0.1: resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== -agent-base@6: +agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" +agentkeepalive@^4.1.3: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" + integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA== + dependencies: + debug "^4.1.0" + depd "^1.1.2" + humanize-ms "^1.2.1" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -3714,6 +3728,14 @@ are-we-there-yet@^2.0.0: delegates "^1.0.0" readable-stream "^3.6.0" +are-we-there-yet@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz#ba20bd6b553e31d62fc8c31bd23d22b95734390d" + integrity sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -4547,7 +4569,7 @@ cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^15.0.5: +cacache@^15.0.5, cacache@^15.2.0: version "15.3.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== @@ -4926,7 +4948,7 @@ color-string@^1.6.0: color-name "^1.0.0" simple-swizzle "^0.2.2" -color-support@^1.1.2: +color-support@^1.1.2, color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== @@ -5526,6 +5548,13 @@ debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: dependencies: ms "2.1.2" +debug@^4.3.3: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + decimal.js@^10.2.1: version "10.3.1" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" @@ -5663,7 +5692,7 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -depd@~1.1.2: +depd@^1.1.2, depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== @@ -6121,6 +6150,13 @@ encodeurl@^1.0.2, encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +encoding@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -6185,6 +6221,11 @@ envinfo@^7.7.3: resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + errno@^0.1.3, errno@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" @@ -7210,6 +7251,20 @@ gauge@^3.0.0: strip-ansi "^3.0.1 || ^4.0.0" wide-align "^1.1.2" +gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -7827,7 +7882,7 @@ htmlparser2@^6.1.0: domutils "^2.5.2" entities "^2.0.0" -http-cache-semantics@^4.0.0: +http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== @@ -7930,6 +7985,13 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + iconv-corefoundation@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/iconv-corefoundation/-/iconv-corefoundation-1.1.6.tgz#27c135470237f6f8d13462fa1f5eaf250523c29a" @@ -8099,6 +8161,11 @@ ip@^1.1.0, ip@^1.1.5: resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -8332,6 +8399,11 @@ is-installed-globally@^0.4.0: global-dirs "^3.0.0" is-path-inside "^3.0.2" +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + is-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" @@ -9567,6 +9639,28 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: dependencies: semver "^6.0.0" +make-fetch-happen@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" + integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.2.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.2" + promise-retry "^2.0.1" + socks-proxy-agent "^6.0.0" + ssri "^8.0.0" + makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -9844,16 +9938,11 @@ minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.5: +minimist@^1.2.0, minimist@^1.2.5, minimist@~0.0.1: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw== - minipass-collect@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" @@ -9861,6 +9950,17 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" +minipass-fetch@^1.3.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" + integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + minipass-flush@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" @@ -9868,13 +9968,20 @@ minipass-flush@^1.0.5: dependencies: minipass "^3.0.0" -minipass-pipeline@^1.2.2: +minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== dependencies: minipass "^3.0.0" +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + minipass@^3.0.0, minipass@^3.1.1: version "3.1.5" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.5.tgz#71f6251b0a33a49c01b3cf97ff77eda030dff732" @@ -9882,7 +9989,14 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" -minizlib@^2.1.1: +minipass@^3.1.0, minipass@^3.1.3: + version "3.3.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.4.tgz#ca99f95dd77c43c7a76bf51e6d200025eee0ffae" + integrity sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw== + dependencies: + yallist "^4.0.0" + +minizlib@^2.0.0, minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -9960,7 +10074,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1: +ms@^2.0.0, ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -10015,6 +10129,11 @@ negotiator@0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +negotiator@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" @@ -10062,6 +10181,22 @@ node-forge@^0.10.0: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== +node-gyp@8.4.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" + integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^9.1.0" + nopt "^5.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -10118,6 +10253,13 @@ node-releases@^2.0.1: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -10175,6 +10317,16 @@ npmlog@^5.0.1: gauge "^3.0.0" set-blocking "^2.0.0" +npmlog@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" + nth-check@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" @@ -11051,6 +11203,14 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + promise.allsettled@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.5.tgz#2443f3d4b2aa8dfa560f6ac2aa6c4ea999d75f53" @@ -11938,6 +12098,11 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + retry@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" @@ -12334,6 +12499,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== +signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -12372,7 +12542,7 @@ slice-ansi@^1.0.0: dependencies: is-fullwidth-code-point "^2.0.0" -smart-buffer@^4.0.2: +smart-buffer@^4.0.2, smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== @@ -12416,6 +12586,23 @@ sockjs@^0.3.21: uuid "^3.4.0" websocket-driver "^0.7.4" +socks-proxy-agent@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz#2687a31f9d7185e38d530bef1944fe1f1496d6ce" + integrity sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks@^2.6.2: + version "2.7.0" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.0.tgz#f9225acdb841e874dca25f870e9130990f3913d0" + integrity sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -12556,7 +12743,7 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" -ssri@^8.0.1: +ssri@^8.0.0, ssri@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== @@ -12661,7 +12848,7 @@ string-length@^4.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12930,7 +13117,7 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar@^6.0.2: +tar@^6.0.2, tar@^6.1.2: version "6.1.11" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== @@ -14076,14 +14263,14 @@ which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" -which@^2.0.1: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@^1.1.2: +wide-align@^1.1.2, wide-align@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== From aea304305287f8e8213491027253cf018ccd7713 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Tue, 19 Jul 2022 09:29:37 -0700 Subject: [PATCH 37/40] creates getInfo for more efficient traversal --- packages/teleport/src/lib/tdp/client.ts | 75 ++++++++++++------- .../src/lib/tdp/sharedDirectoryManager.ts | 47 ++++++------ 2 files changed, 73 insertions(+), 49 deletions(-) diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index f20a24001..0a82abd6d 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -23,10 +23,14 @@ import Codec, { ClientScreenSpec, PngFrame, ClipboardData, + FileType, SharedDirectoryErrCode, SharedDirectoryInfoResponse, } from './codec'; -import { SharedDirectoryManager } from './sharedDirectoryManager'; +import { + PathDoesNotExistError, + SharedDirectoryManager, +} from './sharedDirectoryManager'; export enum TdpClientEvent { TDP_CLIENT_SCREEN_SPEC = 'tdp client screen spec', @@ -212,18 +216,34 @@ export default class Client extends EventEmitterWebAuthnSender { async handleSharedDirectoryInfoRequest(buffer: ArrayBuffer) { const req = this.codec.decodeSharedDirectoryInfoRequest(buffer); - this.logger.debug( - 'Received SharedDirectoryInfoRequest: ' + JSON.stringify(req) - ); try { - const size = await this.sdManager.getSize(req.path); - console.log('size = ' + size); - const lastModified = await this.sdManager.getLastModified(req.path); - console.log('lastModified = ' + lastModified); + // TODO(isaiah): try different paths here + let info = await this.sdManager.getInfo(req.path); + this.sendSharedDirectoryInfoResponse({ + completionId: req.completionId, + errCode: SharedDirectoryErrCode.Nil, + fso: { + lastModified: BigInt(info.lastModified), + fileType: info.kind === 'file' ? FileType.File : FileType.Directory, + size: BigInt(info.size), + path: req.path, + }, + }); } catch (e) { - // TODO(isaiah) I think sometimes we want to just pass this back, - // since windows defaults to look for certain files like desktop.ini - this.handleError(e); + if (e.constructor === PathDoesNotExistError) { + this.sendSharedDirectoryInfoResponse({ + completionId: req.completionId, + errCode: SharedDirectoryErrCode.DoesNotExist, + fso: { + lastModified: BigInt(0), + fileType: FileType.File, + size: BigInt(0), + path: req.path, + }, + }); + } else { + this.handleError(e); + } } // TODO(isaiah): here's where we'll respond with SharedDirectoryInfoResponse @@ -233,7 +253,11 @@ export default class Client extends EventEmitterWebAuthnSender { data: string | ArrayBufferLike | Blob | ArrayBufferView ): void { if (this.socket && this.socket.readyState === 1) { - this.socket.send(data); + try { + this.socket.send(data); + } catch (e) { + this.handleError(e); + } return; } @@ -283,19 +307,20 @@ export default class Client extends EventEmitterWebAuthnSender { } sendSharedDirectoryAnnounce() { - try { - this.socket.send( - this.codec.encodeSharedDirectoryAnnounce({ - completionId: 0, // This is always the first request. - // Hardcode directoryId for now since we only support sharing 1 directory. - // We're using 2 because the smartcard device is hardcoded to 1 in the backend. - directoryId: 2, - name: this.sdManager.getName(), - }) - ); - } catch (err) { - this.handleError(err); - } + this.send( + this.codec.encodeSharedDirectoryAnnounce({ + completionId: 0, // This is always the first request. + // Hardcode directoryId for now since we only support sharing 1 directory. + // We're using 2 because the smartcard device is hardcoded to 1 in the backend. + directoryId: 2, + name: this.sdManager.getName(), + }) + ); + } + + sendSharedDirectoryInfoResponse(res: SharedDirectoryInfoResponse) { + this.logger.debug(res); //TODO(isaiah): remove + this.send(this.codec.encodeSharedDirectoryInfoResponse(res)); } resize(spec: ClientScreenSpec) { diff --git a/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts b/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts index cfe607dc3..174545619 100644 --- a/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts +++ b/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts @@ -32,37 +32,30 @@ export class SharedDirectoryManager { return this.dir.name; } - // gets the size of item at path, where - // path is the relative path from the root - // directory. Size returned is in bytes. - async getSize(path: string): Promise { + // Gets the information for the file or directory + // at path where path is the relative path from the + // root directory. + async getInfo(path: string): Promise<{ + size: number; // bytes + lastModified: number; // ms since unix epoch + kind: 'file' | 'directory'; + }> { this.checkReady(); const fileOrDir = await this.walkPath(path); if (fileOrDir.kind === 'directory') { - // Magic value for directories per the TDP spec. - return 4096; + // Magic numbers are the values for directories where the true + // value is unavailable, according to the TDP spec. + return { size: 4096, lastModified: 0, kind: fileOrDir.kind }; } - let file = await fileOrDir.getFile(); - return file.size; - } - - // gets the last modified date at path, where - // path is the relative path from the root directory. - // The number returned is the last modified date in - // milliseconds since the unix epoch. - async getLastModified(path: string): Promise { - this.checkReady(); - - const fileOrDir = await this.walkPath(path); - if (fileOrDir.kind === 'directory') { - // Magic value for directories per the TDP spec. - return 0; - } let file = await fileOrDir.getFile(); - return file.lastModified; + return { + size: file.size, + lastModified: file.lastModified, + kind: fileOrDir.kind, + }; } // walkPath walks a pathstr (assumed to be in the qualified Unix format specified @@ -104,7 +97,7 @@ export class SharedDirectoryManager { } } - throw new Error('Invalid path'); + throw new PathDoesNotExistError('path does not exist'); }; return walkIt(this.dir, path); @@ -118,3 +111,9 @@ export class SharedDirectoryManager { } } } + +export class PathDoesNotExistError extends Error { + constructor(message: string) { + super(message); + } +} From 9b1e905ecd4b98f6206db9b7929bcbf36b330f32 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Tue, 19 Jul 2022 14:01:24 -0700 Subject: [PATCH 38/40] manually tested, cleaning up --- packages/teleport/src/lib/tdp/client.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index 0a82abd6d..9ff2d37dc 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -216,9 +216,9 @@ export default class Client extends EventEmitterWebAuthnSender { async handleSharedDirectoryInfoRequest(buffer: ArrayBuffer) { const req = this.codec.decodeSharedDirectoryInfoRequest(buffer); + const path = req.path; try { - // TODO(isaiah): try different paths here - let info = await this.sdManager.getInfo(req.path); + const info = await this.sdManager.getInfo(path); this.sendSharedDirectoryInfoResponse({ completionId: req.completionId, errCode: SharedDirectoryErrCode.Nil, @@ -226,7 +226,7 @@ export default class Client extends EventEmitterWebAuthnSender { lastModified: BigInt(info.lastModified), fileType: info.kind === 'file' ? FileType.File : FileType.Directory, size: BigInt(info.size), - path: req.path, + path: path, }, }); } catch (e) { @@ -238,15 +238,13 @@ export default class Client extends EventEmitterWebAuthnSender { lastModified: BigInt(0), fileType: FileType.File, size: BigInt(0), - path: req.path, + path: path, }, }); } else { this.handleError(e); } } - - // TODO(isaiah): here's where we'll respond with SharedDirectoryInfoResponse } protected send( @@ -319,7 +317,6 @@ export default class Client extends EventEmitterWebAuthnSender { } sendSharedDirectoryInfoResponse(res: SharedDirectoryInfoResponse) { - this.logger.debug(res); //TODO(isaiah): remove this.send(this.codec.encodeSharedDirectoryInfoResponse(res)); } From 9a732a570ec61866016775a15fb5ddecabd5d2f6 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Tue, 19 Jul 2022 15:44:56 -0700 Subject: [PATCH 39/40] removing duplicate function definition --- packages/teleport/src/lib/tdp/client.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/teleport/src/lib/tdp/client.ts b/packages/teleport/src/lib/tdp/client.ts index 9cb26aa44..9ff2d37dc 100644 --- a/packages/teleport/src/lib/tdp/client.ts +++ b/packages/teleport/src/lib/tdp/client.ts @@ -247,15 +247,6 @@ export default class Client extends EventEmitterWebAuthnSender { } } - handleSharedDirectoryInfoRequest(buffer: ArrayBuffer) { - const req = this.codec.decodeSharedDirectoryInfoRequest(buffer); - // TODO(isaiah): remove debug once message is handled. - this.logger.debug( - 'Received SharedDirectoryInfoRequest: ' + JSON.stringify(req) - ); - // TODO(isaiah): here's where we'll respond with SharedDirectoryInfoResponse - } - protected send( data: string | ArrayBufferLike | Blob | ArrayBufferView ): void { From 97cc3c0f9cd960a12aadb61bfaf91f796ce7dd35 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Wed, 27 Jul 2022 18:06:33 -0400 Subject: [PATCH 40/40] Update packages/teleport/src/lib/tdp/sharedDirectoryManager.ts Co-authored-by: Lisa Kim --- packages/teleport/src/lib/tdp/sharedDirectoryManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts b/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts index 174545619..96eda0432 100644 --- a/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts +++ b/packages/teleport/src/lib/tdp/sharedDirectoryManager.ts @@ -13,7 +13,7 @@ // limitations under the License. // SharedDirectoryManager manages a FileSystemDirectoryHandle for use -// by the TDP client. Most of it's methods can potentially throw errors +// by the TDP client. Most of its methods can potentially throw errors // and so should be wrapped in try/catch blocks. export class SharedDirectoryManager { private dir: FileSystemDirectoryHandle | undefined;