Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions web-client/iron-remote-desktop-rdp/src/interfaces/Extension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
type ExtensionValue = { Pcb: string } | { KdcProxyUrl: string } | { DisplayControl: boolean };

export class Extension {
static init(ident: string, value: unknown): ExtensionValue {
switch (ident) {
case 'Pcb':
if (typeof value === 'string') {
return { Pcb: value };
} else {
throw new Error('Pcb must be a string');
}
case 'KdcProxyUrl':
if (typeof value === 'string') {
return { KdcProxyUrl: value };
} else {
throw new Error('KdcProxyUrl must be a string');
}
case 'DisplayControl':
if (typeof value === 'boolean') {
return { DisplayControl: value };
} else {
throw new Error('DisplayControl must be a boolean');
}
default:
throw new Error(`Invalid extension type: ${ident}`);
}
}
}
2 changes: 2 additions & 0 deletions web-client/iron-remote-desktop-rdp/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import init, {
ClipboardTransaction,
ClipboardContent,
} from '../../../crates/ironrdp-web/pkg/ironrdp_web';
import { Extension } from './interfaces/Extension';

export default {
init,
Expand All @@ -23,4 +24,5 @@ export default {
ClipboardContent,
Session,
SessionTerminationInfo,
Extension,
};
5 changes: 5 additions & 0 deletions web-client/iron-remote-desktop/src/interfaces/Extension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { ExtensionValue } from './ExtensionValue';

export interface Extension {
init(ident: string, value: unknown): ExtensionValue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type ExtensionValue = unknown;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { SessionBuilder } from './SessionBuilder';
import type { SessionTerminationInfo } from './SessionTerminationInfo';
import type { ClipboardTransaction } from './ClipboardTransaction';
import type { ClipboardContent } from './ClipboardContent';
import type { Extension } from './Extension';

export interface RemoteDesktopModule {
init: () => Promise<unknown>;
Expand All @@ -20,4 +21,5 @@ export interface RemoteDesktopModule {
SessionTerminationInfo: SessionTerminationInfo;
ClipboardTransaction: ClipboardTransaction;
ClipboardContent: ClipboardContent;
Extension: Extension;
}
18 changes: 5 additions & 13 deletions web-client/iron-remote-desktop/src/interfaces/UserInteraction.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
import type { ScreenScale } from '../enums/ScreenScale';
import type { NewSessionInfo } from './NewSessionInfo';
import type { SessionEvent } from './session-event';
import type { DesktopSize } from './DesktopSize';
import { ConfigBuilder } from '../services/ConfigBuilder';
import type { Config } from '../services/Config';

export interface UserInteraction {
setVisibility(state: boolean): void;

setScale(scale: ScreenScale): void;

connect(
username: string,
password: string,
destination: string,
proxyAddress: string,
serverDomain: string,
authToken: string,
desktopSize?: DesktopSize,
preConnectionBlob?: string,
kdc_proxy_url?: string,
use_display_control?: boolean,
): Promise<NewSessionInfo>;
configBuilder(): ConfigBuilder;

connect(config: Config): Promise<NewSessionInfo>;

setKeyboardUnicodeMode(use_unicode: boolean): void;

Expand Down
33 changes: 33 additions & 0 deletions web-client/iron-remote-desktop/src/services/Config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { DesktopSize } from '../interfaces/DesktopSize';
import type { ExtensionValue } from '../interfaces/ExtensionValue';

export class Config {
readonly username: string;
readonly password: string;
readonly destination: string;
readonly proxyAddress: string;
readonly serverDomain: string;
readonly authToken: string;
readonly desktopSize?: DesktopSize;
readonly extensions: ExtensionValue[];

constructor(
userData: { username: string; password: string },
proxyData: { address: string; authToken: string },
configOptions: {
destination: string;
serverDomain: string;
extensions: ExtensionValue[];
desktopSize?: DesktopSize;
},
) {
this.username = userData.username;
this.password = userData.password;
this.proxyAddress = proxyData.address;
this.authToken = proxyData.authToken;
this.destination = configOptions.destination;
this.serverDomain = configOptions.serverDomain;
this.extensions = configOptions.extensions;
this.desktopSize = configOptions.desktopSize;
}
}
160 changes: 160 additions & 0 deletions web-client/iron-remote-desktop/src/services/ConfigBuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import type { DesktopSize } from '../interfaces/DesktopSize';
import { Config } from './Config';
import type { ExtensionValue } from '../interfaces/ExtensionValue';

type ExtensionConstructor = (ident: string, value: unknown) => ExtensionValue;

/**
* Builder class for creating Config objects with a fluent interface.
*
* @example
* ```typescript
* const configBuilder = new ConfigBuilder(createExtensionFunction);
* const config = configBuilder
* .withDestination(destination)
* .withProxyAddress(proxyAddress)
* .withAuthToken(authToken)
* ...
* .build();
* ```
*/
export class ConfigBuilder {
private extensionConstructor: ExtensionConstructor;

private username: string = '';
private password: string = '';
private destination: string = '';
private proxyAddress: string = '';
private serverDomain: string = '';
private authToken: string = '';
private desktopSize?: DesktopSize;

private extensions: ExtensionValue[] = [];

/**
* Creates a new ConfigBuilder instance.
*
* @param extensionConstructor - Function that creates extension values from identifiers and values.
*/
constructor(extensionConstructor: ExtensionConstructor) {
this.extensionConstructor = extensionConstructor;
}

/**
* Optional parameter
*
* @param username - The username to use for authentication
* @returns The builder instance for method chaining
*/
withUsername(username: string): ConfigBuilder {
this.username = username;
return this;
}

/**
* Optional parameter
*
* @param password - The password for authentication
* @returns The builder instance for method chaining
*/
withPassword(password: string): ConfigBuilder {
this.password = password;
return this;
}

/**
* Required parameter
*
* @param destination - The destination address to connect to
* @returns The builder instance for method chaining
*/
withDestination(destination: string): ConfigBuilder {
this.destination = destination;
return this;
}

/**
* Required parameter
*
* @param proxyAddress - The address of the proxy server
* @returns The builder instance for method chaining
*/
withProxyAddress(proxyAddress: string): ConfigBuilder {
this.proxyAddress = proxyAddress;
return this;
}

/**
* Optional parameter
*
* @param serverDomain - The server domain to connect to
* @returns The builder instance for method chaining
*/
withServerDomain(serverDomain: string): ConfigBuilder {
this.serverDomain = serverDomain;
return this;
}

/**
* Required parameter
*
* @param authToken - JWT token to connect to the proxy
* @returns The builder instance for method chaining
*/
withAuthToken(authToken: string): ConfigBuilder {
this.authToken = authToken;
return this;
}

/**
* Optional parameter
*
* @param ident - The identifier for the extension
* @param value - The value for the extension
* @returns The builder instance for method chaining
*/
withExtension(ident: string, value: unknown): ConfigBuilder {
this.extensions.push(this.extensionConstructor(ident, value));
return this;
}

/**
* Optional
*
* @param desktopSize - The desktop size configuration object
* @returns The builder instance for method chaining
*/
withDesktopSize(desktopSize: DesktopSize): ConfigBuilder {
this.desktopSize = desktopSize;
return this;
}

/**
* Builds a new Config instance.
*
* @throws {Error} If required parameters (destination, proxyAddress, authToken) are not set
* @returns A new Config instance with the configured values
*/
build(): Config {
if (this.destination === '') {
throw new Error('destination has to be specified');
}
if (this.proxyAddress === '') {
throw new Error('proxy address has to be specified');
}
if (this.authToken === '') {
throw new Error('authentication token has to be specified');
}
const userData = { username: this.username, password: this.password };
const proxyData = { address: this.proxyAddress, authToken: this.authToken };

const configOptions = {
destination: this.destination,
serverDomain: this.serverDomain,
extensions: this.extensions,
desktopSize: this.desktopSize,
};

return new Config(userData, proxyData, configOptions);
}
}
34 changes: 9 additions & 25 deletions web-client/iron-remote-desktop/src/services/PublicAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { SpecialCombination } from '../enums/SpecialCombination';
import { RemoteDesktopService } from './remote-desktop.service';
import type { UserInteraction } from '../interfaces/UserInteraction';
import type { ScreenScale } from '../enums/ScreenScale';
import type { DesktopSize } from '../interfaces/DesktopSize';
import { ConfigBuilder } from './ConfigBuilder';
import { Config } from './Config';

export class PublicAPI {
private remoteDesktopService: RemoteDesktopService;
Expand All @@ -13,31 +14,13 @@ export class PublicAPI {
this.remoteDesktopService = remoteDesktopService;
}

private connect(
username: string,
password: string,
destination: string,
proxyAddress: string,
serverDomain: string,
authToken: string,
desktopSize?: DesktopSize,
preConnectionBlob?: string,
kdc_proxy_url?: string,
use_display_control = false,
): Promise<NewSessionInfo> {
private configBuilder(): ConfigBuilder {
return this.remoteDesktopService.configBuilder();
}

private connect(config: Config): Promise<NewSessionInfo> {
loggingService.info('Initializing connection.');
const resultObservable = this.remoteDesktopService.connect(
username,
password,
destination,
proxyAddress,
serverDomain,
authToken,
desktopSize,
preConnectionBlob,
kdc_proxy_url,
use_display_control,
);
const resultObservable = this.remoteDesktopService.connect(config);

return resultObservable.toPromise();
}
Expand Down Expand Up @@ -82,6 +65,7 @@ export class PublicAPI {
getExposedFunctions(): UserInteraction {
return {
setVisibility: this.setVisibility.bind(this),
configBuilder: this.configBuilder.bind(this),
connect: this.connect.bind(this),
setScale: this.setScale.bind(this),
onSessionEvent: (callback) => {
Expand Down
Loading
Loading