@theia/filesystem 1.74.0-next.8 → 1.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,6 +24,7 @@ const ipc_connection_provider_1 = require("@theia/core/lib/node/messaging/ipc-co
24
24
  const inversify_1 = require("@theia/core/shared/inversify");
25
25
  const assert_1 = require("assert");
26
26
  const fs_1 = require("fs");
27
+ const os = require("os");
27
28
  const path_1 = require("path");
28
29
  const temp = require("temp");
29
30
  const uuid_1 = require("@theia/core/lib/common/uuid");
@@ -96,7 +97,10 @@ describe('disk-file-system-provider', () => {
96
97
  });
97
98
  it('delete is able to delete file', async function () {
98
99
  this.timeout(10000);
99
- const tempDirPath = tracked.mkdirSync();
100
+ // Place the temp dir under $HOME so the XDG trash dir (~/.local/share/Trash) is on the same
101
+ // filesystem. Otherwise the trash spec falls back to creating `.Trash-$UID` at the mount's
102
+ // topdir, which fails when /tmp is on a filesystem whose root is not user-writable.
103
+ const tempDirPath = tracked.mkdirSync({ dir: os.homedir(), prefix: 'theia-fs-test-' });
100
104
  const testFile = (0, path_1.join)(tempDirPath, 'test.file');
101
105
  const testFileUri = file_uri_1.FileUri.create(testFile);
102
106
  for (const recursive of [true, false]) {
@@ -1 +1 @@
1
- {"version":3,"file":"disk-file-system-provider.spec.js","sourceRoot":"","sources":["../../src/node/disk-file-system-provider.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"disk-file-system-provider.spec.js","sourceRoot":"","sources":["../../src/node/disk-file-system-provider.spec.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,4CAA4C;AAC5C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,kEAAqF;AACrF,8EAA0E;AAC1E,0DAAwD;AACxD,yEAAqE;AACrE,8DAA0D;AAC1D,oGAA+F;AAC/F,4DAA0E;AAC1E,mCAAqC;AACrC,2BAAoC;AACpC,yBAAyB;AACzB,+BAA4B;AAC5B,6BAA6B;AAC7B,sDAA2D;AAC3D,2CAAuI;AACvI,2EAAqE;AACrE,2EAA0E;AAE1E,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;AAE7B,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACvC,IAAI,cAAoC,CAAC;IACzC,IAAI,UAAkC,CAAC;IAEvC,MAAM,CAAC,GAAG,EAAE;QACR,UAAU,GAAG,eAAe,EAAE,CAAC,GAAG,CAC9B,kDAAsB,CACzB,CAAC;QACF,cAAc,GAAG,IAAI,iCAAoB,CACrC,UAAU,EACV,uBAAU,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CACjD,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,GAAG,EAAE;QACP,cAAc,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QAClB,EAAE,CAAC,2FAA2F,EAAE,KAAK,IAAI,EAAE;YACvG,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;YACxC,MAAM,YAAY,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,GAAG,IAAA,mBAAY,GAAE,MAAM,CAAC,CAAC;YAChE,MAAM,aAAE,CAAC,SAAS,CAAC,YAAY,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YAEvE,IAAI,OAAO,GAAG,MAAM,aAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YACpE,IAAA,cAAK,EAAC,OAAO,EAAE,cAAc,CAAC,CAAC;YAE/B,MAAM,aAAE,CAAC,SAAS,CAAC,YAAY,EAAE,eAAe,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YAExE,OAAO,GAAG,MAAM,aAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YAChE,IAAA,cAAK,EAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YAEhC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,kBAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;YACjE,IAAA,cAAK,EAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2FAA2F,EAAE,KAAK,IAAI,EAAE;YACvG,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;YACxC,MAAM,YAAY,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,GAAG,IAAA,mBAAY,GAAE,MAAM,CAAC,CAAC;YAChE,MAAM,aAAE,CAAC,SAAS,CAAC,YAAY,EAAE,kBAAkB,EAAE;gBACjD,QAAQ,EAAE,MAAM;aACnB,CAAC,CAAC;YAEH,MAAM,aAAE,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,kCAAkC;YAEvE,IAAI,CAAC;gBACD,MAAM,UAAU,CAAC,SAAS,CAAC,kBAAO,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC/G,IAAA,aAAI,EAAC,yDAAyD,CAAC,CAAC;YACpE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,IAAA,cAAK,EAAC,GAAG,YAAY,+BAAuB,EAAE,IAAI,CAAC,CAAC;gBACpD,IAAA,cAAK,EAA2B,GAAI,CAAC,IAAI,EAAE,mCAA2B,CAAC,aAAa,CAAC,CAAC;YAC1F,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,aAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YACtE,IAAA,cAAK,EAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;YAEnC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,kBAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;YACjE,IAAA,cAAK,EAAC,IAAI,CAAC,WAAW,EAAE,sBAAc,CAAC,QAAQ,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;YAC7C,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;YACxC,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YAC7C,MAAM,SAAS,GAAG,kBAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC7C,KAAK,MAAM,SAAS,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;gBACpC,uCAAuC;gBACvC,MAAM,QAAQ,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,UAAU,CAAC,YAAY,uDAAwC,CAAC,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;oBACtF,SAAS;gBACb,CAAC;gBACD,MAAM,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBAClC,IAAI,SAAS,EAAE,CAAC;oBACZ,MAAM,UAAU,CAAC,SAAS,CAAC,kBAAO,CAAC,MAAM,CAAC,IAAA,WAAI,EAAC,UAAU,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;oBACnI,MAAM,UAAU,CAAC,KAAK,CAAC,kBAAO,CAAC,MAAM,CAAC,IAAA,WAAI,EAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;gBAC1E,CAAC;gBACD,MAAM,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;YAChE,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE,KAAK;YACrC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACpB,4FAA4F;YAC5F,2FAA2F;YAC3F,oFAAoF;YACpF,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;YACvF,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,kBAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7C,KAAK,MAAM,SAAS,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;gBACpC,KAAK,MAAM,QAAQ,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;oBACnC,MAAM,UAAU,CAAC,SAAS,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;oBACjG,MAAM,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAClE,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,SAAS,eAAe;QACpB,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,IAAI,2BAAe,CAAC,IAAI,CAAC,EAAE;YACtC,IAAI,CAAC,kDAAsB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;YACzD,IAAI,CAAC,kCAAe,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;YAClD,IAAA,uDAA2B,EAAC,IAAI,CAAC,CAAC;YAClC,IAAI,CAAC,wBAAU,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;YAC7C,IAAI,CAAC,gBAAO,CAAC,CAAC,SAAS,CAAC,wBAAU,CAAC,CAAC;YACpC,IAAI,CAAC,+CAAqB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;QAC5D,CAAC,CAAC,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,SAAS,CAAC;IACrB,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,11 +1,13 @@
1
1
  import { Application } from '@theia/core/shared/express';
2
2
  import { BackendApplicationContribution } from '@theia/core/lib/node/backend-application';
3
+ import { HttpConnectionValidator } from '@theia/core/lib/node';
3
4
  import { FileDownloadHandler } from './file-download-handler';
4
5
  export declare class FileDownloadEndpoint implements BackendApplicationContribution {
5
6
  protected static PATH: string;
6
7
  protected readonly singleFileDownloadHandler: FileDownloadHandler;
7
8
  protected readonly multiFileDownloadHandler: FileDownloadHandler;
8
9
  protected readonly downloadLinkHandler: FileDownloadHandler;
10
+ protected readonly connectionValidator: HttpConnectionValidator;
9
11
  configure(app: Application): void;
10
12
  }
11
13
  //# sourceMappingURL=file-download-endpoint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-download-endpoint.d.ts","sourceRoot":"","sources":["../../../src/node/download/file-download-endpoint.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,WAAW,EAAU,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,8BAA8B,EAAE,MAAM,0CAA0C,CAAC;AAE1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,qBACa,oBAAqB,YAAW,8BAA8B;IAEvE,SAAS,CAAC,MAAM,CAAC,IAAI,SAAY;IAIjC,SAAS,CAAC,QAAQ,CAAC,yBAAyB,EAAE,mBAAmB,CAAC;IAIlE,SAAS,CAAC,QAAQ,CAAC,wBAAwB,EAAE,mBAAmB,CAAC;IAIjE,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAE5D,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;CAmBpC"}
1
+ {"version":3,"file":"file-download-endpoint.d.ts","sourceRoot":"","sources":["../../../src/node/download/file-download-endpoint.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,WAAW,EAA0B,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,8BAA8B,EAAE,MAAM,0CAA0C,CAAC;AAC1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,qBACa,oBAAqB,YAAW,8BAA8B;IAEvE,SAAS,CAAC,MAAM,CAAC,IAAI,SAAY;IAIjC,SAAS,CAAC,QAAQ,CAAC,yBAAyB,EAAE,mBAAmB,CAAC;IAIlE,SAAS,CAAC,QAAQ,CAAC,wBAAwB,EAAE,mBAAmB,CAAC;IAIjE,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAG5D,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE,uBAAuB,CAAC;IAEhE,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;CAqBpC"}
@@ -19,25 +19,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.FileDownloadEndpoint = void 0;
20
20
  const tslib_1 = require("tslib");
21
21
  /* eslint-disable @typescript-eslint/no-explicit-any */
22
- const url = require("url");
23
22
  const inversify_1 = require("@theia/core/shared/inversify");
24
23
  const body_parser_1 = require("body-parser");
25
24
  const express_1 = require("@theia/core/shared/express");
25
+ const node_1 = require("@theia/core/lib/node");
26
26
  const file_uri_1 = require("@theia/core/lib/common/file-uri");
27
27
  const file_download_handler_1 = require("./file-download-handler");
28
28
  let FileDownloadEndpoint = class FileDownloadEndpoint {
29
29
  static { FileDownloadEndpoint_1 = this; }
30
30
  static { this.PATH = '/files'; }
31
31
  configure(app) {
32
+ // Reject unauthenticated/cross-origin requests to the file read endpoints.
33
+ const guard = (request, response, next) => this.connectionValidator.validateRequest(request, response, next);
32
34
  const router = (0, express_1.Router)();
33
35
  router.get('/download', (request, response) => this.downloadLinkHandler.handle(request, response));
34
36
  router.get('/', (request, response) => this.singleFileDownloadHandler.handle(request, response));
35
37
  router.put('/', (request, response) => this.multiFileDownloadHandler.handle(request, response));
36
38
  // Content-Type: application/json
37
39
  app.use((0, body_parser_1.json)());
38
- app.use(FileDownloadEndpoint_1.PATH, router);
39
- app.get('/file', (request, response) => {
40
- const uri = url.parse(request.url).query;
40
+ app.use(FileDownloadEndpoint_1.PATH, guard, router);
41
+ app.get('/file', guard, (request, response) => {
42
+ const uri = new URL(request.url, 'http://localhost').search.slice(1);
41
43
  if (!uri) {
42
44
  response.status(400).send('invalid uri');
43
45
  return;
@@ -63,6 +65,10 @@ tslib_1.__decorate([
63
65
  (0, inversify_1.named)(file_download_handler_1.FileDownloadHandler.DOWNLOAD_LINK),
64
66
  tslib_1.__metadata("design:type", file_download_handler_1.FileDownloadHandler)
65
67
  ], FileDownloadEndpoint.prototype, "downloadLinkHandler", void 0);
68
+ tslib_1.__decorate([
69
+ (0, inversify_1.inject)(node_1.HttpConnectionValidator),
70
+ tslib_1.__metadata("design:type", Object)
71
+ ], FileDownloadEndpoint.prototype, "connectionValidator", void 0);
66
72
  exports.FileDownloadEndpoint = FileDownloadEndpoint = FileDownloadEndpoint_1 = tslib_1.__decorate([
67
73
  (0, inversify_1.injectable)()
68
74
  ], FileDownloadEndpoint);
@@ -1 +1 @@
1
- {"version":3,"file":"file-download-endpoint.js","sourceRoot":"","sources":["../../../src/node/download/file-download-endpoint.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;;;AAEhF,uDAAuD;AAEvD,2BAA2B;AAC3B,4DAAyE;AACzE,6CAAmC;AACnC,wDAAiE;AAEjE,8DAA0D;AAC1D,mEAA8D;AAGvD,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;;aAEZ,SAAI,GAAG,QAAQ,AAAX,CAAY;IAcjC,SAAS,CAAC,GAAgB;QACtB,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnG,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjG,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChG,iCAAiC;QACjC,GAAG,CAAC,GAAG,CAAC,IAAA,kBAAI,GAAE,CAAC,CAAC;QAChB,GAAG,CAAC,GAAG,CAAC,sBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;YACnC,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;YACzC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACP,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBACzC,OAAO;YACX,CAAC;YACD,MAAM,MAAM,GAAG,kBAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;YACvD,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACP,CAAC;;AAjCQ,oDAAoB;AAMV;IAFlB,IAAA,kBAAM,EAAC,2CAAmB,CAAC;IAC3B,IAAA,iBAAK,EAAC,2CAAmB,CAAC,MAAM,CAAC;sCACY,2CAAmB;uEAAC;AAI/C;IAFlB,IAAA,kBAAM,EAAC,2CAAmB,CAAC;IAC3B,IAAA,iBAAK,EAAC,2CAAmB,CAAC,KAAK,CAAC;sCACY,2CAAmB;sEAAC;AAI9C;IAFlB,IAAA,kBAAM,EAAC,2CAAmB,CAAC;IAC3B,IAAA,iBAAK,EAAC,2CAAmB,CAAC,aAAa,CAAC;sCACD,2CAAmB;iEAAC;+BAdnD,oBAAoB;IADhC,IAAA,sBAAU,GAAE;GACA,oBAAoB,CAmChC"}
1
+ {"version":3,"file":"file-download-endpoint.js","sourceRoot":"","sources":["../../../src/node/download/file-download-endpoint.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;;;AAEhF,uDAAuD;AAEvD,4DAAyE;AACzE,6CAAmC;AACnC,wDAAiF;AAEjF,+CAA+D;AAC/D,8DAA0D;AAC1D,mEAA8D;AAGvD,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;;aAEZ,SAAI,GAAG,QAAQ,AAAX,CAAY;IAiBjC,SAAS,CAAC,GAAgB;QACtB,2EAA2E;QAC3E,MAAM,KAAK,GAAmB,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC7H,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnG,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjG,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChG,iCAAiC;QACjC,GAAG,CAAC,GAAG,CAAC,IAAA,kBAAI,GAAE,CAAC,CAAC;QAChB,GAAG,CAAC,GAAG,CAAC,sBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAClD,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;YAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACrE,IAAI,CAAC,GAAG,EAAE,CAAC;gBACP,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBACzC,OAAO;YACX,CAAC;YACD,MAAM,MAAM,GAAG,kBAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;YACvD,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACP,CAAC;;AAtCQ,oDAAoB;AAMV;IAFlB,IAAA,kBAAM,EAAC,2CAAmB,CAAC;IAC3B,IAAA,iBAAK,EAAC,2CAAmB,CAAC,MAAM,CAAC;sCACY,2CAAmB;uEAAC;AAI/C;IAFlB,IAAA,kBAAM,EAAC,2CAAmB,CAAC;IAC3B,IAAA,iBAAK,EAAC,2CAAmB,CAAC,KAAK,CAAC;sCACY,2CAAmB;sEAAC;AAI9C;IAFlB,IAAA,kBAAM,EAAC,2CAAmB,CAAC;IAC3B,IAAA,iBAAK,EAAC,2CAAmB,CAAC,aAAa,CAAC;sCACD,2CAAmB;iEAAC;AAGzC;IADlB,IAAA,kBAAM,EAAC,8BAAuB,CAAC;;iEACgC;+BAjBvD,oBAAoB;IADhC,IAAA,sBAAU,GAAE;GACA,oBAAoB,CAwChC"}
@@ -1,8 +1,9 @@
1
1
  import express = require('@theia/core/shared/express');
2
- import { BackendApplicationContribution } from '@theia/core/lib/node';
2
+ import { BackendApplicationContribution, HttpConnectionValidator } from '@theia/core/lib/node';
3
3
  import { ILogger } from '@theia/core';
4
4
  export declare class NodeFileUploadService implements BackendApplicationContribution {
5
5
  protected readonly logger: ILogger;
6
+ protected readonly connectionValidator: HttpConnectionValidator;
6
7
  private static readonly UPLOAD_DIR;
7
8
  configure(app: express.Application): Promise<void>;
8
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"node-file-upload-service.d.ts","sourceRoot":"","sources":["../../../src/node/upload/node-file-upload-service.ts"],"names":[],"mappings":"AAmBA,OAAO,OAAO,GAAG,QAAQ,4BAA4B,CAAC,CAAC;AAEvD,OAAO,EAAE,8BAA8B,EAAW,MAAM,sBAAsB,CAAC;AAG/E,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,qBACa,qBAAsB,YAAW,8BAA8B;IAGxE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAE9C,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAexD;;OAEG;cACa,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxD;;OAEG;cACa,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;cAIzC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CA2BxG"}
1
+ {"version":3,"file":"node-file-upload-service.d.ts","sourceRoot":"","sources":["../../../src/node/upload/node-file-upload-service.ts"],"names":[],"mappings":"AAmBA,OAAO,OAAO,GAAG,QAAQ,4BAA4B,CAAC,CAAC;AAEvD,OAAO,EAAE,8BAA8B,EAAW,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAGxG,OAAO,EAAE,OAAO,EAAO,MAAM,aAAa,CAAC;AAE3C,qBACa,qBAAsB,YAAW,8BAA8B;IAGxE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAGnC,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE,uBAAuB,CAAC;IAEhE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAE9C,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxD;;OAEG;cACa,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxD;;OAEG;cACa,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;cAIzC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CA2BxG"}
@@ -36,7 +36,9 @@ let NodeFileUploadService = class NodeFileUploadService {
36
36
  ]);
37
37
  this.logger.debug(`HTTP file upload URL path: ${http_path}`);
38
38
  this.logger.debug(`Backend file upload cache path: ${dest}`);
39
- app.post(http_path,
39
+ // Reject unauthenticated/cross-origin requests before `multer` writes any temp file.
40
+ const guard = (request, response, next) => this.connectionValidator.validateRequest(request, response, next);
41
+ app.post(http_path, guard,
40
42
  // `multer` handles `multipart/form-data` containing our file to upload.
41
43
  multer({ dest }).single('file'), (request, response, next) => this.handleFileUpload(request, response));
42
44
  }
@@ -54,7 +56,7 @@ let NodeFileUploadService = class NodeFileUploadService {
54
56
  }
55
57
  async handleFileUpload(request, response) {
56
58
  const fields = request.body;
57
- if (!request.file || typeof fields !== 'object' || typeof fields.uri !== 'string') {
59
+ if (!request.file || typeof fields !== 'object' || typeof fields.uri !== 'string' || new core_1.URI(fields.uri).scheme !== 'file') {
58
60
  response.sendStatus(400); // bad request
59
61
  return;
60
62
  }
@@ -88,6 +90,10 @@ tslib_1.__decorate([
88
90
  (0, inversify_1.named)('filesystem:NodeFileUploadService'),
89
91
  tslib_1.__metadata("design:type", Object)
90
92
  ], NodeFileUploadService.prototype, "logger", void 0);
93
+ tslib_1.__decorate([
94
+ (0, inversify_1.inject)(node_1.HttpConnectionValidator),
95
+ tslib_1.__metadata("design:type", Object)
96
+ ], NodeFileUploadService.prototype, "connectionValidator", void 0);
91
97
  exports.NodeFileUploadService = NodeFileUploadService = NodeFileUploadService_1 = tslib_1.__decorate([
92
98
  (0, inversify_1.injectable)()
93
99
  ], NodeFileUploadService);
@@ -1 +1 @@
1
- {"version":3,"file":"node-file-upload-service.js","sourceRoot":"","sources":["../../../src/node/upload/node-file-upload-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node-file-upload-service.js","sourceRoot":"","sources":["../../../src/node/upload/node-file-upload-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=node-file-upload-service.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-file-upload-service.spec.d.ts","sourceRoot":"","sources":["../../../src/node/upload/node-file-upload-service.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2026 EclipseSource GmbH and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ const chai_1 = require("chai");
19
+ const os = require("os");
20
+ const path = require("path");
21
+ const fs = require("@theia/core/shared/fs-extra");
22
+ const file_uri_1 = require("@theia/core/lib/common/file-uri");
23
+ const node_file_upload_service_1 = require("./node-file-upload-service");
24
+ describe('NodeFileUploadService', () => {
25
+ let tempDir;
26
+ function createService() {
27
+ const service = new node_file_upload_service_1.NodeFileUploadService();
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ service['logger'] = { error: () => { } };
30
+ return service;
31
+ }
32
+ function createResponse() {
33
+ const captured = {};
34
+ const res = {
35
+ status(code) {
36
+ captured.statusCode = code;
37
+ return res;
38
+ },
39
+ send(body) {
40
+ captured.body = body;
41
+ },
42
+ sendStatus(code) {
43
+ captured.sentStatus = code;
44
+ }
45
+ };
46
+ return { res, captured };
47
+ }
48
+ async function handleUpload(filePath, body) {
49
+ const service = createService();
50
+ const { res, captured } = createResponse();
51
+ const request = { file: filePath === undefined ? undefined : { path: filePath }, body };
52
+ // handleFileUpload is protected; invoke it directly to exercise the input validation.
53
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
+ await service.handleFileUpload(request, res);
55
+ return captured;
56
+ }
57
+ beforeEach(async () => {
58
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'theia-upload-spec-'));
59
+ });
60
+ afterEach(async () => {
61
+ await fs.remove(tempDir);
62
+ });
63
+ it('should reject a non-file: URI with 400', async () => {
64
+ const source = path.join(tempDir, 'source.txt');
65
+ await fs.writeFile(source, 'payload');
66
+ const captured = await handleUpload(source, { uri: 'http://evil.example/usr/bin/bash' });
67
+ (0, chai_1.expect)(captured.sentStatus).to.equal(400);
68
+ // The scoped-write guard must reject before any file operation runs.
69
+ (0, chai_1.expect)(await fs.pathExists(source)).to.be.true;
70
+ });
71
+ it('should reject a remote-scheme URI with 400', async () => {
72
+ const source = path.join(tempDir, 'source.txt');
73
+ await fs.writeFile(source, 'payload');
74
+ const captured = await handleUpload(source, { uri: 'vscode-remote://host/usr/bin/bash' });
75
+ (0, chai_1.expect)(captured.sentStatus).to.equal(400);
76
+ (0, chai_1.expect)(await fs.pathExists(source)).to.be.true;
77
+ });
78
+ it('should reject a missing uri field with 400', async () => {
79
+ const source = path.join(tempDir, 'source.txt');
80
+ await fs.writeFile(source, 'payload');
81
+ const captured = await handleUpload(source, {});
82
+ (0, chai_1.expect)(captured.sentStatus).to.equal(400);
83
+ });
84
+ it('should reject a missing file with 400', async () => {
85
+ const target = file_uri_1.FileUri.create(path.join(tempDir, 'target.txt')).toString();
86
+ const captured = await handleUpload(undefined, { uri: target });
87
+ (0, chai_1.expect)(captured.sentStatus).to.equal(400);
88
+ });
89
+ it('should accept a file: URI and move the upload to the target', async () => {
90
+ const source = path.join(tempDir, 'source.txt');
91
+ await fs.writeFile(source, 'payload');
92
+ const targetPath = path.join(tempDir, 'target.txt');
93
+ const target = file_uri_1.FileUri.create(targetPath).toString();
94
+ const captured = await handleUpload(source, { uri: target });
95
+ (0, chai_1.expect)(captured.sentStatus).to.be.undefined;
96
+ (0, chai_1.expect)(captured.statusCode).to.equal(200);
97
+ // Compare against the canonical fs-path of the URI: on Windows the create/fsPath round-trip
98
+ // normalizes the drive letter to lower-case (e.g. `C:` -> `c:`), which would otherwise fail
99
+ // an exact string match against `targetPath` derived from `os.tmpdir()`.
100
+ (0, chai_1.expect)(captured.body).to.equal(file_uri_1.FileUri.fsPath(target));
101
+ (0, chai_1.expect)(await fs.pathExists(targetPath)).to.be.true;
102
+ (0, chai_1.expect)(await fs.readFile(targetPath, 'utf8')).to.equal('payload');
103
+ // The temp source file was moved, not copied.
104
+ (0, chai_1.expect)(await fs.pathExists(source)).to.be.false;
105
+ });
106
+ });
107
+ //# sourceMappingURL=node-file-upload-service.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-file-upload-service.spec.js","sourceRoot":"","sources":["../../../src/node/upload/node-file-upload-service.spec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@theia/filesystem",
3
- "version": "1.74.0-next.8+2cd198687",
3
+ "version": "1.74.0",
4
4
  "description": "Theia - FileSystem Extension",
5
5
  "dependencies": {
6
- "@theia/core": "1.74.0-next.8+2cd198687",
6
+ "@theia/core": "1.74.0",
7
7
  "@types/body-parser": "^1.19.6",
8
8
  "@types/multer": "^1.4.13",
9
9
  "@types/tar-fs": "^1.16.3",
@@ -13,11 +13,11 @@
13
13
  "http-status-codes": "^1.4.0",
14
14
  "ignore": "^6.0.2",
15
15
  "minimatch": "^10.2.5",
16
- "multer": "^2.1.1",
16
+ "multer": "^2.2.0",
17
17
  "opfs-worker": "1.3.1",
18
18
  "rimraf": "^5.0.10",
19
19
  "stat-mode": "^1.0.0",
20
- "tar-fs": "^3.1.2",
20
+ "tar-fs": "^3.1.3",
21
21
  "tar-stream": "^3.2.0",
22
22
  "trash": "^7.2.0",
23
23
  "tslib": "^2.8.1",
@@ -77,10 +77,10 @@
77
77
  "watch": "theiaext watch"
78
78
  },
79
79
  "devDependencies": {
80
- "@theia/ext-scripts": "1.73.0"
80
+ "@theia/ext-scripts": "1.74.0"
81
81
  },
82
82
  "nyc": {
83
83
  "extends": "../../configs/nyc.json"
84
84
  },
85
- "gitHead": "2cd1986875513fd02f645a2b8e69a68832a3a990"
85
+ "gitHead": "7b7376225f0825b4f13d296d686cc13db95fdb69"
86
86
  }
@@ -23,6 +23,7 @@ import { IPCConnectionProvider } from '@theia/core/lib/node/messaging/ipc-connec
23
23
  import { Container, ContainerModule } from '@theia/core/shared/inversify';
24
24
  import { equal, fail } from 'assert';
25
25
  import { promises as fs } from 'fs';
26
+ import * as os from 'os';
26
27
  import { join } from 'path';
27
28
  import * as temp from 'temp';
28
29
  import { generateUuid } from '@theia/core/lib/common/uuid';
@@ -115,7 +116,10 @@ describe('disk-file-system-provider', () => {
115
116
 
116
117
  it('delete is able to delete file', async function (): Promise<void> {
117
118
  this.timeout(10000);
118
- const tempDirPath = tracked.mkdirSync();
119
+ // Place the temp dir under $HOME so the XDG trash dir (~/.local/share/Trash) is on the same
120
+ // filesystem. Otherwise the trash spec falls back to creating `.Trash-$UID` at the mount's
121
+ // topdir, which fails when /tmp is on a filesystem whose root is not user-writable.
122
+ const tempDirPath = tracked.mkdirSync({ dir: os.homedir(), prefix: 'theia-fs-test-' });
119
123
  const testFile = join(tempDirPath, 'test.file');
120
124
  const testFileUri = FileUri.create(testFile);
121
125
  for (const recursive of [true, false]) {
@@ -16,11 +16,11 @@
16
16
 
17
17
  /* eslint-disable @typescript-eslint/no-explicit-any */
18
18
 
19
- import * as url from 'url';
20
19
  import { injectable, inject, named } from '@theia/core/shared/inversify';
21
20
  import { json } from 'body-parser';
22
- import { Application, Router } from '@theia/core/shared/express';
21
+ import { Application, Router, RequestHandler } from '@theia/core/shared/express';
23
22
  import { BackendApplicationContribution } from '@theia/core/lib/node/backend-application';
23
+ import { HttpConnectionValidator } from '@theia/core/lib/node';
24
24
  import { FileUri } from '@theia/core/lib/common/file-uri';
25
25
  import { FileDownloadHandler } from './file-download-handler';
26
26
 
@@ -41,16 +41,21 @@ export class FileDownloadEndpoint implements BackendApplicationContribution {
41
41
  @named(FileDownloadHandler.DOWNLOAD_LINK)
42
42
  protected readonly downloadLinkHandler: FileDownloadHandler;
43
43
 
44
+ @inject(HttpConnectionValidator)
45
+ protected readonly connectionValidator: HttpConnectionValidator;
46
+
44
47
  configure(app: Application): void {
48
+ // Reject unauthenticated/cross-origin requests to the file read endpoints.
49
+ const guard: RequestHandler = (request, response, next) => this.connectionValidator.validateRequest(request, response, next);
45
50
  const router = Router();
46
51
  router.get('/download', (request, response) => this.downloadLinkHandler.handle(request, response));
47
52
  router.get('/', (request, response) => this.singleFileDownloadHandler.handle(request, response));
48
53
  router.put('/', (request, response) => this.multiFileDownloadHandler.handle(request, response));
49
54
  // Content-Type: application/json
50
55
  app.use(json());
51
- app.use(FileDownloadEndpoint.PATH, router);
52
- app.get('/file', (request, response) => {
53
- const uri = url.parse(request.url).query;
56
+ app.use(FileDownloadEndpoint.PATH, guard, router);
57
+ app.get('/file', guard, (request, response) => {
58
+ const uri = new URL(request.url, 'http://localhost').search.slice(1);
54
59
  if (!uri) {
55
60
  response.status(400).send('invalid uri');
56
61
  return;
@@ -0,0 +1,126 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 EclipseSource GmbH and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { expect } from 'chai';
18
+ import * as os from 'os';
19
+ import * as path from 'path';
20
+ import * as fs from '@theia/core/shared/fs-extra';
21
+ import { FileUri } from '@theia/core/lib/common/file-uri';
22
+ import { NodeFileUploadService } from './node-file-upload-service';
23
+
24
+ /** Captures what the upload handler wrote to the Express response. */
25
+ interface CapturedResponse {
26
+ statusCode?: number;
27
+ sentStatus?: number;
28
+ body?: unknown;
29
+ }
30
+
31
+ describe('NodeFileUploadService', () => {
32
+
33
+ let tempDir: string;
34
+
35
+ function createService(): NodeFileUploadService {
36
+ const service = new NodeFileUploadService();
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ (service as any)['logger'] = { error: () => { } };
39
+ return service;
40
+ }
41
+
42
+ function createResponse(): { res: unknown, captured: CapturedResponse } {
43
+ const captured: CapturedResponse = {};
44
+ const res = {
45
+ status(code: number): unknown {
46
+ captured.statusCode = code;
47
+ return res;
48
+ },
49
+ send(body: unknown): void {
50
+ captured.body = body;
51
+ },
52
+ sendStatus(code: number): void {
53
+ captured.sentStatus = code;
54
+ }
55
+ };
56
+ return { res, captured };
57
+ }
58
+
59
+ async function handleUpload(filePath: string | undefined, body: unknown): Promise<CapturedResponse> {
60
+ const service = createService();
61
+ const { res, captured } = createResponse();
62
+ const request = { file: filePath === undefined ? undefined : { path: filePath }, body };
63
+ // handleFileUpload is protected; invoke it directly to exercise the input validation.
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ await (service as any).handleFileUpload(request, res);
66
+ return captured;
67
+ }
68
+
69
+ beforeEach(async () => {
70
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'theia-upload-spec-'));
71
+ });
72
+
73
+ afterEach(async () => {
74
+ await fs.remove(tempDir);
75
+ });
76
+
77
+ it('should reject a non-file: URI with 400', async () => {
78
+ const source = path.join(tempDir, 'source.txt');
79
+ await fs.writeFile(source, 'payload');
80
+ const captured = await handleUpload(source, { uri: 'http://evil.example/usr/bin/bash' });
81
+ expect(captured.sentStatus).to.equal(400);
82
+ // The scoped-write guard must reject before any file operation runs.
83
+ expect(await fs.pathExists(source)).to.be.true;
84
+ });
85
+
86
+ it('should reject a remote-scheme URI with 400', async () => {
87
+ const source = path.join(tempDir, 'source.txt');
88
+ await fs.writeFile(source, 'payload');
89
+ const captured = await handleUpload(source, { uri: 'vscode-remote://host/usr/bin/bash' });
90
+ expect(captured.sentStatus).to.equal(400);
91
+ expect(await fs.pathExists(source)).to.be.true;
92
+ });
93
+
94
+ it('should reject a missing uri field with 400', async () => {
95
+ const source = path.join(tempDir, 'source.txt');
96
+ await fs.writeFile(source, 'payload');
97
+ const captured = await handleUpload(source, {});
98
+ expect(captured.sentStatus).to.equal(400);
99
+ });
100
+
101
+ it('should reject a missing file with 400', async () => {
102
+ const target = FileUri.create(path.join(tempDir, 'target.txt')).toString();
103
+ const captured = await handleUpload(undefined, { uri: target });
104
+ expect(captured.sentStatus).to.equal(400);
105
+ });
106
+
107
+ it('should accept a file: URI and move the upload to the target', async () => {
108
+ const source = path.join(tempDir, 'source.txt');
109
+ await fs.writeFile(source, 'payload');
110
+ const targetPath = path.join(tempDir, 'target.txt');
111
+ const target = FileUri.create(targetPath).toString();
112
+
113
+ const captured = await handleUpload(source, { uri: target });
114
+
115
+ expect(captured.sentStatus).to.be.undefined;
116
+ expect(captured.statusCode).to.equal(200);
117
+ // Compare against the canonical fs-path of the URI: on Windows the create/fsPath round-trip
118
+ // normalizes the drive letter to lower-case (e.g. `C:` -> `c:`), which would otherwise fail
119
+ // an exact string match against `targetPath` derived from `os.tmpdir()`.
120
+ expect(captured.body).to.equal(FileUri.fsPath(target));
121
+ expect(await fs.pathExists(targetPath)).to.be.true;
122
+ expect(await fs.readFile(targetPath, 'utf8')).to.equal('payload');
123
+ // The temp source file was moved, not copied.
124
+ expect(await fs.pathExists(source)).to.be.false;
125
+ });
126
+ });
@@ -19,10 +19,10 @@ import path = require('path');
19
19
  import os = require('os');
20
20
  import express = require('@theia/core/shared/express');
21
21
  import fs = require('@theia/core/shared/fs-extra');
22
- import { BackendApplicationContribution, FileUri } from '@theia/core/lib/node';
22
+ import { BackendApplicationContribution, FileUri, HttpConnectionValidator } from '@theia/core/lib/node';
23
23
  import { injectable, inject, named } from '@theia/core/shared/inversify';
24
24
  import { HTTP_FILE_UPLOAD_PATH } from '../../common/file-upload';
25
- import { ILogger } from '@theia/core';
25
+ import { ILogger, URI } from '@theia/core';
26
26
 
27
27
  @injectable()
28
28
  export class NodeFileUploadService implements BackendApplicationContribution {
@@ -30,6 +30,9 @@ export class NodeFileUploadService implements BackendApplicationContribution {
30
30
  @inject(ILogger) @named('filesystem:NodeFileUploadService')
31
31
  protected readonly logger: ILogger;
32
32
 
33
+ @inject(HttpConnectionValidator)
34
+ protected readonly connectionValidator: HttpConnectionValidator;
35
+
33
36
  private static readonly UPLOAD_DIR = 'theia_upload';
34
37
 
35
38
  async configure(app: express.Application): Promise<void> {
@@ -39,8 +42,11 @@ export class NodeFileUploadService implements BackendApplicationContribution {
39
42
  ]);
40
43
  this.logger.debug(`HTTP file upload URL path: ${http_path}`);
41
44
  this.logger.debug(`Backend file upload cache path: ${dest}`);
45
+ // Reject unauthenticated/cross-origin requests before `multer` writes any temp file.
46
+ const guard: express.RequestHandler = (request, response, next) => this.connectionValidator.validateRequest(request, response, next);
42
47
  app.post(
43
48
  http_path,
49
+ guard,
44
50
  // `multer` handles `multipart/form-data` containing our file to upload.
45
51
  multer({ dest }).single('file'),
46
52
  (request, response, next) => this.handleFileUpload(request, response)
@@ -63,7 +69,7 @@ export class NodeFileUploadService implements BackendApplicationContribution {
63
69
 
64
70
  protected async handleFileUpload(request: express.Request, response: express.Response): Promise<void> {
65
71
  const fields = request.body;
66
- if (!request.file || typeof fields !== 'object' || typeof fields.uri !== 'string') {
72
+ if (!request.file || typeof fields !== 'object' || typeof fields.uri !== 'string' || new URI(fields.uri).scheme !== 'file') {
67
73
  response.sendStatus(400); // bad request
68
74
  return;
69
75
  }