@nocobase/server 2.1.0-alpha.30 → 2.1.0-alpha.32

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.
@@ -60,6 +60,8 @@ export declare class Gateway extends EventEmitter {
60
60
  private socketPath;
61
61
  private v2IndexTemplateCache;
62
62
  private terminating;
63
+ private getOriginalRequestUrl;
64
+ private proxyRequestToSubApp;
63
65
  private onTerminate;
64
66
  private constructor();
65
67
  static getInstance(options?: any): Gateway;
@@ -103,6 +103,18 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
103
103
  socketPath = getSocketPath();
104
104
  v2IndexTemplateCache = null;
105
105
  terminating = false;
106
+ getOriginalRequestUrl(req) {
107
+ return req.originalUrl || req.url;
108
+ }
109
+ async proxyRequestToSubApp(supervisor, appName, req, res) {
110
+ const internalUrl = req.url;
111
+ req.url = this.getOriginalRequestUrl(req);
112
+ try {
113
+ return await supervisor.proxyWeb(appName, req, res);
114
+ } finally {
115
+ req.url = internalUrl;
116
+ }
117
+ }
106
118
  onTerminate = /* @__PURE__ */ __name(async (signal) => {
107
119
  var _a;
108
120
  if (this.terminating) {
@@ -340,7 +352,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
340
352
  }
341
353
  if (pathname.startsWith(APP_PUBLIC_PATH + "storage/uploads/")) {
342
354
  if (handleApp !== "main") {
343
- const isProxy = await supervisor.proxyWeb(handleApp, req, res);
355
+ const isProxy = await this.proxyRequestToSubApp(supervisor, handleApp, req, res);
344
356
  if (isProxy) {
345
357
  return;
346
358
  }
@@ -354,7 +366,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
354
366
  }
355
367
  if (pathname.startsWith(PLUGIN_STATICS_PATH) && !pathname.includes("/server/")) {
356
368
  if (handleApp !== "main") {
357
- const isProxy = await supervisor.proxyWeb(handleApp, req, res);
369
+ const isProxy = await this.proxyRequestToSubApp(supervisor, handleApp, req, res);
358
370
  if (isProxy) {
359
371
  return;
360
372
  }
@@ -376,7 +388,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
376
388
  if (!pathname.startsWith(import_node_process.default.env.API_BASE_PATH)) {
377
389
  if (this.isV2Request(pathname)) {
378
390
  if (handleApp !== "main") {
379
- const isProxy = await supervisor.proxyWeb(handleApp, req, res);
391
+ const isProxy = await this.proxyRequestToSubApp(supervisor, handleApp, req, res);
380
392
  if (isProxy) {
381
393
  return;
382
394
  }
@@ -396,7 +408,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
396
408
  });
397
409
  }
398
410
  if (handleApp !== "main") {
399
- const isProxy = await supervisor.proxyWeb(handleApp, req, res);
411
+ const isProxy = await this.proxyRequestToSubApp(supervisor, handleApp, req, res);
400
412
  if (isProxy) {
401
413
  return;
402
414
  }
@@ -409,7 +421,7 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
409
421
  });
410
422
  }
411
423
  if (handleApp !== "main") {
412
- const isProxy = await supervisor.proxyWeb(handleApp, req, res);
424
+ const isProxy = await this.proxyRequestToSubApp(supervisor, handleApp, req, res);
413
425
  if (isProxy) {
414
426
  return;
415
427
  }
@@ -96,6 +96,7 @@ const _MainDataSource = class _MainDataSource extends import_data_source_manager
96
96
  const results = await this.tables2Collections(toAddTables);
97
97
  const values = results.map((result) => ({
98
98
  ...result,
99
+ from: "dbsync",
99
100
  underscored: false
100
101
  }));
101
102
  await repo.create({ values, context: ctx });
@@ -115,10 +116,12 @@ const _MainDataSource = class _MainDataSource extends import_data_source_manager
115
116
  ...filter
116
117
  }
117
118
  });
118
- const collections = loadedCollections.filter((collection) => {
119
- var _a;
120
- return ((_a = collection.options) == null ? void 0 : _a.from) !== "db2cm";
121
- });
119
+ const collections = loadedCollections.filter(
120
+ (collection) => {
121
+ var _a;
122
+ return !["db2cm", "dbsync"].includes((_a = collection.options) == null ? void 0 : _a.from);
123
+ }
124
+ );
122
125
  const loadedData = {};
123
126
  for (const collection of collections) {
124
127
  const c = db.getCollection(collection.name);
@@ -44,7 +44,7 @@ const deps = {
44
44
  mathjs: "15.x",
45
45
  winston: "3.x",
46
46
  "winston-daily-rotate-file": "4.x",
47
- koa: "2.x",
47
+ koa: "3.x",
48
48
  "@koa/cors": "5.x",
49
49
  "@koa/router": "13.x",
50
50
  multer: "1.x",
@@ -17,6 +17,8 @@ import Application from '../application';
17
17
  * getTempDir() => '/tmp/nocobase'
18
18
  */
19
19
  export declare function getTempDir(): Promise<string>;
20
+ export declare function assertSafePluginPackageName(packageName: string): void;
21
+ export declare function resolveSafeChildPath(baseDir: string, child: string): string;
20
22
  export declare function getLocalPluginPackagesPathArr(): string[];
21
23
  export declare function getStoragePluginDir(packageName: string): string;
22
24
  export declare function getLocalPluginDir(packageDirBasename: string): string;
@@ -37,6 +37,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
37
37
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
38
38
  var utils_exports = {};
39
39
  __export(utils_exports, {
40
+ assertSafePluginPackageName: () => assertSafePluginPackageName,
40
41
  checkAndGetCompatible: () => checkAndGetCompatible,
41
42
  checkCompatible: () => checkCompatible,
42
43
  copyTempPackageToStorageAndLinkToNodeModules: () => copyTempPackageToStorageAndLinkToNodeModules,
@@ -71,6 +72,7 @@ __export(utils_exports, {
71
72
  removeTmpDir: () => removeTmpDir,
72
73
  requireModule: () => requireModule,
73
74
  requireNoCache: () => requireNoCache,
75
+ resolveSafeChildPath: () => resolveSafeChildPath,
74
76
  updatePluginByCompressedFileUrl: () => updatePluginByCompressedFileUrl
75
77
  });
76
78
  module.exports = __toCommonJS(utils_exports);
@@ -96,6 +98,34 @@ async function getTempDir() {
96
98
  return import_path.default.join(temporaryDirectory, import_constants.APP_NAME);
97
99
  }
98
100
  __name(getTempDir, "getTempDir");
101
+ function assertSafePluginPackageName(packageName) {
102
+ if (!packageName || typeof packageName !== "string") {
103
+ throw new Error("Invalid plugin package name");
104
+ }
105
+ if (packageName.includes("\0")) {
106
+ throw new Error("Invalid plugin package name");
107
+ }
108
+ if (import_path.default.isAbsolute(packageName)) {
109
+ throw new Error("Invalid plugin package name");
110
+ }
111
+ if (packageName.includes("..") || packageName.includes("\\")) {
112
+ throw new Error("Invalid plugin package name");
113
+ }
114
+ const valid = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/i.test(packageName);
115
+ if (!valid) {
116
+ throw new Error("Invalid plugin package name");
117
+ }
118
+ }
119
+ __name(assertSafePluginPackageName, "assertSafePluginPackageName");
120
+ function resolveSafeChildPath(baseDir, child) {
121
+ const resolvedBase = import_path.default.resolve(baseDir);
122
+ const resolvedTarget = import_path.default.resolve(baseDir, child);
123
+ if (resolvedTarget !== resolvedBase && !resolvedTarget.startsWith(`${resolvedBase}${import_path.default.sep}`)) {
124
+ throw new Error("Path traversal detected");
125
+ }
126
+ return resolvedTarget;
127
+ }
128
+ __name(resolveSafeChildPath, "resolveSafeChildPath");
99
129
  function getLocalPluginPackagesPathArr() {
100
130
  const pluginPackagesPathArr = process.env.PLUGIN_PATH || import_constants.DEFAULT_PLUGIN_PATH;
101
131
  return pluginPackagesPathArr.split(",").map((pluginPackagesPath) => {
@@ -106,7 +136,8 @@ function getLocalPluginPackagesPathArr() {
106
136
  __name(getLocalPluginPackagesPathArr, "getLocalPluginPackagesPathArr");
107
137
  function getStoragePluginDir(packageName) {
108
138
  const pluginStoragePath = (0, import_utils.resolvePluginStoragePath)();
109
- return import_path.default.join(pluginStoragePath, packageName);
139
+ assertSafePluginPackageName(packageName);
140
+ return resolveSafeChildPath(pluginStoragePath, packageName);
110
141
  }
111
142
  __name(getStoragePluginDir, "getStoragePluginDir");
112
143
  function getLocalPluginDir(packageDirBasename) {
@@ -118,7 +149,8 @@ function getLocalPluginDir(packageDirBasename) {
118
149
  }
119
150
  __name(getLocalPluginDir, "getLocalPluginDir");
120
151
  function getNodeModulesPluginDir(packageName) {
121
- return import_path.default.join(process.env.NODE_MODULES_PATH, packageName);
152
+ assertSafePluginPackageName(packageName);
153
+ return resolveSafeChildPath(process.env.NODE_MODULES_PATH, packageName);
122
154
  }
123
155
  __name(getNodeModulesPluginDir, "getNodeModulesPluginDir");
124
156
  function getAuthorizationHeaders(registry, authToken) {
@@ -551,6 +583,7 @@ async function pmListSummary(app) {
551
583
  __name(pmListSummary, "pmListSummary");
552
584
  // Annotate the CommonJS export names for ESM import in node:
553
585
  0 && (module.exports = {
586
+ assertSafePluginPackageName,
554
587
  checkAndGetCompatible,
555
588
  checkCompatible,
556
589
  copyTempPackageToStorageAndLinkToNodeModules,
@@ -585,5 +618,6 @@ __name(pmListSummary, "pmListSummary");
585
618
  removeTmpDir,
586
619
  requireModule,
587
620
  requireNoCache,
621
+ resolveSafeChildPath,
588
622
  updatePluginByCompressedFileUrl
589
623
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/server",
3
- "version": "2.1.0-alpha.30",
3
+ "version": "2.1.0-alpha.32",
4
4
  "main": "lib/index.js",
5
5
  "types": "./lib/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -10,21 +10,21 @@
10
10
  "@koa/cors": "^5.0.0",
11
11
  "@koa/multer": "^3.1.0",
12
12
  "@koa/router": "^13.1.0",
13
- "@nocobase/acl": "2.1.0-alpha.30",
14
- "@nocobase/actions": "2.1.0-alpha.30",
15
- "@nocobase/ai": "2.1.0-alpha.30",
16
- "@nocobase/auth": "2.1.0-alpha.30",
17
- "@nocobase/cache": "2.1.0-alpha.30",
18
- "@nocobase/data-source-manager": "2.1.0-alpha.30",
19
- "@nocobase/database": "2.1.0-alpha.30",
20
- "@nocobase/evaluators": "2.1.0-alpha.30",
21
- "@nocobase/lock-manager": "2.1.0-alpha.30",
22
- "@nocobase/logger": "2.1.0-alpha.30",
23
- "@nocobase/resourcer": "2.1.0-alpha.30",
24
- "@nocobase/sdk": "2.1.0-alpha.30",
25
- "@nocobase/snowflake-id": "2.1.0-alpha.30",
26
- "@nocobase/telemetry": "2.1.0-alpha.30",
27
- "@nocobase/utils": "2.1.0-alpha.30",
13
+ "@nocobase/acl": "2.1.0-alpha.32",
14
+ "@nocobase/actions": "2.1.0-alpha.32",
15
+ "@nocobase/ai": "2.1.0-alpha.32",
16
+ "@nocobase/auth": "2.1.0-alpha.32",
17
+ "@nocobase/cache": "2.1.0-alpha.32",
18
+ "@nocobase/data-source-manager": "2.1.0-alpha.32",
19
+ "@nocobase/database": "2.1.0-alpha.32",
20
+ "@nocobase/evaluators": "2.1.0-alpha.32",
21
+ "@nocobase/lock-manager": "2.1.0-alpha.32",
22
+ "@nocobase/logger": "2.1.0-alpha.32",
23
+ "@nocobase/resourcer": "2.1.0-alpha.32",
24
+ "@nocobase/sdk": "2.1.0-alpha.32",
25
+ "@nocobase/snowflake-id": "2.1.0-alpha.32",
26
+ "@nocobase/telemetry": "2.1.0-alpha.32",
27
+ "@nocobase/utils": "2.1.0-alpha.32",
28
28
  "@types/decompress": "4.2.7",
29
29
  "@types/ini": "^1.3.31",
30
30
  "@types/koa-send": "^4.1.3",
@@ -42,7 +42,7 @@
42
42
  "fs-extra": "^11.1.1",
43
43
  "i18next": "^22.4.9",
44
44
  "ini": "^4.1.1",
45
- "koa": "^2.15.4",
45
+ "koa": "^3.2.0",
46
46
  "koa-bodyparser": "^4.3.0",
47
47
  "koa-send": "^5.0.1",
48
48
  "koa-static": "^5.0.0",
@@ -61,5 +61,5 @@
61
61
  "@types/serve-handler": "^6.1.1",
62
62
  "@types/ws": "^8.5.5"
63
63
  },
64
- "gitHead": "292ae0ad87f195ed201b274902d21ecd96f5ddd0"
64
+ "gitHead": "1ba7d717e156651db17c615f9b9c48edd669d19b"
65
65
  }