feat(medusa): Improve transform middleware (#2271)
**What** Improve transform query middleware management of the allowed fields and relations in order to improve security upon access data FIXES CORE-651
This commit is contained in:
committed by
GitHub
parent
2be00007b2
commit
9a532de7bd
@@ -213,6 +213,18 @@ describe("[MEDUSA_FF_ORDER_EDITING] /store/order-edits", () => {
|
||||
expect(response.data.order_edit.canceled_by).not.toBeDefined()
|
||||
expect(response.data.order_edit.confirmed_by).not.toBeDefined()
|
||||
})
|
||||
|
||||
it("fails to get an order edit with disallowed fields query params", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const err = await api
|
||||
.get(`/store/order-edits/${orderEditId}?fields=internal_note,order_id`)
|
||||
.catch((e) => e)
|
||||
|
||||
expect(err.response.data.message).toBe(
|
||||
"Fields [internal_note] are not valid"
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /store/order-edits/:id/decline", () => {
|
||||
|
||||
@@ -91,6 +91,7 @@ export type QueryConfig<TEntity extends BaseEntity> = {
|
||||
defaultFields?: (keyof TEntity | string)[]
|
||||
defaultRelations?: string[]
|
||||
allowedFields?: string[]
|
||||
allowedRelations?: string[]
|
||||
defaultLimit?: number
|
||||
isList?: boolean
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ export const defaultOrderEditFields: (keyof OrderEdit)[] = [
|
||||
"internal_note",
|
||||
]
|
||||
|
||||
export const storeOrderEditNotAllowedFields = [
|
||||
export const storeOrderEditNotAllowedFieldsAndRelations = [
|
||||
"internal_note",
|
||||
"created_by",
|
||||
"confirmed_by",
|
||||
@@ -54,8 +54,8 @@ export const storeOrderEditNotAllowedFields = [
|
||||
]
|
||||
|
||||
export const defaultStoreOrderEditRelations = defaultOrderEditRelations.filter(
|
||||
(field) => !storeOrderEditNotAllowedFields.includes(field)
|
||||
(field) => !storeOrderEditNotAllowedFieldsAndRelations.includes(field)
|
||||
)
|
||||
export const defaultStoreOrderEditFields = defaultOrderEditFields.filter(
|
||||
(field) => !storeOrderEditNotAllowedFields.includes(field)
|
||||
(field) => !storeOrderEditNotAllowedFieldsAndRelations.includes(field)
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { pick } from "lodash"
|
||||
import { FindConfig, QueryConfig, RequestQueryFields } from "../types/common"
|
||||
import { MedusaError } from "medusa-core-utils/dist"
|
||||
import { BaseEntity } from "../interfaces/models/base-entity"
|
||||
import { BaseEntity } from "../interfaces"
|
||||
import { isDefined } from "."
|
||||
|
||||
export function pickByConfig<TModel extends BaseEntity>(
|
||||
@@ -96,6 +96,14 @@ export function prepareListQuery<
|
||||
expandFields = fields.split(",") as (keyof TEntity)[]
|
||||
}
|
||||
|
||||
if (expandFields?.length && queryConfig?.allowedFields?.length) {
|
||||
validateFields(expandFields as string[], queryConfig.allowedFields)
|
||||
}
|
||||
|
||||
if (expandRelations?.length && queryConfig?.allowedRelations?.length) {
|
||||
validateRelations(expandRelations, queryConfig.allowedRelations)
|
||||
}
|
||||
|
||||
let orderBy: { [k: symbol]: "DESC" | "ASC" } | undefined
|
||||
if (isDefined(order)) {
|
||||
let orderField = order
|
||||
@@ -145,15 +153,12 @@ export function prepareRetrieveQuery<
|
||||
expandFields = fields.split(",") as (keyof TEntity)[]
|
||||
}
|
||||
|
||||
if (queryConfig?.allowedFields?.length) {
|
||||
expandFields?.forEach((field) => {
|
||||
if (!queryConfig?.allowedFields?.includes(field as string)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Field ${field.toString()} is not valid`
|
||||
)
|
||||
}
|
||||
})
|
||||
if (expandFields?.length && queryConfig?.allowedFields?.length) {
|
||||
validateFields(expandFields as string[], queryConfig.allowedFields)
|
||||
}
|
||||
|
||||
if (expandRelations?.length && queryConfig?.allowedRelations?.length) {
|
||||
validateRelations(expandRelations, queryConfig.allowedRelations)
|
||||
}
|
||||
|
||||
return getRetrieveConfig<TEntity>(
|
||||
@@ -163,3 +168,38 @@ export function prepareRetrieveQuery<
|
||||
expandRelations
|
||||
)
|
||||
}
|
||||
|
||||
function validateRelations(
|
||||
relations: string[],
|
||||
allowed: string[]
|
||||
): void | never {
|
||||
const disallowedRelationsFound: string[] = []
|
||||
relations?.forEach((field) => {
|
||||
if (!allowed.includes(field as string)) {
|
||||
disallowedRelationsFound.push(field)
|
||||
}
|
||||
})
|
||||
|
||||
if (disallowedRelationsFound.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Relations [${disallowedRelationsFound.join(", ")}] are not valid`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function validateFields(fields: string[], allowed: string[]): void | never {
|
||||
const disallowedFieldsFound: string[] = []
|
||||
fields?.forEach((field) => {
|
||||
if (!allowed.includes(field as string)) {
|
||||
disallowedFieldsFound.push(field)
|
||||
}
|
||||
})
|
||||
|
||||
if (disallowedFieldsFound.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Fields [${disallowedFieldsFound.join(", ")}] are not valid`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user