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:
Stevche Radevski
2024-05-22 10:27:32 +02:00
committed by GitHub
parent b7df447682
commit 5ede560f70
88 changed files with 887 additions and 1014 deletions
@@ -15,7 +15,7 @@ export const POST = async (
selector: { id: req.params.id },
revoke: {
...req.validatedBody,
revoked_by: req.auth.actor_id,
revoked_by: req.auth_context.actor_id,
},
},
throwOnError: false,
@@ -41,7 +41,7 @@ export const POST = async (
const input = [
{
...req.validatedBody,
created_by: req.auth.actor_id,
created_by: req.auth_context.actor_id,
},
]
@@ -43,7 +43,7 @@ export const POST = async (
const customersData = [
{
...req.validatedBody,
created_by: req.auth.actor_id,
created_by: req.auth_context.actor_id,
},
]
@@ -48,7 +48,7 @@ export const POST = async (
const customersData = [
{
...req.validatedBody,
created_by: req.auth?.actor_id,
created_by: req.auth_context.actor_id,
},
]
@@ -1,28 +1,26 @@
import { acceptInviteWorkflow } from "@medusajs/core-flows"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { IUserModuleService, InviteWorkflow } from "@medusajs/types"
import { InviteWorkflow } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../types/routing"
import { AdminInviteAcceptType } from "../validators"
import { MedusaError } from "@medusajs/utils"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminInviteAcceptType>,
res: MedusaResponse
) => {
if (req.auth.actor_id) {
const moduleService: IUserModuleService = req.scope.resolve(
ModuleRegistrationName.USER
if (req.auth_context.actor_id) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"The user is already authenticated and cannot accept an invite."
)
const user = await moduleService.retrieve(req.auth.actor_id)
res.status(200).json({ user })
return
}
const input = {
invite_token: req.filterableFields.token as string,
auth_user_id: req.auth?.auth_user_id,
auth_identity_id: req.auth_context.auth_identity_id,
user: req.validatedBody,
} as InviteWorkflow.AcceptInviteWorkflowInputDTO
@@ -36,10 +34,5 @@ export const POST = async (
return
}
// Set customer_id on session user if we are in session
if (req.session.auth_user) {
req.session.auth_user.app_metadata.user_id = users[0].id
}
res.status(200).json({ user: users[0] })
}
@@ -15,7 +15,7 @@ export const POST = async (
const { errors } = await capturePaymentWorkflow(req.scope).run({
input: {
payment_id: id,
captured_by: req.auth?.actor_id,
captured_by: req.auth_context.actor_id,
amount: req.validatedBody.amount,
},
throwOnError: false,
@@ -14,7 +14,7 @@ export const POST = async (
const { errors } = await refundPaymentWorkflow(req.scope).run({
input: {
payment_id: id,
created_by: req.auth?.actor_id,
created_by: req.auth_context.actor_id,
amount: req.validatedBody.amount,
},
throwOnError: false,
@@ -23,7 +23,7 @@ export const POST = async (
const { errors } = await updateTaxRatesWorkflow(req.scope).run({
input: {
selector: { id: req.params.id },
update: { ...req.validatedBody, updated_by: req.auth.actor_id },
update: { ...req.validatedBody, updated_by: req.auth_context.actor_id },
},
throwOnError: false,
})
@@ -16,7 +16,7 @@ export const POST = async (
{
...req.validatedBody,
tax_rate_id: req.params.id,
created_by: req.auth.actor_id,
created_by: req.auth_context.actor_id,
},
],
},
@@ -21,7 +21,7 @@ export const POST = async (
input: [
{
...req.validatedBody,
created_by: req.auth.actor_id,
created_by: req.auth_context.actor_id,
},
],
throwOnError: false,
@@ -21,7 +21,7 @@ export const POST = async (
input: [
{
...req.validatedBody,
created_by: req.auth.actor_id,
created_by: req.auth_context.actor_id,
},
],
throwOnError: false,
@@ -12,7 +12,7 @@ export const GET = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse
) => {
const id = req.auth.app_metadata.user_id
const id = req.auth_context.actor_id
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
if (!id) {
+25 -13
View File
@@ -5,12 +5,12 @@ import {
MedusaError,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import jwt from "jsonwebtoken"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../types/routing"
import { refetchUser } from "./helpers"
import { generateJwtToken } from "../../utils/auth/token"
export const GET = async (
req: AuthenticatedMedusaRequest,
@@ -41,7 +41,7 @@ export const POST = async (
res: MedusaResponse
) => {
// If `actor_id` is present, the request carries authentication for an existing user
if (req.auth.actor_id) {
if (req.auth_context.actor_id) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Request carries authentication for an existing user"
@@ -51,30 +51,42 @@ export const POST = async (
const input = {
input: {
userData: req.validatedBody,
authUserId: req.auth.auth_user_id,
authIdentityId: req.auth_context.auth_identity_id,
},
throwOnError: false,
}
const { errors } = await createUserAccountWorkflow(req.scope).run(input)
const { result, errors } = await createUserAccountWorkflow(req.scope).run(
input
)
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
const { http } = req.scope.resolve(
ContainerRegistrationKeys.CONFIG_MODULE
).projectConfig
const { jwtSecret, jwtExpiresIn } = http
const token = generateJwtToken(
{
actor_id: result.id,
actor_type: "user",
auth_identity_id: req.auth_context.auth_identity_id,
app_metadata: {},
scope: "admin",
},
{
secret: jwtSecret,
expiresIn: jwtExpiresIn,
}
)
const user = await refetchUser(
req.auth.auth_user_id,
result.id,
req.scope,
req.remoteQueryConfig.fields
)
const { http } = req.scope.resolve(
ContainerRegistrationKeys.CONFIG_MODULE
).projectConfig
const token = jwt.sign(user, http.jwtSecret, {
expiresIn: http.jwtExpiresIn,
})
res.status(200).json({ user, token })
}