docs: new + improved auth documentation pages (#7529)

* added and improved auth docs

* add prep to generates resources action

* add module options to sidebar

* fix broken link
This commit is contained in:
Shahed Nasser
2024-06-09 16:18:29 +03:00
committed by GitHub
parent 3f661c917b
commit e472aed00f
17 changed files with 958 additions and 265 deletions
@@ -46,11 +46,15 @@ jobs:
working-directory: www
run: yarn install
- name: Build Docs packages
working-directory: www
run: yarn build:packages
- name: Install Workspace dependencies
run: yarn install
working-directory: www/utils
- name: Build Workspace dependencies
- name: Build Workspace packages
run: yarn build
working-directory: www/utils
@@ -64,6 +68,10 @@ jobs:
run: "yarn start generate all --merge"
working-directory: www/utils/packages/typedoc-generate-references
- name: Generate Sidebar and File Map
run: "yarn prep"
working-directory: www/apps/resources
- name: Generate Changeset
run: "yarn generate:changeset"
working-directory: www/utils/packages/scripts
@@ -12,7 +12,7 @@ In this document, you'll learn about how the Auth Provider is used in an authent
## How to Authenticate a User
To authenticate a user, you use the [authenticate method of the Auth Module's main service](/references/auth/authenticate) (`IAuthModuleService`). For example:
To authenticate a user, you use the [authenticate method of the Auth Module's main service](/references/auth/authenticate). For example:
```ts
const data = await authModuleService.authenticate(
@@ -0,0 +1,58 @@
export const metadata = {
title: `Auth Identity and Actor Types`,
}
# {metadata.title}
In this document, youll learn about concepts related to identity and actors in the Auth Module.
## What is an Auth Identity?
The [AuthIdentity data model](/references/auth/model/AuthIdentity) represents a previously-authenticated user.
When a user is authenticated, a record of `AuthIdentity` is created. This record is used to validate the users authentication in future requests.
---
## 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.
For example, the `customer` belongs to the Customer Modules `Customer` data model. Similarly, the `user` belongs to the User Modules `User` data model.
### 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.
For example:
export const highlights = [
["8", `"user"`, "The actor type that must be authenticated to access the specified routes."]
]
```ts title="src/api/middlewares.ts" highlights={highlights}
import { MiddlewaresConfig, authenticate } from "@medusajs/medusa"
export const config: MiddlewaresConfig = {
routes: [
{
matcher: "/custom/admin*",
middlewares: [
authenticate("user", ["session", "bearer", "api-key"]),
],
},
],
}
```
By specifying `user` as the first parameter of `authenticate`, only authenticated users of actor type `user` can access API routes starting with `/custom/admin`.
---
## Custom Actor Types
You can define custom actor types that point to the data model of your module.
For example, if you have a custom module with a `Manager` data model, you can authenticate managers with the `manager` actor type.
Learn how to create a custom actor type in [this guide](../create-actor-type/page.mdx).
@@ -0,0 +1,189 @@
import { Table } from "docs-ui"
export const metadata = {
title: `Google Auth Provider Module`,
}
# {metadata.title}
In this document, youll learn about the Google auth provider module and how to install and use it in the Auth Module.
## Features
The Google auth provider module handles authenticating users with their Google accounts.
By integrating the Google auth provider, you provide your users and customers with the ability to login with their Google account.
---
## Install the Google Auth Provider Module
<Note type="check">
- [Create a project in Google Cloud.](https://cloud.google.com/resource-manager/docs/creating-managing-projects).
- [Create authorization credentials](https://developers.google.com/identity/protocols/oauth2/web-server#creatingcred).
- Set the Redirect Uri of your Oauth Client ID to `{medusa_url}/auth/{actor_type}/google/callback`, where:
- `{medusa_url}` is the URL of your Medusa backend.
- `{actor_type}` is the actor type that the Google auth provider can authenticate. For example, `customer`.
</Note>
To install the Google auth provider module, run the following command in the directory of your Medusa application:
```bash npm2yarn
npm install @medusajs/auth-google
```
Next, add the module to the array of providers passed to the Auth Module:
```js title="medusa-config.js"
const { Modules } = require("@medusajs/modules-sdk")
// ...
const modules = {
// ...
[Modules.AUTH]: {
resolve: "@medusajs/auth",
options: {
providers: [
{
resolve: "@medusajs/auth-google",
options: {
config: {
google: {
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: process.env.GOOGLE_CALLBACK_URL,
successRedirectUrl:
process.env.GOOGLE_SUCCESS_REDIRECT_URL,
}
}
}
},
],
},
},
}
```
### Environment Variables
Make sure to add the necessary environment variables for the above options in `.env`:
```bash
GOOGLE_CLIENT_ID=<YOUR_GOOGLE_CLIENT_ID>
GOOGLE_CLIENT_SECRET=<YOUR_GOOGLE_CLIENT_SECRET>
GOOGLE_CALLBACK_URL=<YOUR_GOOGLE_CALLBACK_URL>
GOOGLE_SUCCESS_REDIRECT_URL=<YOUR_GOOGLE_SUCCESS_REDIRECT_URL>
```
### Module Options
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Configuration</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
<Table.HeaderCell>Required</Table.HeaderCell>
<Table.HeaderCell>Default</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
`clientID`
</Table.Cell>
<Table.Cell>
A string indicating the [Google API Client ID](https://developers.google.com/identity/oauth2/web/guides/get-google-api-clientid).
</Table.Cell>
<Table.Cell>
Yes
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`clientSecret`
</Table.Cell>
<Table.Cell>
A string indicating the [Google Client Secret](https://support.google.com/cloud/answer/6158849?hl=en#zippy=%2Cstep-create-a-new-client-secret).
</Table.Cell>
<Table.Cell>
Yes
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`callbackURL`
</Table.Cell>
<Table.Cell>
A string indicating the URL to redirect to in your app after the user completes their authentication in Google.
The Medusa application provides the API route `/auth/[scope]/google/callback` that you can use, where `[scope]` is the scope this config belongs to.
For example, `/auth/store/google/callback`.
</Table.Cell>
<Table.Cell>
Yes
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`successRedirectUrl`
</Table.Cell>
<Table.Cell>
A string indicating the URL to redirect to in your app after the authentication has been successful.
If not provided, the Medusa application's callback route just returns a JSON with the JWT token of the auth identity.
</Table.Cell>
<Table.Cell>
No
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
{/* TODO add how to implement authentication flow with google */}
@@ -0,0 +1,95 @@
import { Table } from "docs-ui"
export const metadata = {
title: `Emailpass Auth Provider Module`,
}
# {metadata.title}
In this document, youll learn about the Emailpass auth provider module and how to install and use it in the Auth Module.
## Features
Using the Emailpass auth provider module, you allow users to register and login with an email and password.
---
## Install the Emailpass Auth Provider Module
The Emailpass auth provider is registered by default with the Auth Module.
If you want to pass options to the provider, add the provider to the `providers` option of the Auth Module:
```js title="medusa-config.js"
const { Modules } = require("@medusajs/modules-sdk")
// ...
const modules = {
// ...
[Modules.AUTH]: {
resolve: "@medusajs/auth",
options: {
providers: [
{
resolve: "@medusajs/auth-emailpass",
config: {
emailpass: {
// options...
}
}
},
],
},
},
}
```
### Module Options
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Configuration</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
<Table.HeaderCell>Required</Table.HeaderCell>
<Table.HeaderCell>Default</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
`hashConfig`
</Table.Cell>
<Table.Cell>
An object of configurations to use when hashing the user's
password. Refer to [scrypt-kdf](https://www.npmjs.com/package/scrypt-kdf#-hash)'s
documentation for accepted options.
</Table.Cell>
<Table.Cell>
No
</Table.Cell>
<Table.Cell>
```ts noCopy noReport noLineNumbers
const hashConfig = {
logN: 15,
r: 8,
p: 1
}
```
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
## Related Guides
- [How to register a customer using email and password](../../../customer/register-customer-email/page.mdx)
@@ -12,7 +12,7 @@ An auth provider module handles authenticating customers and users, either using
For example, the EmailPass Auth Provider Module authenticates a user using their email and password, whereas the Google Auth Provider Module authenticates users using their Google account.
<Note type="check">
<Note type="soon">
Support for the Google Auth Provider Module is coming soon.
@@ -20,11 +20,11 @@ Support for the Google Auth Provider Module is coming soon.
---
## Configure Auth Provider Modules
## Configure Allowed Auth Providers of Actor Types
By default, admin users and customers can login with all installed auth provider moduless.
By default, users of all actor types can authenticate with all installed auth provider moduless.
To limit the auth providers that used for admin users and customers, use the [authMethodsPerActor option](/references/medusa-config#http-authMethodsPerActor-1-3) in Medusa's configurations:
To restrict the auth providers used for actor types, use the [authMethodsPerActor option](/references/medusa-config#http-authMethodsPerActor-1-3) in Medusa's configurations:
```js title="medusa-config.js"
module.exports = defineConfig({
@@ -41,6 +41,12 @@ module.exports = defineConfig({
})
```
<Note title="Important">
When you specify the `authMethodsPerActor` configuration, it overrides the default. So, if you don't specify any providers for an actor type, users of that actor type can't authenticate with any provider.
</Note>
---
## How to Create an Auth Provider Module
@@ -0,0 +1,37 @@
export const metadata = {
title: `Authentication Route`,
}
# {metadata.title}
In this document, you'll learn about the `/auth` route and how to use it to create or log-in users.
## `/auth` Route
The Medusa application defines an API route at `/auth/{actor_type}/{provider}` used to obtain a token used later for authentication purposes.
Its path parameters are:
- `{actor_type}`: the actor type of the user you're authenticating. For example, `customer`.
- `{provider}`: the auth provider to handle the authentication. For example, `emailpass`.
This route accepts in the request body the data that the specified authentication provider requires to handle authentication.
For example, the EmailPass provider requires an `email` and `password` fields in the request body.
If the authentication is successful, you'll receive a `token` field in the response body.
---
## How to Use the Authentication Token
There are two ways the returned authentication token is useful:
1. Send authenticated requests to restricted routes. For example, if the token is of an admin user, you use it in the bearer header of subsequent requests to the admin API routes.
2. Before creating a user of an actor type, such as a `customer` or a custom actor type. You use it in the bearer header of the request to the API route that creates the user.
<Note title="Example">
[How to register Customers using the authentication route](../../customer/register-customer-email/page.mdx).
</Note>
@@ -0,0 +1,316 @@
export const metadata = {
title: `How to Create an Actor Type`,
}
# {metadata.title}
In this document, learn how to create an actor type and authenticate its associated data model.
## 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.
The rest of this guide uses this `Manager` data model as an example:
```ts title="src/modules/manager/models/manager.ts"
import { BaseEntity } from "@medusajs/utils"
import {
Entity,
PrimaryKey,
Property,
} from "@mikro-orm/core"
@Entity()
export class Manager extends BaseEntity {
@PrimaryKey({ columnType: "text" })
id!: string
@Property({ columnType: "text" })
first_name: string
@Property({ columnType: "text" })
last_name: string
@Property({ columnType: "text" })
email: string
}
```
The modules main service must also have a `create` method to create a record of the `Manager` data model.
---
## 1. Create Workflow
Start by creating a workflow that does two things:
- Create a record of the `Manager` data model.
- Sets the `app_metadata` field 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:
export const workflowHighlights = [
["27", "createManagerStep", "Thi step creates a manager."],
["44", "createManagerWorkflow", "The workflow used to create a manager and set its auth identity's actor type."],
["53", "setAuthAppMetadataStep", "Set the actor type of the manager's associated auth identity."],
["55", '"manager"', "The actor type of the manager."]
]
```ts title="src/workflows/create-manager.ts" highlights={workflowHighlights}
import {
createWorkflow,
createStep,
StepResponse
} from "@medusajs/workflows-sdk"
import {
setAuthAppMetadataStep
} from "@medusajs/core-flows"
import ManagerModuleService from "../modules/manager/service"
type CreateManagerWorkflowInput = {
manager: {
first_name: string
last_name: string
email: string
}
authIdentityId: string
}
type CreateManagerWorkflowOutput = {
id: string
first_name: string
last_name: string
email: string
}
const createManagerStep = createStep(
"create-manager-step",
async ({
manager: managerData
}: Pick<CreateManagerWorkflowInput, "manager">,
{ container }) => {
const managerModuleService: ManagerModuleService =
container.resolve("managerModuleService")
const manager = await managerModuleService.create(
managerData
)
return new StepResponse(manager)
}
)
const createManagerWorkflow = createWorkflow<
CreateManagerWorkflowInput, CreateManagerWorkflowOutput
>(
"create-manager",
function (input) {
const manager = createManagerStep({
manager: input.manager
})
setAuthAppMetadataStep({
authIdentityId: input.authIdentityId,
actorType: "manager",
value: manager.id
})
return manager
}
)
export default createManagerWorkflow
```
This workflow accepts the managers data and the associated auth identitys ID as inputs. The next sections explain how the auth identity ID is retrieved.
The workflow has two steps:
1. Create the manager using the `createManagerStep`.
2. Set the `app_metadata` field of the associated auth identity using the `setAuthAppMetadataStep` step imported from `@medusajs/core-flows`. You specify the actor type `manager` in the `actorType` property of the steps input.
---
## 2. Define the Create API Route
Next, youll use the workflow defined in the previous section in an API route that creates a manager.
So, create the file `src/api/manager/route.ts` with the following content:
export const createRouteHighlights = [
["15", "AuthenticatedMedusaRequest", "The request must be authenticated to associate the manager with an auth identity."],
["27", "createManagerWorkflow", "Use the workflow created previously to create the manager."],
["31", "auth_identity_id", "Access the associated auth identity's ID in `req.auth_context.auth_identity_id`."]
]
```ts title="src/api/manager/route.ts" highlights={createRouteHighlights}
import type {
AuthenticatedMedusaRequest,
MedusaResponse
} from "@medusajs/medusa"
import { MedusaError } from "@medusajs/utils"
import createManagerWorkflow from "../../workflows/create-manager"
type RequestBody = {
first_name: string
last_name: string
email: string
}
export async function POST(
req: AuthenticatedMedusaRequest<RequestBody>,
res: MedusaResponse
) {
// If `actor_id` is present, the request carries
// authentication for an existing manager
if (req.auth_context.actor_id) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Request already authenticated as a manager."
)
}
const { result } = await createManagerWorkflow(req.scope)
.run({
input: {
manager: req.body,
authIdentityId: req.auth_context.auth_identity_id
}
})
res.status(200).json({ manager: result })
}
```
Since the manager must be associated with an `AuthIdentity` record, the request is expected to be authenticated, even if the manager isnt created yet. This can be achieved by:
1. Obtaining a token usng the [/auth route](../authentication-route/page.mdx).
2. Passing the token in the bearer header of the request to this route.
In the API route, you create the manager using the workflow from the previous section and return it in the response.
---
## 3. Apply the `authenticate` Middleware
The last step is to apply the `authenticate` middleware on the API routes that require a managers authentication.
To do that, create the file `src/api/middlewares.ts` with the following content:
export const middlewareHighlights = [
["9", "authenticate", "Require the user to be authenticated to access the `/manager` API route when sending a `POST` request."],
["10", "allowUnregistered", "The user doesn't need to be registered to access the API route."],
["17", "authenticate", "Require the user to be authenticated as a manager when accessing `/manager/me` API routes."]
]
```ts title="src/api/middlewares.ts" highlights={middlewareHighlights}
import { MiddlewaresConfig, authenticate } from "@medusajs/medusa"
export const config: MiddlewaresConfig = {
routes: [
{
matcher: "/manager",
method: "POST",
middlewares: [
authenticate("manager", ["session", "bearer"], {
allowUnregistered: true
}),
],
},
{
matcher: "/manager/me*",
middlewares: [
authenticate("manager", ["session", "bearer"]),
],
},
],
}
```
This applies middlewares on two route patterns:
1. The `authenticate` middleware is applied on the `/manager` API route for `POST` requests while allowing unregistered managers. This requires that a bearer token be passed in the request to access the managers auth identity but doesnt require the manager to be registered.
2. The `authenticate` middleware is applied on all routes starting with `/manager/me`, restricting these routes to authenticated managers only.
### Retrieve Manager API Route
For example, create the file `src/api/manager/me/route.ts` with the following content:
```ts title="src/api/manager/me/route.ts"
import {
AuthenticatedMedusaRequest,
MedusaResponse
} from "@medusajs/medusa";
import ManagerModuleService from "../../../modules/manager/service";
export async function GET(
req: AuthenticatedMedusaRequest,
res: MedusaResponse
): Promise<void> {
const managerModuleService: ManagerModuleService =
req.scope.resolve("managerModuleService")
const manager = await managerModuleService.retrieve(
req.auth_context.actor_id
)
res.json({ manager })
}
```
This route is only accessible by authenticated managers. You access the managers ID using `req.auth_context.actor_id`.
---
## Test Custom Actor Type Authentication Flow
To authenticate managers:
1. Send a `POST` request to `/auth/manager/emailpass` to create an auth identity for the manager:
```bash
curl -X POST 'http://localhost:9000/auth/manager/emailpass' \
-H 'Content-Type: application/json' \
--data-raw '{
"email": "manager@gmail.com",
"password": "supersecret"
}'
```
Copy the returned token to use it in the next request.
2. Send a `POST` request to `/manager` to create a manager:
```bash
curl -X POST 'http://localhost:9000/manager' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {token}' \
--data-raw '{
"first_name": "John",
"last_name": "Doe",
"email": "manager@gmail.com"
}'
```
Replace `{token}` with the token returned in the previous step.
3. Send a `POST` request to `/auth/manager/emailpass` again to retrieve an authenticated token for the manager:
```bash
curl -X POST 'http://localhost:9000/auth/manager/emailpass' \
-H 'Content-Type: application/json' \
--data-raw '{
"email": "manager@gmail.com",
"password": "supersecret"
}'
```
4. You can now send authenticated requests as a manager. For example, send a `GET` request to `/manager/me` to retrieve the authenticated managers details:
```bash
curl 'http://localhost:9000/manager/me' \
-H 'Authorization: Bearer {token}'
```
Whenever you want to log in as a manager, use the `/auth/manager/emailpass` API route, as explained in step 3.
@@ -14,6 +14,12 @@ In this document, you'll learn about the options of the Auth Module.
## providers
The `providers` option is an array of auth provider modules.
When the Medusa application starts, these providers are registered and can be used to handle authentication.
For example:
```js title="medusa-config.js"
const { Modules } = require("@medusajs/modules-sdk")
@@ -22,212 +28,30 @@ const { Modules } = require("@medusajs/modules-sdk")
module.exports = defineConfig({
// ...
modules: {
[Modules.AUTH]: {
resolve: "@medusajs/auth",
options: {
providers: [
{
name: "emailpass",
scopes: {
store: {},
admin: {},
},
resolve: "@medusajs/auth",
options: {
providers: [
{
resolve: "@medusajs/auth-google",
options: {
config: {
google: {
// provider options...
}
}
},
{
name: "google",
scopes: {
admin: {
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: process.env.GOOGLE_CALLBACK_URL,
successRedirectUrl:
process.env.GOOGLE_SUCCESS_REDIRECT_URL,
},
},
},
],
},
}
}
},
],
},
},
})
```
The `providers` option is an array of objects indicating the auth providers to register, their scopes, and configurations.
The `providers` option is an array of objects that accept the following properties:
Each object accepts the following properties:
- `name`: The provider's name, which is set in the auth provider class's `PROVIDER` field. For example, `emailpass` or `google`.
- `scopes`: An object of scopes. The keys are a scope's name, which in the Medusa application would be either `admin` or `store`. The value is an object of configurations for that scope. Each provider accepts different scope configurations as detailed below.
### emailpass Scope Configurations
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Configuration</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
<Table.HeaderCell>Required</Table.HeaderCell>
<Table.HeaderCell>Default</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
`hashConfig`
</Table.Cell>
<Table.Cell>
An object of configurations to use when hashing the user's
password. Refer to [scrypt-kdf](https://www.npmjs.com/package/scrypt-kdf#-hash)'s
documentation for accepted options.
</Table.Cell>
<Table.Cell>
No
</Table.Cell>
<Table.Cell>
```ts noCopy noReport noLineNumbers
const hashConfig = {
logN: 15,
r: 8,
p: 1
}
```
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
### google Scope Configurations
<Note type="check">
Follow [this Google documentation](https://developers.google.com/identity/protocols/oauth2/web-server#prerequisites) to enable Google's APIs and retrieve the necessary credentials.
</Note>
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Configuration</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
<Table.HeaderCell>Required</Table.HeaderCell>
<Table.HeaderCell>Default</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
`clientID`
</Table.Cell>
<Table.Cell>
A string indicating the [Google API Client ID](https://developers.google.com/identity/oauth2/web/guides/get-google-api-clientid).
</Table.Cell>
<Table.Cell>
Yes
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`clientSecret`
</Table.Cell>
<Table.Cell>
A string indicating the [Google Client Secret](https://support.google.com/cloud/answer/6158849?hl=en#zippy=%2Cstep-create-a-new-client-secret).
</Table.Cell>
<Table.Cell>
Yes
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`callbackURL`
</Table.Cell>
<Table.Cell>
A string indicating the URL to redirect to in your app after the user completes their authentication in Google.
The Medusa application provides the API route `/auth/[scope]/google/callback` that you can use, where `[scope]` is the scope this config belongs to.
For example, `/auth/store/google/callback`.
</Table.Cell>
<Table.Cell>
Yes
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`successRedirectUrl`
</Table.Cell>
<Table.Cell>
A string indicating the URL to redirect to in your app after the authentication has been successful.
If not provided, the Medusa application's callback route just returns a JSON with the JWT token of the auth identity.
</Table.Cell>
<Table.Cell>
No
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
### Environment Variables
Make sure to add the necessary environment variables for the above options in `.env`:
```bash
GOOGLE_CLIENT_ID=<YOUR_GOOGLE_CLIENT_ID>
GOOGLE_CLIENT_SECRET=<YOUR_GOOGLE_CLIENT_SECRET>
GOOGLE_CALLBACK_URL=<YOUR_GOOGLE_CALLBACK_URL>
GOOGLE_SUCCESS_REDIRECT_URL=<YOUR_GOOGLE_SUCCESS_REDIRECT_URL>
```
- `resolve`: A string indicating the package name of the auth provider module or the path to it.
- `options`: An optional object of the auth provider module's options. The object must have the following property:
- `config`: An object whose key is the ID of the auth provider, and its value is an object of options to pass to the provider module.
---
@@ -236,3 +60,11 @@ GOOGLE_SUCCESS_REDIRECT_URL=<YOUR_GOOGLE_SUCCESS_REDIRECT_URL>
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.
Refer to [Medusa's configuration guide](/references/medusa-config#authCors) for more details.
---
## authMethodsPerActor Configuration
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).
@@ -26,10 +26,9 @@ const { success, authIdentity, error } =
} as AuthenticationInput)
if (!success) {
// incorrect authentication details
throw new Error(error)
}
// user is authenticated
```
### Third-Party and Social Authentication
@@ -1,37 +0,0 @@
---
sidebar_label: "User Creation"
---
export const metadata = {
title: `User Creation`,
}
# {metadata.title}
In this document, youll learn about creating a user with the User Module after authentication.
## Creating a User using the User Module
The User Module provides user and invite management functionalities. However, it doesnt provide authentication functionalities or store any related data.
By combining the User and Auth Modules, you can use the Auth Module for authenticating users, and the User Module to manage those users.
So, when a user is authenticated, and you receive the `AuthIdentity` object, you can use it to create a user if it doesnt exist:
```ts
const { success, authIdentity } =
await authModuleService.authenticate("emailpass", {
// ...
})
// assuming authIdentity is defined
const [, count] = await userModuleService.listAndCount({
email: authIdentity.entity_id,
})
if (!count) {
const user = await userModuleService.create({
email: authIdentity.entity_id,
})
}
```
@@ -0,0 +1,74 @@
export const metadata = {
title: `How to Register a Customer with Email and Password`,
}
# {metadata.title}
In this guide, you'll learn the steps to register and authenticate a customer.
<Note title="Steps Summary">
1. Send a `POST` request to `/auth/customer/emailpass`.
2. Send a request to the [Create Customer API route](!api!/store#customers_postcustomers) passing the token obtained from the first step as a bearer token.
3. Send a `POST` request to `/auth/customer/emailpass` to log-in.
</Note>
## 1. Obtain Authentication Token
Before registering and creating the customer, you must create an authentication identity that's associated with that customer.
To do that, use the `/auth/customer/{provider}` API route, where `{provider}` is the auth provider to use to handle authentication.
<Note>
Learn more about the `/auth` route in [this document](../../auth/authentication-route/page.mdx)
</Note>
For example, send a `POST` request to `/auth/customer/emailpass`:
```bash
curl -X POST 'http://localhost:9000/auth/customer/emailpass' \
--header 'Content-Type: application/json' \
--data-raw '{
"email": "customer@gmail.com",
"password": "supersecret"
}'
```
---
## 2. Register Customer
Then, use the returned token in the header of the [Create Customer API route](!api!/store#customers_postcustomers):
```bash
curl -X POST 'http://localhost:9000/store/customers' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {token}' \
--data-raw '{
"email": "customer@gmail.com",
"first_name": "John",
"last_name": "Doe"
}'
```
This creates and returns the customer.
---
## 3. Login Customer
Finally, to log-in the customer, send a `POST` request again to `/auth/customer/emailpass`:
```bash
curl -X POST 'http://localhost:9000/auth/customer/emailpass' \
--header 'Content-Type: application/json' \
--data-raw '{
"email": "customer@gmail.com",
"password": "supersecret"
}'
```
You can now use the returned token to send authenticated requests as a customer.
@@ -97,7 +97,7 @@ In this document, you'll learn about the options of the Payment Module.
## providers
The `providers` option is an array of either payment provider modules, payment plugins, or path to a file that holds a payment provider.
The `providers` option is an array of payment provider modules.
When the Medusa application starts, these providers are registered and can be used to process payments.
@@ -6,14 +6,6 @@ export const metadata = {
This document provides flows to create a user.
## Using the Auth Module
The Auth Module allows you to create a user with different providers, such as creating a user with an email and password or creating a user using their Google account.
Learn more about this creation flow in [this Auth Module guide](../../auth/user-creation/page.mdx).
---
## Invite Users
Another possible flow to create a user is by sending them an invite. Then, once they accept it, you create a new user for them:
@@ -58,4 +50,26 @@ const user = await userModuleService.create({
})
```
However, the User Module doesnt handle authentication methods or store a users password. For that, youd need to use the [Auth Module](../../auth/page.mdx).
### With the Auth Module
By combining the User and Auth Modules, you can use the Auth Module for authenticating users, and the User Module to manage those users.
So, when a user is authenticated, and you receive the `AuthIdentity` object, you can use it to create a user if it doesnt exist:
```ts
const { success, authIdentity } =
await authModuleService.authenticate("emailpass", {
// ...
})
// assuming authIdentity is defined
const [, count] = await userModuleService.listAndCount({
email: authIdentity.entity_id,
})
if (!count) {
const user = await userModuleService.create({
email: authIdentity.entity_id,
})
}
```
+24 -4
View File
@@ -255,10 +255,30 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/auth/auth-flows/page.mdx",
"pathname": "/commerce-modules/auth/auth-flows"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/auth-identity-and-actor-types/page.mdx",
"pathname": "/commerce-modules/auth/auth-identity-and-actor-types"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/auth-providers/_google/page.mdx",
"pathname": "/commerce-modules/auth/auth-providers/_google"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/auth-providers/emailpass/page.mdx",
"pathname": "/commerce-modules/auth/auth-providers/emailpass"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/auth-providers/page.mdx",
"pathname": "/commerce-modules/auth/auth-providers"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/authentication-route/page.mdx",
"pathname": "/commerce-modules/auth/authentication-route"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/create-actor-type/page.mdx",
"pathname": "/commerce-modules/auth/create-actor-type"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/events/_events-table/page.mdx",
"pathname": "/commerce-modules/auth/events/_events-table"
@@ -279,10 +299,6 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/auth/page.mdx",
"pathname": "/commerce-modules/auth"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/user-creation/page.mdx",
"pathname": "/commerce-modules/auth/user-creation"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/cart/concepts/page.mdx",
"pathname": "/commerce-modules/cart/concepts"
@@ -355,6 +371,10 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/customer/page.mdx",
"pathname": "/commerce-modules/customer"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/customer/register-customer-email/page.mdx",
"pathname": "/commerce-modules/customer/register-customer-email"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/customer/relations-to-other-modules/page.mdx",
"pathname": "/commerce-modules/customer/relations-to-other-modules"
+53 -3
View File
@@ -181,6 +181,13 @@ export const generatedSidebar = [
"title": "Auth Module",
"hasTitleStyling": true,
"children": [
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/auth/module-options",
"title": "Module Options",
"children": []
},
{
"loaded": true,
"isPathHref": true,
@@ -193,11 +200,33 @@ export const generatedSidebar = [
"isPathHref": true,
"title": "Concepts",
"children": [
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/auth/auth-identity-and-actor-types",
"title": "Identity and Actor Types",
"children": []
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/auth/auth-providers",
"title": "Auth Providers",
"children": [
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/auth/auth-providers/emailpass",
"title": "Emailpass Auth Provider Module",
"children": []
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/auth/authentication-route",
"title": "Authentication Route",
"children": []
},
{
@@ -206,12 +235,19 @@ export const generatedSidebar = [
"path": "/commerce-modules/auth/auth-flows",
"title": "Auth Flows",
"children": []
},
}
]
},
{
"loaded": true,
"isPathHref": true,
"title": "Guides",
"children": [
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/auth/user-creation",
"title": "User Creation",
"path": "/commerce-modules/auth/create-actor-type",
"title": "Create an Actor Type",
"children": []
}
]
@@ -994,6 +1030,20 @@ export const generatedSidebar = [
}
]
},
{
"loaded": true,
"isPathHref": true,
"title": "Guides",
"children": [
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/customer/register-customer-email",
"title": "Register a Customer with Email",
"children": []
}
]
},
{
"loaded": true,
"isPathHref": true,
+34 -2
View File
@@ -78,6 +78,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
title: "Auth Module",
hasTitleStyling: true,
children: [
{
path: "/commerce-modules/auth/module-options",
title: "Module Options",
},
{
path: "/commerce-modules/auth/examples",
title: "Examples",
@@ -85,17 +89,36 @@ export const sidebar = sidebarAttachHrefCommonOptions([
{
title: "Concepts",
children: [
{
path: "/commerce-modules/auth/auth-identity-and-actor-types",
title: "Identity and Actor Types",
},
{
path: "/commerce-modules/auth/auth-providers",
title: "Auth Providers",
children: [
{
path: "/commerce-modules/auth/auth-providers/emailpass",
title: "Emailpass Auth Provider Module",
},
],
},
{
path: "/commerce-modules/auth/authentication-route",
title: "Authentication Route",
},
{
path: "/commerce-modules/auth/auth-flows",
title: "Auth Flows",
},
],
},
{
title: "Guides",
children: [
{
path: "/commerce-modules/auth/user-creation",
title: "User Creation",
path: "/commerce-modules/auth/create-actor-type",
title: "Create an Actor Type",
},
],
},
@@ -287,6 +310,15 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
title: "Guides",
children: [
{
path: "/commerce-modules/customer/register-customer-email",
title: "Register a Customer with Email",
},
],
},
{
title: "References",
children: [