diff --git a/imports/plugins/core/discounts/client/components/form.js b/imports/plugins/core/discounts/client/components/form.js
index ad77351fcc3..e5fbf80c895 100644
--- a/imports/plugins/core/discounts/client/components/form.js
+++ b/imports/plugins/core/discounts/client/components/form.js
@@ -19,9 +19,10 @@ export default class DiscountForm extends Component {
// debounce helper so to wait on user input
this.debounceDiscounts = debounce(() => {
this.setState({ validationMessage: "" });
+ const { collection, id, token } = this.props;
const { discount } = this.state;
// handle discount code validation messages after attempt to apply
- Meteor.call("discounts/codes/apply", this.props.id, discount, this.props.collection, (error, result) => {
+ Meteor.call("discounts/codes/apply", id, discount, collection, token, (error, result) => {
if (error) {
Alerts.toast(i18next.t(error.reason), "error");
}
@@ -38,9 +39,6 @@ export default class DiscountForm extends Component {
}
});
}, 800);
-
- this.handleChange = this.handleChange.bind(this);
- this.handleClick = this.handleClick.bind(this);
}
componentWillUnmount() {
@@ -64,7 +62,7 @@ export default class DiscountForm extends Component {
}
// handle keydown and change events
- handleChange(event) {
+ handleChange = (event) => {
const { attempts } = this.state;
// ensure we don't submit on enter
if (event.keyCode === 13) {
@@ -85,7 +83,7 @@ export default class DiscountForm extends Component {
}
// handle display or not
- handleClick(event) {
+ handleClick = (event) => {
event.preventDefault();
this.setState({ validatedInput: true });
}
@@ -163,5 +161,6 @@ DiscountForm.propTypes = {
collection: PropTypes.string,
discount: PropTypes.string,
id: PropTypes.string,
+ token: PropTypes.string,
validatedInput: PropTypes.bool // eslint-disable-line react/boolean-prop-naming
};
diff --git a/imports/plugins/core/discounts/client/components/list.js b/imports/plugins/core/discounts/client/components/list.js
index 9694abcedad..15c02e3f779 100644
--- a/imports/plugins/core/discounts/client/components/list.js
+++ b/imports/plugins/core/discounts/client/components/list.js
@@ -14,8 +14,10 @@ class DiscountList extends Component {
// handle remove click
handleClick(event, codeId) {
- return Meteor.call("discounts/codes/remove", this.props.id, codeId, this.props.collection);
+ const { collection, id, token } = this.props;
+ return Meteor.call("discounts/codes/remove", id, codeId, collection, token);
}
+
// list items
renderList() {
const listItems = this.props.listItems.map((listItem) => this.renderItem(listItem));
@@ -24,6 +26,7 @@ class DiscountList extends Component {
{listItems}
);
}
+
// render item
renderItem(listItem) {
let TrashCan;
@@ -47,8 +50,9 @@ class DiscountList extends Component {
// load form input view
renderNoneFound() {
+ const { collection, id, token, validatedInput } = this.props;
return (
-
+
);
}
@@ -63,9 +67,16 @@ DiscountList.propTypes = {
collection: PropTypes.string,
id: PropTypes.string,
listItems: PropTypes.array,
+ token: PropTypes.string,
validatedInput: PropTypes.bool // eslint-disable-line react/boolean-prop-naming
};
+/**
+ * @summary Tracker reactive props
+ * @param {Object} props Incoming props
+ * @param {Function} onData Callback for more props
+ * @returns {undefined}
+ */
function composer(props, onData) {
const currentCart = Reaction.Collections[props.collection].findOne({
_id: props.id
diff --git a/imports/plugins/core/discounts/server/index.js b/imports/plugins/core/discounts/server/index.js
index 70a8129598e..f738cabaac7 100644
--- a/imports/plugins/core/discounts/server/index.js
+++ b/imports/plugins/core/discounts/server/index.js
@@ -2,4 +2,3 @@
import "./i18n";
import "./security/discounts";
import "./publications/discounts";
-import "./methods";
diff --git a/imports/plugins/core/discounts/server/methods/index.js b/imports/plugins/core/discounts/server/methods/index.js
deleted file mode 100644
index c8abe684b3c..00000000000
--- a/imports/plugins/core/discounts/server/methods/index.js
+++ /dev/null
@@ -1 +0,0 @@
-import "./methods";
diff --git a/imports/plugins/core/discounts/server/methods/methods.app-test.js b/imports/plugins/core/discounts/server/methods/methods.app-test.js
deleted file mode 100644
index fbce8307034..00000000000
--- a/imports/plugins/core/discounts/server/methods/methods.app-test.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* eslint prefer-arrow-callback:0 */
-import { Meteor } from "meteor/meteor";
-import { Roles } from "meteor/alanning:roles";
-import { expect } from "meteor/practicalmeteor:chai";
-import { sinon } from "meteor/practicalmeteor:sinon";
-import { Discounts } from "/imports/plugins/core/discounts/lib/collections";
-
-const code = {
- discount: 12,
- label: "Discount 5",
- description: "Discount by 5%",
- discountMethod: "code",
- code: "promocode"
-};
-
-describe("discounts methods", function () {
- let sandbox;
-
- beforeEach(function () {
- sandbox = sinon.sandbox.create();
- });
-
- afterEach(function () {
- sandbox.restore();
- });
-
- describe("discounts/deleteRate", function () {
- it("should delete rate with discounts permission", function () {
- this.timeout(15000);
- sandbox.stub(Roles, "userIsInRole", () => true);
- const discountInsertSpy = sandbox.spy(Discounts, "insert");
- const discountId = Meteor.call("discounts/addCode", code);
- expect(discountInsertSpy).to.have.been.called;
-
- Meteor.call("discounts/deleteRate", discountId);
- const discountCount = Discounts.find(discountId).count();
- expect(discountCount).to.equal(0);
- });
- });
-});
diff --git a/imports/plugins/core/discounts/server/methods/methods.js b/imports/plugins/core/discounts/server/methods/methods.js
deleted file mode 100644
index 175bf94f2f0..00000000000
--- a/imports/plugins/core/discounts/server/methods/methods.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import { Meteor } from "meteor/meteor";
-import { Match, check } from "meteor/check";
-import ReactionError from "@reactioncommerce/reaction-error";
-import { Cart } from "/lib/collections";
-import appEvents from "/imports/node-app/core/util/appEvents";
-import { Discounts } from "../../lib/collections";
-import Reaction from "../api";
-
-/**
- *
- * @namespace Discounts/Methods
- */
-
-export const methods = {
- /**
- * @name discounts/deleteRate
- * @method
- * @memberof Discounts/Methods
- * @param {String} discountId discount id to delete
- * @return {String} returns update/insert result
- */
- "discounts/deleteRate"(discountId) {
- check(discountId, String);
-
- // check permissions to delete
- if (!Reaction.hasPermission("discounts")) {
- throw new ReactionError("access-denied", "Access Denied");
- }
-
- return Discounts.remove({ _id: discountId });
- },
-
- /**
- * @name discounts/setRate
- * @method
- * @memberof Discounts/Methods
- * @summary Update the cart discounts without hooks
- * @param {String} cartId cartId
- * @param {Number} discountRate discountRate
- * @param {Object} discounts discounts
- * @return {Number} returns update result
- */
- "discounts/setRate"(cartId, discountRate, discounts) {
- check(cartId, String);
- check(discountRate, Number);
- check(discounts, Match.Optional(Array));
-
- const result = Cart.update({ _id: cartId }, {
- $set: {
- discounts,
- discount: discountRate
- }
- });
-
- const updatedCart = Cart.findOne({ _id: cartId });
- Promise.await(appEvents.emit("afterCartUpdate", updatedCart));
-
- return result;
- },
-
- /**
- * @name discounts/editRate
- * @method
- * @memberof Discounts/Rates/Methods
- * @param {Object} details An object with _id and modifier props
- * @return {String} Update result
- */
- "discounts/editRate"(details) {
- check(details, {
- _id: String,
- modifier: Object // actual schema validation happens during update below
- });
- if (!Reaction.hasPermission("discount-rates")) throw new ReactionError("access-denied", "Access Denied");
- const { _id, modifier } = details;
- return Discounts.update(_id, modifier);
- }
-};
-
-Meteor.methods(methods);
diff --git a/imports/plugins/included/discount-codes/client/templates/codes.html b/imports/plugins/included/discount-codes/client/templates/codes.html
index 5aaaca952d5..6ccb39e294b 100644
--- a/imports/plugins/included/discount-codes/client/templates/codes.html
+++ b/imports/plugins/included/discount-codes/client/templates/codes.html
@@ -1,5 +1,5 @@
- {{> React component=DiscountList id=cartId collection="Cart"}}
+ {{> React component=DiscountList id=cartProps.cartId token=cartProps.cartToken collection="Cart"}}
diff --git a/imports/plugins/included/discount-codes/client/templates/codes.js b/imports/plugins/included/discount-codes/client/templates/codes.js
index ae6d818dd0f..babc28eac34 100644
--- a/imports/plugins/included/discount-codes/client/templates/codes.js
+++ b/imports/plugins/included/discount-codes/client/templates/codes.js
@@ -7,8 +7,11 @@ Template.discountCodesCheckout.helpers({
DiscountList() {
return DiscountList;
},
- cartId() {
- const { cart } = getCart();
- return cart && cart._id;
+ cartProps() {
+ const { cart, token } = getCart();
+ return {
+ cartId: cart && cart._id,
+ cartToken: token
+ };
}
});
diff --git a/imports/plugins/included/discount-codes/client/templates/settings.js b/imports/plugins/included/discount-codes/client/templates/settings.js
index 8c1e180e64d..a907c3561cd 100644
--- a/imports/plugins/included/discount-codes/client/templates/settings.js
+++ b/imports/plugins/included/discount-codes/client/templates/settings.js
@@ -170,7 +170,7 @@ Template.customDiscountCodes.events({
}, (isConfirm) => {
if (isConfirm) {
if (id) {
- Meteor.call("discounts/deleteRate", id);
+ Meteor.call("discounts/deleteCode", id);
instance.state.set({
isEditing: false,
editingId: null
diff --git a/imports/plugins/included/discount-codes/server/methods/methods.app-test.js b/imports/plugins/included/discount-codes/server/methods/methods.app-test.js
index 80457a42840..7c43fa09a65 100644
--- a/imports/plugins/included/discount-codes/server/methods/methods.app-test.js
+++ b/imports/plugins/included/discount-codes/server/methods/methods.app-test.js
@@ -5,6 +5,7 @@ import { Factory } from "meteor/dburles:factory";
import { expect } from "meteor/practicalmeteor:chai";
import { sinon } from "meteor/practicalmeteor:sinon";
import { Discounts } from "/imports/plugins/core/discounts/lib/collections";
+import { getShop } from "/imports/plugins/core/core/server/fixtures/shops";
import { Cart } from "/lib/collections";
import Reaction from "/imports/plugins/core/core/server/Reaction";
import ReactionError from "@reactioncommerce/reaction-error";
@@ -22,7 +23,17 @@ before(function () {
});
describe("discount code methods", function () {
+ const shop = getShop();
let sandbox;
+ let user;
+ let account;
+ let accountId;
+
+ before(function () {
+ user = Factory.create("user");
+ account = Factory.create("account", { userId: user._id });
+ accountId = account._id;
+ });
beforeEach(function () {
sandbox = sinon.sandbox.create();
@@ -51,12 +62,29 @@ describe("discount code methods", function () {
});
});
+ describe("discounts/deleteCode", function () {
+ it("should delete rate with discounts permission", function () {
+ this.timeout(15000);
+ sandbox.stub(Roles, "userIsInRole", () => true);
+ const discountInsertSpy = sandbox.spy(Discounts, "insert");
+ const discountId = Meteor.call("discounts/addCode", code);
+ expect(discountInsertSpy).to.have.been.called;
+
+ Meteor.call("discounts/deleteCode", discountId);
+ const discountCount = Discounts.find(discountId).count();
+ expect(discountCount).to.equal(0);
+ });
+ });
+
describe("discounts/codes/apply", function () {
it("should apply code when called for a cart with multiple items from same shop", function () {
+ this.timeout(5000);
+ sandbox.stub(Reaction, "getCartShopId", () => shop._id);
+ sandbox.stub(Reaction, "getUserId", () => user._id);
sandbox.stub(Reaction, "hasPermission", () => true);
// make a cart with two items from same shop
- const cart = Factory.create("cartMultiItems");
+ const cart = Factory.create("cartMultiItems", { accountId });
Meteor.call("discounts/addCode", code);
Meteor.call("discounts/codes/apply", cart._id, code.code);
@@ -69,10 +97,13 @@ describe("discount code methods", function () {
});
it("should not apply code when applied to multi-shop order or cart", function () {
+ this.timeout(5000);
+ sandbox.stub(Reaction, "getCartShopId", () => shop._id);
+ sandbox.stub(Reaction, "getUserId", () => user._id);
sandbox.stub(Reaction, "hasPermission", () => true);
// make a cart with two items from separate shops
- const cart = Factory.create("cartMultiShop");
+ const cart = Factory.create("cartMultiShop", { accountId });
expect(() =>
Meteor.call("discounts/codes/apply", cart._id, code.code)).to.throw(ReactionError, /multiShopError/);
diff --git a/imports/plugins/included/discount-codes/server/methods/methods.js b/imports/plugins/included/discount-codes/server/methods/methods.js
index 20ab683bb0c..b8058d3503c 100644
--- a/imports/plugins/included/discount-codes/server/methods/methods.js
+++ b/imports/plugins/included/discount-codes/server/methods/methods.js
@@ -1,9 +1,10 @@
import Random from "@reactioncommerce/random";
import { Meteor } from "meteor/meteor";
-import { Match, check } from "meteor/check";
+import { check, Match } from "meteor/check";
import Reaction from "/imports/plugins/core/core/server/Reaction";
import ReactionError from "@reactioncommerce/reaction-error";
import appEvents from "/imports/node-app/core/util/appEvents";
+import getCart from "/imports/plugins/core/cart/server/util/getCart";
import { Discounts } from "/imports/plugins/core/discounts/lib/collections";
import { DiscountCodes as DiscountSchema } from "../../lib/collections/schemas";
@@ -20,18 +21,18 @@ export const methods = {
* @method
* @memberof Discounts/Codes/Methods
* @param {Object} doc A Discounts document to be inserted
- * @param {String} [docId] DEPRECATED. Existing ID to trigger an update. Use discounts/editCode method instead.
* @return {String} Insert result
*/
- "discounts/addCode"(doc, docId) {
+ "discounts/addCode"(doc) {
check(doc, Object); // actual schema validation happens during insert below
- // Backward compatibility
- check(docId, Match.Optional(String));
- if (docId) return Meteor.call("discounts/editCode", { _id: docId, modifier: doc });
+ const shopId = Reaction.getShopId();
- if (!Reaction.hasPermission("discount-codes")) throw new ReactionError("access-denied", "Access Denied");
- doc.shopId = Reaction.getShopId();
+ if (!Reaction.hasPermission("discounts", Reaction.getUserId(), shopId)) {
+ throw new ReactionError("access-denied", "Access Denied");
+ }
+
+ doc.shopId = shopId;
return Discounts.insert(doc);
},
@@ -47,9 +48,37 @@ export const methods = {
_id: String,
modifier: Object // actual schema validation happens during update below
});
- if (!Reaction.hasPermission("discount-codes")) throw new ReactionError("access-denied", "Access Denied");
+
+ const shopId = Reaction.getShopId();
+
+ if (!Reaction.hasPermission("discounts", Reaction.getUserId(), shopId)) {
+ throw new ReactionError("access-denied", "Access Denied");
+ }
+
const { _id, modifier } = details;
- return Discounts.update(_id, modifier);
+ return Discounts.update({ _id, shopId }, modifier);
+ },
+
+ /**
+ * @name discounts/deleteCode
+ * @method
+ * @memberof Discounts/Codes/Methods
+ * @param {String} discountId discount id to delete
+ * @return {String} returns remove result
+ */
+ "discounts/deleteCode"(discountId) {
+ check(discountId, String);
+
+ const shopId = Reaction.getShopId();
+
+ if (!Reaction.hasPermission("discounts", Reaction.getUserId(), shopId)) {
+ throw new ReactionError("access-denied", "Access Denied");
+ }
+
+ return Discounts.remove({
+ _id: discountId,
+ shopId
+ });
},
/**
@@ -60,14 +89,42 @@ export const methods = {
* @param {String} id cart id of which to remove a code
* @param {String} codeId discount Id from cart.billing
* @param {String} collection collection (either Orders or Cart)
+ * @param {String} [token] Cart or order token if anonymous
* @return {String} returns update/insert result
*/
- "discounts/codes/remove"(id, codeId, collection = "Cart") {
+ "discounts/codes/remove"(id, codeId, collection = "Cart", token) {
check(id, String);
check(codeId, String);
check(collection, String);
+ check(token, Match.Maybe(String));
+
const Collection = Reaction.Collections[collection];
+ if (collection === "Cart") {
+ let { cart } = getCart(id, { cartToken: token, throwIfNotFound: true });
+
+ // If we found a cart, then the current account owns it
+ if (!cart) {
+ cart = Collection.findOne({ _id: id });
+ if (!cart) {
+ throw new ReactionError("not-found", "Cart not found");
+ }
+
+ if (!Reaction.hasPermission("discounts", Reaction.getUserId(), cart.shopId)) {
+ throw new ReactionError("access-denied", "Access Denied");
+ }
+ }
+ } else {
+ const order = Collection.findOne({ _id: id });
+ if (!order) {
+ throw new ReactionError("not-found", "Order not found");
+ }
+
+ if (!Reaction.hasPermission("discounts", Reaction.getUserId(), order.shopId)) {
+ throw new ReactionError("access-denied", "Access Denied");
+ }
+ }
+
// TODO: update a history record of transaction
// The Payment schema currency defaultValue is adding {} to the $pull condition.
// If this issue is eventually fixed, autoValues can be re-enabled here
@@ -94,22 +151,53 @@ export const methods = {
* @param {String} id cart/order id of which to remove a code
* @param {String} code valid discount code
* @param {String} collection collection (either Orders or Cart)
+ * @param {String} [token] Cart or order token if anonymous
* @return {Boolean} returns true if successfully applied
*/
- "discounts/codes/apply"(id, code, collection = "Cart") {
+ "discounts/codes/apply"(id, code, collection = "Cart", token) {
check(id, String);
check(code, String);
check(collection, String);
+ check(token, Match.Maybe(String));
let userCount = 0;
let orderCount = 0;
+ const Collection = Reaction.Collections[collection];
+ let objectToApplyDiscount;
+
+ if (collection === "Cart") {
+ let { cart } = getCart(id, { cartToken: token, throwIfNotFound: true });
+
+ // If we found a cart, then the current account owns it
+ if (!cart) {
+ cart = Collection.findOne({ _id: id });
+ if (!cart) {
+ throw new ReactionError("not-found", "Cart not found");
+ }
+
+ if (!Reaction.hasPermission("discounts", Reaction.getUserId(), cart.shopId)) {
+ throw new ReactionError("access-denied", "Access Denied");
+ }
+ }
+
+ objectToApplyDiscount = cart;
+ } else {
+ const order = Collection.findOne({ _id: id });
+ if (!order) {
+ throw new ReactionError("not-found", "Order not found");
+ }
+
+ if (!Reaction.hasPermission("discounts", Reaction.getUserId(), order.shopId)) {
+ throw new ReactionError("access-denied", "Access Denied");
+ }
+
+ objectToApplyDiscount = order;
+ }
+
// check to ensure discounts can only apply to single shop carts
// TODO: Remove this check after implementation of shop-by-shop discounts
- const Collection = Reaction.Collections[collection];
- const objectToApplyDiscount = Collection.findOne({ _id: id });
- const items = objectToApplyDiscount && objectToApplyDiscount.items;
// loop through all items and filter down to unique shops (in order to get participating shops in the order/cart)
- const uniqueShopObj = items.reduce((shopObj, item) => {
+ const uniqueShopObj = objectToApplyDiscount.items.reduce((shopObj, item) => {
if (!shopObj[item.shopId]) {
shopObj[item.shopId] = true;
}
diff --git a/imports/plugins/included/email-smtp/server/methods/retryFailed.js b/imports/plugins/included/email-smtp/server/methods/retryFailed.js
index 09f2612f803..d88c241dba7 100644
--- a/imports/plugins/included/email-smtp/server/methods/retryFailed.js
+++ b/imports/plugins/included/email-smtp/server/methods/retryFailed.js
@@ -13,7 +13,7 @@ import ReactionError from "@reactioncommerce/reaction-error";
* @return {Boolean} - returns true if job is successfully restarted
*/
export default function retryFailed(jobId) {
- if (!Reaction.hasPermission(["owner", "admin", "reaction-email"], this.userId)) {
+ if (!Reaction.hasPermission(["owner", "admin", "reaction-email"], this.userId, Reaction.getPrimaryShopId())) {
Logger.error("email/retryFailed: Access Denied");
throw new ReactionError("access-denied", "Access Denied");
}
diff --git a/imports/plugins/included/shipping-rates/server/index.js b/imports/plugins/included/shipping-rates/server/index.js
index 6641da28c8a..3979f964b5a 100644
--- a/imports/plugins/included/shipping-rates/server/index.js
+++ b/imports/plugins/included/shipping-rates/server/index.js
@@ -1,2 +1 @@
import "./i18n";
-import "./methods/rates";
diff --git a/imports/plugins/included/shipping-rates/server/methods/rates.js b/imports/plugins/included/shipping-rates/server/methods/rates.js
deleted file mode 100644
index bbc7b0dc505..00000000000
--- a/imports/plugins/included/shipping-rates/server/methods/rates.js
+++ /dev/null
@@ -1,111 +0,0 @@
-import Random from "@reactioncommerce/random";
-import { Meteor } from "meteor/meteor";
-import { check, Match } from "meteor/check";
-import { Shipping } from "/lib/collections";
-import { ShippingMethod } from "/lib/collections/schemas";
-import Reaction from "/imports/plugins/core/core/server/Reaction";
-import ReactionError from "@reactioncommerce/reaction-error";
-
-const shippingRoles = ["admin", "owner", "shipping", "reaction-shippo"];
-
-export const methods = {
- /**
- * shipping/rates/add
- * add new shipping flat rate methods
- * @summary insert shipping method for a flat rate provider
- * @param {Object} rate a valid ShippingMethod object
- * @return {Number} insert result
- */
- "shipping/rates/add"(rate) {
- check(rate, {
- name: String,
- label: String,
- group: String,
- cost: Match.OneOf(Number, null, undefined),
- handling: Number,
- rate: Number,
- enabled: Boolean
- });
-
- if (!Reaction.hasPermission(shippingRoles)) {
- throw new ReactionError("access-denied", "Access Denied");
- }
-
- const shopId = Reaction.getShopId();
- if (!Shipping.findOne({ "provider.name": "flatRates", shopId })) {
- Shipping.insert({
- name: "Default Shipping Provider",
- shopId,
- provider: {
- name: "flatRates",
- label: "Flat Rate"
- }
- });
- }
-
- rate._id = Random.id();
- return Shipping.update({
- shopId,
- "provider.name": "flatRates"
- }, {
- $addToSet: {
- methods: rate
- }
- });
- },
-
- /**
- * shipping/rates/update
- * @summary update shipping rate methods
- * @param { Object } method shipping method object
- * @return { Number } update result
- */
- "shipping/rates/update"(method) {
- ShippingMethod.validate(method);
- if (!Reaction.hasPermission(shippingRoles)) {
- throw new ReactionError("access-denied", "Access Denied");
- }
- const methodId = method._id;
-
- return Shipping.update({
- "methods._id": methodId
- }, {
- $set: {
- "methods.$": method
- }
- });
- },
-
- /**
- * shipping/rates/delete
- * @summary delete shipping rate method
- * @param { String } rateId id of method to delete
- * @return { Number } update result
- */
- "shipping/rates/delete"(rateId) {
- check(rateId, String);
-
- if (!Reaction.hasPermission(shippingRoles)) {
- throw new ReactionError("access-denied", "Access Denied");
- }
-
- const rates = Shipping.findOne({ "methods._id": rateId });
- const { methods: shippingMethods } = rates;
- const updatedMethods = shippingMethods.filter((method) => method._id !== rateId);
-
- // HACK: not sure why we need to do this.. but it works.
- // Replaced a $pull which in theory is better, but was broken.
- // Issue w/ pull was introduced during the simpl-schema update
- const deleted = Shipping.update({
- "methods._id": rateId
- }, {
- $set: {
- methods: updatedMethods
- }
- });
-
- return deleted;
- }
-};
-
-Meteor.methods(methods);
diff --git a/imports/plugins/included/taxes-rates/server/methods.js b/imports/plugins/included/taxes-rates/server/methods.js
index b174156f2b3..633723bb1a4 100644
--- a/imports/plugins/included/taxes-rates/server/methods.js
+++ b/imports/plugins/included/taxes-rates/server/methods.js
@@ -1,6 +1,6 @@
import ReactionError from "@reactioncommerce/reaction-error";
import { Meteor } from "meteor/meteor";
-import { Match, check } from "meteor/check";
+import { check } from "meteor/check";
import Reaction from "/imports/plugins/core/core/server/Reaction";
import { Taxes } from "../lib/collections";
@@ -22,12 +22,13 @@ const methods = {
"taxes/deleteRate"(taxId) {
check(taxId, String);
- // check permissions to delete
- if (!Reaction.hasPermission("taxes")) {
+ const shopId = Reaction.getShopId();
+
+ if (!Reaction.hasPermission("taxes", Reaction.getUserId(), shopId)) {
throw new ReactionError("access-denied", "Access Denied");
}
- return Taxes.remove(taxId);
+ return Taxes.remove({ _id: taxId, shopId });
},
/**
@@ -35,18 +36,18 @@ const methods = {
* @method
* @memberof TaxesRates/Methods
* @param {Object} doc A Taxes document to be inserted
- * @param {String} [docId] DEPRECATED. Existing ID to trigger an update. Use taxes/editRate method instead.
* @return {String} Insert result
*/
- "taxes/addRate"(doc, docId) {
+ "taxes/addRate"(doc) {
check(doc, Object); // actual schema validation happens during insert below
- // Backward compatibility
- check(docId, Match.Optional(String));
- if (docId) return Meteor.call("taxes/editRate", { _id: docId, modifier: doc });
+ const shopId = Reaction.getShopId();
- if (!Reaction.hasPermission("taxes")) throw new ReactionError("access-denied", "Access Denied");
- doc.shopId = Reaction.getShopId();
+ if (!Reaction.hasPermission("taxes", Reaction.getUserId(), shopId)) {
+ throw new ReactionError("access-denied", "Access Denied");
+ }
+
+ doc.shopId = shopId;
return Taxes.insert(doc);
},
@@ -62,9 +63,15 @@ const methods = {
_id: String,
modifier: Object // actual schema validation happens during update below
});
- if (!Reaction.hasPermission("taxes")) throw new ReactionError("access-denied", "Access Denied");
+
+ const shopId = Reaction.getShopId();
+
+ if (!Reaction.hasPermission("taxes", Reaction.getUserId(), shopId)) {
+ throw new ReactionError("access-denied", "Access Denied");
+ }
+
const { _id, modifier } = details;
- return Taxes.update(_id, modifier);
+ return Taxes.update({ _id, shopId }, modifier);
}
};