From 2f7eb0ee030966844b45dd00b2259e68b9fb0e83 Mon Sep 17 00:00:00 2001 From: Harminder Virk Date: Fri, 28 Mar 2025 22:39:39 +0530 Subject: [PATCH] fix: validate module names to disallow unallowed characters (#12025) --- .changeset/strange-sloths-hope.md | 6 +++ .../__tests__/validate-module-name.spec.ts | 54 +++++++++++++++++++ packages/core/utils/src/common/index.ts | 1 + .../utils/src/common/validate-module-name.ts | 25 +++++++++ packages/medusa/src/loaders/index.ts | 5 ++ 5 files changed, 91 insertions(+) create mode 100644 .changeset/strange-sloths-hope.md create mode 100644 packages/core/utils/src/common/__tests__/validate-module-name.spec.ts create mode 100644 packages/core/utils/src/common/validate-module-name.ts diff --git a/.changeset/strange-sloths-hope.md b/.changeset/strange-sloths-hope.md new file mode 100644 index 0000000000..5e45256cb5 --- /dev/null +++ b/.changeset/strange-sloths-hope.md @@ -0,0 +1,6 @@ +--- +"@medusajs/medusa": patch +"@medusajs/utils": patch +--- + +fix: validate module names to disallow unallowed characters diff --git a/packages/core/utils/src/common/__tests__/validate-module-name.spec.ts b/packages/core/utils/src/common/__tests__/validate-module-name.spec.ts new file mode 100644 index 0000000000..ffc81decbf --- /dev/null +++ b/packages/core/utils/src/common/__tests__/validate-module-name.spec.ts @@ -0,0 +1,54 @@ +import { validateModuleName } from "../validate-module-name" + +describe("validateModuleName", function () { + it("should disallow variable unsafe module names", function () { + const expectations = [ + { + input: "hello-world", + state: "fail", + }, + { + input: "hello_world", + state: "pass", + }, + { + input: "1st_plugin", + state: "fail", + }, + { + input: "plugin_1st", + state: "pass", + }, + { + input: "acme.module", + state: "fail", + }, + { + input: "acme$module", + state: "fail", + }, + { + input: "$module", + state: "fail", + }, + { + input: "_private_module", + state: "pass", + }, + { + input: "acme&corp_module", + state: "fail", + }, + ] + + expectations.forEach((expectation) => { + if (expectation.state === "fail") { + expect(() => validateModuleName(expectation.input)).toThrow( + `Invalid module name "${expectation.input}". Module names must be alpha numeric and may contain an underscore` + ) + } else { + expect(() => validateModuleName(expectation.input)).not.toThrow() + } + }) + }) +}) diff --git a/packages/core/utils/src/common/index.ts b/packages/core/utils/src/common/index.ts index 34952511c2..bb80855e8f 100644 --- a/packages/core/utils/src/common/index.ts +++ b/packages/core/utils/src/common/index.ts @@ -85,3 +85,4 @@ export * from "./unflatten-object-keys" export * from "./upper-case-first" export * from "./validate-handle" export * from "./wrap-handler" +export * from "./validate-module-name" diff --git a/packages/core/utils/src/common/validate-module-name.ts b/packages/core/utils/src/common/validate-module-name.ts new file mode 100644 index 0000000000..ab4b49e295 --- /dev/null +++ b/packages/core/utils/src/common/validate-module-name.ts @@ -0,0 +1,25 @@ +/** + * Validates the module name to be variable safe. Since we generate + * a lot of code, types under the hood using the module name we + * have ensure that each module name is variable safe. + * + * Ofcourse, we can transform the module name to a variable safe value, + * but that might result into naming conflicts. For example: There are + * two module named as + * + * - sanity-products + * - sanity_products + * + * After transforming them, they will endup with the same output. This is + * a very simple example, but cases like these will lead to naming + * conflicts, so its better to use the names as it is and restrict + * them to be variable safe + */ +const RE = /^[a-zA-Z_][0-9a-zA-Z_]*$/ +export function validateModuleName(name: string) { + if (!RE.test(name)) { + throw new Error( + `Invalid module name "${name}". Module names must be alpha numeric and may contain an underscore` + ) + } +} diff --git a/packages/medusa/src/loaders/index.ts b/packages/medusa/src/loaders/index.ts index f0bbb3a2b3..9ad7390271 100644 --- a/packages/medusa/src/loaders/index.ts +++ b/packages/medusa/src/loaders/index.ts @@ -19,6 +19,7 @@ import { GraphQLSchema, mergePluginModules, promiseAll, + validateModuleName, } from "@medusajs/framework/utils" import { WorkflowLoader } from "@medusajs/framework/workflows" import { asValue } from "awilix" @@ -150,6 +151,10 @@ export default async ({ const plugins = await getResolvedPlugins(rootDirectory, configModule, true) mergePluginModules(configModule, plugins) + Object.keys(configModule.modules ?? {}).forEach((key) => { + validateModuleName(key) + }) + const linksSourcePaths = plugins.map((plugin) => join(plugin.resolve, "links") )