diff --git a/www/apps/book/app/learn/configurations/medusa-config/asymmetric-encryption/page.mdx b/www/apps/book/app/learn/configurations/medusa-config/asymmetric-encryption/page.mdx new file mode 100644 index 0000000000..afa3beb911 --- /dev/null +++ b/www/apps/book/app/learn/configurations/medusa-config/asymmetric-encryption/page.mdx @@ -0,0 +1,484 @@ +import { TypeList, Table } from "docs-ui" + +export const metadata = { + title: `${pageNumber} Asymmetric Encryption`, +} + +# {metadata.title} + +In this chapter, you'll learn how to configure asymmetric encryption in Medusa using public/private key pairs instead of a shared secret. + +## What is Asymmetric Encryption? + +By default, Medusa uses symmetric JWT authentication, where the same secret signs and verifies tokens. With asymmetric encryption, you use a private key to sign tokens and a public key to verify them. + +This approach provides better security, supports key rotation, and enables distributed systems where multiple services can verify tokens without needing access to the signing key. + +### When to Use Asymmetric Encryption + +Asymmetric encryption is useful in several scenarios: + + + + + + Scenario + + + Description + + + Benefits + + + + + + + Multi-Instance Deployments + + + Running multiple Medusa instances behind a load balancer. + + + Centralized signing, reduced risk if an instance is compromised. + + + + + Microservices Architecture + + + Medusa as part of a larger microservices ecosystem. + + + Independent token verification across services. + + + + + JWKS Support + + + Dynamic key rotation using JSON Web Key Sets. + + + Seamless key rotation without service disruption. + + + +
+ +--- + +## How to Configure Asymmetric Encryption + +### Step 1: Set Asymmetric JWT Configuration + +To configure asymmetric encryption, you need to set up both signing and verification options in your `medusa-config.ts` file. + +In `medusa-config.ts`, create a helper function to load the JWT configuration, and use it in the exported configuration: + +```ts title="medusa-config.ts" +// other imports... +import jwt from "jsonwebtoken" + +export const getJwtConfig = () => { + return { + jwtSecret: process.env.JWT_SECRET_KEY, + jwtPublicKey: process.env.JWT_PUBLIC_KEY, + jwtExpiresIn: process.env.JWT_EXPIRES_IN || "1d", + jwtOptions: { + algorithm: (process.env.JWT_ALGORITHM || "RS256") as jwt.Algorithm, + audience: process.env.JWT_AUDIENCE + ? process.env.JWT_AUDIENCE.split(",") + : undefined, + issuer: process.env.JWT_ISSUER, + keyid: process.env.JWT_KEYID, + }, + jwtVerifyOptions: { + algorithms: [(process.env.JWT_ALGORITHM || "RS256") as jwt.Algorithm], + audience: process.env.JWT_AUDIENCE + ? process.env.JWT_AUDIENCE.split(",") + : undefined, + issuer: process.env.JWT_ISSUER, + }, + } +} + +const jwtConfig = getJwtConfig() + +module.exports = defineConfig({ + projectConfig: { + http: { + // ... + jwtSecret: jwtConfig.jwtSecret, + jwtPublicKey: jwtConfig.jwtPublicKey, + jwtExpiresIn: jwtConfig.jwtExpiresIn, + jwtOptions: jwtConfig.jwtOptions, + jwtVerifyOptions: jwtConfig.jwtVerifyOptions, + }, + // ... + }, + modules: [ + { + resolve: "@medusajs/medusa/user", + options: { + jwt_secret: { + key: jwtConfig.jwtSecret, + }, + jwt_public_key: jwtConfig.jwtPublicKey, + jwt_options: jwtConfig.jwtOptions, + }, + }, + ], +}) +``` + +You set the JWT configurations in the following options: + +1. [http options](../page.mdx#http): You set the global JWT options for Medusa's HTTP layer, which are used to sign and verify JWT authentication tokens. + - Refer to the [Medusa Configuration chapter](../page.mdx#http) for more details on these options and their default values. +2. [User Module options](!resources!/commerce-modules/user/module-options): You set the JWT options specific to the User Module, which are used to sign and verify invite tokens. + +### Step 2: Generate Key Pair + +Next, generate an RSA key pair (private and public keys) for signing and verifying tokens. You can use OpenSSL to generate the keys: + +```bash +# Generate private key +openssl genrsa -out private-key.pem 2048 + +# Extract public key +openssl rsa -in private-key.pem -pubout -out public-key.pem +``` + +Make sure not to commit your private key to Git or any public repository. Add it to your `.gitignore` file to prevent accidental commits: + +```title=".gitignore" +# Asymmetric encryption keys (DO NOT COMMIT) +private-key.pem +*.pem +``` + +### Step 3: Set Environment Variables + +Finally, set the following environment variables using the generated keys: + +```bash +# JWT Configuration +JWT_SECRET_KEY="-----BEGIN RSA PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC... +-----END RSA PRIVATE KEY-----" + +JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvTtLGDIK... +-----END PUBLIC KEY-----" + +JWT_ALGORITHM=RS256 +JWT_EXPIRES_IN=1d +JWT_ISSUER=medusa +JWT_AUDIENCE=medusa-api +JWT_KEYID=medusa-key-1 +``` + +Where: + +- `JWT_SECRET_KEY`: Your RSA private key for signing tokens. +- `JWT_PUBLIC_KEY`: Your RSA public key for verifying tokens. +- `JWT_ALGORITHM`: The [signing algorithm](https://www.npmjs.com/package/jsonwebtoken#algorithms-supported). +- `JWT_EXPIRES_IN`: The token expiration time. +- `JWT_ISSUER`: (Optional) The issuer claim for tokens. +- `JWT_AUDIENCE`: (Optional) The audience claim for tokens. +- `JWT_KEYID`: (Optional) The key ID for JWKS support. + + + +For multiline keys in `.env` files, wrap the key with double quotes and use `\n` for newlines. + + + +--- + +## Using JWKS (JSON Web Key Set) + +JWKS (JSON Web Key Set) is a set of public keys used to verify JWT tokens. By exposing a JWKS endpoint, you allow clients to dynamically fetch your public keys for token verification, enabling key rotation without requiring clients to update their configurations. + +This section explains how to set up JWKS support in Medusa and verify tokens using JWKS. + +### Step 1: Install Required Packages + +First, install the packages for handling JWKS and JWT verification. Run the following command in your Medusa application: + +```bash npm2yarn +npm install jwks-rsa jsonwebtoken +npm install @types/jsonwebtoken@8.5.9 --save-dev +``` + +You install the following packages: + +1. `jwks-rsa`: A library to create a JWKS client that can fetch and cache public keys. +2. `jsonwebtoken`: A library to handle JWT token creation and verification. +3. `@types/jsonwebtoken`: TypeScript types for the `jsonwebtoken` package. Make sure to install version `8.5.9` for compatibility. + +### Step 2: Expose JWKS Endpoint + +To allow clients to fetch the JWKS, expose it in an [API route](../../../fundamentals/api-routes/page.mdx). + +In the API route, return the JWKS content containing your public keys. You can set the JWKS content using an environment variable or by manually converting your public key to JWK format. + +#### Option 1: Environment Variable + +The first option is to set the JWKS content using an environment variable. Convert your public key to JWK format using online tools or libraries like [node-jose](https://www.npmjs.com/package/node-jose). + +For example, add the following environment variable: + +```bash +JWKS_CONTENT='{"keys":[{"kty":"RSA","use":"sig","kid":"medusa-key-1","n":"vTtLGDIK...","e":"AQAB"}]}' +``` + +Then, create the API route at `src/api/.well-known/jwks.json/route.ts` with the following content: + +```ts title="src/api/.well-known/jwks.json/route.ts" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" + +export const GET = async ( + req: MedusaRequest, + res: MedusaResponse +) => { + if (!process.env.JWKS_CONTENT) { + return res.status(500).json({ error: "JWKS_CONTENT not configured" }) + } + + res.status(200).json(JSON.parse(process.env.JWKS_CONTENT)) +} +``` + +This exposes your public key at `/.well-known/jwks.json`, which clients can fetch to verify tokens. + +#### Option 2: Manual JWK Conversion + +If you prefer not to use an environment variable, manually convert your public key to JWK format using the JWT configurations you set in `medusa-config.ts`. + +For example, create the API route at `src/api/.well-known/jwks.json/route.ts` with the following content: + +```ts title="src/api/.well-known/jwks.json/route.ts" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import crypto from "crypto" + +export const GET = async ( + req: MedusaRequest, + res: MedusaResponse +) => { + const configModule = req.scope.resolve("configModule") + const { projectConfig } = configModule + + // If JWKS_CONTENT is set, use it + if (process.env.JWKS_CONTENT) { + return res.status(200).json(JSON.parse(process.env.JWKS_CONTENT)) + } + + // Otherwise, generate from public key + const publicKey = projectConfig.http.jwtPublicKey + if (!publicKey) { + return res.status(500).json({ error: "No public key configured" }) + } + + try { + // Convert PEM to JWK + const jwk = crypto.createPublicKey(publicKey).export({ format: "jwk" }) + + const jwks = { + keys: [{ + ...jwk, + use: "sig", + kid: projectConfig.http.jwtOptions?.keyid || "medusa-key-1", + alg: projectConfig.http.jwtOptions?.algorithm || "RS256", + }], + } + + res.status(200).json(jwks) + } catch (error: any) { + return res.status(500).json({ + error: "Failed to generate JWKS", + message: error.message, + }) + } +} +``` + +In the above example: + +1. Check if the `JWKS_CONTENT` environment variable is set and return it if available. +2. If not, retrieve the public key from the Medusa configuration and convert it to JWK format using Node's `crypto` module. +3. Construct the JWKS response and return it. + +The public key will be available at `/.well-known/jwks.json` for clients to fetch. + +### Step 3: Verify Tokens Using JWKS + +Finally, verify JWT tokens from incoming requests using the JWKS API route. + +Create a [middleware](../../../fundamentals/api-routes/middlewares/page.mdx) function at `src/api/middlewares/jwks-auth.ts` that uses the `jwks-rsa` package to fetch the public key and verify the token: + +```ts title="src/api/middlewares/jwks-auth.ts" +import { + MedusaRequest, + MedusaNextFunction, + MedusaResponse, +} from "@medusajs/framework/http" +import jwt from "jsonwebtoken" +import { JwksClient } from "jwks-rsa" + +const MEDUSA_BACKEND_URL = process.env.MEDUSA_BACKEND_URL || "http://localhost:9000" + +// Create JWKS client with caching +const jwksClient = new JwksClient({ + // This is the API route where your JWKS is exposed + jwksUri: `${MEDUSA_BACKEND_URL}/.well-known/jwks.json`, + cache: true, + rateLimit: true, + jwksRequestsPerMinute: 5, + cacheMaxAge: 60 * 60 * 1000, // 1 hour in ms +}) + +// Helper to get signing key +async function getKey(header: any) { + try { + const key = await jwksClient.getSigningKey(header.kid) + + return key.getPublicKey() + } catch (err: any) { + throw new Error(`Failed to get signing key: ${err.message}`) + } +} + +// Function that validates JWT token +export async function isValidJWTToken(token: string): Promise { + if (!token) { + return false + } + + try { + // Decode the token to get the header + const decoded = jwt.decode(token, { complete: true }) as { + header: { kid: string } + payload: { + actor_id: string + } + } | null + + if ( + !decoded || + !decoded.header || + !decoded.header.kid || + !decoded.payload.actor_id + ) { + return false + } + + const publicKey = await getKey(decoded.header) + + return new Promise((resolve) => { + jwt.verify( + token, + publicKey, + { + ignoreExpiration: false, + ignoreNotBefore: false, + }, + (err) => { + if (err) { + console.error("Error verifying JWT token:", err) + resolve(false) + } + + resolve(true) + } + ) + }) + } catch (err: any) { + console.error("Error validating JWT token:", err) + return false + } +} + +// Authentication middleware +export const jwtAuthMiddleware = async ( + req: MedusaRequest, + res: MedusaResponse, + next: MedusaNextFunction +) => { + const authHeader = req.headers.authorization + const jwtToken = authHeader?.split(" ")[1] + + // If we should check login and the JWT token is invalid, return 401 + if (!jwtToken || !(await isValidJWTToken(jwtToken))) { + const error = new Error( + "Invalid auth token provided" + ) + + return next(error) + } + + return next() +} +``` + +The `jwtAuthMiddleware` function extracts the JWT token from the `Authorization` header, fetches the appropriate public key from the JWKS endpoint, and verifies the token. + +Apply this middleware to your protected API routes to ensure that only requests with valid JWT tokens are allowed. + +For example, apply the middleware in `src/api/middlewares.ts`: + +```ts title="src/api/middlewares.ts" +import { defineMiddlewares } from "@medusajs/framework/http" +import { jwtAuthMiddleware } from "./middlewares/jwks-auth" + +export default defineMiddlewares({ + routes: [ + { + matcher: "/custom-protected-route*", + middlewares: [jwtAuthMiddleware], + }, + ], +}) +``` + +### Test JWKS Verification + +To test the JWKS verification, start the Medusa application: + +```bash npm2yarn +npm run dev +``` + +Next, obtain a valid JWT token by authenticating a user. For example, to authenticate an admin user, send a `POST` request to `/auth/user/emailpass`: + +```bash +curl -X POST http://localhost:9000/auth/user/emailpass \ + -H "Content-Type: application/json" \ + -d '{ + "email": "admin@medusa-test.com", + "password": "supersecret" + }' +``` + +Make sure to replace the email and password with valid credentials for your Medusa application. + +The response will include a `token` field, which is your JWT token. + +Finally, make a request to your protected route using the obtained JWT token: + +```bash +curl http://localhost:9000/custom-protected-route \ + -H "Authorization: Bearer YOUR_JWT_TOKEN" +``` + +If the token is valid, the middleware will successfully verify it using the public key fetched from the JWKS endpoint, and you'll receive a successful response. If the token is invalid or expired, you'll receive an error. diff --git a/www/apps/book/app/learn/configurations/medusa-config/page.mdx b/www/apps/book/app/learn/configurations/medusa-config/page.mdx index 5798b9b2fc..aadc093273 100644 --- a/www/apps/book/app/learn/configurations/medusa-config/page.mdx +++ b/www/apps/book/app/learn/configurations/medusa-config/page.mdx @@ -337,6 +337,69 @@ module.exports = defineConfig({ The `http` configures the application's http-specific settings, such as the JWT secret, CORS configurations, and more. +#### http.jwtOptions + +The `projectConfig.http.jwtOptions` configuration specifies options for the JWT token when using asymmetric signing private/public key. These options will be used for validation if `jwtVerifyOptions` is not provided. + +This configuration accepts an object with the same properties as the [jsonwebtoken sign options](https://www.npmjs.com/package/jsonwebtoken#jwtsignpayload-secretorprivatekey-options-callback). + + + +Learn more in the [Asymmetric Encryption chapter](./asymmetric-encryption/page.mdx). + + + +#### Example + +```ts title="medusa-config.ts" +module.exports = defineConfig({ + projectConfig: { + http: { + jwtOptions: { + algorithm: "RS256", + expiresIn: "1h", + issuer: "medusa", + keyid: "medusa", + }, + }, + // ... + }, + // ... +}) +``` + +#### http.jwtPublicKey + +The `projectConfig.http.jwtPublicKey` configuration specifies the public key used to verify the JWT token in combination with the JWT secret and the JWT options. This is only used when the JWT secret is a secret key for asymmetric validation. + +It accepts one of the following values: + +- A string containing the public key in PEM format. +- A `Buffer` containing the public key in PEM format. +- An object containing the following properties: + - `key`: A string or `Buffer` containing the public key in PEM format. + - `passphrase`: A string containing the passphrase for the public key, if applicable. + + + +Learn more in the [Asymmetric Encryption chapter](./asymmetric-encryption/page.mdx). + + + +#### Example + +```ts title="medusa-config.ts" +module.exports = defineConfig({ + projectConfig: { + http: { + jwtPublicKey: process.env.JWT_PUBLIC_KEY, + }, + // ... + }, + // ... +}) +``` + #### http.jwtSecret The `projectConfig.http.jwtSecret` configuration is a random string used to create authentication tokens in the HTTP layer. This configuration is not required in development, but must be set in production. @@ -357,6 +420,35 @@ module.exports = defineConfig({ }) ``` +#### http.jwtVerifyOptions + +The `projectConfig.http.jwtVerifyOptions` configuration specifies options for the JWT token when using asymmetric validation private/public key. + +This configuration accepts the same options as the [jsonwebtoken verify options](https://www.npmjs.com/package/jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback). + + + +Learn more in the [Asymmetric Encryption chapter](./asymmetric-encryption/page.mdx). + + + +#### Example + +```ts title="medusa-config.ts" +module.exports = defineConfig({ + projectConfig: { + http: { + jwtVerifyOptions: { + algorithms: ["RS256"], + issuer: "medusa", + }, + }, + // ... + }, + // ... +}) +``` + #### http.jwtExpiresIn The `projectConfig.http.jwtExpiresIn` configuration specifies the expiration time for the JWT token. Its value format is based off the [ms package](https://github.com/vercel/ms). @@ -944,8 +1036,9 @@ For example, if you're using a third-party library that isn't ESM-compatible, ad ```ts title="medusa-config.ts" module.exports = defineConfig({ admin: { - vite: () => { + vite: (config) => { return { + ...config, optimizeDeps: { include: ["qs"], }, diff --git a/www/apps/book/generated/edit-dates.mjs b/www/apps/book/generated/edit-dates.mjs index 507135ab0e..7bb838bf00 100644 --- a/www/apps/book/generated/edit-dates.mjs +++ b/www/apps/book/generated/edit-dates.mjs @@ -111,7 +111,7 @@ export const generatedEditDates = { "app/learn/resources/contribution-guidelines/admin-translations/page.mdx": "2025-02-11T16:57:46.726Z", "app/learn/resources/contribution-guidelines/docs/page.mdx": "2025-09-26T13:53:55.070Z", "app/learn/resources/usage/page.mdx": "2025-02-26T13:35:34.824Z", - "app/learn/configurations/medusa-config/page.mdx": "2025-09-30T06:04:15.705Z", + "app/learn/configurations/medusa-config/page.mdx": "2025-10-31T09:58:10.385Z", "app/learn/configurations/ts-aliases/page.mdx": "2025-07-23T15:32:18.008Z", "app/learn/production/worker-mode/page.mdx": "2025-10-13T10:33:27.403Z", "app/learn/fundamentals/module-links/read-only/page.mdx": "2025-10-15T15:42:22.610Z", @@ -135,5 +135,6 @@ export const generatedEditDates = { "app/learn/fundamentals/workflows/locks/page.mdx": "2025-09-15T09:37:00.808Z", "app/learn/codemods/page.mdx": "2025-09-29T15:40:03.620Z", "app/learn/codemods/replace-imports/page.mdx": "2025-10-09T11:37:44.754Z", - "app/learn/fundamentals/admin/translations/page.mdx": "2025-10-30T11:55:32.221Z" + "app/learn/fundamentals/admin/translations/page.mdx": "2025-10-30T11:55:32.221Z", + "app/learn/configurations/medusa-config/asymmetric-encryption/page.mdx": "2025-10-31T09:53:38.607Z" } \ No newline at end of file diff --git a/www/apps/book/generated/sidebar.mjs b/www/apps/book/generated/sidebar.mjs index 2c58de34f8..ff3e8c5ab5 100644 --- a/www/apps/book/generated/sidebar.mjs +++ b/www/apps/book/generated/sidebar.mjs @@ -1127,7 +1127,18 @@ export const generatedSidebars = [ "type": "link", "title": "Medusa Configuations", "path": "/learn/configurations/medusa-config", - "children": [], + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Asymmetric Encryption", + "path": "/learn/configurations/medusa-config/asymmetric-encryption", + "children": [], + "chapterTitle": "6.2.1. Asymmetric Encryption", + "number": "6.2.1." + } + ], "chapterTitle": "6.2. Medusa Configuations", "number": "6.2." }, diff --git a/www/apps/book/public/llms-full.txt b/www/apps/book/public/llms-full.txt index 4b2a635f4b..ab59974e3d 100644 --- a/www/apps/book/public/llms-full.txt +++ b/www/apps/book/public/llms-full.txt @@ -427,6 +427,437 @@ If everything is working correctly, you can remove the `replace-imports.js` file - `@opentelemetry/sdk-trace-node` +# Asymmetric Encryption + +In this chapter, you'll learn how to configure asymmetric encryption in Medusa using public/private key pairs instead of a shared secret. + +## What is Asymmetric Encryption? + +By default, Medusa uses symmetric JWT authentication, where the same secret signs and verifies tokens. With asymmetric encryption, you use a private key to sign tokens and a public key to verify them. + +This approach provides better security, supports key rotation, and enables distributed systems where multiple services can verify tokens without needing access to the signing key. + +### When to Use Asymmetric Encryption + +Asymmetric encryption is useful in several scenarios: + +|Scenario|Description|Benefits| +|---|---|---| +|Multi-Instance Deployments|Running multiple Medusa instances behind a load balancer.|Centralized signing, reduced risk if an instance is compromised.| +|Microservices Architecture|Medusa as part of a larger microservices ecosystem.|Independent token verification across services.| +|JWKS Support|Dynamic key rotation using JSON Web Key Sets.|Seamless key rotation without service disruption.| + +*** + +## How to Configure Asymmetric Encryption + +### Step 1: Set Asymmetric JWT Configuration + +To configure asymmetric encryption, you need to set up both signing and verification options in your `medusa-config.ts` file. + +In `medusa-config.ts`, create a helper function to load the JWT configuration, and use it in the exported configuration: + +```ts title="medusa-config.ts" +// other imports... +import jwt from "jsonwebtoken" + +export const getJwtConfig = () => { + return { + jwtSecret: process.env.JWT_SECRET_KEY, + jwtPublicKey: process.env.JWT_PUBLIC_KEY, + jwtExpiresIn: process.env.JWT_EXPIRES_IN || "1d", + jwtOptions: { + algorithm: (process.env.JWT_ALGORITHM || "RS256") as jwt.Algorithm, + audience: process.env.JWT_AUDIENCE + ? process.env.JWT_AUDIENCE.split(",") + : undefined, + issuer: process.env.JWT_ISSUER, + keyid: process.env.JWT_KEYID, + }, + jwtVerifyOptions: { + algorithms: [(process.env.JWT_ALGORITHM || "RS256") as jwt.Algorithm], + audience: process.env.JWT_AUDIENCE + ? process.env.JWT_AUDIENCE.split(",") + : undefined, + issuer: process.env.JWT_ISSUER, + }, + } +} + +const jwtConfig = getJwtConfig() + +module.exports = defineConfig({ + projectConfig: { + http: { + // ... + jwtSecret: jwtConfig.jwtSecret, + jwtPublicKey: jwtConfig.jwtPublicKey, + jwtExpiresIn: jwtConfig.jwtExpiresIn, + jwtOptions: jwtConfig.jwtOptions, + jwtVerifyOptions: jwtConfig.jwtVerifyOptions, + }, + // ... + }, + modules: [ + { + resolve: "@medusajs/medusa/user", + options: { + jwt_secret: { + key: jwtConfig.jwtSecret, + }, + jwt_public_key: jwtConfig.jwtPublicKey, + jwt_options: jwtConfig.jwtOptions, + }, + }, + ], +}) +``` + +You set the JWT configurations in the following options: + +1. [http options](https://docs.medusajs.com/learn/configurations/medusa-config#http/index.html.md): You set the global JWT options for Medusa's HTTP layer, which are used to sign and verify JWT authentication tokens. + - Refer to the [Medusa Configuration chapter](https://docs.medusajs.com/learn/configurations/medusa-config#http/index.html.md) for more details on these options and their default values. +2. [User Module options](https://docs.medusajs.com/resources/commerce-modules/user/module-options/index.html.md): You set the JWT options specific to the User Module, which are used to sign and verify invite tokens. + +### Step 2: Generate Key Pair + +Next, generate an RSA key pair (private and public keys) for signing and verifying tokens. You can use OpenSSL to generate the keys: + +```bash +# Generate private key +openssl genrsa -out private-key.pem 2048 + +# Extract public key +openssl rsa -in private-key.pem -pubout -out public-key.pem +``` + +Make sure not to commit your private key to Git or any public repository. Add it to your `.gitignore` file to prevent accidental commits: + +```title=".gitignore" +# Asymmetric encryption keys (DO NOT COMMIT) +private-key.pem +*.pem +``` + +### Step 3: Set Environment Variables + +Finally, set the following environment variables using the generated keys: + +```bash +# JWT Configuration +JWT_SECRET_KEY="-----BEGIN RSA PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC... +-----END RSA PRIVATE KEY-----" + +JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvTtLGDIK... +-----END PUBLIC KEY-----" + +JWT_ALGORITHM=RS256 +JWT_EXPIRES_IN=1d +JWT_ISSUER=medusa +JWT_AUDIENCE=medusa-api +JWT_KEYID=medusa-key-1 +``` + +Where: + +- `JWT_SECRET_KEY`: Your RSA private key for signing tokens. +- `JWT_PUBLIC_KEY`: Your RSA public key for verifying tokens. +- `JWT_ALGORITHM`: The [signing algorithm](https://www.npmjs.com/package/jsonwebtoken#algorithms-supported). +- `JWT_EXPIRES_IN`: The token expiration time. +- `JWT_ISSUER`: (Optional) The issuer claim for tokens. +- `JWT_AUDIENCE`: (Optional) The audience claim for tokens. +- `JWT_KEYID`: (Optional) The key ID for JWKS support. + +For multiline keys in `.env` files, wrap the key with double quotes and use `\n` for newlines. + +*** + +## Using JWKS (JSON Web Key Set) + +JWKS (JSON Web Key Set) is a set of public keys used to verify JWT tokens. By exposing a JWKS endpoint, you allow clients to dynamically fetch your public keys for token verification, enabling key rotation without requiring clients to update their configurations. + +This section explains how to set up JWKS support in Medusa and verify tokens using JWKS. + +### Step 1: Install Required Packages + +First, install the packages for handling JWKS and JWT verification. Run the following command in your Medusa application: + +```bash npm2yarn +npm install jwks-rsa jsonwebtoken +npm install @types/jsonwebtoken@8.5.9 --save-dev +``` + +You install the following packages: + +1. `jwks-rsa`: A library to create a JWKS client that can fetch and cache public keys. +2. `jsonwebtoken`: A library to handle JWT token creation and verification. +3. `@types/jsonwebtoken`: TypeScript types for the `jsonwebtoken` package. Make sure to install version `8.5.9` for compatibility. + +### Step 2: Expose JWKS Endpoint + +To allow clients to fetch the JWKS, expose it in an [API route](https://docs.medusajs.com/learn/fundamentals/api-routes/index.html.md). + +In the API route, return the JWKS content containing your public keys. You can set the JWKS content using an environment variable or by manually converting your public key to JWK format. + +#### Option 1: Environment Variable + +The first option is to set the JWKS content using an environment variable. Convert your public key to JWK format using online tools or libraries like [node-jose](https://www.npmjs.com/package/node-jose). + +For example, add the following environment variable: + +```bash +JWKS_CONTENT='{"keys":[{"kty":"RSA","use":"sig","kid":"medusa-key-1","n":"vTtLGDIK...","e":"AQAB"}]}' +``` + +Then, create the API route at `src/api/.well-known/jwks.json/route.ts` with the following content: + +```ts title="src/api/.well-known/jwks.json/route.ts" +import type { + MedusaRequest, + MedusaResponse +} from "@medusajs/framework/http" + +export const GET = async ( + req: MedusaRequest, + res: MedusaResponse +) => { + if (!process.env.JWKS_CONTENT) { + return res.status(500).json({ error: "JWKS_CONTENT not configured" }) + } + + res.status(200).json(JSON.parse(process.env.JWKS_CONTENT)) +} +``` + +This exposes your public key at `/.well-known/jwks.json`, which clients can fetch to verify tokens. + +#### Option 2: Manual JWK Conversion + +If you prefer not to use an environment variable, manually convert your public key to JWK format using the JWT configurations you set in `medusa-config.ts`. + +For example, create the API route at `src/api/.well-known/jwks.json/route.ts` with the following content: + +```ts title="src/api/.well-known/jwks.json/route.ts" +import type { + MedusaRequest, + MedusaResponse +} from "@medusajs/framework/http" +import crypto from "crypto" + +export const GET = async ( + req: MedusaRequest, + res: MedusaResponse +) => { + const configModule = req.scope.resolve("configModule") + const { projectConfig } = configModule + + // If JWKS_CONTENT is set, use it + if (process.env.JWKS_CONTENT) { + return res.status(200).json(JSON.parse(process.env.JWKS_CONTENT)) + } + + // Otherwise, generate from public key + const publicKey = projectConfig.http.jwtPublicKey + if (!publicKey) { + return res.status(500).json({ error: "No public key configured" }) + } + + try { + // Convert PEM to JWK + const jwk = crypto.createPublicKey(publicKey).export({ format: "jwk" }) + + const jwks = { + keys: [{ + ...jwk, + use: "sig", + kid: projectConfig.http.jwtOptions?.keyid || "medusa-key-1", + alg: projectConfig.http.jwtOptions?.algorithm || "RS256" + }] + } + + res.status(200).json(jwks) + } catch (error: any) { + return res.status(500).json({ + error: "Failed to generate JWKS", + message: error.message + }) + } +} +``` + +In the above example: + +1. Check if the `JWKS_CONTENT` environment variable is set and return it if available. +2. If not, retrieve the public key from the Medusa configuration and convert it to JWK format using Node's `crypto` module. +3. Construct the JWKS response and return it. + +The public key will be available at `/.well-known/jwks.json` for clients to fetch. + +### Step 3: Verify Tokens Using JWKS + +Finally, verify JWT tokens from incoming requests using the JWKS API route. + +Create a [middleware](https://docs.medusajs.com/learn/fundamentals/api-routes/middlewares/index.html.md) function at `src/api/middlewares/jwks-auth.ts` that uses the `jwks-rsa` package to fetch the public key and verify the token: + +```ts title="src/api/middlewares/jwks-auth.ts" +import { + MedusaRequest, + MedusaNextFunction, + MedusaResponse, +} from "@medusajs/framework/http" +import jwt from "jsonwebtoken" +import { JwksClient } from "jwks-rsa" + +const MEDUSA_BACKEND_URL = process.env.MEDUSA_BACKEND_URL || "http://localhost:9000" + +// Create JWKS client with caching +const jwksClient = new JwksClient({ + // This is the API route where your JWKS is exposed + jwksUri: `${MEDUSA_BACKEND_URL}/.well-known/jwks.json`, + cache: true, + rateLimit: true, + jwksRequestsPerMinute: 5, + cacheMaxAge: 60 * 60 * 1000, // 1 hour in ms +}) + +// Helper to get signing key +async function getKey(header: any) { + try { + const key = await jwksClient.getSigningKey(header.kid) + + return key.getPublicKey() + } catch (err: any) { + throw new Error(`Failed to get signing key: ${err.message}`) + } +} + +// Function that validates JWT token +export async function isValidJWTToken(token: string): Promise { + if (!token) { + return false + } + + try { + // Decode the token to get the header + const decoded = jwt.decode(token, { complete: true }) as { + header: { kid: string } + payload: { + actor_id: string + } + } | null + + if ( + !decoded || + !decoded.header || + !decoded.header.kid || + !decoded.payload.actor_id + ) { + return false + } + + const publicKey = await getKey(decoded.header) + + return new Promise((resolve) => { + jwt.verify( + token, + publicKey, + { + ignoreExpiration: false, + ignoreNotBefore: false, + }, + (err) => { + if (err) { + console.error("Error verifying JWT token:", err) + resolve(false) + } + + resolve(true) + } + ) + }) + } catch (err: any) { + console.error("Error validating JWT token:", err) + return false + } +} + +// Authentication middleware +export const jwtAuthMiddleware = async ( + req: MedusaRequest, + res: MedusaResponse, + next: MedusaNextFunction +) => { + const authHeader = req.headers.authorization + const jwtToken = authHeader?.split(" ")[1] + + // If we should check login and the JWT token is invalid, return 401 + if (!jwtToken || !(await isValidJWTToken(jwtToken))) { + const error = new Error( + "Invalid auth token provided" + ) + + return next(error) + } + + return next() +} +``` + +The `jwtAuthMiddleware` function extracts the JWT token from the `Authorization` header, fetches the appropriate public key from the JWKS endpoint, and verifies the token. + +Apply this middleware to your protected API routes to ensure that only requests with valid JWT tokens are allowed. + +For example, apply the middleware in `src/api/middlewares.ts`: + +```ts title="src/api/middlewares.ts" +import { defineMiddlewares } from "@medusajs/framework/http" +import { jwtAuthMiddleware } from "./middlewares/jwks-auth" + +export default defineMiddlewares({ + routes: [ + { + matcher: "/custom-protected-route*", + middlewares: [jwtAuthMiddleware], + } + ] +}) +``` + +### Test JWKS Verification + +To test the JWKS verification, start the Medusa application: + +```bash npm2yarn +npm run dev +``` + +Next, obtain a valid JWT token by authenticating a user. For example, to authenticate an admin user, send a `POST` request to `/auth/user/emailpass`: + +```bash +curl -X POST http://localhost:9000/auth/user/emailpass \ + -H "Content-Type: application/json" \ + -d '{ + "email": "admin@medusa-test.com", + "password": "supersecret" + }' +``` + +Make sure to replace the email and password with valid credentials for your Medusa application. + +The response will include a `token` field, which is your JWT token. + +Finally, make a request to your protected route using the obtained JWT token: + +```bash +curl http://localhost:9000/custom-protected-route \ + -H "Authorization: Bearer YOUR_JWT_TOKEN" +``` + +If the token is valid, the middleware will successfully verify it using the public key fetched from the JWKS endpoint, and you'll receive a successful response. If the token is invalid or expired, you'll receive an error. + + # Medusa Application Configuration In this chapter, you'll learn available configurations in the Medusa application. You can change the application's configurations to customize the behavior of the application, its integrated modules and plugins, and more. @@ -646,6 +1077,61 @@ module.exports = defineConfig({ The `http` configures the application's http-specific settings, such as the JWT secret, CORS configurations, and more. +#### http.jwtOptions + +The `projectConfig.http.jwtOptions` configuration specifies options for the JWT token when using asymmetric signing private/public key. These options will be used for validation if `jwtVerifyOptions` is not provided. + +This configuration accepts an object with the same properties as the [jsonwebtoken sign options](https://www.npmjs.com/package/jsonwebtoken#jwtsignpayload-secretorprivatekey-options-callback). + +Learn more in the [Asymmetric Encryption chapter](https://docs.medusajs.com/learn/configurations/medusa-config/asymmetric-encryption/index.html.md). + +#### Example + +```ts title="medusa-config.ts" +module.exports = defineConfig({ + projectConfig: { + http: { + jwtOptions: { + algorithm: "RS256", + expiresIn: "1h", + issuer: "medusa", + keyid: "medusa", + }, + }, + // ... + }, + // ... +}) +``` + +#### http.jwtPublicKey + +The `projectConfig.http.jwtPublicKey` configuration specifies the public key used to verify the JWT token in combination with the JWT secret and the JWT options. This is only used when the JWT secret is a secret key for asymmetric validation. + +It accepts one of the following values: + +- A string containing the public key in PEM format. +- A `Buffer` containing the public key in PEM format. +- An object containing the following properties: + - `key`: A string or `Buffer` containing the public key in PEM format. + - `passphrase`: A string containing the passphrase for the public key, if applicable. + +Learn more in the [Asymmetric Encryption chapter](https://docs.medusajs.com/learn/configurations/medusa-config/asymmetric-encryption/index.html.md). + +#### Example + +```ts title="medusa-config.ts" +module.exports = defineConfig({ + projectConfig: { + http: { + jwtPublicKey: process.env.JWT_PUBLIC_KEY, + }, + // ... + }, + // ... +}) +``` + #### http.jwtSecret The `projectConfig.http.jwtSecret` configuration is a random string used to create authentication tokens in the HTTP layer. This configuration is not required in development, but must be set in production. @@ -666,6 +1152,31 @@ module.exports = defineConfig({ }) ``` +#### http.jwtVerifyOptions + +The `projectConfig.http.jwtVerifyOptions` configuration specifies options for the JWT token when using asymmetric validation private/public key. + +This configuration accepts the same options as the [jsonwebtoken verify options](https://www.npmjs.com/package/jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback). + +Learn more in the [Asymmetric Encryption chapter](https://docs.medusajs.com/learn/configurations/medusa-config/asymmetric-encryption/index.html.md). + +#### Example + +```ts title="medusa-config.ts" +module.exports = defineConfig({ + projectConfig: { + http: { + jwtVerifyOptions: { + algorithms: ["RS256"], + issuer: "medusa", + }, + }, + // ... + }, + // ... +}) +``` + #### http.jwtExpiresIn The `projectConfig.http.jwtExpiresIn` configuration specifies the expiration time for the JWT token. Its value format is based off the [ms package](https://github.com/vercel/ms). @@ -1165,8 +1676,9 @@ For example, if you're using a third-party library that isn't ESM-compatible, ad ```ts title="medusa-config.ts" module.exports = defineConfig({ admin: { - vite: () => { + vite: (config) => { return { + ...config, optimizeDeps: { include: ["qs"], }, @@ -25470,12 +25982,12 @@ Businesses of all sizes can use Medusa, from small start ups to large enterprise Below are some stories from companies that use Medusa: +- [Use Case: Advanced Fulfillment](https://medusajs.com/blog/eight-sleep/): How Eight Sleeps built their fulfillment setup with Medusa - [Use Case: D2C](https://medusajs.com/blog/matt-sleeps/): How Matt Sleeps built a unique D2C experience with Medusa -- [Use Case: OMS](https://medusajs.com/blog/makro-pro/): How Makro Pro Built an OMS with Medusa - [Use Case: Marketplace](https://medusajs.com/blog/foraged/): How Foraged built a custom marketplace with Medusa -- [Use Case: POS](https://medusajs.com/blog/tekla-pos/): How Tekla built a global webshop and a POS system with Medusa -- [Use Case: B2B](https://medusajs.com/blog/visionary/): How Visionary built B2B commerce with Medusa -- [Use Case: Platform](https://medusajs.com/blog/catalog/): How Catalog built a B2B platform for SMBs with Medusa +- [Use Case: Distributor Platform](https://medusajs.com/blog/redington): How Redington built a B2B distributor platform with Medusa +- [Use Case: Quick to market](https://medusajs.com/blog/partbase): How Partbase built their distributor platform with Medusa +- [Use Case: Complex products & pricing](https://medusajs.com/blog/eki/): How EKI built a B2B platform with complex products and pricing *** @@ -41099,38 +41611,54 @@ class ResendNotificationProviderService extends AbstractNotificationProviderServ In this guide, you'll learn about the options you can pass to the User Module. -## Module Options +## Options Example ```ts title="medusa-config.ts" -import { Modules } from "@medusajs/framework/utils" - -// ... - module.exports = defineConfig({ // ... modules: [ { - resolve: "@medusajs/user", + resolve: "@medusajs/medusa/user", options: { jwt_secret: process.env.JWT_SECRET, + jwt_public_key: process.env.JWT_PUBLIC_KEY, + valid_duration: 60 * 60 * 24, // 24 hours + jwt_options: { + algorithm: process.env.JWT_ALGORITHM || "RS256", + issuer: process.env.JWT_ISSUER || "medusa", + }, + jwt_verify_options: { + algorithms: [process.env.JWT_ALGORITHM || "RS256"], + issuer: process.env.JWT_ISSUER || "medusa", + }, }, }, ], }) ``` -|Option|Description|Required| -|---|---|---|---|---| -|\`jwt\_secret\`|A string indicating the secret used to sign the invite tokens.|Yes| - ### Environment Variables Make sure to add the necessary environment variables for the above options to your `.env` file: ```bash JWT_SECRET=supersecret +# Optional: For asymmetric key validation +JWT_PUBLIC_KEY=your_public_key_here +JWT_ALGORITHM=RS256 +JWT_ISSUER=medusa ``` +### All Options + +|Option|Description|Required|Default| +|---|---|---|---|---|---|---| +|\`jwt\_secret\`|A string indicating the secret used to sign the invite tokens.|Yes|-| +|\`jwt\_public\_key\`|A string indicating the public key used to verify JWT tokens when using asymmetric validation. Only used when the JWT secret is a private key for asymmetric signing.|No|-| +|\`valid\_duration\`|A number indicating the duration in seconds that an invite token is valid. This is used to set the expiration time for invite tokens.|No|\`86400\`| +|\`jwt\_options\`|An object containing options for signing JWT tokens when using asymmetric signing with a private/public key pair. Accepts any options from |No|\`\{}\`| +|\`jwt\_verify\_options\`|An object containing options for verifying JWT tokens when using asymmetric validation with a private/public key pair. Accepts any options from |No|Value of | + # User Module @@ -62527,7 +63055,7 @@ export const createCategoryImagesWorkflow = createWorkflow( .then( () => { const categoryIds = transform({ - input + input, }, (data) => { return data.input.category_images.filter( (img) => img.type === "thumbnail" @@ -62630,10 +63158,10 @@ To apply middleware to a route, create the file `src/api/middlewares.ts` with th ```ts title="src/api/middlewares.ts" import { defineMiddlewares, - validateAndTransformBody -} from "@medusajs/framework/http"; + validateAndTransformBody, +} from "@medusajs/framework/http" import { - CreateCategoryImagesSchema + CreateCategoryImagesSchema, } from "./admin/categories/[category_id]/images/route" export default defineMiddlewares({ @@ -62642,11 +63170,11 @@ export default defineMiddlewares({ matcher: "/admin/categories/:category_id/images", method: ["POST"], middlewares: [ - validateAndTransformBody(CreateCategoryImagesSchema) - ] + validateAndTransformBody(CreateCategoryImagesSchema), + ], }, ], -}); +}) ``` You apply Medusa's `validateAndTransformBody` middleware to `POST` requests sent to the `/admin/categories/:category_id/images` route. The middleware function accepts a Zod schema that you created in the API route's file. @@ -62919,7 +63447,7 @@ export const CategoryImageGallery = ({
{/* Existing images */} {visibleExistingImages.map((image) => { - if (!image.id) return null + if (!image.id) {return null} const imageId = image.id const isThumbnail = currentThumbnailId === imageId @@ -63244,7 +63772,7 @@ Next, you'll add a function to handle file uploads. Replace the `// TODO handle ```tsx title="src/admin/components/category-media/category-media-modal.tsx" const handleUploadFile = (files: FileList | null) => { - if (!files || files.length === 0) return + if (!files || files.length === 0) {return} const filesArray = Array.from(files) uploadFilesMutation.mutate(filesArray, { @@ -63476,6 +64004,8 @@ export const updateCategoryImagesStep = createStep( type: img.type, })) ) + } +) ``` This step accepts an array of updates, where each update contains the category image ID to update and the new type. @@ -63513,7 +64043,7 @@ export const updateCategoryImagesWorkflow = createWorkflow( .then( () => { const categoryImageIds = transform({ - input + input, }, (data) => data.input.updates.filter( (u) => u.type === "thumbnail" ).map((u) => u.id)) @@ -63524,11 +64054,11 @@ export const updateCategoryImagesWorkflow = createWorkflow( id: categoryImageIds, }, options: { - throwIfKeyNotFound: true - } + throwIfKeyNotFound: true, + }, }) const categoryIds = transform({ - categoryImages + categoryImages, }, (data) => data.categoryImages.map((img) => img.category_id)) convertCategoryThumbnailsStep({ @@ -63563,7 +64093,7 @@ Create the file `src/api/admin/categories/[category_id]/images/batch/route.ts` w ```ts title="src/api/admin/categories/[category_id]/images/batch/route.ts" import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" import { - updateCategoryImagesWorkflow + updateCategoryImagesWorkflow, } from "../../../../../../workflows/update-category-images" import { z } from "zod" @@ -63854,7 +64384,7 @@ Then, add a function that sets the selected image as the thumbnail: ```tsx title="src/admin/components/category-media/category-media-modal.tsx" const handleSetAsThumbnail = () => { - if (selectedImageIds.size !== 1) return + if (selectedImageIds.size !== 1) {return} const selectedId = Array.from(selectedImageIds)[0] setCurrentThumbnailId(selectedId) @@ -63862,7 +64392,9 @@ const handleSetAsThumbnail = () => { // update uploaded file type to thumbnail const uploadedFileId = selectedId.replace("uploaded:", "") setUploadedFiles((prev) => - prev.map((file) => file.id === uploadedFileId ? { ...file, type: "thumbnail" } : file) + prev.map((file) => { + return file.id === uploadedFileId ? { ...file, type: "thumbnail" } : file + }) ) } @@ -64100,8 +64632,8 @@ export const deleteCategoryImagesWorkflow = createWorkflow( id: input.ids, }, options: { - throwIfKeyNotFound: true - } + throwIfKeyNotFound: true, + }, }) // Transform the category images to extract file IDs @@ -64142,7 +64674,7 @@ In `src/api/admin/categories/[category_id]/images/batch/route.ts`, add the follo ```ts title="src/api/admin/categories/[category_id]/images/batch/route.ts" import { - deleteCategoryImagesWorkflow + deleteCategoryImagesWorkflow, } from "../../../../../../workflows/delete-category-image" ``` @@ -64321,7 +64853,7 @@ After that, add a function that marks selected images for deletion: ```tsx title="src/admin/components/category-media/category-media-modal.tsx" const handleDelete = () => { - if (selectedImageIds.size === 0) return + if (selectedImageIds.size === 0) {return} const uploadedFileIds: string[] = [] const savedImageIds: string[] = [] @@ -64436,12 +64968,17 @@ You update the `handleSave` function to: Finally, in the `return` statement, replace the `/* TODO add delete command */` comment with the following: ```tsx title="src/admin/components/category-media/category-media-modal.tsx" - - +return ( + 0}> + {/* ... */} + + + +) ``` You add a command to "Delete" the selected images. You can also press the "d" key as a shortcut. @@ -64869,7 +65406,7 @@ export default function CategoryTemplate({ const pageNumber = page ? parseInt(page) : 1 const sort = sortBy || "created_at" - if (!category || !countryCode) notFound() + if (!category || !countryCode) {notFound()} const parents = [] as HttpTypes.StoreProductCategory[] @@ -64974,7 +65511,7 @@ You've now added support for category images in Medusa. You can expand on this b - Adding images to other models, such as collections. - Adding support for reordering category images. -- Allowing setting multiple thumbnails for different use cases (e.g., mobile vs. desktop). +- Allowing setting multiple thumbnails for different use cases (for example, mobile vs. desktop). - Adding alt text for category images for better accessibility and SEO. ### Learn More About Medusa diff --git a/www/apps/book/public/llms.txt b/www/apps/book/public/llms.txt index 65d540aef7..69fca7d48b 100644 --- a/www/apps/book/public/llms.txt +++ b/www/apps/book/public/llms.txt @@ -14,374 +14,121 @@ Businesses of all sizes can use Medusa, from small start ups to large enterprise > When searching for Medusa documentation, append `index.html.md` to the end of the URL to get a plain-text version of the document. -## Docs +## Get Started - [Get Started](https://docs.medusajs.com/learn/installation/index.html.md): Install a digital commerce application with Medusa. - [Main docs](https://docs.medusajs.com/learn/index.html.md): Chapters to learn Medusa's concepts and toolings. -- [Development guides and resources](https://docs.medusajs.com/resources/index.html.md): Development guides for storefront, admin, Commerce Modules, and more. -- [Medusa UI](https://docs.medusajs.com/ui/index.html.md): A React library to build applications using Medusa's primitives and design system. -- [Admin API Reference](https://docs.medusajs.com/api/admin): List of all Admin API routes in Medusa with code snippets. -- [Store API Reference](https://docs.medusajs.com/api/store): List of all Store API Routes in Medusa with code snippets. -## Framework +## Product -- [Architecture](https://docs.medusajs.com/learn/introduction/architecture/index.html.md): Overview of Medusa's architecture. -- [Medusa Container](https://docs.medusajs.com/learn/fundamentals/medusa-container/index.html.md): The Medusa container is a registry of framework and commerce tools that's accessible across your application. -- [Modules](https://docs.medusajs.com/learn/fundamentals/modules/index.html.md): A module is a reusable package of functionalities related to a single domain or integration. Medusa comes with multiple pre-built modules for core commerce needs, such as the Cart Module that holds the data models and business logic for cart operations. -- [Module Isolation](https://docs.medusajs.com/learn/fundamentals/modules/isolation/index.html.md): Modules are isolated to ensure they can be integrated into your setup without side-effects. -- [Module Links](https://docs.medusajs.com/learn/fundamentals/module-links/index.html.md): A module link forms an association between two data models of different modules, while maintaining module isolation. -- [Link](https://docs.medusajs.com/learn/fundamentals/module-links/link/index.html.md): Link is a class with utility methods to manage links between data models. -- [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query/index.html.md): Query is a tool that fetches data across modules. -- [Data Models](https://docs.medusajs.com/learn/fundamentals/data-models/index.html.md): A data model represents a table in the database. You create data models using Medusa's data modeling language (DML). -- [API Routes](https://docs.medusajs.com/learn/fundamentals/api-routes/index.html.md): An API Route is an endpoint. It exposes commerce features to external applications, such as storefronts, the admin dashboard, or third-party systems. -- [Workflows](https://docs.medusajs.com/learn/fundamentals/workflows/index.html.md): A workflow is a series of queries and actions, called steps, that complete a task. -- [Events and Subscribers](https://docs.medusajs.com/learn/fundamentals/events-and-subscribers/index.html.md): Medusa emits events when core commerce features are performed, and you can listen to and handle these events in asynchronous functions, called subscribers. -- [Scheduled Jobs](https://docs.medusajs.com/learn/fundamentals/scheduled-jobs/index.html.md): A scheduled job is an asynchronous function that the Medusa application runs at the interval you specify during the Medusa application's runtime. -- [Loaders](https://docs.medusajs.com/learn/fundamentals/modules/loaders/index.html.md): A loader is a function exported by a module. When the Medusa application starts, it executes all loaders exported by configured modules. -- [Admin Widgets](https://docs.medusajs.com/learn/fundamentals/admin/widgets/index.html.md): The Medusa Admin dashboard's pages are customizable to insert widgets of custom content in pre-defined injection zones. You create these widgets as React components that allow admin users to perform custom actions. -- [Admin UI Routes](https://docs.medusajs.com/learn/fundamentals/admin/ui-routes/index.html.md): The Medusa Admin dashboard is customizable, allowing you to add new pages, called UI routes. You create a UI route as a React component showing custom content that allow admin users to perform custom actions. +### Framework -## Built-in Modules +- [Framework Overview](https://docs.medusajs.com/learn/fundamentals/framework/index.html.md): Overview of Medusa's Framework and concepts in it like API routes, modules, data models, etc... +- [API Routes](https://docs.medusajs.com/learn/fundamentals/api-routes/index.html.md): Create custom API endpoints. +- [Data Models](https://docs.medusajs.com/learn/fundamentals/data-models/index.html.md): Define and manage data models. +- [Events and Subscribers](https://docs.medusajs.com/learn/fundamentals/events-and-subscribers/index.html.md): Handle events and create subscribers. +- [Index Module](https://docs.medusajs.com/learn/fundamentals/module-links/index-module/index.html.md): Use the Index Module for module links. +- [Medusa Container](https://docs.medusajs.com/learn/fundamentals/medusa-container/index.html.md): Access registered resources in Medusa. +- [Modules](https://docs.medusajs.com/learn/fundamentals/modules/index.html.md): Build reusable commerce functionalities. +- [Module Links](https://docs.medusajs.com/learn/fundamentals/module-links/index.html.md): Link data models across modules. +- [Plugins](https://docs.medusajs.com/learn/fundamentals/plugins/index.html.md): Extend Medusa with plugins. +- [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query/index.html.md): Query linked data models. +- [Scheduled Jobs](https://docs.medusajs.com/learn/fundamentals/scheduled-jobs/index.html.md): Create and manage scheduled jobs. +- [Workflows](https://docs.medusajs.com/learn/fundamentals/workflows/index.html.md): Build workflows and automations. -- [Commerce Modules](https://docs.medusajs.com/resources/commerce-modules): A Commerce Module provides features for a commerce domain within its service. The Medusa application exposes these features in its API routes to clients. -- [Infrastructure Modules](https://docs.medusajs.com/resources/infrastructure-modules): An infrastructure module is a package that can be installed and used in any Medusa application. These modules allow you to choose and integrate custom services to modify your application's infrastructure. +### Modules -## Tools and SDKs +- [Commerce Modules](https://docs.medusajs.com/resources/commerce-modules/index.html.md): List of all Commerce Modules in Medusa and an entry point to their documentation. +- [Infrastructure Modules](https://docs.medusajs.com/resources/infrastructure-modules/index.html.md): List of all Infrastructure Modules in Medusa and an entry point to their documentation. -- [Medusa CLI](https://docs.medusajs.com/resources/medusa-cli/index.html.md): A CLI tool to perform database operations, create admin users, and run the Medusa application. -- [create-medusa-app](https://docs.medusajs.com/resources/create-medusa-app/index.html.md): A CLI tool that creates a Medusa application. -- [Next.js Starter Storefront](https://docs.medusajs.com/resources/nextjs-starter/index.html.md): The Next.js Starter storefront provides rich commerce features and a sleek design. Developers and businesses can use it as-is or build on top of it to tailor it for the business's unique use case, design, and customer experience. -- [JS SDK](https://docs.medusajs.com/resources/js-sdk/index.html.md): Medusa's JS SDK is a library to easily send requests to your Medusa application. You can use it in your admin customizations or custom storefronts. -- [Integrations](https://docs.medusajs.com/resources/integrations/index.html.md): Medusa provides integrations out-of-the-box, such as integrations to Stripe or AWS S3, and you can also develop your own integrations. +## Commerce Modules -## Guides +### Cart & Purchase -- [Build a Brands Module](https://docs.medusajs.com/learn/customization/custom-features/index.html.md): Customize Medusa by building a Brand Module. -- [Admin Components](https://docs.medusajs.com/resources/admin-components/index.html.md): Components you can use in your admin customizations to build widgets and routes that match the Medusa Admin's design system. -- [Examples](https://docs.medusajs.com/resources/examples/index.html.md): Examples and code snippets of how to use different Medusa concepts. -- [Recipes](https://docs.medusajs.com/resources/recipes/index.html.md): Learn how to build common commerce use cases, such as marketplace and subscription-based purchases, with Medusa. -- [Deployment Guides](https://docs.medusajs.com/resources/deployment/index.html.md): Deploy to Medusa Cloud or self-host Medusa. +- [Cart](https://docs.medusajs.com/resources/commerce-modules/cart/index.html.md): Add to cart, checkout, and totals. +- [Payment](https://docs.medusajs.com/resources/commerce-modules/payment/index.html.md): Process any payment type. +- [Customer](https://docs.medusajs.com/resources/commerce-modules/customer/index.html.md): Customer and group management. -## Storefront Development +### Merchandising -- [Storefront Development Tips](https://docs.medusajs.com/resources/storefront-development/tips/index.html.md): Tips and best practices for building storefronts with Medusa. -- [Use a Publishable API Key in the Storefront](https://docs.medusajs.com/resources/storefront-development/publishable-api-keys/index.html.md): Learn how to use publishable API keys to scope API requests to sales channels. +- [Pricing](https://docs.medusajs.com/resources/commerce-modules/pricing/index.html.md): Configurable pricing engine. +- [Promotion](https://docs.medusajs.com/resources/commerce-modules/promotion/index.html.md): Discounts and promotions. +- [Product](https://docs.medusajs.com/resources/commerce-modules/product/index.html.md): Variants, categories, and bulk edits. -### Products +### Fulfillment -- [Products in Storefront](https://docs.medusajs.com/resources/storefront-development/products/index.html.md): Learn how to display and manage products in your storefront. -- [Show Products in Storefront](https://docs.medusajs.com/resources/storefront-development/products/list/index.html.md): Learn how to retrieve and display a list of products. -- [Retrieve a Product in Storefront](https://docs.medusajs.com/resources/storefront-development/products/retrieve/index.html.md): Learn how to retrieve and display a single product's details. -- [Select Product Variants in Storefront](https://docs.medusajs.com/resources/storefront-development/products/variants/index.html.md): Learn how to handle product variant selection in your storefront. -- [Retrieve Product Variant's Prices in Storefront](https://docs.medusajs.com/resources/storefront-development/products/price/index.html.md): Learn how to retrieve and display product variant prices. -- [Retrieve Product Variant's Inventory in Storefront](https://docs.medusajs.com/resources/storefront-development/products/inventory/index.html.md): Learn how to check product variant inventory availability. +- [Order](https://docs.medusajs.com/resources/commerce-modules/order/index.html.md): Omnichannel order management. +- [Inventory](https://docs.medusajs.com/resources/commerce-modules/inventory/index.html.md): Multi-warehouse and reservations. +- [Fulfillment](https://docs.medusajs.com/resources/commerce-modules/fulfillment/index.html.md): Order fulfillment and shipping. +- [Stock Location](https://docs.medusajs.com/resources/commerce-modules/stock-location/index.html.md): Locations of stock-kept items. -### Product Categories +### Regions & Channels -- [Product Categories in Storefront](https://docs.medusajs.com/resources/storefront-development/products/categories/index.html.md): Learn how to work with product categories in your storefront. -- [Show Product Categories in Storefront](https://docs.medusajs.com/resources/storefront-development/products/categories/list/index.html.md): Learn how to retrieve and display product categories. -- [Retrieve a Category in Storefront](https://docs.medusajs.com/resources/storefront-development/products/categories/retrieve/index.html.md): Learn how to retrieve and display a specific category. -- [Retrieve Nested Categories in Storefront](https://docs.medusajs.com/resources/storefront-development/products/categories/nested-categories/index.html.md): Learn how to handle nested category structures. -- [Retrieve a Category's Products in Storefront](https://docs.medusajs.com/resources/storefront-development/products/categories/products/index.html.md): Learn how to retrieve products that belong to a specific category. +- [Region](https://docs.medusajs.com/resources/commerce-modules/region/index.html.md): Cross-border commerce. +- [Sales Channel](https://docs.medusajs.com/resources/commerce-modules/sales-channel/index.html.md): Omnichannel sales. +- [Tax](https://docs.medusajs.com/resources/commerce-modules/tax/index.html.md): Granular tax control. +- [Currency](https://docs.medusajs.com/resources/commerce-modules/currency/index.html.md): Multi-currency support. -### Product Collections +### User Access -- [Product Collections in Storefront](https://docs.medusajs.com/resources/storefront-development/products/collections/index.html.md): Learn how to work with product collections in your storefront. -- [List Product Collections in Storefront](https://docs.medusajs.com/resources/storefront-development/products/collections/list/index.html.md): Learn how to retrieve and display product collections. -- [Retrieve a Collection in Storefront](https://docs.medusajs.com/resources/storefront-development/products/collections/retrieve/index.html.md): Learn how to retrieve and display a specific collection. -- [Retrieve a Collection's Products in Storefront](https://docs.medusajs.com/resources/storefront-development/products/collections/products/index.html.md): Learn how to retrieve products that belong to a specific collection. - -### Cart Management - -- [Carts in Storefront](https://docs.medusajs.com/resources/storefront-development/cart/index.html.md): Learn how to manage shopping carts in your storefront. -- [Create Cart in Storefront](https://docs.medusajs.com/resources/storefront-development/cart/create/index.html.md): Learn how to create a new shopping cart. -- [Retrieve Cart in Storefront](https://docs.medusajs.com/resources/storefront-development/cart/retrieve/index.html.md): Learn how to retrieve an existing cart. -- [Update Cart in Storefront](https://docs.medusajs.com/resources/storefront-development/cart/update/index.html.md): Learn how to update cart information. -- [Manage Cart's Items in Storefront](https://docs.medusajs.com/resources/storefront-development/cart/manage-items/index.html.md): Learn how to add, update, and remove items from a cart. -- [Show Cart Totals](https://docs.medusajs.com/resources/storefront-development/cart/totals/index.html.md): Learn how to calculate and display cart totals. -- [Create Cart Context in Storefront](https://docs.medusajs.com/resources/storefront-development/cart/context/index.html.md): Learn how to create a React context for cart management. - -### Checkout Process - -- [Checkout in Storefront](https://docs.medusajs.com/resources/storefront-development/checkout/index.html.md): Learn how to implement the complete checkout process. -- [Checkout Step 1: Enter Email](https://docs.medusajs.com/resources/storefront-development/checkout/email/index.html.md): Learn how to implement the email entry step in checkout. -- [Checkout Step 2: Set Shipping and Billing Addresses](https://docs.medusajs.com/resources/storefront-development/checkout/address/index.html.md): Learn how to handle address collection in checkout. -- [Checkout Step 3: Choose Shipping Method](https://docs.medusajs.com/resources/storefront-development/checkout/shipping/index.html.md): Learn how to implement shipping method selection. -- [Checkout Step 4: Choose Payment Provider](https://docs.medusajs.com/resources/storefront-development/checkout/payment/index.html.md): Learn how to implement payment provider selection. -- [Payment with Stripe in React Storefront](https://docs.medusajs.com/resources/storefront-development/checkout/payment/stripe/index.html.md): Learn how to integrate Stripe payments in your React storefront. -- [Checkout Step 5: Complete Cart](https://docs.medusajs.com/resources/storefront-development/checkout/complete-cart/index.html.md): Learn how to complete the checkout process. -- [Order Confirmation in Storefront](https://docs.medusajs.com/resources/storefront-development/checkout/order-confirmation/index.html.md): Learn how to display order confirmation to customers. - -### Customer Management - -- [Customers in Storefront](https://docs.medusajs.com/resources/storefront-development/customers/index.html.md): Learn how to manage customer accounts in your storefront. -- [Customer Context in Storefront](https://docs.medusajs.com/resources/storefront-development/customers/context/index.html.md): Learn how to create a React context for customer management. -- [Register Customer in Storefront](https://docs.medusajs.com/resources/storefront-development/customers/register/index.html.md): Learn how to implement customer registration. -- [Login Customer in Storefront](https://docs.medusajs.com/resources/storefront-development/customers/login/index.html.md): Learn how to implement customer login functionality. -- [Third-Party or Social Login in Storefront](https://docs.medusajs.com/resources/storefront-development/customers/third-party-login/index.html.md): Learn how to implement social login options. -- [Retrieve Logged-In Customer in Storefront](https://docs.medusajs.com/resources/storefront-development/customers/retrieve/index.html.md): Learn how to retrieve customer information. -- [Edit Customer Profile in Storefront](https://docs.medusajs.com/resources/storefront-development/customers/profile/index.html.md): Learn how to allow customers to edit their profiles. -- [Manage Customer Addresses in Storefront](https://docs.medusajs.com/resources/storefront-development/customers/addresses/index.html.md): Learn how to manage customer shipping and billing addresses. -- [Reset Customer Password in Storefront](https://docs.medusajs.com/resources/storefront-development/customers/reset-password/index.html.md): Learn how to implement password reset functionality. -- [Log-out Customer in Storefront](https://docs.medusajs.com/resources/storefront-development/customers/log-out/index.html.md): Learn how to implement customer logout functionality. - -### Regions - -- [Regions in Storefront](https://docs.medusajs.com/resources/storefront-development/regions/index.html.md): Learn how to handle multi-region support in your storefront. -- [List Regions in Storefront](https://docs.medusajs.com/resources/storefront-development/regions/list/index.html.md): Learn how to retrieve and display available regions. -- [Store Selected Region in Storefront](https://docs.medusajs.com/resources/storefront-development/regions/store-retrieve-region/index.html.md): Learn how to persist and retrieve the selected region. -- [Region React Context in Storefront](https://docs.medusajs.com/resources/storefront-development/regions/context/index.html.md): Learn how to create a React context for region management. - -### Advanced Guides - -- [Implement Express Checkout with Medusa](https://docs.medusajs.com/resources/storefront-development/guides/express-checkout/index.html.md): Learn how to implement a streamlined express checkout flow. - -## API Reference - -- [Admin Authentication](https://docs.medusajs.com/api/admin#authentication): Send authenticated requests as an admin user. -- [Customer Authentication](https://docs.medusajs.com/api/store#authentication): Send authenticated requests as a customer. -- [Configure HTTP Compression](https://docs.medusajs.com/api/admin#http-compression): Override Medusa's configurations for HTTP Compression in requests. -- [Select Fields and Relations](https://docs.medusajs.com/api/admin#select-fields-and-relations): Specify the fields and relations to retrieve in objects returned by an API route. -- [Query Parameter Types](https://docs.medusajs.com/api/admin#query-parameter-types): Examples of how to pass query parameters based on their data type. -- [Pagination](https://docs.medusajs.com/api/admin#pagination): Learn how to configure pagination of lists returned by API routes. -- [Publishable API Key](https://docs.medusajs.com/api/store#publishable-api-key): Pass publishable API key in requests to Store API Routes. - -## API Key Module - -- [API Key Features](https://docs.medusajs.com/resources/commerce-modules/api-key/index.html.md): List of features the API Key Module provides. -- [API Key Concepts](https://docs.medusajs.com/resources/commerce-modules/api-key/concepts/index.html.md): Overview of API key types, expiration, and token verification. -- [API Key Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/api-key/admin-widget-zones/index.html.md): List of zones related to the API Key Module that you can inject admin widgets to. -- [API Key Module's Service Reference](https://docs.medusajs.com/resources/references/api-key/index.html.md): Methods of the API Key Module's Service. -- [API Key Module's Data Models Reference](https://docs.medusajs.com/resources/references/api-key/models/index.html.md): Data models created by the API Key Module. - -## Auth Module - -- [Auth Features](https://docs.medusajs.com/resources/commerce-modules/auth#auth-features/index.html.md): List of features the Auth Module provides. -- [Auth Module Options](https://docs.medusajs.com/resources/commerce-modules/auth/module-options/index.html.md): Options to pass to the Auth Module. -- [Auth Identity and Actor Types](https://docs.medusajs.com/resources/commerce-modules/auth/auth-identity-and-actor-types/index.html.md): Auth identity represents a user registered by an authentication provider. An actor type is a type of user that can be authenticated. -- [Auth Providers](https://docs.medusajs.com/resources/commerce-modules/auth/auth-providers/index.html.md): Use Emailpass, Google, or GitHub auth providers, or create a custom auth provider. -- [Auth Flow with Module](https://docs.medusajs.com/resources/commerce-modules/auth/auth-flows/index.html.md): Build an authentication flow with the Auth Module. -- [Auth Flow with Routes](https://docs.medusajs.com/resources/commerce-modules/auth/authentication-route/index.html.md): Build an authentication flow with Medusa's authentication routes. -- [Create Actor Type](https://docs.medusajs.com/resources/commerce-modules/auth/authentication-route/index.html.md): Create a custom actor type to allow it to authenticate into Medusa. -- [Handle Password Reset Event](https://docs.medusajs.com/resources/commerce-modules/auth/reset-password/index.html.md): Handle password reset event by sending the user a notification. -- [Auth Module Events Reference](https://docs.medusajs.com/resources/commerce-modules/auth/events/index.html.md): List of events related to the Auth Module that you can listen to in subscribers. -- [Auth Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/auth/admin-widget-zones/index.html.md): List of zones related to the Auth Module that you can inject admin widgets to. -- [Auth Module's Service Reference](https://docs.medusajs.com/resources/references/auth/index.html.md): Methods of the Auth Module's Service. -- [Auth Module's Data Models Reference](https://docs.medusajs.com/resources/references/auth/models/index.html.md): Data models created by the Auth Module. - -## Cart Module - -- [Cart Features](https://docs.medusajs.com/resources/commerce-modules/cart#cart-features/index.html.md): List of features the Cart Module provides. -- [Cart Concepts](https://docs.medusajs.com/resources/commerce-modules/cart/concepts/index.html.md): Overview of shipping and billing addresses, line items, and shipping methods. -- [Promotion Adjustments in Carts](https://docs.medusajs.com/resources/commerce-modules/cart/promotions/index.html.md): Apply promotions on a cart's line items and shipping methods. -- [Tax Lines in Carts](https://docs.medusajs.com/resources/commerce-modules/cart/tax-lines/index.html.md): Calculate tax lines for a cart's line items and shipping methods. -- [Extend Cart Module](https://docs.medusajs.com/resources/commerce-modules/cart/extend/index.html.md): Extend the Cart Module to add a custom property to the Cart data model. -- [Cart Module Events Reference](https://docs.medusajs.com/resources/commerce-modules/cart/events/index.html.md): List of events related to the Cart Module that you can listen to in subscribers. -- [Cart Module's Service Reference](https://docs.medusajs.com/resources/references/cart/index.html.md): Methods of the Cart Module's Service. -- [Cart Module's Data Models Reference](https://docs.medusajs.com/resources/references/cart/models/index.html.md): Data models created by the Cart Module. - -## Currency Module - -- [Currency Features](https://docs.medusajs.com/resources/commerce-modules/currency/index.html.md): List of features that the Currency Module provides. -- [Currency Module's Service Reference](https://docs.medusajs.com/resources/references/currency/index.html.md): Methods of the Currency Module's Service. -- [Currency Module's Data Models Reference](https://docs.medusajs.com/resources/references/currency/models/index.html.md): Data models created by the Currency Module. - -## Customer Module - -- [Customer Features](https://docs.medusajs.com/resources/commerce-modules/customer/index.html.md): List of features that the Customer Module provides. -- [Customer Accounts](https://docs.medusajs.com/resources/commerce-modules/customer/customer-accounts/index.html.md): The Customer data model has a has_account property, which is a boolean that indicates whether a customer is registered. There can only be one guest customer (having has_account=false) and one registered customer (having has_account=true) with the same email. -- [Extend Customer Module](https://docs.medusajs.com/resources/commerce-modules/customer/extend/index.html.md): Extend the Customer module to add a custom property to the Customer data model. -- [Customer Module Events Reference](https://docs.medusajs.com/resources/commerce-modules/customer/events/index.html.md): List of events related to the Customer Module that you can listen to in subscribers. -- [Customer Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/customer/admin-widget-zones/index.html.md): List of zones related to the Customer Module that you can inject admin widgets to. -- [Customer Module's Service Reference](https://docs.medusajs.com/resources/references/customer/index.html.md): Methods of the Customer Module's Service. -- [Customer Module's Data Models Reference](https://docs.medusajs.com/resources/references/customer/models/index.html.md): Data models created by the Customer Module. - -## Fulfillment Module - -- [Fulfillment Features](https://docs.medusajs.com/resources/commerce-modules/fulfillment/index.html.md): List of features that the Fulfillment Module provides. -- [Fulfillment Module Options](https://docs.medusajs.com/resources/commerce-modules/fulfillment/module-options/index.html.md): Options to pass to the Fulfillment Module. -- [Fulfillment Concepts](https://docs.medusajs.com/resources/commerce-modules/fulfillment/concepts/index.html.md): Overview of fulfillment sets, service zones, and shipping profiles. -- [Fulfillment Module Provider](https://docs.medusajs.com/resources/commerce-modules/fulfillment/fulfillment-provider/index.html.md): Integrate custom fulfillment providers to process fulfillments. -- [Shipping Options](https://docs.medusajs.com/resources/commerce-modules/fulfillment/shipping-option/index.html.md): A shipping option is a way of shipping an item. Each fulfillment provider provides a set of shipping options. When the customer places their order, they choose a shipping option to be used to fulfill their items. -- [Item Fulfillment](https://docs.medusajs.com/resources/commerce-modules/fulfillment/item-fulfillment/index.html.md): Overview of fulfillment processing by a fulfillment provider, creating fulfillment items. -- [Fulfillment Module Events Reference](https://docs.medusajs.com/resources/commerce-modules/fulfillment/events/index.html.md): List of events related to the Fulfillment Module that you can listen to in subscribers. -- [Fulfillment Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/fulfillment/admin-widget-zones/index.html.md): List of zones related to the Fulfillment Module that you can inject admin widgets to. -- [Fulfillment Module's Service Reference](https://docs.medusajs.com/resources/references/fulfillment/index.html.md): Methods of the Fulfillment Module's Service. -- [Fulfillment Module's Data Models Reference](https://docs.medusajs.com/resources/references/fulfillment/models/index.html.md): Data models created by the Fulfillment Module. - -## Inventory Module - -- [Inventory Features](https://docs.medusajs.com/resources/commerce-modules/inventory/index.html.md): List of features that the Inventory Module provides. -- [Inventory Module in Medusa Flows](https://docs.medusajs.com/resources/commerce-modules/inventory/inventory-in-flows/index.html.md): The Inventory Module is used in Medusa flows like product-variant creation, add-to-cart, order-placement, order-fulfillment, and order-return flows. -- [Inventory Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/inventory/admin-widget-zones/index.html.md): List of zones related to the Fulfillment Module that you can inject admin widgets to. -- [Inventory Module's Service Reference](https://docs.medusajs.com/resources/references/inventory-next/index.html.md): Methods of the Fulfillment Module's Service. -- [Inventory Module's Data Models Reference](https://docs.medusajs.com/resources/references/inventory-next/models/index.html.md): Data models created by the Fulfillment Module. - -## Order Module - -- [Order Features](https://docs.medusajs.com/resources/commerce-modules/order/index.html.md): List of features that the Order Module provides. -- [Order Concepts](https://docs.medusajs.com/resources/commerce-modules/order/concepts/index.html.md): Overview of order items, order shipping methods, order totals, and order payments. -- [Promotions in Orders](https://docs.medusajs.com/resources/commerce-modules/order/promotion-adjustments/index.html.md): Apply promotions to an order's items and shipping methods. -- [Tax Lines in Orders](https://docs.medusajs.com/resources/commerce-modules/order/tax-lines/index.html.md): Calculate tax lines of an order's items and shipping methods. -- [Transactions](https://docs.medusajs.com/resources/commerce-modules/order/transactions/index.html.md): A transaction represents any order payment process, such as capturing or refunding an amount. -- [Order Versioning](https://docs.medusajs.com/resources/commerce-modules/order/order-versioning/index.html.md): Versioning means assigning a version number to a record, such as an order and its items. This is useful to view the different versions of the order following changes in its lifetime. -- [Order Return](https://docs.medusajs.com/resources/commerce-modules/order/return/index.html.md): A return is the return of items delivered from the customer back to the merchant. -- [Order Exchange](https://docs.medusajs.com/resources/commerce-modules/order/exchange/index.html.md): An exchange is the replacement of an item that the customer ordered with another. -- [Order Claim](https://docs.medusajs.com/resources/commerce-modules/order/claim/index.html.md): When a customer receives a defective or incorrect item, the merchant can create a claim to refund or replace the item. -- [Order Edit](https://docs.medusajs.com/resources/commerce-modules/order/edit/index.html.md): A merchant can edit an order to add new items or change the quantity of existing items in the order. -- [Order Change](https://docs.medusajs.com/resources/commerce-modules/order/order-change/index.html.md): An order change represents any kind of change to an order, such as a return, exchange, or edit. -- [Order Module Events Reference](https://docs.medusajs.com/resources/commerce-modules/order/events/index.html.md): List of events related to the Order Module that you can listen to in subscribers. -- [Order Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/order/admin-widget-zones/index.html.md): List of zones related to the Order Module that you can inject admin widgets to. -- [Order Module's Service Reference](https://docs.medusajs.com/resources/references/order/index.html.md): Methods of the Order Module's Service. -- [Order Module's Data Models Reference](https://docs.medusajs.com/resources/references/order/models/index.html.md): Data models created by the Order Module. - -## Payment Module - -- [Payment Features](https://docs.medusajs.com/resources/commerce-modules/payment#payment-features/index.html.md): List of features that the Payment Module provides. -- [Payment Collection](https://docs.medusajs.com/resources/commerce-modules/payment/payment-collection/index.html.md): A payment collection stores payment details related to a resource, such as a cart or an order. -- [Payment Session](https://docs.medusajs.com/resources/commerce-modules/payment/payment-session/index.html.md): A payment session is a payment amount to be authorized. It’s associated with a payment provider that handles authorizing it. -- [Payment](https://docs.medusajs.com/resources/commerce-modules/payment/payment/index.html.md): When a payment session is authorized, a payment is created. This payment can later be captured or refunded. -- [Payment Providers](https://docs.medusajs.com/resources/commerce-modules/payment/payment-provider/index.html.md): Use Stripe for payment processing, or integrate custom payment providers. -- [Webhook Events](https://docs.medusajs.com/resources/commerce-modules/payment/webhook-events/index.html.md): A webhook event is sent from a third-party payment provider to your application. It indicates a change in a payment’s status. -- [Accept Payment Flow](https://docs.medusajs.com/resources/commerce-modules/payment/payment-flow/index.html.md): The steps to accept payment using the Payment Module. -- [Payment Module Events Reference](https://docs.medusajs.com/resources/commerce-modules/payment/events/index.html.md): List of events related to the Payment Module that you can listen to in subscribers. -- [Payment Module's Service Reference](https://docs.medusajs.com/resources/references/payment/index.html.md): Methods of the Payment Module's Service. -- [Payment Module's Data Models Reference](https://docs.medusajs.com/resources/references/payment/models/index.html.md): Data models created by the Payment Module. - -## Pricing Module - -- [Pricing Features](https://docs.medusajs.com/resources/commerce-modules/pricing/index.html.md): List of features that the Pricing Module provides. -- [Pricing Concepts](https://docs.medusajs.com/resources/commerce-modules/pricing/concepts/index.html.md): Overview of price sets and price lists. -- [Price Rules](https://docs.medusajs.com/resources/commerce-modules/pricing/price-rules/index.html.md): Price rules allow you to restrict prices by rules, such as the cart's zip code. -- [Prices Calculation](https://docs.medusajs.com/resources/commerce-modules/pricing/price-calculation/index.html.md): The Price Module's calculatePrices method returns the best-matching price for a provided context. -- [Tax-Inclusive Pricing](https://docs.medusajs.com/resources/commerce-modules/pricing/tax-inclusive-pricing/index.html.md): A tax-inclusive price is a price of a resource that includes taxes. Medusa calculates the tax amount from the price rather than adds the amount to it. -- [Pricing Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/pricing/admin-widget-zones/index.html.md): List of zones related to the Pricing Module that you can inject admin widgets to. -- [Pricing Module's Service Reference](https://docs.medusajs.com/resources/references/pricing/index.html.md): Methods of the Pricing Module's Service. -- [Pricing Module's Data Models Reference](https://docs.medusajs.com/resources/references/pricing/models/index.html.md): Data models created by the Pricing Module. - -## Product Module - -- [Product Features](https://docs.medusajs.com/resources/commerce-modules/product/index.html.md): List of features that the Product Module provides. -- [Extend Product Module](https://docs.medusajs.com/resources/commerce-modules/product/extend/index.html.md): Extend the Product module to add a custom property to the Product data model. -- [Get Product Variant Prices using Query](https://docs.medusajs.com/resources/commerce-modules/product/guides/price/index.html.md): Use Query to retrieve the price of a product variant. -- [Calculate Product Variant Price with Taxes](https://docs.medusajs.com/resources/commerce-modules/product/guides/price-with-taxes/index.html.md): Retrieve a product variant's price with taxes. -- [Product Module Events Reference](https://docs.medusajs.com/resources/commerce-modules/product/events/index.html.md): List of events related to the Product Module that you can listen to in subscribers. -- [Product Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/product/admin-widget-zones/index.html.md): List of zones related to the Product Module that you can inject admin widgets to. -- [Product Module's Service Reference](https://docs.medusajs.com/resources/references/product/index.html.md): Methods of the Product Module's Service. -- [Product Module's Data Models Reference](https://docs.medusajs.com/resources/references/product/models/index.html.md): Data models created by the Product Module. - -## Promotion Module - -- [Promotion Features](https://docs.medusajs.com/resources/commerce-modules/promotion/index.html.md): List of features that the Promotion Module provides. -- [Promotion Concepts](https://docs.medusajs.com/resources/commerce-modules/promotion/concepts/index.html.md): Overview of promotions and promotion rules. -- [Application Method](https://docs.medusajs.com/resources/commerce-modules/promotion/application-method/index.html.md): An application method defines how a promotion is applied. -- [Campaign](https://docs.medusajs.com/resources/commerce-modules/promotion/campaign/index.html.md): A Campaign combines promotions under the same conditions, such as start and end dates. -- [Promotion Actions](https://docs.medusajs.com/resources/commerce-modules/promotion/actions/index.html.md): Actions inform you what adjustment must be made to a cart item or shipping method. Each action is an object having the action property indicating the type of action. -- [Extend Promotion Module](https://docs.medusajs.com/resources/commerce-modules/promotion/extend/index.html.md): Extend the Promotion module to add a custom property to the Promotion data model. -- [Promotion Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/promotion/admin-widget-zones/index.html.md): List of zones related to the Promotion Module that you can inject admin widgets to. -- [Promotion Module's Service Reference](https://docs.medusajs.com/resources/references/promotion/index.html.md): Methods of the Promotion Module's Service. -- [Promotion Module's Data Models Reference](https://docs.medusajs.com/resources/references/promotion/models/index.html.md): Data models created by the Promotion Module. - -## Region Module - -- [Region Features](https://docs.medusajs.com/resources/commerce-modules/region/index.html.md): List of features that the Region Module provides. -- [Region Module Events Reference](https://docs.medusajs.com/resources/commerce-modules/region/events/index.html.md): List of events related to the Region Module that you can listen to in subscribers. -- [Region Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/region/admin-widget-zones/index.html.md): List of zones related to the Region Module that you can inject admin widgets to. -- [Region Module's Service Reference](https://docs.medusajs.com/resources/references/region/index.html.md): Methods of the Region Module's Service. -- [Region Module's Data Models Reference](https://docs.medusajs.com/resources/references/region/models/index.html.md): Data models created by the Region Module. - -## Sales Channel Module - -- [Sales Channel Features](https://docs.medusajs.com/resources/commerce-modules/sales-channel/index.html.md): List of features that the Sales Channel Module provides. -- [Publishable API Keys with Sales Channels](https://docs.medusajs.com/resources/commerce-modules/sales-channel/publishable-api-keys/index.html.md): A publishable API key, provided by the API Key Module, is a client key scoped to one or more sales channels. -- [Sales Channel Module Events Reference](https://docs.medusajs.com/resources/commerce-modules/sales-channel/events/index.html.md): List of events related to the Sales Channel Module that you can listen to in subscribers. -- [Sales Channel Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/sales-channel/admin-widget-zones/index.html.md): List of zones related to the Sales Channel Module that you can inject admin widgets to. -- [Sales Channel Module's Service Reference](https://docs.medusajs.com/resources/references/sales-channel/index.html.md): Methods of the Sales Channel Module's Service. -- [Sales Channel Module's Data Models Reference](https://docs.medusajs.com/resources/references/sales-channel/models/index.html.md): Data models created by the Sales Channel Module. - -## Stock Location Module - -- [Stock Location Features](https://docs.medusajs.com/resources/commerce-modules/stock-location/index.html.md): List of stock locations that the Stock Location Module provides. -- [Stock Location Concepts](https://docs.medusajs.com/resources/commerce-modules/stock-location/concepts/index.html.md): Overview of stock locations and addresses. -- [Stock Location Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/stock-location/admin-widget-zones/index.html.md): List of zones related to the Stock Location Module that you can inject admin widgets to. -- [Stock Location Module's Service Reference](https://docs.medusajs.com/resources/references/stock-location-next/index.html.md): Methods of the Stock Location Module's Service. -- [Stock Location Module's Data Models Reference](https://docs.medusajs.com/resources/references/stock-location-next/models/index.html.md): Data models created by the Stock Location Module. - -## Store Module - -- [Store Features](https://docs.medusajs.com/resources/commerce-modules/store/index.html.md): List of features that the Store Module provides. -- [Store Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/store/admin-widget-zones): List of zones related to the Store Module that you can inject admin widgets to. -- [Store Module's Service Reference](https://docs.medusajs.com/resources/references/store/index.html.md): Methods of the Store Module's Service. -- [Store Module's Data Models Reference](https://docs.medusajs.com/resources/references/store/models/index.html.md): Data models created by the Store Module. - -## Tax Module - -- [Tax Features](https://docs.medusajs.com/resources/commerce-modules/tax/index.html.md): List of features that the Tax Module provides. -- [Tax Module Options](https://docs.medusajs.com/resources/commerce-modules/tax/module-options/index.html.md): Options you can pass to the Tax Module. -- [Tax Region](https://docs.medusajs.com/resources/commerce-modules/tax/tax-region/index.html.md): A tax region stores tax settings related to a region that your store serves. -- [Tax Rates and Rules](https://docs.medusajs.com/resources/commerce-modules/tax/tax-rates-and-rules/index.html.md): A tax rate is a percentage amount used to calculate the tax amount for each taxable item’s price, such as line items or shipping methods, in a cart. You can create tax rates that override the default for specific conditions or rules. -- [Tax Calculation with Tax Providers](https://docs.medusajs.com/resources/commerce-modules/tax/tax-calculation-with-provider/index.html.md): Tax lines are calculated and retrieved using the getTaxLines method of the Tax Module’s main service, which are retrieved from the underlying tax provider. -- [Tax Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/tax/admin-widget-zones/index.html.md): List of zones related to the Tax Module that you can inject admin widgets to. -- [Tax Module's Service Reference](https://docs.medusajs.com/resources/references/tax/index.html.md): Methods of the Tax Module's Service. -- [Tax Module's Data Models Reference](https://docs.medusajs.com/resources/references/tax/models/index.html.md): Data models created by the Tax Module. - -## User Module - -- [User Features](https://docs.medusajs.com/resources/commerce-modules/user/index.html.md): List of features that the User Module provides. -- [User Module Options](https://docs.medusajs.com/resources/commerce-modules/user/module-options/index.html.md): Options you can pass to the User Module. -- [User Creation Flows](https://docs.medusajs.com/resources/commerce-modules/user/user-creation-flows/index.html.md): Create and invite users with the User Module's service. -- [User Module Events Reference](https://docs.medusajs.com/resources/commerce-modules/user/events/index.html.md): List of events related to the OUserder Module that you can listen to in subscribers. -- [User Module's Admin Widget Injection Zones](https://docs.medusajs.com/resources/commerce-modules/user/admin-widget-zones/index.html.md): List of zones related to the User Module that you can inject admin widgets to. -- [User Module's Service Reference](https://docs.medusajs.com/resources/references/user/index.html.md): Methods of the User Module's Service. -- [User Module's Data Models Reference](https://docs.medusajs.com/resources/references/user/models/index.html.md): Data models created by the User Module. +- [API Keys](https://docs.medusajs.com/resources/commerce-modules/api-key/index.html.md): Store and admin access. +- [User Module](https://docs.medusajs.com/resources/commerce-modules/user/index.html.md): Admin user management. +- [Auth](https://docs.medusajs.com/resources/commerce-modules/auth/index.html.md): Integrate authentication methods. ## Infrastructure Modules -- [Cache Modules](https://docs.medusajs.com/resources/infrastructure-modules/cache/index.html.md): A Cache Module is used to cache the results of computations such as price selection or various tax calculations. -- [Event Modules](https://docs.medusajs.com/resources/infrastructure-modules/event/index.html.md): An Event Module implements the underlying publish/subscribe system that handles queueing events, emitting them, and executing their subscribers. -- [File Module Providers](https://docs.medusajs.com/resources/infrastructure-modules/file/index.html.md): A file module provider implements the underlying logic of handling uploads and downloads of assets, such as integrating third-party services. The File Module must have one file module provider configured. -- [Notification Module Provider](https://docs.medusajs.com/resources/infrastructure-modules/notification/index.html.md): A notification module provider implements the underlying logic of sending notification. It either integrates a third-party service or uses custom logic to send the notification. -- [Workflow Engine Modules](https://docs.medusajs.com/resources/infrastructure-modules/workflow-engine/index.html.md): Workflow engine modules handle tracking and recording the transactions and statuses of workflows and their steps. +- [Analytics](https://docs.medusajs.com/resources/infrastructure-modules/analytics/index.html.md): Track and analyze user interactions and system events with third-party services. +- [Caching](https://docs.medusajs.com/resources/infrastructure-modules/caching/index.html.md): Cache data in your Medusa application, improving performance and reducing latency for frequently accessed data. +- [Event](https://docs.medusajs.com/resources/infrastructure-modules/event/index.html.md): Handles queueing events, emitting them, and executing their subscribers. +- [File](https://docs.medusajs.com/resources/infrastructure-modules/file/index.html.md): Store assets, such as product images, in third-party providers. +- [Locking](https://docs.medusajs.com/resources/infrastructure-modules/locking/index.html.md): Manages access to shared resources by multiple processes or threads. +- [Notification](https://docs.medusajs.com/resources/infrastructure-modules/notification/index.html.md): Send a notification to customers or users, such as order confirmation emails. +- [Workflow Engine](https://docs.medusajs.com/resources/infrastructure-modules/workflow-engine/index.html.md): Handles tracking and recording the transactions and statuses of workflows and their steps. -## Integration Guides +## Build -- [Algolia](https://docs.medusajs.com/resources/integrations/guides/algolia/index.html.md): Learn how to integrate Algolia with Medusa and add search functionalities. -- [Contentful](https://docs.medusajs.com/resources/integrations/guides/contentful/index.html.md): Learn how to integrate Contentful with Medusa and add localization to your Medusa store. -- [Magento](https://docs.medusajs.com/resources/integrations/guides/magento/index.html.md): Learn how to migrate your products and categories from Magento to Medusa. -- [Mailchimp](https://docs.medusajs.com/resources/integrations/guides/mailchimp/index.html.md): Learn how to integrate Mailchimp into Medusa and send notifications like newsletters. -- [Resend](https://docs.medusajs.com/resources/integrations/guides/resend/index.html.md): Learn how to integrate Resend into Medusa and send notifications, such as order-confirmation emails. -- [Sanity](https://docs.medusajs.com/resources/integrations/guides/sanity/index.html.md): Learn how to integrate Sanity into Medusa to use rich CMS capabilities. -- [Segment](https://docs.medusajs.com/resources/integrations/guides/segment/index.html.md): Learn how to integrate Segment into Medusa to track events and user behavior. -- [Sentry](https://docs.medusajs.com/resources/integrations/guides/sentry/index.html.md): Learn how to integrate Senrty into Medusa to monitor performance and track errors. -- [ShipStation](https://docs.medusajs.com/resources/integrations/guides/shipstation/index.html.md): Learn how to integrate ShipStation into Medusa to fulfill orders. -- [Slack](https://docs.medusajs.com/resources/integrations/guides/slack/index.html.md): Learn how to integrate Slack into Medusa to send notifications, such as new-order notifications. +- [Recipes](https://docs.medusajs.com/resources/recipes/index.html.md): Build common use cases with step-by-step guides. +- [How-to & Tutorials](https://docs.medusajs.com/resources/how-to-tutorials/index.html.md): How-to guides and tutorials for building with Medusa. +- [Integrations](https://docs.medusajs.com/resources/integrations/index.html.md): Integrate third-party services with Medusa. +- [Storefront](https://docs.medusajs.com/resources/storefront-development/index.html.md): Build storefronts with Medusa. -## Tutorials +## Tools -- [Use Saved Payment Methods During Checkout](https://docs.medusajs.com/resources/tutorials/saved-payment-methods/index.html.md): Learn how to allow customers to save their payment methods and use them for future purchases. -- [Implement Product Reviews in Medusa](https://docs.medusajs.com/resources/tutorials/product-reviews/index.html.md): Learn how to implement a product review system with ratings and comments. -- [Add Gift Message to Line Items in Medusa](https://docs.medusajs.com/resources/tutorials/gift-message/index.html.md): Learn how to add gift message functionality to line items in orders. -- [Send Abandoned Cart Notifications in Medusa](https://docs.medusajs.com/resources/tutorials/abandoned-cart/index.html.md): Learn how to implement abandoned cart email notifications to recover lost sales. -- [Implement Loyalty Points System in Medusa](https://docs.medusajs.com/resources/tutorials/loyalty-points/index.html.md): Learn how to build a customer loyalty points system with rewards. -- [Implement Quick Re-Order Functionality in Medusa](https://docs.medusajs.com/resources/tutorials/re-order/index.html.md): Learn how to allow customers to quickly reorder their previous purchases. -- [Implement Phone Authentication and Integrate Twilio SMS](https://docs.medusajs.com/resources/tutorials/phone-auth/index.html.md): Learn how to implement phone number authentication using Twilio SMS verification. -- [Implement First-Purchase Discount in Medusa](https://docs.medusajs.com/resources/tutorials/first-purchase-discounts/index.html.md): Learn how to create automatic discounts for first-time customers. -- [Marketplace Recipe: Vendors Example](https://docs.medusajs.com/resources/recipes/marketplace/examples/vendors/index.html.md): Learn how to build a marketplace with multiple vendors, vendor admins, and order splitting. -- [Marketplace Recipe: Restaurant Delivery Example](https://docs.medusajs.com/resources/recipes/marketplace/examples/restaurant-delivery/index.html.md): Learn how to build a restaurant delivery marketplace with location-based ordering. -- [Create Wishlist Plugin](https://docs.medusajs.com/resources/plugins/guides/wishlist/index.html.md): Learn how to build a wishlist plugin. +### CLI Tools -## Optional +- [create-medusa-app](https://docs.medusajs.com/resources/create-medusa-app/index.html.md): CLI tool to create Medusa applications. +- [Medusa CLI](https://docs.medusajs.com/resources/medusa-cli/index.html.md): CLI tool for managing Medusa projects. -- [Medusa Configurations](https://docs.medusajs.com/resources/references/medusa-config/index.html.md): Configure the Medusa application for your use case. -- [Troubleshooting Guides](https://docs.medusajs.com/resources/troubleshooting/index.html.md): Find solutions for common problems you face during your development. -- [Admin Widget Injection Zones](https://docs.medusajs.com/resources/admin-widget-injection-zones/index.html.md): List of zones you can inject admin widgets into. -- [Medusa Container Resources](https://docs.medusajs.com/resources/medusa-container-resources/index.html.md): List of resources or dependencies you can resolve from the Medusa container. -- [Events Reference](https://docs.medusajs.com/resources/references/events/index.html.md): List of events you can listen to in a subscriber. -- [Workflows SDK Reference](https://docs.medusajs.com/resources/references/workflows/index.html.md): A reference to the SDK to create workflows in your Medusa application. -- [DML Reference](https://docs.medusajs.com/resources/references/data-model/index.html.md): A reference to Medusa's data-modeling language. -- [Data Model Repository Reference](https://docs.medusajs.com/resources/data-model-repository-reference/index.html.md): A reference to the repository generated for data models. -- [Service Factory Reference](https://docs.medusajs.com/resources/service-factory-reference/index.html.md): A reference to the methods generated by the service factory. -- [Helper Steps Reference](https://docs.medusajs.com/resources/references/helper-steps/index.html.md): A reference to the helper steps you can use in your custom workflows. -- [Core Workflows Reference](https://docs.medusajs.com/resources/medusa-workflows-reference/index.html.md): A reference to all workflows and steps provided by Medusa. -- [Testing Framework Reference](https://docs.medusajs.com/resources/test-tools-reference/index.html.md): A reference to Medusa's testing framework toolkit. -- [Full Documentation file](https://docs.medusajs.com/llms-full.txt): An llms-full.txt file that holds the entire documentation in plain text. +### Development Tools + +- [JS SDK](https://docs.medusajs.com/resources/js-sdk/index.html.md): JavaScript SDK for interacting with Medusa. +- [Next.js Starter](https://docs.medusajs.com/resources/nextjs-starter/index.html.md): Next.js storefront starter template and how to install it. +- [Medusa UI](https://docs.medusajs.com/ui/index.html.md): A React library to build applications using Medusa's primitives and design system. + +## References + +### API References + +- [Admin API Reference](https://docs.medusajs.com/api/admin): List of all Admin API routes in Medusa with code snippets. +- [Store API Reference](https://docs.medusajs.com/api/store): List of all Store API Routes in Medusa with code snippets. + +### Development References + +- [Admin Injection Zones](https://docs.medusajs.com/resources/admin-widget-injection-zones/index.html.md): Injection zones for customizing the admin dashboard. +- [Container Resources](https://docs.medusajs.com/resources/medusa-container-resources/index.html.md): Resources available in the Medusa Container. +- [Core Workflows](https://docs.medusajs.com/resources/medusa-workflows-reference/index.html.md): Reference for core workflows in Medusa. +- [Data Model Language](https://docs.medusajs.com/resources/references/data-model/index.html.md): Reference for the Data Model Language. +- [Data Model Repository](https://docs.medusajs.com/resources/data-model-repository-reference/index.html.md): Reference for the Data Model Repository. +- [Events Reference](https://docs.medusajs.com/resources/references/events/index.html.md): Reference for events in Medusa. +- [Helper Steps](https://docs.medusajs.com/resources/references/helper-steps/index.html.md): Reference for helper steps in workflows. +- [Service Factory](https://docs.medusajs.com/resources/service-factory-reference/index.html.md): Reference for the Service Factory. +- [Testing Framework](https://docs.medusajs.com/resources/test-tools-reference/index.html.md): Reference for testing tools in Medusa. +- [Workflows SDK](https://docs.medusajs.com/resources/references/workflows/index.html.md): Reference for the Workflows SDK. + +## Medusa Admin + +- [User Guide](https://docs.medusajs.com/user-guide/index.html.md): Guide for merchants and users to manage their Medusa store with the Medusa Admin. + +## Cloud + +- [Medusa Cloud](https://docs.medusajs.com/cloud/index.html.md): Deploy and manage Medusa projects on Medusa Cloud. diff --git a/www/apps/book/sidebar.mjs b/www/apps/book/sidebar.mjs index 3114788b00..5300c02324 100644 --- a/www/apps/book/sidebar.mjs +++ b/www/apps/book/sidebar.mjs @@ -590,6 +590,13 @@ export const sidebars = [ type: "link", title: "Medusa Configuations", path: "/learn/configurations/medusa-config", + children: [ + { + type: "link", + title: "Asymmetric Encryption", + path: "/learn/configurations/medusa-config/asymmetric-encryption", + }, + ], }, { type: "link", diff --git a/www/apps/resources/app/commerce-modules/user/module-options/page.mdx b/www/apps/resources/app/commerce-modules/user/module-options/page.mdx index 85bbb58983..50a67127ab 100644 --- a/www/apps/resources/app/commerce-modules/user/module-options/page.mdx +++ b/www/apps/resources/app/commerce-modules/user/module-options/page.mdx @@ -12,32 +12,53 @@ export const metadata = { In this guide, you'll learn about the options you can pass to the User Module. -## Module Options +## Options Example ```ts title="medusa-config.ts" -import { Modules } from "@medusajs/framework/utils" - -// ... - module.exports = defineConfig({ // ... modules: [ { - resolve: "@medusajs/user", + resolve: "@medusajs/medusa/user", options: { jwt_secret: process.env.JWT_SECRET, + jwt_public_key: process.env.JWT_PUBLIC_KEY, + valid_duration: 60 * 60 * 24, // 24 hours + jwt_options: { + algorithm: process.env.JWT_ALGORITHM || "RS256", + issuer: process.env.JWT_ISSUER || "medusa", + }, + jwt_verify_options: { + algorithms: [process.env.JWT_ALGORITHM || "RS256"], + issuer: process.env.JWT_ISSUER || "medusa", + }, }, }, ], }) ``` +### Environment Variables + +Make sure to add the necessary environment variables for the above options to your `.env` file: + +```bash +JWT_SECRET=supersecret +# Optional: For asymmetric key validation +JWT_PUBLIC_KEY=your_public_key_here +JWT_ALGORITHM=RS256 +JWT_ISSUER=medusa +``` + +### All Options + Option Description - Required + Required + Default @@ -56,15 +77,107 @@ module.exports = defineConfig({ Yes + + + + \- + + + + + + + `jwt_public_key` + + + + + A string indicating the public key used to verify JWT tokens when using asymmetric validation. Only used when the JWT secret is a private key for asymmetric signing. + + Learn more in the [Asymmetric Encryption](!docs!/learn/configurations/medusa-config/asymmetric-encryption) guide. + + + + + No + + + + + \- + + + + + + + `valid_duration` + + + + + A number indicating the duration in seconds that an invite token is valid. This is used to set the expiration time for invite tokens. + + + + + No + + + + + `86400` seconds (`1` day) + + + + + + + `jwt_options` + + + + + An object containing options for signing JWT tokens when using asymmetric signing with a private/public key pair. Accepts any options from [jsonwebtoken's SignOptions](https://github.com/auth0/node-jsonwebtoken#usage), such as `algorithm`. If `expiresIn` is provided here, it will be used as a fallback if `valid_duration` is not set. + + Learn more in the [Asymmetric Encryption](!docs!/learn/configurations/medusa-config/asymmetric-encryption) guide. + + + + + No + + + + + `{}` + + + + + + + `jwt_verify_options` + + + + + An object containing options for verifying JWT tokens when using asymmetric validation with a private/public key pair. Accepts any options from [jsonwebtoken's VerifyOptions](https://github.com/auth0/node-jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback), such as `algorithms`. If not provided, the `jwt_options` will be used for verification. + + Learn more in the [Asymmetric Encryption](!docs!/learn/configurations/medusa-config/asymmetric-encryption) guide. + + + + + No + + + + + Value of `jwt_options` +
-### Environment Variables - -Make sure to add the necessary environment variables for the above options to your `.env` file: - -```bash -JWT_SECRET=supersecret -``` diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 6781238827..cf162d1cae 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -95,7 +95,7 @@ export const generatedEditDates = { "app/commerce-modules/tax/page.mdx": "2025-05-20T07:51:40.711Z", "app/commerce-modules/user/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/user/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/user/module-options/page.mdx": "2025-09-01T15:26:21.317Z", + "app/commerce-modules/user/module-options/page.mdx": "2025-10-31T10:08:14.831Z", "app/commerce-modules/user/user-creation-flows/page.mdx": "2025-02-26T11:35:54.685Z", "app/commerce-modules/user/page.mdx": "2025-04-17T08:48:17.980Z", "app/commerce-modules/page.mdx": "2025-04-17T08:48:34.855Z",