feat(auth): Revamp authentication setup (#7387)
* chore: Clean up authentication middlewares * chore: Rename AuthUser to AuthIdentity * feat: Define link between user, customer, and auth identity * feat: Use links for auth, update auth context content * fix: Adjust user create command with new auth setup * fix: Make auth login more dynamic, review fixes * fix: Change test assertions for created by
This commit is contained in:
@@ -1,12 +1,18 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { AuthenticationInput, IAuthModuleService } from "@medusajs/types"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import jwt from "jsonwebtoken"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
MedusaError,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
||||
import { generateJwtToken } from "../../../../utils/auth/token"
|
||||
|
||||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
const { scope, auth_provider } = req.params
|
||||
const actorType = scope === "admin" ? "user" : "customer"
|
||||
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
const service: IAuthModuleService = req.scope.resolve(
|
||||
ModuleRegistrationName.AUTH
|
||||
)
|
||||
@@ -20,16 +26,37 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
protocol: req.protocol,
|
||||
} as AuthenticationInput
|
||||
|
||||
const authResult = await service.validateCallback(auth_provider, authData)
|
||||
const { success, error, authIdentity, successRedirectUrl } =
|
||||
await service.validateCallback(auth_provider, authData)
|
||||
|
||||
const { success, error, authUser, successRedirectUrl } = authResult
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "auth_identity",
|
||||
fields: [`${actorType}.id`],
|
||||
variables: { id: authIdentity.id },
|
||||
})
|
||||
const [actorData] = await remoteQuery(queryObject)
|
||||
const entityId = actorData?.[actorType]?.id
|
||||
|
||||
if (success) {
|
||||
const { http } = req.scope.resolve("configModule").projectConfig
|
||||
const { http } = req.scope.resolve(
|
||||
ContainerRegistrationKeys.CONFIG_MODULE
|
||||
).projectConfig
|
||||
|
||||
const { jwtSecret, jwtExpiresIn } = http
|
||||
|
||||
const token = jwt.sign(authUser, jwtSecret, { expiresIn: jwtExpiresIn })
|
||||
// TODO: Clean up mapping between scope and actor type
|
||||
const token = generateJwtToken(
|
||||
{
|
||||
actor_id: entityId,
|
||||
actor_type: actorType,
|
||||
auth_identity_id: authIdentity.id,
|
||||
app_metadata: {},
|
||||
scope,
|
||||
},
|
||||
{
|
||||
secret: jwtSecret,
|
||||
expiresIn: jwtExpiresIn,
|
||||
}
|
||||
)
|
||||
|
||||
if (successRedirectUrl) {
|
||||
const url = new URL(successRedirectUrl!)
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { AuthenticationInput, IAuthModuleService } from "@medusajs/types"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import jwt from "jsonwebtoken"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
MedusaError,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||
import { generateJwtToken } from "../../../utils/auth/token"
|
||||
|
||||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
const { scope, auth_provider } = req.params
|
||||
const actorType = scope === "admin" ? "user" : "customer"
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const service: IAuthModuleService = req.scope.resolve(
|
||||
ModuleRegistrationName.AUTH
|
||||
@@ -20,9 +26,10 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
protocol: req.protocol,
|
||||
} as AuthenticationInput
|
||||
|
||||
const authResult = await service.authenticate(auth_provider, authData)
|
||||
|
||||
const { success, error, authUser, location } = authResult
|
||||
const { success, error, authIdentity, location } = await service.authenticate(
|
||||
auth_provider,
|
||||
authData
|
||||
)
|
||||
|
||||
if (location) {
|
||||
res.redirect(location)
|
||||
@@ -30,11 +37,33 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
}
|
||||
|
||||
if (success) {
|
||||
const { http } = req.scope.resolve("configModule").projectConfig
|
||||
const { http } = req.scope.resolve(
|
||||
ContainerRegistrationKeys.CONFIG_MODULE
|
||||
).projectConfig
|
||||
|
||||
const token = jwt.sign(authUser, http.jwtSecret, {
|
||||
expiresIn: http.jwtExpiresIn,
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "auth_identity",
|
||||
fields: [`${actorType}.id`],
|
||||
variables: { id: authIdentity.id },
|
||||
})
|
||||
const [actorData] = await remoteQuery(queryObject)
|
||||
const entityId = actorData?.[actorType]?.id
|
||||
|
||||
const { jwtSecret, jwtExpiresIn } = http
|
||||
// TODO: Clean up mapping between scope and actor type
|
||||
const token = generateJwtToken(
|
||||
{
|
||||
actor_id: entityId,
|
||||
actor_type: actorType,
|
||||
auth_identity_id: authIdentity.id,
|
||||
app_metadata: {},
|
||||
scope,
|
||||
},
|
||||
{
|
||||
secret: jwtSecret,
|
||||
expiresIn: jwtExpiresIn,
|
||||
}
|
||||
)
|
||||
|
||||
return res.status(200).json({ token })
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@ export const authRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/auth/session",
|
||||
middlewares: [authenticate(/.*/, "bearer")],
|
||||
middlewares: [authenticate("*", "bearer")],
|
||||
},
|
||||
{
|
||||
method: ["DELETE"],
|
||||
matcher: "/auth/session",
|
||||
middlewares: [authenticate(/.*/, ["session"])],
|
||||
middlewares: [authenticate("*", ["session"])],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
|
||||
@@ -7,9 +7,9 @@ export const POST = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
req.session.auth_user = req.auth
|
||||
req.session.auth_context = req.auth_context
|
||||
|
||||
res.status(200).json({ user: req.auth })
|
||||
res.status(200).json({ user: req.auth_context })
|
||||
}
|
||||
|
||||
export const DELETE = async (
|
||||
|
||||
Reference in New Issue
Block a user