fix: Update auth app_metadata when deleting users + customers (#9041)
* wip * more work * working on stuff * more * fix test * remove incorrect test * fix test * fix: Only allow deletion of yourself * remove redundant tests
This commit is contained in:
1 parent
e9e0267aa8
commit
4bf42f7889
14 files changed
+322
-183
No files matched your search
@@ -1,6 +1,7 @@
|
|||||||
import { IAuthModuleService, IUserModuleService } from "@medusajs/types"
|
import { IAuthModuleService, IUserModuleService } from "@medusajs/types"
|
||||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||||
import jwt from "jsonwebtoken"
|
import jwt from "jsonwebtoken"
|
||||||
|
import Scrypt from "scrypt-kdf"
|
||||||
import { getContainer } from "../environment-helpers/use-container"
|
import { getContainer } from "../environment-helpers/use-container"
|
||||||
|
|
||||||
export const adminHeaders = {
|
export const adminHeaders = {
|
||||||
@@ -26,13 +27,16 @@ export const createAdminUser = async (
|
|||||||
email: "admin@medusa.js",
|
email: "admin@medusa.js",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const hashConfig = { logN: 15, r: 8, p: 1 }
|
||||||
|
const passwordHash = await Scrypt.kdf("somepassword", hashConfig)
|
||||||
|
|
||||||
const authIdentity = await authModule.createAuthIdentities({
|
const authIdentity = await authModule.createAuthIdentities({
|
||||||
provider_identities: [
|
provider_identities: [
|
||||||
{
|
{
|
||||||
provider: "emailpass",
|
provider: "emailpass",
|
||||||
entity_id: "admin@medusa.js",
|
entity_id: "admin@medusa.js",
|
||||||
provider_metadata: {
|
provider_metadata: {
|
||||||
password: "somepassword",
|
password: passwordHash.toString("base64"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -55,5 +59,5 @@ export const createAdminUser = async (
|
|||||||
|
|
||||||
adminHeaders.headers["authorization"] = `Bearer ${token}`
|
adminHeaders.headers["authorization"] = `Bearer ${token}`
|
||||||
|
|
||||||
return { user }
|
return { user, authIdentity }
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { generateResetPasswordTokenWorkflow } from "@medusajs/core-flows"
|
import { generateResetPasswordTokenWorkflow } from "@medusajs/core-flows"
|
||||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
|
||||||
import jwt from "jsonwebtoken"
|
import jwt from "jsonwebtoken"
|
||||||
|
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||||
import {
|
import {
|
||||||
adminHeaders,
|
adminHeaders,
|
||||||
createAdminUser,
|
createAdminUser,
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import { IAuthModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||||
|
import jwt from "jsonwebtoken"
|
||||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||||
import {
|
import {
|
||||||
adminHeaders,
|
adminHeaders,
|
||||||
@@ -13,9 +16,10 @@ medusaIntegrationTestRunner({
|
|||||||
let customer3
|
let customer3
|
||||||
let customer4
|
let customer4
|
||||||
let customer5
|
let customer5
|
||||||
|
let container
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const appContainer = getContainer()
|
container = getContainer()
|
||||||
await createAdminUser(dbConnection, adminHeaders, appContainer)
|
await createAdminUser(dbConnection, adminHeaders, container)
|
||||||
|
|
||||||
customer1 = (
|
customer1 = (
|
||||||
await api.post(
|
await api.post(
|
||||||
@@ -392,5 +396,63 @@ medusaIntegrationTestRunner({
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("DELETE /admin/customers/:id", () => {
|
||||||
|
it("should delete a customer and update auth identity", async () => {
|
||||||
|
const registeredCustomerToken = (
|
||||||
|
await api.post("/auth/customer/emailpass/register", {
|
||||||
|
email: "test@email.com",
|
||||||
|
password: "password",
|
||||||
|
})
|
||||||
|
).data.token
|
||||||
|
|
||||||
|
const customer = (
|
||||||
|
await api.post(
|
||||||
|
"/store/customers",
|
||||||
|
{
|
||||||
|
email: "test@email.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${registeredCustomerToken}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).data.customer
|
||||||
|
|
||||||
|
const response = await api.delete(
|
||||||
|
`/admin/customers/${customer.id}`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: customer.id,
|
||||||
|
deleted: true,
|
||||||
|
object: "customer",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const { auth_identity_id } = jwt.decode(registeredCustomerToken)
|
||||||
|
|
||||||
|
const authModule: IAuthModuleService = container.resolve(
|
||||||
|
ModuleRegistrationName.AUTH
|
||||||
|
)
|
||||||
|
|
||||||
|
const authIdentity = await authModule.retrieveAuthIdentity(
|
||||||
|
auth_identity_id
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(authIdentity).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: authIdentity.id,
|
||||||
|
app_metadata: expect.not.objectContaining({
|
||||||
|
customer_id: expect.any(String),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { IAuthModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||||
import {
|
import {
|
||||||
adminHeaders,
|
adminHeaders,
|
||||||
@@ -8,17 +10,18 @@ jest.setTimeout(30000)
|
|||||||
|
|
||||||
medusaIntegrationTestRunner({
|
medusaIntegrationTestRunner({
|
||||||
testSuite: ({ dbConnection, getContainer, api }) => {
|
testSuite: ({ dbConnection, getContainer, api }) => {
|
||||||
let user
|
let user, container, authIdentity
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const container = getContainer()
|
container = getContainer()
|
||||||
const { user: adminUser } = await createAdminUser(
|
const { user: adminUser, authIdentity: authId } = await createAdminUser(
|
||||||
dbConnection,
|
dbConnection,
|
||||||
adminHeaders,
|
adminHeaders,
|
||||||
container
|
container
|
||||||
)
|
)
|
||||||
|
|
||||||
user = adminUser
|
user = adminUser
|
||||||
|
authIdentity = authId
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("GET /admin/users/:id", () => {
|
describe("GET /admin/users/:id", () => {
|
||||||
@@ -102,20 +105,76 @@ medusaIntegrationTestRunner({
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("DELETE /admin/users", () => {
|
describe("DELETE /admin/users", () => {
|
||||||
it("Deletes a user", async () => {
|
it("Deletes a user and updates associated auth identity", async () => {
|
||||||
const userId = "member-user"
|
|
||||||
|
|
||||||
const response = await api.delete(
|
const response = await api.delete(
|
||||||
`/admin/users/${userId}`,
|
`/admin/users/${user.id}`,
|
||||||
adminHeaders
|
adminHeaders
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(response.status).toEqual(200)
|
expect(response.status).toEqual(200)
|
||||||
expect(response.data).toEqual({
|
expect(response.data).toEqual({
|
||||||
id: userId,
|
id: user.id,
|
||||||
object: "user",
|
object: "user",
|
||||||
deleted: true,
|
deleted: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const authModule: IAuthModuleService = container.resolve(
|
||||||
|
ModuleRegistrationName.AUTH
|
||||||
|
)
|
||||||
|
|
||||||
|
const updatedAuthIdentity = await authModule.retrieveAuthIdentity(
|
||||||
|
authIdentity.id
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ensure the auth identity has been updated to not contain the user's id
|
||||||
|
expect(updatedAuthIdentity).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: authIdentity.id,
|
||||||
|
app_metadata: expect.not.objectContaining({
|
||||||
|
user_id: user.id,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// Authentication should still succeed
|
||||||
|
const authenticateToken = (
|
||||||
|
await api.post(`/auth/user/emailpass`, {
|
||||||
|
email: user.email,
|
||||||
|
password: "somepassword",
|
||||||
|
})
|
||||||
|
).data.token
|
||||||
|
|
||||||
|
expect(authenticateToken).toEqual(expect.any(String))
|
||||||
|
|
||||||
|
// However, it should not be possible to access routes any longer
|
||||||
|
const meResponse = await api
|
||||||
|
.get(`/admin/users/me`, {
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${authenticateToken}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch((e) => e)
|
||||||
|
|
||||||
|
expect(meResponse.response.status).toEqual(401)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("throws if you attempt to delete another user", async () => {
|
||||||
|
const userModule = container.resolve(ModuleRegistrationName.USER)
|
||||||
|
|
||||||
|
const userTwo = await userModule.createUsers({
|
||||||
|
email: "test@test.com",
|
||||||
|
password: "test",
|
||||||
|
role: "member",
|
||||||
|
})
|
||||||
|
|
||||||
|
const error = await api
|
||||||
|
.delete(`/admin/users/${userTwo.id}`, adminHeaders)
|
||||||
|
.catch((e) => e)
|
||||||
|
|
||||||
|
expect(error.response.status).toEqual(400)
|
||||||
|
expect(error.response.data.message).toEqual(
|
||||||
|
"You are not allowed to delete other users"
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: Migrate when analytics config is implemented in 2.0
|
// TODO: Migrate when analytics config is implemented in 2.0
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
import { IUserModuleService } from "@medusajs/types"
|
|
||||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
|
||||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
|
||||||
import { createAdminUser } from "../../../helpers/create-admin-user"
|
|
||||||
|
|
||||||
jest.setTimeout(50000)
|
|
||||||
|
|
||||||
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
|
||||||
const adminHeaders = {
|
|
||||||
headers: { "x-medusa-access-token": "test_token" },
|
|
||||||
}
|
|
||||||
|
|
||||||
medusaIntegrationTestRunner({
|
|
||||||
env,
|
|
||||||
testSuite: ({ dbConnection, getContainer, api }) => {
|
|
||||||
describe("DELETE /admin/users/:id", () => {
|
|
||||||
let appContainer
|
|
||||||
let userModuleService: IUserModuleService
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
appContainer = getContainer()
|
|
||||||
userModuleService = appContainer.resolve(ModuleRegistrationName.USER)
|
|
||||||
})
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await createAdminUser(dbConnection, adminHeaders, appContainer)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should delete a single user", async () => {
|
|
||||||
const user = await userModuleService.createUsers({
|
|
||||||
email: "member@test.com",
|
|
||||||
})
|
|
||||||
|
|
||||||
const response = await api.delete(
|
|
||||||
`/admin/users/${user.id}`,
|
|
||||||
adminHeaders
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(response.status).toEqual(200)
|
|
||||||
expect(response.data).toEqual({
|
|
||||||
id: user.id,
|
|
||||||
object: "user",
|
|
||||||
deleted: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
const { response: deletedResponse } = await api
|
|
||||||
.get(`/admin/users/${user.id}`, adminHeaders)
|
|
||||||
.catch((e) => e)
|
|
||||||
|
|
||||||
expect(deletedResponse.status).toEqual(404)
|
|
||||||
expect(deletedResponse.data.type).toEqual("not_found")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
import { IUserModuleService } from "@medusajs/types"
|
|
||||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
|
||||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
|
||||||
import { createAdminUser } from "../../../helpers/create-admin-user"
|
|
||||||
|
|
||||||
jest.setTimeout(50000)
|
|
||||||
|
|
||||||
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
|
||||||
const adminHeaders = {
|
|
||||||
headers: { "x-medusa-access-token": "test_token" },
|
|
||||||
}
|
|
||||||
|
|
||||||
medusaIntegrationTestRunner({
|
|
||||||
env,
|
|
||||||
testSuite: ({ dbConnection, getContainer, api }) => {
|
|
||||||
describe("GET /admin/users", () => {
|
|
||||||
let appContainer
|
|
||||||
let userModuleService: IUserModuleService
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
appContainer = getContainer()
|
|
||||||
userModuleService = appContainer.resolve(ModuleRegistrationName.USER)
|
|
||||||
})
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await createAdminUser(dbConnection, adminHeaders, appContainer)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should list users", async () => {
|
|
||||||
await userModuleService.createUsers([
|
|
||||||
{
|
|
||||||
email: "member@test.com",
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
const response = await api.get(`/admin/users`, adminHeaders)
|
|
||||||
|
|
||||||
expect(response.status).toEqual(200)
|
|
||||||
expect(response.data).toEqual({
|
|
||||||
users: expect.arrayContaining([
|
|
||||||
expect.objectContaining({
|
|
||||||
email: "admin@medusa.js",
|
|
||||||
}),
|
|
||||||
expect.objectContaining({ email: "member@test.com" }),
|
|
||||||
]),
|
|
||||||
count: 2,
|
|
||||||
offset: 0,
|
|
||||||
limit: 50,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
import { IUserModuleService } from "@medusajs/types"
|
|
||||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
|
||||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
|
||||||
import { createAdminUser } from "../../../helpers/create-admin-user"
|
|
||||||
|
|
||||||
jest.setTimeout(50000)
|
|
||||||
|
|
||||||
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
|
||||||
const adminHeaders = {
|
|
||||||
headers: { "x-medusa-access-token": "test_token" },
|
|
||||||
}
|
|
||||||
|
|
||||||
medusaIntegrationTestRunner({
|
|
||||||
env,
|
|
||||||
testSuite: ({ dbConnection, getContainer, api }) => {
|
|
||||||
describe("GET /admin/users/:id", () => {
|
|
||||||
let appContainer
|
|
||||||
let userModuleService: IUserModuleService
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
appContainer = getContainer()
|
|
||||||
userModuleService = appContainer.resolve(ModuleRegistrationName.USER)
|
|
||||||
})
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await createAdminUser(dbConnection, adminHeaders, appContainer)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should retrieve a single user", async () => {
|
|
||||||
const user = await userModuleService.createUsers({
|
|
||||||
email: "member@test.com",
|
|
||||||
})
|
|
||||||
|
|
||||||
const response = await api.get(`/admin/users/${user.id}`, adminHeaders)
|
|
||||||
|
|
||||||
expect(response.status).toEqual(200)
|
|
||||||
expect(response.data.user).toEqual(
|
|
||||||
expect.objectContaining({ email: "member@test.com" })
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@@ -6,7 +6,7 @@ import { isDefined, ModuleRegistrationName } from "@medusajs/utils"
|
|||||||
export type SetAuthAppMetadataStepInput = {
|
export type SetAuthAppMetadataStepInput = {
|
||||||
authIdentityId: string
|
authIdentityId: string
|
||||||
actorType: string
|
actorType: string
|
||||||
value: string
|
value: string | null // null means delete the key
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setAuthAppMetadataStepId = "set-auth-app-metadata"
|
export const setAuthAppMetadataStepId = "set-auth-app-metadata"
|
||||||
@@ -24,10 +24,13 @@ export const setAuthAppMetadataStep = createStep(
|
|||||||
const authIdentity = await service.retrieveAuthIdentity(data.authIdentityId)
|
const authIdentity = await service.retrieveAuthIdentity(data.authIdentityId)
|
||||||
|
|
||||||
const appMetadata = authIdentity.app_metadata || {}
|
const appMetadata = authIdentity.app_metadata || {}
|
||||||
if (isDefined(appMetadata[key])) {
|
|
||||||
|
// If the value is null, we are deleting the association with an actor
|
||||||
|
if (isDefined(appMetadata[key]) && data.value !== null) {
|
||||||
throw new Error(`Key ${key} already exists in app metadata`)
|
throw new Error(`Key ${key} already exists in app metadata`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const oldValue = appMetadata[key]
|
||||||
appMetadata[key] = data.value
|
appMetadata[key] = data.value
|
||||||
|
|
||||||
await service.updateAuthIdentities({
|
await service.updateAuthIdentities({
|
||||||
@@ -38,14 +41,16 @@ export const setAuthAppMetadataStep = createStep(
|
|||||||
return new StepResponse(authIdentity, {
|
return new StepResponse(authIdentity, {
|
||||||
id: authIdentity.id,
|
id: authIdentity.id,
|
||||||
key: key,
|
key: key,
|
||||||
|
value: data.value,
|
||||||
|
oldValue,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async (idAndKey, { container }) => {
|
async (idAndKeyAndValue, { container }) => {
|
||||||
if (!idAndKey) {
|
if (!idAndKeyAndValue) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const { id, key } = idAndKey
|
const { id, key, oldValue, value } = idAndKeyAndValue
|
||||||
|
|
||||||
const service = container.resolve<IAuthModuleService>(
|
const service = container.resolve<IAuthModuleService>(
|
||||||
ModuleRegistrationName.AUTH
|
ModuleRegistrationName.AUTH
|
||||||
@@ -54,7 +59,11 @@ export const setAuthAppMetadataStep = createStep(
|
|||||||
const authIdentity = await service.retrieveAuthIdentity(id)
|
const authIdentity = await service.retrieveAuthIdentity(id)
|
||||||
|
|
||||||
const appMetadata = authIdentity.app_metadata || {}
|
const appMetadata = authIdentity.app_metadata || {}
|
||||||
if (isDefined(appMetadata[key])) {
|
|
||||||
|
// If the value is null, we WERE deleting the association with an actor, so we need to restore it
|
||||||
|
if (value === null) {
|
||||||
|
appMetadata[key] = oldValue
|
||||||
|
} else {
|
||||||
delete appMetadata[key]
|
delete appMetadata[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
export * from "./create-customers"
|
|
||||||
export * from "./update-customers"
|
|
||||||
export * from "./delete-customers"
|
|
||||||
export * from "./create-customer-account"
|
|
||||||
export * from "./create-addresses"
|
export * from "./create-addresses"
|
||||||
export * from "./update-addresses"
|
export * from "./create-customer-account"
|
||||||
|
export * from "./create-customers"
|
||||||
export * from "./delete-addresses"
|
export * from "./delete-addresses"
|
||||||
|
export * from "./delete-customers"
|
||||||
|
export * from "./remove-customer-account"
|
||||||
|
export * from "./update-addresses"
|
||||||
|
export * from "./update-customers"
|
||||||
|
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import { MedusaError } from "@medusajs/utils"
|
||||||
|
import {
|
||||||
|
WorkflowData,
|
||||||
|
WorkflowResponse,
|
||||||
|
createWorkflow,
|
||||||
|
transform,
|
||||||
|
when,
|
||||||
|
} from "@medusajs/workflows-sdk"
|
||||||
|
import { setAuthAppMetadataStep } from "../../auth"
|
||||||
|
import { useRemoteQueryStep } from "../../common"
|
||||||
|
import { deleteCustomersWorkflow } from "./delete-customers"
|
||||||
|
|
||||||
|
export type RemoveCustomerAccountWorkflowInput = {
|
||||||
|
customerId: string
|
||||||
|
}
|
||||||
|
export const removeCustomerAccountWorkflowId = "remove-customer-account"
|
||||||
|
/**
|
||||||
|
* This workflow deletes a user and remove the association in the auth identity.
|
||||||
|
*/
|
||||||
|
export const removeCustomerAccountWorkflow = createWorkflow(
|
||||||
|
removeCustomerAccountWorkflowId,
|
||||||
|
(
|
||||||
|
input: WorkflowData<RemoveCustomerAccountWorkflowInput>
|
||||||
|
): WorkflowResponse<string> => {
|
||||||
|
const customers = useRemoteQueryStep({
|
||||||
|
entry_point: "customer",
|
||||||
|
fields: ["id", "has_account"],
|
||||||
|
variables: {
|
||||||
|
id: input.customerId,
|
||||||
|
},
|
||||||
|
}).config({ name: "get-customer" })
|
||||||
|
|
||||||
|
deleteCustomersWorkflow.runAsStep({
|
||||||
|
input: {
|
||||||
|
ids: [input.customerId],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
when({ customers }, ({ customers }) => {
|
||||||
|
return !!customers[0]?.has_account
|
||||||
|
}).then(() => {
|
||||||
|
const authIdentities = useRemoteQueryStep({
|
||||||
|
entry_point: "auth_identity",
|
||||||
|
fields: ["id"],
|
||||||
|
variables: {
|
||||||
|
filters: {
|
||||||
|
app_metadata: {
|
||||||
|
customer_id: input.customerId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const authIdentity = transform(
|
||||||
|
{ authIdentities },
|
||||||
|
({ authIdentities }) => {
|
||||||
|
const authIdentity = authIdentities[0]
|
||||||
|
|
||||||
|
if (!authIdentity) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.NOT_FOUND,
|
||||||
|
"Auth identity not found"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return authIdentity
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
setAuthAppMetadataStep({
|
||||||
|
authIdentityId: authIdentity.id,
|
||||||
|
actorType: "customer",
|
||||||
|
value: null,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return new WorkflowResponse(input.customerId)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
export * from "./create-user-account"
|
export * from "./create-user-account"
|
||||||
export * from "./create-users"
|
export * from "./create-users"
|
||||||
export * from "./delete-users"
|
export * from "./delete-users"
|
||||||
|
export * from "./remove-user-account"
|
||||||
export * from "./update-users"
|
export * from "./update-users"
|
||||||
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import {
|
||||||
|
WorkflowData,
|
||||||
|
WorkflowResponse,
|
||||||
|
createWorkflow,
|
||||||
|
transform,
|
||||||
|
when,
|
||||||
|
} from "@medusajs/workflows-sdk"
|
||||||
|
import { setAuthAppMetadataStep } from "../../auth"
|
||||||
|
import { useRemoteQueryStep } from "../../common"
|
||||||
|
import { deleteUsersWorkflow } from "./delete-users"
|
||||||
|
|
||||||
|
export type RemoveUserAccountWorkflowInput = {
|
||||||
|
userId: string
|
||||||
|
}
|
||||||
|
export const removeUserAccountWorkflowId = "remove-user-account"
|
||||||
|
/**
|
||||||
|
* This workflow deletes a user and remove the association in the auth identity.
|
||||||
|
*/
|
||||||
|
export const removeUserAccountWorkflow = createWorkflow(
|
||||||
|
removeUserAccountWorkflowId,
|
||||||
|
(
|
||||||
|
input: WorkflowData<RemoveUserAccountWorkflowInput>
|
||||||
|
): WorkflowResponse<string> => {
|
||||||
|
deleteUsersWorkflow.runAsStep({
|
||||||
|
input: {
|
||||||
|
ids: [input.userId],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const authIdentities = useRemoteQueryStep({
|
||||||
|
entry_point: "auth_identity",
|
||||||
|
fields: ["id"],
|
||||||
|
variables: {
|
||||||
|
filters: {
|
||||||
|
app_metadata: {
|
||||||
|
user_id: input.userId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const authIdentity = transform(
|
||||||
|
{ authIdentities, input },
|
||||||
|
({ authIdentities }) => {
|
||||||
|
return authIdentities[0]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
when({ authIdentity }, ({ authIdentity }) => {
|
||||||
|
return !!authIdentity
|
||||||
|
}).then(() => {
|
||||||
|
setAuthAppMetadataStep({
|
||||||
|
authIdentityId: authIdentity.id,
|
||||||
|
actorType: "user",
|
||||||
|
value: null,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return new WorkflowResponse(input.userId)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
deleteCustomersWorkflow,
|
removeCustomerAccountWorkflow,
|
||||||
updateCustomersWorkflow,
|
updateCustomersWorkflow,
|
||||||
} from "@medusajs/core-flows"
|
} from "@medusajs/core-flows"
|
||||||
import { AdditionalData, HttpTypes } from "@medusajs/types"
|
import { AdditionalData, HttpTypes } from "@medusajs/types"
|
||||||
@@ -68,10 +68,11 @@ export const DELETE = async (
|
|||||||
res: MedusaResponse<HttpTypes.AdminCustomerDeleteResponse>
|
res: MedusaResponse<HttpTypes.AdminCustomerDeleteResponse>
|
||||||
) => {
|
) => {
|
||||||
const id = req.params.id
|
const id = req.params.id
|
||||||
const deleteCustomers = deleteCustomersWorkflow(req.scope)
|
|
||||||
|
|
||||||
await deleteCustomers.run({
|
await removeCustomerAccountWorkflow(req.scope).run({
|
||||||
input: { ids: [id] },
|
input: {
|
||||||
|
customerId: id,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
import { deleteUsersWorkflow, updateUsersWorkflow } from "@medusajs/core-flows"
|
import {
|
||||||
|
removeUserAccountWorkflow,
|
||||||
|
updateUsersWorkflow,
|
||||||
|
} from "@medusajs/core-flows"
|
||||||
import { HttpTypes, UpdateUserDTO } from "@medusajs/types"
|
import { HttpTypes, UpdateUserDTO } from "@medusajs/types"
|
||||||
import {
|
import {
|
||||||
AuthenticatedMedusaRequest,
|
AuthenticatedMedusaRequest,
|
||||||
@@ -10,8 +13,8 @@ import {
|
|||||||
MedusaError,
|
MedusaError,
|
||||||
remoteQueryObjectFromString,
|
remoteQueryObjectFromString,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { AdminUpdateUserType } from "../validators"
|
|
||||||
import { refetchUser } from "../helpers"
|
import { refetchUser } from "../helpers"
|
||||||
|
import { AdminUpdateUserType } from "../validators"
|
||||||
|
|
||||||
// Get user
|
// Get user
|
||||||
export const GET = async (
|
export const GET = async (
|
||||||
@@ -71,10 +74,19 @@ export const DELETE = async (
|
|||||||
res: MedusaResponse<HttpTypes.AdminUserDeleteResponse>
|
res: MedusaResponse<HttpTypes.AdminUserDeleteResponse>
|
||||||
) => {
|
) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
const workflow = deleteUsersWorkflow(req.scope)
|
const { actor_id } = req.auth_context
|
||||||
|
|
||||||
|
if (actor_id !== id) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.NOT_ALLOWED,
|
||||||
|
"You are not allowed to delete other users"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const workflow = removeUserAccountWorkflow(req.scope)
|
||||||
|
|
||||||
await workflow.run({
|
await workflow.run({
|
||||||
input: { ids: [id] },
|
input: { userId: id },
|
||||||
})
|
})
|
||||||
|
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
|
|||||||
Reference in new issue
Block a user