From 79ad53ef9d4c3f481f14df87bf778a6f57854113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Mar=C3=A9chal?= Date: Thu, 19 Apr 2018 08:41:50 -0400 Subject: [PATCH] [workspace] Better localstorage keys #904 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because Theia is both meant to roll on a local machine and in the cloud, this commit adds better browser localstorage keys, so that Theia gets less confused as to what is being displayed in case that some URI points to different remotes (reverse proxying the same URL -at different times- to different theia instances). This ensures that despite sharing the same local storage domain (host:port), multiple theias can be differentiated by passing a `--domain` argument. This means that we can identify different theias behind proxies, as long as the instances are run with a different `--domain `. When this domain is not specified, then theia will use `window.location.pathname`. Signed-off-by: Paul Maréchal --- .../src/browser/workspace-service.ts | 4 +++ .../src/browser/workspace-storage-service.ts | 28 ++++++++++------- .../src/common/test/mock-workspace-server.ts | 2 ++ .../src/common/workspace-protocol.ts | 5 ++++ .../src/node/default-workspace-server.ts | 30 ++++++++++++------- 5 files changed, 48 insertions(+), 21 deletions(-) diff --git a/packages/workspace/src/browser/workspace-service.ts b/packages/workspace/src/browser/workspace-service.ts index 430e849e6b955..95eb00eeda0fe 100644 --- a/packages/workspace/src/browser/workspace-service.ts +++ b/packages/workspace/src/browser/workspace-service.ts @@ -54,6 +54,10 @@ export class WorkspaceService implements FrontendApplicationContribution { this.deferredRoot.resolve(this._root); } + async getDomain(): Promise { + return this.server.getDomain(); + } + protected updateTitle(uri: URI): void { document.title = uri.displayName; } diff --git a/packages/workspace/src/browser/workspace-storage-service.ts b/packages/workspace/src/browser/workspace-storage-service.ts index d02a288fce2a6..1d606f824d324 100644 --- a/packages/workspace/src/browser/workspace-storage-service.ts +++ b/packages/workspace/src/browser/workspace-storage-service.ts @@ -7,9 +7,10 @@ import { StorageService } from '@theia/core/lib/browser/storage-service'; import { WorkspaceService } from './workspace-service'; -import { inject, injectable } from 'inversify'; +import { inject, injectable, postConstruct } from 'inversify'; import { ILogger } from '@theia/core/lib/common'; import { LocalStorageService } from '@theia/core/lib/browser/storage-service'; +import URI from '@theia/core/lib/common/uri'; /* * Prefixes any stored data with the current workspace path. @@ -21,18 +22,25 @@ export class WorkspaceStorageService implements StorageService { private initialized: Promise; protected storageService: StorageService; - constructor( @inject(WorkspaceService) protected workspaceService: WorkspaceService, - @inject(ILogger) protected logger: ILogger) { - this.initialized = this.workspaceService.root.then(stat => { - if (stat) { - this.prefix = stat.uri; - } else { - this.prefix = '_global_'; - } - }); + @inject(WorkspaceService) + protected workspaceService: WorkspaceService; + + @inject(ILogger) + protected logger: ILogger; + + constructor() { this.storageService = new LocalStorageService(this.logger); } + @postConstruct() + protected async init(): Promise { + const domain = await this.workspaceService.getDomain(); + const statFile = await this.workspaceService.root; + const workspace = statFile ? new URI(statFile.uri).path : '_global_'; + this.prefix = `${domain ? domain : window.location.pathname}:${workspace}`; + this.initialized = Promise.resolve(); + } + async setData(key: string, data: T): Promise { if (!this.prefix) { await this.initialized; diff --git a/packages/workspace/src/common/test/mock-workspace-server.ts b/packages/workspace/src/common/test/mock-workspace-server.ts index a7d3284702bf2..922d268d4bc8e 100644 --- a/packages/workspace/src/common/test/mock-workspace-server.ts +++ b/packages/workspace/src/common/test/mock-workspace-server.ts @@ -10,6 +10,8 @@ import { WorkspaceServer } from '../workspace-protocol'; @injectable() export class MockWorkspaceServer implements WorkspaceServer { + getDomain(): Promise { return Promise.resolve('mock'); } + getRoot(): Promise { return Promise.resolve(''); } setRoot(uri: string): Promise { return Promise.resolve(); } diff --git a/packages/workspace/src/common/workspace-protocol.ts b/packages/workspace/src/common/workspace-protocol.ts index 00d45448f45d0..7b2d9e594dca4 100644 --- a/packages/workspace/src/common/workspace-protocol.ts +++ b/packages/workspace/src/common/workspace-protocol.ts @@ -13,6 +13,11 @@ export const workspacePath = '/services/workspace'; export const WorkspaceServer = Symbol('WorkspaceServer'); export interface WorkspaceServer { + /** + * Returns the random identifier to the running theia instance + */ + getDomain(): Promise; + /** * Returns with a promise that resolves to the workspace root URI as a string. Resolves to `undefined` if the workspace root is not yet set. */ diff --git a/packages/workspace/src/node/default-workspace-server.ts b/packages/workspace/src/node/default-workspace-server.ts index bbaff6530a646..32e7e2ca128a7 100644 --- a/packages/workspace/src/node/default-workspace-server.ts +++ b/packages/workspace/src/node/default-workspace-server.ts @@ -10,7 +10,7 @@ import * as yargs from 'yargs'; import * as fs from 'fs-extra'; import * as os from 'os'; -import { injectable, inject } from "inversify"; +import { injectable, inject, postConstruct } from "inversify"; import { FileUri } from '@theia/core/lib/node'; import { CliContribution } from '@theia/core/lib/node/cli'; import { Deferred } from '@theia/core/lib/common/promise-util'; @@ -20,15 +20,19 @@ import { WorkspaceServer } from "../common"; export class WorkspaceCliContribution implements CliContribution { workspaceRoot = new Deferred(); + domain?: string; configure(conf: yargs.Argv): void { conf.usage("$0 [workspace-directory] [options]"); conf.option('root-dir', { description: 'DEPRECATED: Sets the workspace directory.', }); + conf.option('domain', { description: 'The domain id-like to represent', type: 'string' }); } setArguments(args: yargs.Arguments): void { + this.domain = args.domain; + let wsPath = args._[2]; if (!wsPath) { wsPath = args['root-dir']; @@ -50,18 +54,22 @@ export class DefaultWorkspaceServer implements WorkspaceServer { protected root: Promise; - constructor( - @inject(WorkspaceCliContribution) protected readonly cliParams: WorkspaceCliContribution - ) { + @inject(WorkspaceCliContribution) + protected readonly cliParams: WorkspaceCliContribution; + + @postConstruct() + protected async init(): Promise { this.root = this.getRootURIFromCli(); - this.root.then(async root => { - if (!root) { - const data = await this.readFromUserHome(); - if (data && data.recentRoots) { - this.root = Promise.resolve(data.recentRoots[0]); - } + if (!await this.root) { + const data = await this.readFromUserHome(); + if (data && data.recentRoots) { + this.root = Promise.resolve(data.recentRoots[0]); } - }); + } + } + + async getDomain(): Promise { + return Promise.resolve(this.cliParams.domain); } getRoot(): Promise {