import { CodeTabs, CodeTab } from "docs-ui"

export const metadata = {
  title: `Examples of the Auth Module`,
}

# {metadata.title}

In this guide, you’ll find common examples of how you can use the Auth Module in your application.

## Authenticate User

<Note>

This example uses the [jsonwebtoken NPM package](https://www.npmjs.com/package/jsonwebtoken) to create the authentication token.

</Note>

<CodeTabs groupId="app-type">
  <CodeTab label="Medusa API Router" value="medusa">

  ```ts
  import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
  import {
    IAuthModuleService,
    AuthenticationInput,
  } from "@medusajs/types"
  import { ModuleRegistrationName } from "@medusajs/modules-sdk"
  import { MedusaError } from "@medusajs/utils"
  import jwt from "jsonwebtoken"

  export async function POST(
    req: MedusaRequest,
    res: MedusaResponse
  ): Promise<void> {
    const authModuleService: IAuthModuleService =
      req.scope.resolve(ModuleRegistrationName.AUTH)

    const { success, authIdentity, location, error } =
      await authModuleService.authenticate("emailpass", {
        url: req.url,
        headers: req.headers,
        query: req.query,
        body: req.body,
        authScope: "admin",
        protocol: req.protocol,
      } as AuthenticationInput)

    if (!success) {
      throw new MedusaError(MedusaError.Types.UNAUTHORIZED, error)
    }

    if (location) {
      res.redirect(location)
      return
    }

    const { jwtSecret } =
      req.scope.resolve("configModule").projectConfig.http
    const token = jwt.sign(authIdentity, jwtSecret)

    res.status(200).json({ token })
  }
  ```

  </CodeTab>
  <CodeTab label="Next.js App Router" value="nextjs">

  ```ts
  import { NextResponse } from "next/server"

  import {
    initialize as initializeAuthModule,
  } from "@medusajs/auth"

  export async function POST(request: Request) {
    const authModuleService = await initializeAuthModule()
    const url = new URL(request.url)

    const { success, authIdentity, location, error } =
      await authModuleService.authenticate("emailpass", {
        url: request.url,
        headers: Object.fromEntries(request.headers),
        query: Object.fromEntries(url.searchParams),
        body: await request.json(),
        authScope: "admin",
        protocol: url.protocol,
      } as AuthenticationInput)

    if (!success) {
      throw new Error(error)
    }

    if (location) {
      return NextResponse.redirect(location)
      return
    }

    const token = jwt.sign(authIdentity, "supersecret")

    return NextResponse.json({
      token,
    }, {
      status: 200,
    })
  }
  ```

  </CodeTab>
</CodeTabs>

---

## Validate Callback

<Note>

This example uses the [jsonwebtoken NPM package](https://www.npmjs.com/package/jsonwebtoken) to create the authentication token.

</Note>

<CodeTabs groupId="app-type">
  <CodeTab label="Medusa API Router" value="medusa">

  ```ts
  import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
  import {
    IAuthModuleService,
    AuthenticationInput,
  } from "@medusajs/types"
  import { ModuleRegistrationName } from "@medusajs/modules-sdk"
  import { MedusaError } from "@medusajs/utils"
  import jwt from "jsonwebtoken"

  export async function POST(
    req: MedusaRequest,
    res: MedusaResponse
  ): Promise<void> {
    const authModuleService: IAuthModuleService =
      req.scope.resolve(ModuleRegistrationName.AUTH)

    const { success, authIdentity, error, successRedirectUrl } =
      await authModuleService.validateCallback("google", {
        url: req.url,
        headers: req.headers,
        query: req.query,
        body: req.body,
        authScope: "admin",
        protocol: req.protocol,
      } as AuthenticationInput)

    if (!success) {
      throw new MedusaError(MedusaError.Types.UNAUTHORIZED, error)
    }

    const { jwtSecret } =
      req.scope.resolve("configModule").projectConfig.http
    const token = jwt.sign(authIdentity, jwtSecret)

    if (successRedirectUrl) {
      const url = new URL(successRedirectUrl!)
      url.searchParams.append("auth_token", token)

      return res.redirect(url.toString())
    }

    res.status(200).json({ token })
  }
  ```

  </CodeTab>
  <CodeTab label="Next.js App Router" value="nextjs">

  ```ts
  import { NextResponse } from "next/server"

  import {
    initialize as initializeAuthModule,
  } from "@medusajs/auth"

  export async function POST(request: Request) {
    const authModuleService = await initializeAuthModule()
    const url = new URL(request.url)

    const { success, authIdentity, location, error } =
      await authModuleService.authenticate("google", {
        url: request.url,
        headers: Object.fromEntries(request.headers),
        query: Object.fromEntries(url.searchParams),
        body: await request.json(),
        authScope: "admin",
        protocol: url.protocol,
      } as AuthenticationInput)

    if (!success) {
      throw new Error(error)
    }

    const token = jwt.sign(authIdentity, "supersecret")

    if (successRedirectUrl) {
      const url = new URL(successRedirectUrl!)
      url.searchParams.append("auth_token", token)

      return NextResponse.redirect(url.toString())
    }

    return NextResponse.json({
      token,
    }, {
      status: 200,
    })
  }
  ```

  </CodeTab>
</CodeTabs>

---

## Create Auth Identity

<CodeTabs groupId="app-type">
  <CodeTab label="Medusa API Router" value="medusa">

  ```ts
  import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
  import { IAuthModuleService } from "@medusajs/types"
  import { ModuleRegistrationName } from "@medusajs/modules-sdk"

  export async function POST(
    req: MedusaRequest,
    res: MedusaResponse
  ): Promise<void> {
    const authModuleService: IAuthModuleService =
      req.scope.resolve(ModuleRegistrationName.AUTH)

    const authIdentity = await authModuleService.create({
      provider: "emailpass",
      entity_id: "user@example.com",
      scope: "admin",
    })

    res.json({ auth_identity: authIdentity })
  }
  ```

  </CodeTab>
  <CodeTab label="Next.js App Router" value="nextjs">

  ```ts
  import { NextResponse } from "next/server"

  import {
    initialize as initializeAuthModule,
  } from "@medusajs/auth"

  export async function POST(request: Request) {
    const authModuleService = await initializeAuthModule()

    const authIdentity = await authModuleService.create({
      provider: "emailpass",
      entity_id: "user@example.com",
      scope: "admin",
    })

    return NextResponse.json({
      auth_identity: authIdentity,
    })
  }
  ```

  </CodeTab>
</CodeTabs>

---

## List Auth Identities

<CodeTabs groupId="app-type">
  <CodeTab label="Medusa API Router" value="medusa">

  ```ts
  import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
  import { IAuthModuleService } from "@medusajs/types"
  import { ModuleRegistrationName } from "@medusajs/modules-sdk"

  export async function GET(
    req: MedusaRequest,
    res: MedusaResponse
  ): Promise<void> {
    const authModuleService: IAuthModuleService =
      req.scope.resolve(ModuleRegistrationName.AUTH)

    res.json({
      auth_identitys: await authModuleService.list(),
    })
  }
  ```

  </CodeTab>
  <CodeTab label="Next.js App Router" value="nextjs">

  ```ts
  import { NextResponse } from "next/server"

  import {
    initialize as initializeAuthModule,
  } from "@medusajs/auth"

  export async function GET(request: Request) {
    const authModuleService = await initializeAuthModule()

    return NextResponse.json({
      auth_identities: await authModuleService.list(),
    })
  }
  ```

  </CodeTab>
</CodeTabs>

---

## Update an Auth Identity

<CodeTabs groupId="app-type">
  <CodeTab label="Medusa API Router" value="medusa">

  ```ts
  import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
  import { IAuthModuleService } from "@medusajs/types"
  import { ModuleRegistrationName } from "@medusajs/modules-sdk"

  export async function POST(
    req: MedusaRequest,
    res: MedusaResponse
  ): Promise<void> {
    const authModuleService: IAuthModuleService =
      req.scope.resolve(ModuleRegistrationName.AUTH)

    const authIdentity = await authModuleService.update({
      id: "authusr_123",
      provider_metadata: {
        test: true,
      },
    })

    res.json({
      auth_identity: authIdentity,
    })
  }
  ```

  </CodeTab>
  <CodeTab label="Next.js App Router" value="nextjs">

  ```ts
  import { NextResponse } from "next/server"

  import {
    initialize as initializeAuthModule,
  } from "@medusajs/auth"

  type ContextType = {
    params: {
      id: string
    }
  }

  export async function POST(
    request: Request,
    { params }: ContextType
  ) {
    const authModuleService = await initializeAuthModule()

    const authIdentity = await authModuleService.update({
      id: "authusr_123",
      provider_metadata: {
        test: true,
      },
    })

    return NextResponse.json({
      auth_identitys: await authModuleService.list(),
    })
  }
  ```

  </CodeTab>
</CodeTabs>

---

## Delete an Auth Identity

<CodeTabs groupId="app-type">
  <CodeTab label="Medusa API Router" value="medusa">

  ```ts
  import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
  import { IAuthModuleService } from "@medusajs/types"
  import { ModuleRegistrationName } from "@medusajs/modules-sdk"

  export async function DELETE(
    req: MedusaRequest,
    res: MedusaResponse
  ): Promise<void> {
    const authModuleService: IAuthModuleService =
      req.scope.resolve(ModuleRegistrationName.AUTH)

    await authModuleService.delete(["authusr_123"])

    res.status(200)
  }
  ```

  </CodeTab>
  <CodeTab label="Next.js App Router" value="nextjs">

  ```ts
  import { NextResponse } from "next/server"

  import {
    initialize as initializeAuthModule,
  } from "@medusajs/auth"

  type ContextType = {
    params: {
      id: string
    }
  }

  export async function DELETE(
    request: Request,
    { params }: ContextType
  ) {
    const authModuleService = await initializeAuthModule()

    await authModuleService.delete(["authusr_123"])
  }
  ```

  </CodeTab>
</CodeTabs>

---

## More Examples

The [Auth Module's main service reference](/references/auth) provides a reference to all the methods available for use with examples for each.
