Skip to content
This repository has been archived by the owner on Apr 4, 2023. It is now read-only.

Use a dedicated server as webview domain #591

Merged
merged 5 commits into from
Feb 5, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { CheApiService } from '../common/che-protocol';
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
import { WebviewEnvironment } from '@theia/plugin-ext/lib/main/browser/webview/webview-environment';
import { WebviewExternalEndpoint } from '@theia/plugin-ext/lib/main/common/webview-protocol';
import { getUrlDomain, SERVER_TYPE_ATTR, SERVER_IDE_ATTR_VALUE } from '../common/che-server-common';
import { getUrlDomain, SERVER_TYPE_ATTR, SERVER_WEBVIEWS_ATTR_VALUE } from '../common/che-server-common';

@injectable()
export class CheWebviewEnvironment extends WebviewEnvironment {
Expand All @@ -27,13 +27,13 @@ export class CheWebviewEnvironment extends WebviewEnvironment {
@postConstruct()
protected async init(): Promise<void> {
try {
const variable = await this.environments.getValue(WebviewExternalEndpoint.pattern);
const ideServer = await this.cheApi.findUniqueServerByAttribute(SERVER_TYPE_ATTR, SERVER_IDE_ATTR_VALUE);
let domain;
if (ideServer && ideServer.url) {
domain = getUrlDomain(ideServer.url);
const webviewExternalEndpointPattern = await this.environments.getValue(WebviewExternalEndpoint.pattern);
const webviewServer = await this.cheApi.findUniqueServerByAttribute(SERVER_TYPE_ATTR, SERVER_WEBVIEWS_ATTR_VALUE);
let webviewDomain: string | undefined;
if (webviewServer && webviewServer.url) {
webviewDomain = getUrlDomain(webviewServer.url);
}
const hostName = variable && variable.value || domain || WebviewExternalEndpoint.pattern;
const hostName = webviewExternalEndpointPattern && webviewExternalEndpointPattern.value || webviewDomain || WebviewExternalEndpoint.pattern;
this.externalEndpointHost.resolve(hostName.replace('{{hostname}}', window.location.host || 'localhost'));
} catch (e) {
this.externalEndpointHost.reject(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export function getUrlDomain(routeUrl: string): string {

export const SERVER_TYPE_ATTR = 'type';
export const SERVER_IDE_ATTR_VALUE = 'ide';
export const SERVER_WEBVIEWS_ATTR_VALUE = 'webview';
export const SERVER_IDE_DEV_ATTR_VALUE = 'ide-dev';
35 changes: 20 additions & 15 deletions extensions/eclipse-che-theia-plugin-ext/src/node/plugin-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import { injectable, inject } from 'inversify';
import { WebviewExternalEndpoint } from '@theia/plugin-ext/lib/main/common/webview-protocol';
import { PluginApiContribution } from '@theia/plugin-ext/lib/main/node/plugin-service';
import { CheApiService } from '../common/che-protocol';
import { getUrlDomain, SERVER_TYPE_ATTR, SERVER_IDE_ATTR_VALUE } from '../common/che-server-common';
import { getUrlDomain, SERVER_TYPE_ATTR, SERVER_WEBVIEWS_ATTR_VALUE } from '../common/che-server-common';
import { Deferred } from '@theia/core/lib/common/promise-util';
import { ILogger } from '@theia/core/lib/common/logger';

const pluginPath = (process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE) + './theia/plugins/';

Expand All @@ -34,6 +35,9 @@ export class PluginApiContributionIntercepted extends PluginApiContribution {
@inject(CheApiService)
private cheApi: CheApiService;

@inject(ILogger)
protected readonly logger: ILogger;

private waitWebviewEndpoint = new Deferred<void>();

configure(app: express.Application): void {
Expand All @@ -46,22 +50,23 @@ export class PluginApiContributionIntercepted extends PluginApiContribution {
const pluginExtModulePath = path.dirname(require.resolve('@theia/plugin-ext/package.json'));
const webviewStaticResources = path.join(pluginExtModulePath, 'src/main/browser/webview/pre');

this.cheApi.findUniqueServerByAttribute(SERVER_TYPE_ATTR, SERVER_IDE_ATTR_VALUE).then(server => {
let domain;
if (server.url) {
domain = getUrlDomain(server.url);
}
const hostName = this.handleAliases(process.env[WebviewExternalEndpoint.pattern] || domain || WebviewExternalEndpoint.pattern);
webviewApp.use('/webview', serveStatic(webviewStaticResources));
this.cheApi.findUniqueServerByAttribute(SERVER_TYPE_ATTR, SERVER_WEBVIEWS_ATTR_VALUE).then(server => {
let domain;
if (server.url) {
domain = getUrlDomain(server.url);
}
const hostName = this.handleAliases(process.env[WebviewExternalEndpoint.pattern] || domain || WebviewExternalEndpoint.pattern);
webviewApp.use('/webview', serveStatic(webviewStaticResources));

console.log(`Configuring to accept webviews on '${hostName}' hostname.`);
app.use(vhost(new RegExp(hostName, 'i'), webviewApp));
this.logger.info(`Configuring to accept webviews on '${hostName}' hostname.`);
app.use(vhost(new RegExp(hostName, 'i'), webviewApp));

this.waitWebviewEndpoint.resolve();
}).catch(err => {
console.log('Unable to configure webview domain: ', err);
this.waitWebviewEndpoint.resolve();
});
this.waitWebviewEndpoint.resolve();
})
.catch(err => {
this.logger.error('Security problem: Unable to configure separate webviews domain: ', err);
this.waitWebviewEndpoint.resolve();
});
}

async onStart(): Promise<void> {
Expand Down