docs: improve commerce modules [1/n] (#9498)

Improve and add docs for API Key, Auth, and Cart Modules

[1/n]
This commit is contained in:
Shahed Nasser
2024-10-11 15:19:13 +00:00
committed by GitHub
parent dd162d69be
commit 69b9e73be7
29 changed files with 1025 additions and 323 deletions
@@ -8,19 +8,39 @@ In this document, youll learn about concepts related to identity and actors i
## What is an Auth Identity?
The [AuthIdentity data model](/references/auth/models/AuthIdentity) represents a registered user.
The [AuthIdentity data model](/references/auth/models/AuthIdentity) represents a user registered by an [authentication provider](../auth-providers/page.mdx).
When a user is registered, a record of `AuthIdentity` is created. This record is used to validate the users authentication in future requests.
When a user is registered using an authentication provider, it creates a record of `AuthIdentity`.
Then, when the user logs-in in the future with the same authentication provider, the associated auth identity is used to validate their credentials.
---
## Actor Types
An actor type is a type of user that can be authenticated. This user is a record of a data model defined by a module.
An actor type is a type of user that can be authenticated.
For example, the `customer` actor type belongs to the Customer Modules `Customer` data model. Similarly, the `user` actor type belongs to the User Modules `User` data model.
The Auth Module doesn't store or manage any user-like models, such as for customers or users.
### Protect Routes by Actor Type
Instead, the user types are created and managed by other modules. For example, a customer is managed by the Customer Module.
Then, when an auth identity is created for the actor type, the ID of the user is stored in the `app_metadata` property of the auth identity.
For example, an auth identity of a customer has the following `app_metadata` property:
```json
{
"app_metadata": {
"customer_id": "cus_123"
}
}
```
The ID of the user is stored in the key `{actor_type}_id` of the `app_metadata` property.
---
## Protect Routes by Actor Type
When you protect routes with the `authenticate` middleware, you specify in its first parameter the actor type that must be authenticated to access the specified API routes.
@@ -54,7 +74,7 @@ By specifying `user` as the first parameter of `authenticate`, only authenticate
## Custom Actor Types
You can define custom actor types that point to the data model of your module.
You can define custom actor types that allows a custom user, managed by your custom module, to authenticate into Medusa.
For example, if you have a custom module with a `Manager` data model, you can authenticate managers with the `manager` actor type.
@@ -88,6 +88,8 @@ const modules = {
</Table.Body>
</Table>
---
## Related Guides
- [How to register a customer using email and password](../../../../storefront-development/customers/register/page.mdx)
@@ -8,7 +8,7 @@ export const metadata = {
In this document, youll learn about the GitHub Auth Module Provider and how to install and use it in the Auth Module.
The Github Auth Module Provider handles authenticating users with their GitHub account.
The Github Auth Module Provider authenticates users with their GitHub account.
<Note title="Tip">
@@ -8,11 +8,11 @@ export const metadata = {
In this document, youll learn about the Google Auth Module Provider and how to install and use it in the Auth Module.
The Google Auth Module Provider handles authenticating users with their Google account.
The Google Auth Module Provider authenticates users with their Google account.
<Note title="Tip">
Learn about the authentication flow in [this guide](../../authentication-route/page.mdx).
Learn about the authentication flow for third-party providers in [this guide](../../authentication-route/page.mdx#2-third-party-service-authenticate-flow).
</Note>
@@ -143,4 +143,4 @@ GOOGLE_CALLBACK_URL=<YOUR_GOOGLE_CALLBACK_URL>
## Examples
- [How to implement Google social login in the storefront.](../../../../storefront-development/customers/third-party-login/page.mdx).
- [How to implement Google social login in the storefront](../../../../storefront-development/customers/third-party-login/page.mdx).
@@ -37,7 +37,7 @@ For example, the EmailPass Auth Module Provider authenticates a user using their
## Configure Allowed Auth Providers of Actor Types
By default, users of all actor types can authenticate with all installed auth module providerss.
By default, users of all actor types can authenticate with all installed auth module providers.
To restrict the auth providers used for actor types, use the [authMethodsPerActor option](/references/medusa-config#http-authMethodsPerActor-1-3) in Medusa's configurations:
@@ -8,7 +8,13 @@ In this document, learn how to create an actor type and authenticate its associa
## 0. Create Module with Data Model
Before creating an actor type, you must define a data model the actor type belongs to. The data model is defined in a custom module.
Before creating an actor type, you must have a module with a data model representing the actor type.
<Note title="Tip">
Learn how to create a module in [this guide](!docs!/basics/modules).
</Note>
The rest of this guide uses this `Manager` data model as an example:
@@ -31,7 +37,7 @@ export default Manager
Start by creating a workflow that does two things:
- Create a record of the `Manager` data model.
- Creates a record of the `Manager` data model.
- Sets the `app_metadata` property of the associated `AuthIdentity` record based on the new actor type.
For example, create the file `src/workflows/create-manager.ts`. with the following content:
@@ -19,21 +19,21 @@ This example uses the [jsonwebtoken NPM package](https://www.npmjs.com/package/j
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts collapsibleLines="1-10" expandButtonLabel="Show Imports"
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import {
IAuthModuleService,
AuthenticationInput,
} from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
import { MedusaError } from "@medusajs/framework/utils"
import jwt from "jsonwebtoken"
```ts collapsibleLines="1-10" expandButtonLabel="Show Imports"
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import {
IAuthModuleService,
AuthenticationInput,
} from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
import { MedusaError } from "@medusajs/framework/utils"
import jwt from "jsonwebtoken"
export async function POST(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const authModuleService: IAuthModuleService = req.scope.resolve(
const authModuleService = req.scope.resolve(
Modules.AUTH
)
@@ -122,21 +122,21 @@ This example uses the [jsonwebtoken NPM package](https://www.npmjs.com/package/j
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts collapsibleLines="1-10" expandButtonLabel="Show Imports"
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import {
IAuthModuleService,
AuthenticationInput,
} from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
import { MedusaError } from "@medusajs/framework/utils"
import jwt from "jsonwebtoken"
```ts collapsibleLines="1-10" expandButtonLabel="Show Imports"
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import {
IAuthModuleService,
AuthenticationInput,
} from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
import { MedusaError } from "@medusajs/framework/utils"
import jwt from "jsonwebtoken"
export async function POST(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const authModuleService: IAuthModuleService = req.scope.resolve(
const authModuleService = req.scope.resolve(
Modules.AUTH
)
@@ -224,16 +224,15 @@ export async function POST(request: Request) {
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { IAuthModuleService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { Modules } from "@medusajs/framework/utils"
export async function POST(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const authModuleService: IAuthModuleService = req.scope.resolve(
const authModuleService = req.scope.resolve(
Modules.AUTH
)
@@ -280,16 +279,15 @@ export async function POST(request: Request) {
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { IAuthModuleService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { Modules } from "@medusajs/framework/utils"
export async function GET(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const authModuleService: IAuthModuleService = req.scope.resolve(
const authModuleService = req.scope.resolve(
Modules.AUTH
)
@@ -327,15 +325,14 @@ export async function GET(request: Request) {
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { IAuthModuleService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { Modules } from "@medusajs/framework/utils"
export async function POST(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const authModuleService: IAuthModuleService = req.scope.resolve(
const authModuleService = req.scope.resolve(
Modules.AUTH
)
@@ -393,15 +390,14 @@ export async function POST(request: Request, { params }: ContextType) {
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { IAuthModuleService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { Modules } from "@medusajs/framework/utils"
export async function DELETE(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const authModuleService: IAuthModuleService = req.scope.resolve(
const authModuleService = req.scope.resolve(
Modules.AUTH
)
@@ -18,6 +18,12 @@ The `providers` option is an array of auth module providers.
When the Medusa application starts, these providers are registered and can be used to handle authentication.
<Note title="Tip">
By default, the `emailpass` provider is registered to authenticate customers and admin users.
</Note>
For example:
```js title="medusa-config.js"
@@ -46,7 +52,7 @@ module.exports = defineConfig({
The `providers` option is an array of objects that accept the following properties:
- `resolve`: A string indicating the package name of the module provider or the path to it.
- `resolve`: A string indicating the package name of the module provider or the path to it relative to the `src` directory.
- `id`: A string indicating the provider's unique name or ID.
- `options`: An optional object of the module provider's options.
@@ -54,9 +60,11 @@ The `providers` option is an array of objects that accept the following properti
## Auth CORS
The Medusa application's authentication API routes are defined under the `/auth` prefix that requires setting the `authCors` property of the `http` configuration. So, before using these routes, make sure to set that configuration.
The Medusa application's authentication API routes are defined under the `/auth` prefix that requires setting the `authCors` property of the `http` configuration.
Refer to [Medusa's configuration guide](/references/medusa-config#authCors) for more details.
By default, the Medusa application you created will have an `AUTH_CORS` environment variable, which is used as the value of `authCors`.
Refer to [Medusa's configuration guide](/references/medusa-config#authCors) to learn more about the `authCors` configuration.
---
@@ -64,4 +72,4 @@ Refer to [Medusa's configuration guide](/references/medusa-config#authCors) for
The Medusa application's configuration accept an `authMethodsPerActor` configuration which restricts the allowed auth providers used with an actor type.
Learn more about the `authMethodsPerActor` configuration in [this guide](../auth-providers/page.mdx#configure-allowed-auth-providers-of-actor-types).
Learn more about the `authMethodsPerActor` configuration in [this guide](../auth-providers/page.mdx#configure-allowed-auth-providers-of-actor-types).
@@ -6,27 +6,41 @@ export const metadata = {
# {metadata.title}
The Auth Module is the `@medusajs/medusa/auth` NPM package that provides authentication-related features in your Medusa and Node.js applications.
The Auth Module provides authentication-related features in your Medusa and Node.js applications.
## How to Use Auth Module's Service
You can use the Auth Module's main service by resolving from the Medusa container the resource `Modules.AUTH` imported from `@medusajs/framework/utils`.
Use the Auth Module's main service by resolving from the Medusa container the resource `Modules.AUTH` imported from `@medusajs/framework/utils`.
For example:
<CodeTabs groupId="resource-type">
<CodeTab label="Workflow Step" value="workflow-step">
```ts title="src/workflows/hello-world/step1.ts"
import { createStep } from "@medusajs/framework/workflows-sdk"
import { Modules } from "@medusajs/framework/utils"
const step1 = createStep("step-1", async (_, { container }) => {
const authModuleService = container.resolve(
Modules.AUTH
)
const authIdentitys = await authModuleService.listAuthIdentities()
})
```
</CodeTab>
<CodeTab label="API Route" value="api-route">
```ts title="src/api/store/custom/route.ts"
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { IAuthModuleService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
export async function GET(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const authModuleService: IAuthModuleService = req.scope.resolve(
const authModuleService = req.scope.resolve(
Modules.AUTH
)
@@ -41,32 +55,15 @@ export async function GET(
```ts title="src/subscribers/custom-handler.ts"
import { SubscriberArgs } from "@medusajs/framework"
import { IAuthModuleService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
export default async function subscriberHandler({ container }: SubscriberArgs) {
const authModuleService: IAuthModuleService = container.resolve(
const authModuleService = container.resolve(
Modules.AUTH
)
const authIdentitys = await authModuleService.listAuthIdentities()
}
```
</CodeTab>
<CodeTab label="Workflow Step" value="workflow-step">
```ts title="src/workflows/hello-world/step1.ts"
import { createStep } from "@medusajs/framework/workflows-sdk"
import { IAuthModuleService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
const step1 = createStep("step-1", async (_, { container }) => {
const authModuleService: IAuthModuleService = container.resolve(
Modules.AUTH
)
const authIdentitys = await authModuleService.listAuthIdentities()
})
```
</CodeTab>
@@ -78,7 +75,7 @@ const step1 = createStep("step-1", async (_, { container }) => {
### Basic User Authentication
With the Auth Module, authenticate users using their email and password credentials.
Authenticate users using their email and password credentials.
```ts
const { success, authIdentity, error } = await authModuleService.authenticate(
@@ -6,7 +6,9 @@ export const metadata = {
# {metadata.title}
In this guide, you'll learn how to handle the `auth.password_reset` event, which is emitted when a request is sent to the [Generate Reset Password Token API route](../authentication-route/page.mdx#generate-reset-password-token-route), to send reset instructions to the user.
In this guide, you'll learn how to handle the `auth.password_reset` event, which is emitted when a request is sent to the [Generate Reset Password Token API route](../authentication-route/page.mdx#generate-reset-password-token-route).
You'll create a subscriber that listens to the event. When the event is emitted, the subscriber sends an email notification to the user.
<Prerequisites
items={[
@@ -29,14 +31,14 @@ export const highlights=[
["10", "token", "The password reset token."],
["11", "actor_type", "The user's actor type."],
["19", "urlPrefix", "Set the page's URL based on the user's actor type."],
["21", "createNotifications", "Send a notification to the user."],
["23", `"email"`, "The channel to send the notification through."],
["24", "template", "The template defined in the third-party provider."],
["25", "data", "The data to pass to the template in the third-party provider."],
["27", "url", "The frontend URL to redirect the user to reset their password."]
["23", "createNotifications", "Send a notification to the user."],
["25", `"email"`, "The channel to send the notification through."],
["26", "template", "The template defined in the third-party provider."],
["27", "data", "The data to pass to the template in the third-party provider."],
["29", "url", "The frontend URL to redirect the user to reset their password."]
]
```ts title="src/subscribers/handle-reset.ts" collapsibleLines="1-6" expandMoreLabel="Show Imports"
```ts title="src/subscribers/handle-reset.ts" highlights={highlights} collapsibleLines="1-6" expandMoreLabel="Show Imports"
import {
SubscriberArgs,
type SubscriberConfig,
@@ -55,7 +57,9 @@ export default async function resetPasswordTokenHandler({
Modules.NOTIFICATION
)
const urlPrefix = actor_type === "customer" ? "https://storefront.com" : "https://admin.com"
const urlPrefix = actor_type === "customer" ?
"https://storefront.com" :
"https://admin.com"
await notificationModuleService.createNotifications({
to: email,