feat(utils,types,framework,medusa): store endpoints should require publishable key (#9068)
* feat(utils,types,framework,medusa): store endpoints should require publishable key * chore: fix specs * chore: fix more specs * chore: update js-sdk * chore: fix specs wrt to default SC * chore: revert custom headers + change error message * chore: fix specs * chore: fix new store specs
This commit is contained in:
@@ -48,6 +48,7 @@ import { storeCartRoutesMiddlewares } from "./store/carts/middlewares"
|
||||
import { storeCollectionRoutesMiddlewares } from "./store/collections/middlewares"
|
||||
import { storeCurrencyRoutesMiddlewares } from "./store/currencies/middlewares"
|
||||
import { storeCustomerRoutesMiddlewares } from "./store/customers/middlewares"
|
||||
import { storeRoutesMiddlewares } from "./store/middlewares"
|
||||
import { storeOrderRoutesMiddlewares } from "./store/orders/middlewares"
|
||||
import { storePaymentCollectionsMiddlewares } from "./store/payment-collections/middlewares"
|
||||
import { storePaymentProvidersMiddlewares } from "./store/payment-providers/middlewares"
|
||||
@@ -58,6 +59,7 @@ import { storeReturnReasonRoutesMiddlewares } from "./store/return-reasons/middl
|
||||
import { storeShippingOptionRoutesMiddlewares } from "./store/shipping-options/middlewares"
|
||||
|
||||
export default defineMiddlewares([
|
||||
...storeRoutesMiddlewares,
|
||||
...adminCustomerGroupRoutesMiddlewares,
|
||||
...adminCustomerRoutesMiddlewares,
|
||||
...adminPromotionRoutesMiddlewares,
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { MiddlewareRoute } from "@medusajs/framework"
|
||||
import { ensurePublishableApiKey } from "../../utils/middlewares/ensure-publishable-api-key"
|
||||
|
||||
export const storeRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
{
|
||||
method: "ALL",
|
||||
matcher: "/store*",
|
||||
middlewares: [ensurePublishableApiKey()],
|
||||
},
|
||||
]
|
||||
+22
-50
@@ -1,77 +1,49 @@
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import { MedusaStoreRequest } from "@medusajs/framework"
|
||||
import { arrayDifference, MedusaError } from "@medusajs/utils"
|
||||
import { NextFunction } from "express"
|
||||
import { AuthenticatedMedusaRequest } from "../../../../types/routing"
|
||||
import { refetchEntity } from "../../refetch-entity"
|
||||
import { arrayDifference } from "@medusajs/utils"
|
||||
|
||||
// Selection of sales channels happens in the following priority:
|
||||
// - If a publishable API key is passed, we take the sales channels attached to it and filter them down based on the query params
|
||||
// - If a sales channel id is passed through query params, we use that
|
||||
// - If not, we use the default sales channel for the store
|
||||
export function filterByValidSalesChannels() {
|
||||
return async (req: AuthenticatedMedusaRequest, _, next: NextFunction) => {
|
||||
const publishableApiKey = req.get("x-publishable-api-key")
|
||||
const salesChannelIds = req.filterableFields.sales_channel_id as
|
||||
| string[]
|
||||
| undefined
|
||||
return async (req: MedusaStoreRequest, _, next: NextFunction) => {
|
||||
const idsFromRequest = req.filterableFields.sales_channel_id
|
||||
const { sales_channel_ids: idsFromPublishableKey = [] } =
|
||||
req.publishable_key_context
|
||||
|
||||
if (publishableApiKey) {
|
||||
const apiKey = await refetchEntity(
|
||||
"api_key",
|
||||
{ token: publishableApiKey },
|
||||
req.scope,
|
||||
["id", "sales_channels_link.sales_channel_id"]
|
||||
// If all sales channel ids are not in the publishable key, we throw an error
|
||||
if (Array.isArray(idsFromRequest) && idsFromRequest.length) {
|
||||
const uniqueInParams = arrayDifference(
|
||||
idsFromRequest,
|
||||
idsFromPublishableKey
|
||||
)
|
||||
|
||||
if (!apiKey) {
|
||||
if (uniqueInParams.length) {
|
||||
return next(
|
||||
new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Publishable API key not found`
|
||||
`Requested sales channel is not part of the publishable key`
|
||||
)
|
||||
)
|
||||
}
|
||||
let result = apiKey.sales_channels_link.map(
|
||||
(link) => link.sales_channel_id
|
||||
)
|
||||
|
||||
if (salesChannelIds?.length) {
|
||||
// If all sales channel ids are not in the publishable key, we throw an error
|
||||
const uniqueInParams = arrayDifference(salesChannelIds, result)
|
||||
if (uniqueInParams.length) {
|
||||
return next(
|
||||
new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Requested sales channel is not part of the publishable key mappings`
|
||||
)
|
||||
)
|
||||
}
|
||||
result = salesChannelIds
|
||||
}
|
||||
req.filterableFields.sales_channel_id = idsFromRequest
|
||||
|
||||
req.filterableFields.sales_channel_id = result
|
||||
return next()
|
||||
}
|
||||
|
||||
if (salesChannelIds?.length) {
|
||||
req.filterableFields.sales_channel_id = salesChannelIds
|
||||
if (idsFromPublishableKey?.length) {
|
||||
req.filterableFields.sales_channel_id = idsFromPublishableKey
|
||||
|
||||
return next()
|
||||
}
|
||||
|
||||
const store = await refetchEntity("stores", {}, req.scope, [
|
||||
"default_sales_channel_id",
|
||||
])
|
||||
|
||||
if (!store) {
|
||||
return next(
|
||||
new MedusaError(MedusaError.Types.INVALID_DATA, `Store not found`)
|
||||
return next(
|
||||
new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Publishable key needs to have a sales channel configured`
|
||||
)
|
||||
}
|
||||
|
||||
if (store.default_sales_channel_id) {
|
||||
req.filterableFields.sales_channel_id = [store.default_sales_channel_id]
|
||||
}
|
||||
|
||||
return next()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user