Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const currentProduct = await Products.findOne({ _id: productId, shopId });
if (!currentProduct) throw new ReactionError("not-found", "Product not found");
const updateDocument = { ...productInput };
// Slugify the handle input
if (typeof productInput.slug === "string") {
updateDocument.handle = await createHandle(context, getSlug(productInput.slug), productId, shopId);
delete updateDocument.slug;
}
// If a title is supplied, and the currently stored product doesn't have a handle,
// then slugify the title and save it as the new handle (slug)
if (typeof productInput.title === "string" && !currentProduct.handle && !updateDocument.handle) {
updateDocument.handle = await createHandle(context, getSlug(productInput.title), productId, shopId);
}
inputSchema.validate(updateDocument);
await Products.updateOne(
{
_id: productId,
shopId
},
{
$set: updateDocument
},
{
returnOriginal: false
}
);
const metafields = [];
// Filter out blank meta fields
Array.isArray(input.metafields) && input.metafields.forEach((field) => {
if (typeof field.value === "string" && field.value.trim().length) {
metafields.push(field);
}
});
let slug = input.name;
if (typeof slugInput === "string" && slugInput.trim().length > 0) {
slug = slugInput;
}
const params = {
slug: getSlug(slug),
name: input.name,
displayTitle: input.displayTitle,
isVisible: input.isVisible,
metafields: (metafields.length && metafields) || null,
featuredProductIds: input.featuredProductIds
};
if (typeof input.heroMediaUrl === "string" && input.heroMediaUrl.length) {
params.heroMediaUrl = input.heroMediaUrl;
} else {
params.heroMediaUrl = null;
}
inputSchema.validate(params);
params.updatedAt = new Date();
export default async function createAccountGroup(context, input) {
const { group, shopId } = input;
let newlyCreatedGroup;
const { Groups } = context.collections;
// we are limiting group method actions to only users within the account managers role
await context.validatePermissions("reaction:account", "create", { shopId, legacyRoles: ["admin"] });
const defaultCustomerGroupForShop = await Groups.findOne({ slug: "customer", shopId }) || {};
// TODO: Remove when we move away from legacy permission verification
const defaultAdminPermissions = (defaultCustomerGroupForShop.permissions || []).concat("dashboard");
const nowDate = new Date(Date.now());
const newGroupData = Object.assign({}, group, {
slug: getSlug(group.name),
shopId,
createdAt: nowDate,
updatedAt: nowDate
});
// TODO: Remove when we move away from legacy permission verification
if (!newGroupData.permissions) {
newGroupData.permissions = [];
}
// TODO: Remove when we move away from legacy permission verification
newGroupData.permissions = _.uniq([...newGroupData.permissions, ...defaultAdminPermissions]);
// ensure one group type per shop
const groupExists = await Groups.findOne({ slug: newGroupData.slug, shopId });
oldId: product._id,
newId: productNewId
});
const newProduct = Object.assign({}, product, {
_id: productNewId
});
delete newProduct.updatedAt;
delete newProduct.createdAt;
delete newProduct.publishedAt;
delete newProduct.positions;
delete newProduct.handle;
newProduct.isVisible = false;
if (newProduct.title) {
newProduct.title = await createTitle(context, newProduct.title, newProduct._id);
newProduct.handle = await createHandle(context, getSlug(newProduct.title), newProduct._id);
}
const { insertedId: productInsertedId } = await Products.insertOne(newProduct, { validate: false });
if (!productInsertedId) {
Logger.error(`cloneProducts: cloning of product ${product._id} failed`);
throw new ReactionError("server-error", `Cloning of product ${product._id} failed`);
}
// cloning variants
const existingVariants = await Products.find({
ancestors: {
$in: [product._id]
},
type: "variant"
}).toArray();
};
if (newProductOrVariant.type === "variant") {
// Apply custom transformations from plugins.
for (const customFunc of context.getFunctionsOfType("mutateNewVariantBeforeCreate")) {
// Functions of type "mutateNewVariantBeforeCreate" are expected to mutate the provided variant.
// We need to run each of these functions in a series, rather than in parallel, because
// we are mutating the same object on each pass.
// eslint-disable-next-line no-await-in-loop
await customFunc(newProductOrVariant, { context, ...info });
}
} else {
// Set handle for products only, not variants
if (!newProductOrVariant.handle) {
if (typeof newProductOrVariant.title === "string" && newProductOrVariant.title.length) {
newProductOrVariant.handle = getSlug(newProductOrVariant.title);
}
}
// Apply custom transformations from plugins.
for (const customFunc of context.getFunctionsOfType("mutateNewProductBeforeCreate")) {
// Functions of type "mutateNewProductBeforeCreate" are expected to mutate the provided variant.
// We need to run each of these functions in a series, rather than in parallel, because
// we are mutating the same object on each pass.
// eslint-disable-next-line no-await-in-loop
await customFunc(newProductOrVariant, { context, ...info });
}
}
const { insertedId } = await Products.insertOne(newProductOrVariant);
return insertedId;
export default async function updateProduct(context, input) {
const { appEvents, collections } = context;
const { Products } = collections;
const { product: productInput, productId, shopId } = input;
// Check that user has permission to create product
await context.validatePermissions(`reaction:products:${productId}`, "update", { shopId, legacyRoles: ["createProduct", "product/admin", "product/update"] });
const currentProduct = await Products.findOne({ _id: productId, shopId });
if (!currentProduct) throw new ReactionError("not-found", "Product not found");
const updateDocument = { ...productInput };
// Slugify the handle input
if (typeof productInput.slug === "string") {
updateDocument.handle = await createHandle(context, getSlug(productInput.slug), productId, shopId);
delete updateDocument.slug;
}
// If a title is supplied, and the currently stored product doesn't have a handle,
// then slugify the title and save it as the new handle (slug)
if (typeof productInput.title === "string" && !currentProduct.handle && !updateDocument.handle) {
updateDocument.handle = await createHandle(context, getSlug(productInput.title), productId, shopId);
}
inputSchema.validate(updateDocument);
await Products.updateOne(
{
_id: productId,
shopId
},
oldId: product._id,
newId: productNewId
});
const newProduct = Object.assign({}, product, {
_id: productNewId
});
delete newProduct.updatedAt;
delete newProduct.createdAt;
delete newProduct.publishedAt;
delete newProduct.positions;
delete newProduct.handle;
newProduct.isVisible = false;
if (newProduct.title) {
newProduct.title = await createTitle(context, newProduct.title, newProduct._id);
newProduct.handle = await createHandle(context, getSlug(newProduct.title), newProduct._id, newProduct.shopId);
}
const { insertedId: productInsertedId } = await Products.insertOne(newProduct, { validate: false });
if (!productInsertedId) {
Logger.error(`cloneProducts: cloning of product ${product._id} failed`);
throw new ReactionError("server-error", `Cloning of product ${product._id} failed`);
}
// cloning variants
const existingVariants = await Products.find({
ancestors: {
$in: [product._id]
},
type: "variant"
}).toArray();
if (!userHasPermission(["owner", "admin"], shopId)) {
throw new ReactionError("access-denied", "User does not have permission");
}
let slug = name;
if (typeof slugInput === "string" && slugInput.trim().length > 0) {
slug = slugInput;
}
const now = new Date();
const tag = {
_id: Random.id(),
isDeleted: false,
isTopLevel: false,
isVisible,
slug: getSlug(slug),
metafields,
name,
displayTitle,
heroMediaUrl,
shopId,
createdAt: now,
updatedAt: now
};
TagSchema.validate(tag);
try {
const { result } = await Tags.insertOne(tag);
if (result.ok !== 1) {
throw new ReactionError("server-error", "Unable to create tag");
const domain = rootUrl && new URL(rootUrl).hostname;
const now = new Date();
const shop = {
_id: Random.id(),
active: true,
availablePaymentMethods: [],
baseUOL: "in",
baseUOM: "oz",
createdAt: now,
currency: currencyCode || "USD",
domains: [domain],
language: defaultLanguage || "en",
name,
paymentMethods: [],
shopType: type || "primary",
slug: getSlug(name),
timezone: defaultTimezone || "US/Pacific",
unitsOfLength: [{
uol: "in",
label: "Inches",
default: true
}, {
uol: "cm",
label: "Centimeters"
}, {
uol: "ft",
label: "Feet"
}],
unitsOfMeasure: [{
uom: "oz",
label: "Ounces",
default: true
const { Tags } = collections;
await checkPermissions(["admin", "owner"], shopId);
let slug = name;
if (typeof slugInput === "string" && slugInput.trim().length > 0) {
slug = slugInput;
}
const now = new Date();
const tag = {
_id: Random.id(),
isDeleted: false,
isTopLevel: false,
isVisible,
slug: getSlug(slug),
metafields,
name,
displayTitle,
heroMediaUrl,
shopId,
createdAt: now,
updatedAt: now
};
TagSchema.validate(tag);
try {
const { result } = await Tags.insertOne(tag);
if (result.ok !== 1) {
throw new ReactionError("server-error", "Unable to create tag");