Skip to content

Commit

Permalink
Merge pull request #4883 from reactioncommerce/fix-aldeed-security-4
Browse files Browse the repository at this point in the history
Meteor method permissions fixes
  • Loading branch information
kieckhafer authored Dec 19, 2018
2 parents 9664a1d + 41ff427 commit 70e018c
Show file tree
Hide file tree
Showing 15 changed files with 184 additions and 278 deletions.
11 changes: 5 additions & 6 deletions imports/plugins/core/discounts/client/components/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand All @@ -38,9 +39,6 @@ export default class DiscountForm extends Component {
}
});
}, 800);

this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
}

componentWillUnmount() {
Expand All @@ -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) {
Expand All @@ -85,7 +83,7 @@ export default class DiscountForm extends Component {
}

// handle display or not
handleClick(event) {
handleClick = (event) => {
event.preventDefault();
this.setState({ validatedInput: true });
}
Expand Down Expand Up @@ -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
};
15 changes: 13 additions & 2 deletions imports/plugins/core/discounts/client/components/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -24,6 +26,7 @@ class DiscountList extends Component {
<div className="rui list-group">{listItems}</div>
);
}

// render item
renderItem(listItem) {
let TrashCan;
Expand All @@ -47,8 +50,9 @@ class DiscountList extends Component {

// load form input view
renderNoneFound() {
const { collection, id, token, validatedInput } = this.props;
return (
<DiscountForm id={this.props.id} collection={this.props.collection} validatedInput={this.props.validatedInput} />
<DiscountForm id={id} collection={collection} token={token} validatedInput={validatedInput} />
);
}

Expand All @@ -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
Expand Down
1 change: 0 additions & 1 deletion imports/plugins/core/discounts/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@
import "./i18n";
import "./security/discounts";
import "./publications/discounts";
import "./methods";
1 change: 0 additions & 1 deletion imports/plugins/core/discounts/server/methods/index.js

This file was deleted.

40 changes: 0 additions & 40 deletions imports/plugins/core/discounts/server/methods/methods.app-test.js

This file was deleted.

79 changes: 0 additions & 79 deletions imports/plugins/core/discounts/server/methods/methods.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template name="discountCodesCheckout">
<div>
{{> React component=DiscountList id=cartId collection="Cart"}}
{{> React component=DiscountList id=cartProps.cartId token=cartProps.cartToken collection="Cart"}}
</div>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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();
Expand Down Expand Up @@ -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);
Expand All @@ -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/);
Expand Down
Loading

0 comments on commit 70e018c

Please sign in to comment.