mirror of
https://github.com/gravitational/teleport.git
synced 2026-11-04 02:21:02 +08:00
* adding desktopPOC player * updates to proper playback test websocket endpoint * Changes EventQuery to take an EventCode in order to facilitate more comprehensible typing for AuditService.fetchEvents. Updates RecordingsService to use the general events search endpoint in order to easily add DESKTOP_SESSION_ENDED events to the response alongside regular [ssh] SESSION_END events. * Adds logic for distinguishing between session types and displaying appropriate icon * Deleting DesktopPlayerPOC which should not have been on this branch * Breaks the handling of the two types of end events passed into makeRecording into two separate functions. Also types RecordingDescription * touchups * yarn tsc fixes * updates storybook * updating snapshot * removing unused import * adds skeleton for distinguishing between ssh and desktop recordings * Testing connection of the playerClient * Puts TdpClientCanvas into the DesktopPlayer * adds toggle to PlayerClient * small fixes * adds an onerror to proxyServer so that websocket closures don't shut down the webpack-dev-server * updates to match backend * shifting preventDefaults out of TdpClientCanvas since that isn't always desired (for example with the desktop player) * Adds a ProgressBarDesktop component and makes it respond to the new PlayerClientEvent.TOGGLE_PLAY_PAUSE event emitted by the PlayerClient * Adds support for decoding client screen spec and using it to determine canvas size during playback. requires some code cleanup * Some significant refactoring, DesktopSession and DesktopPlayer now both up to par in terms of function. Requires further refactoring for storybook. * fixes storybook * fixes codec test * fixing build warnings * reverts audit log changes * removes unused type Region * decodes the jsons that are now sent over websocket * replace fqdm with fqdn * Stops re-adding TOGGLE_PLAY_PAUSE listener each rerender and adds cleanup for that listener * Make naming more precise * removing unnecessary logging and fixing a type * adding todo * makes recordingType the more appropriate query param * change let to const * tiny fixes * reverting * The progress bar now moves with the recording timing * Makes the rest of TdpClientCanvas props optional and wraps relevant logic in relevant if statements where necessary. Gets rid of ugly doNothing * fixes event listener cleanup * removes unnecessary prop * Adds standard error handling display and a storybook for it * moving detailed TODO to an issue * changing toHuman to remove brittle reliance on iso string * removes base64-arraybuffer, refactors base64url.ts into the more general base64.ts and uses it for base64 to array buffer translation * fixes Storybook * fixes validDurationMs * Copies in base64url-arraybuffer library and modifies it for our purposes * putting import statements in their proper place * Moves Base64urlString type to where its needed * removes DS_Store * addresses code review * simplifies and fixes durationMs logic * final touches
115 lines
4.1 KiB
TypeScript
115 lines
4.1 KiB
TypeScript
// Modified from https://github.com/niklasvh/base64-arraybuffer/
|
|
|
|
// Copyright (c) 2012 Niklas von Hertzen
|
|
|
|
// Permission is hereby granted, free of charge, to any person
|
|
// obtaining a copy of this software and associated documentation
|
|
// files (the "Software"), to deal in the Software without
|
|
// restriction, including without limitation the rights to use,
|
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the
|
|
// Software is furnished to do so, subject to the following
|
|
// conditions:
|
|
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
// OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
import { arrayBufferToBase64, base64ToArrayBuffer } from './base64-arraybuffer';
|
|
|
|
function stringArrayBuffer(str: string) {
|
|
const buffer = new ArrayBuffer(str.length);
|
|
const bytes = new Uint8Array(buffer);
|
|
|
|
str.split('').forEach(function (str, i) {
|
|
bytes[i] = str.charCodeAt(0);
|
|
});
|
|
|
|
return buffer;
|
|
}
|
|
|
|
function testArrayBuffers(buffer1: ArrayBuffer, buffer2: ArrayBuffer) {
|
|
const len1 = buffer1.byteLength;
|
|
const len2 = buffer2.byteLength;
|
|
const view1 = new Uint8Array(buffer1);
|
|
const view2 = new Uint8Array(buffer2);
|
|
|
|
if (len1 !== len2) {
|
|
return false;
|
|
}
|
|
|
|
for (let i = 0; i < len1; i++) {
|
|
if (view1[i] === undefined || view1[i] !== view2[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function rangeArrayBuffer() {
|
|
const buffer = new ArrayBuffer(256);
|
|
const bytes = new Uint8Array(buffer);
|
|
for (let i = 0; i < 256; i++) {
|
|
bytes[i] = i;
|
|
}
|
|
|
|
return buffer;
|
|
}
|
|
|
|
describe('encode', () => {
|
|
it('encode "Hello world"', () =>
|
|
expect(arrayBufferToBase64(stringArrayBuffer('Hello world'))).toBe(
|
|
'SGVsbG8gd29ybGQ='
|
|
));
|
|
it('encode "Man"', () =>
|
|
expect(arrayBufferToBase64(stringArrayBuffer('Man'))).toBe('TWFu'));
|
|
it('encode "Ma"', () =>
|
|
expect(arrayBufferToBase64(stringArrayBuffer('Ma'))).toBe('TWE='));
|
|
it('encode "Hello worlds!"', () =>
|
|
expect(arrayBufferToBase64(stringArrayBuffer('Hello worlds!'))).toBe(
|
|
'SGVsbG8gd29ybGRzIQ=='
|
|
));
|
|
it('encode all binary characters', () =>
|
|
expect(arrayBufferToBase64(rangeArrayBuffer())).toBe(
|
|
'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=='
|
|
));
|
|
});
|
|
|
|
describe('decode', () => {
|
|
it('decode "Man"', () =>
|
|
expect(
|
|
testArrayBuffers(base64ToArrayBuffer('TWFu'), stringArrayBuffer('Man'))
|
|
).toBeTruthy());
|
|
it('decode "Hello world"', () =>
|
|
expect(
|
|
testArrayBuffers(
|
|
base64ToArrayBuffer('SGVsbG8gd29ybGQ='),
|
|
stringArrayBuffer('Hello world')
|
|
)
|
|
).toBeTruthy());
|
|
it('decode "Hello worlds!"', () =>
|
|
expect(
|
|
testArrayBuffers(
|
|
base64ToArrayBuffer('SGVsbG8gd29ybGRzIQ=='),
|
|
stringArrayBuffer('Hello worlds!')
|
|
)
|
|
).toBeTruthy());
|
|
it('decode all binary characters', () =>
|
|
expect(
|
|
testArrayBuffers(
|
|
base64ToArrayBuffer(
|
|
'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=='
|
|
),
|
|
rangeArrayBuffer()
|
|
)
|
|
).toBeTruthy());
|
|
});
|