Skip to content

Commit

Permalink
Release v0.15.0 (#1308)
Browse files Browse the repository at this point in the history
* create launchdock-connect plugin (#1241)

* rebuild launchdock-connect as a plugin module

* build more flexible admin email verification method

* add Stripe dependency for launchdock-connect

* fix linting issues

* Adjust inventory on shipment (#1240)

* Trap order-completed change

* Add missing import

* Add cartItemId field to order so that we can modify inventory

* Add new "inventory/sold" method

* Explicitly set from and to statuses

* Handle order insert hook to move ordered inventory to "sold" status

* Handle moving inventory from "reserved" to "sold" status

* Fix email import

* Fix tests

* Not so much logging

* Call status change method with explicit values

* Add test for moving inventory from "reserved" to "sold"

* Add test for moving inventory from "sold" to "shipped"

* Force eslint to recognize that switch/case should be indented (#1250)

* Force eslint to recognize that swtich/case should be indented
eslint/eslint#1797

* remove eslint-plugin-meteor

- we need to tune this, removing until we have time

* enable eslint-2 codeclimate

- remove meteor-eslint plugin, failing to load with eslint-2

* updated switch indentation

- test eslint switch, case indent

* Add route hooks API (#1253)

* build initial implementation of route hooks

* extend Router with Hooks and register all hooks

* more route hooks tweaks

* router namespace cleanup

* removed unused values from registry entry (linter)

* Refactor inventory (#1251)

* As noted in comments from previous PR, just some reorg kept separate from the functionality PR

* Correct matching

* Fix for decrement cart function  (#1273)

* Add failing test

* Fix for update Mongo command

* Add failing test for "decrease below zero"

* If removeQuantity is more than quantity remove the entire line

* updated linting error

* linting error fix

* listing issues

* more cleanup and linting tweaks

* fix eslint config for object key quotes

* fix tests after error message update

* revert quote-props linter change

* revert lint changes

* Simplify logic per CR comment

* import moment-timezone (#1261)

- fixes error .names undefined
- for loading tz in i18n settings

* Fix inventory tests (#1254)

* Reduce size of the cart so that orders don't take so long to process.

* Add a wait before pulling record

* Add a wait before pulling record

* Wait after calling Meteor method

* Longer timeout

* Longer timeout

* Temporarily bypass failiing inventory test (#1280)

* fix for #1072 (#1247)

fix for #1072

* Use forked version of authorize.net that doesn't have vulnerability (#1252)

* Update circle node (#1281)

* update circle node to v4.4.7

* remove unused packages

- remove eslint-plugin-meteor
- remove bunyan-loggly (insecure dependency)
- currently not in use

* updated package.json (#1286)

- updates jquery-i18next
- updates i18next-browser-languagedetector

* Create email job queue and Reaction.Email namespace (#1282)

* build job queue for email and refactor related methods

* put placeholder content in coreDefault email template

* add rate limiting for accounts and notification methods

* put order completed template at correct path

* update old jquery-i18next

* remove log

* remove unused var

* remove unnecessary filler in placeholder template

* log warning when email template isn’t found

* return job object from Reaction.Email.send()

* fix missing import

* fix comment for email method

* remove debugging logger

* updated to remove name from email

should be enough info

* logout and hasPermission updates (#1290)

* updated hasPermissions, router behaviour

- resolves #1122
- refactors client hasPermissions to wait for a userId if one isn’t
immediately found
- intentionally not redirecting to home page (not sure if that’s the
best behavior, better to have login?)
- adds subscription manager to a few more collections

* fix typo

* import lodash

might work better if _.find exists

* check for existing route table

* Fix PayPal PayFlow discounts and refunds (#1275)

* allow discounts and refunds with PayPal PayFlow

- Fix discounts so they are working
- Allow 100% discounts
- Fix refunds so they are working

* wrap PayPal PayFlow in wrapper for easier testing

* PayPal PayFlow refund test

* removed temporary file

* updated cc error message

* update cardNumber schemas

cardNumber schemas were not allowing valid credit cards, such as Amex
(15 digits), some Visa (13 digits), and foreign Maestro (12 - 19
digits). This updates to allow these lengths to be input.

* Remove bash script from postinstall to fix Windows installs (#1299)

* don’t run bash scripts in postinstall because Windows

* add fallback fonts back to public dir

* release 0.15.0

- updated package in preparation for new release

* Allow any user who has the createProduct permission to also delete products (#1263)

* - ignoring my custom entrypoint (for running prod image with src)

* - allow users with createProduct permission to delete products (for marketplace withmultiple sellers)

* - removing .gitignore files that is not welcome in repo

* Fix Braintree discounts and refunds (#1265)

* add Braintree Payment error to en.json

* enable discounts for Braintree payments

Braintree was not capturing discounts, instead using the amount in the
original authorization for the capturing. This update changes the
amount to the paymentMethod.amount, which includes discounts.

* removed else statement after an if containing a return

Since the return inside the IF statement will effectively kill the
process if it’s hit, there is no need for the else.

* added testing for Braintree refunds

This code still needs some love, just wanted to get it up for others to
take a look at.

* remove no longer needed commented code

* remove no longer needed commented code

* added field to expected response for testing

* moved braintree/refund/list methods into BraintreeApi wrapper

Creating a wrapper for Braintree in order to more easily perform testing

* move braintree methods into new file

* reconfigure all braintree payment code to no longer use ValidateMethod

* fixed lint issues

* removed code used to skip over 24 hour braintree delay (for testing)

* Rename braintreeapi.js to braintreeApi.js

* display absolute number of adjustedTotal

due to various instances of rounding numbers for display purposes, the
adjustedTotal would sometimes display -0.00, as the adjusted total was
technically -.00000000000000000000001, even though we display 0.00 when
we round it. This update just shows the absolute number, as this is
simple a display number and does not have any affect on what is being
sent to and from the payment provider.

* updated schema to match supported payment methods

The current Schema had a 16 number minimum for credit cards, however
braintree supports cards which have number lengths ranging from 12-19

* min -> max

* removed comments

* test testing

* update braintree test

* update exports of braintreeApi functions

* fixed callback error when action has no callback

* Updated error message to make more sense to a human user

* linter fixes

* updated 'Logger.info' to Logger.debug

* removed unused test

* removed commented callback

* don't log full order details on transaction error

* fix refunds and discounts for authorize.net (#1279)

- Fix discounts so that they are correctly sent to authorize.net

- Allow 100% discounts by adding the “voidTransaction” function and
voiding transactions

- Update error messaging for Refunds, as we do not (yet) allow them
from Authorize.net

* Fix Stripe refunds and Double Discounts (#1304)

* added comment to explain voiding vs applying discount

* add ___ for correctly calculating Stripe adjusted totals

Stripe doesn’t “do” discounts, instead they take the discount sent to
them, and apply it as a refund. This was causing any discounts to show
up twice - once as a discount, once as a refund - in our adjusted
total. This update fixes that by re-adding the discount price into the
adjusted total when the payment provider is Stripe.

* also 100% discounts on Stripe

* humanizing an error code

* removed unintentional text

* linting fixes

* removed unused commented code

* removed unused commented code

* Taxes (#1289)

* initial commit tax-rebase plugin

Initial commit for issue #972

* split providers to plugins/included

* Griddle updates

- fork MeteorGriddle into core/ui-grid
- move fetchTI
- add i18n taxSettings

* initial grid editing

* add taxSettings labels

* initial custom add / edit tax rates

- initial working forms, edit toggling.. bit rough..

* rename tax-base to taxes

* updated custom grid

 - adds row selection

* add custom rate form reset

* updated custom settings

* add cart hooks to trigger taxes/calculate

* update hooks, taxes/deleteRate

- also adds taxes/deleteRate

* migrate schemas to plugins

- also set taxCloud jobs to not run by default

* add custom tax rates calculation

- add taxes, tax to cart schema
- taxes not published to client
- updates global cartTotal helpers

* check for shipping

* migrate settings to plugins

* add tax hooks to plugins

 -abort idea on “provides” as a package property

* Avalara Tax Lookup

 - adds taxes/setRate method

* comment unused fields

- comment out first implementation unused fields

These are fields that will be used future enhancements to taxes.  They
are commented out for now.

* logger cleanup

- move info to debug

* updated product data with default taxable items

- add taxCode placeholder to schema

* taxCloud tax rate calculations

* disable taxjar, check for packages

- disable while module is not functional
- WIP fetch rates and api configuration

* custom rate ui cleanup

* taxes method test

- a weak attempt at a test but gets the ball rolling and actually fixes
a todo

* updated test, versions

- add done to test
- updated meteor package versions

* remove unused template registry entries

- final cleanup, ready for PR to development
- pending tests
- pending docs

* avoid running country-data unless address exists

* add tax rate delete

- adds delete and confirm to edit form

* linted griddle.js

* remove unused import

* fix display of taxes in order workflow

perhaps this should be updated to “tax”, instead of taxes in the
invoice object.

* line item calculations

- added for custom rates
- added for avalara

rates are calculated by individual line items but on a general rate for
the cart.

* update case linted

* updated variant methods

- update products/updateProductField to handle boolean
- kludge update of childVariants when parentVariant is updated
- remove default value from form
- small cleanups
  • Loading branch information
brent-hoover authored and kieckhafer committed Aug 18, 2016
1 parent 7f9b9a2 commit cc13cef
Show file tree
Hide file tree
Showing 159 changed files with 7,301 additions and 1,508 deletions.
1 change: 1 addition & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ exclude_paths:
engines:
eslint:
enabled: true
channel: "eslint-2"
csslint:
enabled: false
duplication:
Expand Down
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
**/*{.,-}min.js
*.min.*
9 changes: 4 additions & 5 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
"ecmaVersion": 6,
"sourceType": "module"
},
"plugins": ["react", "meteor"],
"extends": ["plugin:meteor/recommended"],
"plugins": ["react"],
"ecmaFeatures": {
"arrowFunctions": true,
"blockBindings": true,
Expand Down Expand Up @@ -168,7 +167,7 @@
/**
* Style
*/
"indent": [2, 2], // http://eslint.org/docs/rules/indent
"indent": [2, 2, {"SwitchCase": 1}], // http://eslint.org/docs/rules/indent
"brace-style": [2, // http://eslint.org/docs/rules/brace-style
"1tbs", {
"allowSingleLine": true
Expand All @@ -194,7 +193,7 @@
}],
"new-cap": [0, { // http://eslint.org/docs/rules/new-cap (turned off for now, as it complains on all Match)
"newIsCap": true,
"capIsNewExceptions": ["Match", "OneOf", "Optional"],
"capIsNewExceptions": ["Match", "OneOf", "Optional"]
}],
"no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines
"max": 2
Expand All @@ -221,6 +220,6 @@
}], // http://eslint.org/docs/rules/space-before-function-paren
"space-infix-ops": 2, // http://eslint.org/docs/rules/space-infix-ops
"space-in-parens": [2, "never"], // http://eslint.org/docs/rules/space-in-parens
"spaced-comment": [2, "always"], // http://eslint.org/docs/rules/spaced-comment
"spaced-comment": [2, "always"] // http://eslint.org/docs/rules/spaced-comment
}
}
2 changes: 2 additions & 0 deletions .meteor/packages
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ cfs:gridfs
cfs:standard-packages
cfs:storage-adapter
cfs:ui
jeremy:stripe
jparker:gravatar
juliancwirko:s-alert
juliancwirko:s-alert-stackslide
Expand All @@ -73,6 +74,7 @@ raix:ui-dropped-event
risul:moment-timezone
tmeasday:publish-counts
vsivsi:job-collection
react-meteor-data

# Testing packages
dburles:factory
Expand Down
16 changes: 9 additions & 7 deletions .meteor/versions
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[email protected].9
[email protected].10
[email protected]
[email protected]
[email protected]
[email protected].12
[email protected].14
[email protected]
alanning:[email protected]
aldeed:[email protected]
Expand Down Expand Up @@ -64,7 +64,7 @@ [email protected]
[email protected]
dispatch:[email protected]
[email protected]
[email protected].12
[email protected].13
[email protected]
[email protected]
[email protected]
Expand All @@ -77,12 +77,13 @@ [email protected]
[email protected]
[email protected]
[email protected]
jeremy:[email protected]
jparker:[email protected]
jparker:[email protected]
jparker:[email protected]
[email protected]
juliancwirko:[email protected]
juliancwirko:s-alert@3.1.4
juliancwirko:s-alert@3.2.0
juliancwirko:[email protected]
kadira:[email protected]
kadira:[email protected]
Expand Down Expand Up @@ -115,11 +116,10 @@ [email protected]
[email protected]
[email protected]
mrt:[email protected]
[email protected].7
[email protected].7_1
[email protected]
[email protected]_4
[email protected]
oauth-encryption@1.1.13
oauth-encryption@1.2.0
[email protected]
[email protected]
[email protected]
Expand All @@ -133,6 +133,7 @@ raix:[email protected]
raix:[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
Expand All @@ -148,6 +149,7 @@ [email protected]
[email protected]
[email protected]
[email protected]
tmeasday:[email protected]
tmeasday:[email protected]
[email protected]
[email protected]
Expand Down
11 changes: 0 additions & 11 deletions .reaction/scripts/postinstall.sh

This file was deleted.

2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
machine:
node:
version: 0.10.46
version: 4.4.7
services:
- docker
pre:
Expand Down
4 changes: 0 additions & 4 deletions client/modules/accounts/templates/dropdown/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ Template.loginDropdown.events({
if (error) {
Logger.warn("Failed to logout.", error);
}
// go home on logout
Reaction.Subscriptions.Manager.reset();
Reaction.Router.reload();
Reaction.Router.go("/");
});
},

Expand Down
2 changes: 1 addition & 1 deletion client/modules/core/helpers/templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as Collections from "/lib/collections";
import * as Schemas from "/lib/collections/schemas";
import { Meteor } from "meteor/meteor";
import { Template } from "meteor/templating";
import moment from "moment";
import moment from "moment-timezone";

/*
*
Expand Down
120 changes: 80 additions & 40 deletions client/modules/core/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Logger from "/client/modules/logger";
import { Countries } from "/client/collections";
import { localeDep } from "/client/modules/i18n";
import { Packages, Shops } from "/lib/collections";
import { Router } from "/client/modules/router";

/**
* Reaction namespace
Expand Down Expand Up @@ -77,56 +78,95 @@ export default {
hasPermission(checkPermissions, checkUserId, checkGroup) {
let group = this.getShopId();
let permissions = ["owner"];
let id = "";
const userId = checkUserId || this.userId || Meteor.userId();
//
// local roleCheck function
// is the bulk of the logic
// called out a userId is validated.
//
function roleCheck() {
// permissions can be either a string or an array
// we'll force it into an array and use that
if (checkPermissions === undefined) {
permissions = ["owner"];
} else if (typeof checkPermissions === "string") {
permissions = [checkPermissions];
} else {
permissions = checkPermissions;
}
// if the user has admin, owner permissions we'll always check if those roles are enough
permissions.push("owner");
permissions = _.uniq(permissions);

// default group to the shop or global if shop
// isn't defined for some reason.
if (checkGroup !== undefined && typeof checkGroup === "string") {
group = checkGroup;
}
if (!group) {
group = Roles.GLOBAL_GROUP;
//
// return if user has permissions in the group
//
if (Roles.userIsInRole(userId, permissions, group)) {
return true;
}
// global roles check
let sellerShopPermissions = Roles.getGroupsForUser(userId, "admin");
// we're looking for seller permissions.
if (sellerShopPermissions) {
// loop through shops roles and check permissions
for (let key in sellerShopPermissions) {
if (key) {
let shop = sellerShopPermissions[key];
if (Roles.userIsInRole(userId, permissions, shop)) {
return true;
}
}
}
}
// no specific permissions found returning false
return false;
}

// use current user if userId if not provided
// becauase you gotta have a user to check permissions
const userId = checkUserId || this.userId || Meteor.userId();
if (!userId) {
//
// check if a user id has been found
// in line 156 setTimeout
//
function validateUserId() {
if (Meteor.userId()) {
Meteor.clearTimeout(id);
Router.reload();
return roleCheck();
}
return false;
}
// permissions can be either a string or an array
// we'll force it into an array and use that
if (checkPermissions === undefined) {
permissions = ["owner"];
} else if (typeof checkPermissions === "string") {
permissions = [checkPermissions];
} else {
permissions = checkPermissions;
}
// if the user has admin, owner permissions we'll always check if those roles are enough
permissions.push("owner");
permissions = _.uniq(permissions);

//
// return if user has permissions in the group
// actual logic block to check permissions
// we'll bypass unecessary checks during
// a user logging, as we'll check again
// when everything is ready
//
if (Roles.userIsInRole(userId, permissions, group)) {
return true;
}
// global roles check
let sellerShopPermissions = Roles.getGroupsForUser(userId, "admin");
// we're looking for seller permissions.
if (sellerShopPermissions) {
// loop through shops roles and check permissions
for (let key in sellerShopPermissions) {
if (key) {
let shop = sellerShopPermissions[key];
if (Roles.userIsInRole(userId, permissions, shop)) {
return true;
}
}
if (Meteor.loggingIn() === false) {
//
// this userId check happens because when logout
// occurs it takes a few cycles for a new anonymous user
// to get created and during this time the user has no
// permission, not even guest permissions so we
// need to wait and reload the routes. This
// mainly affects the logout from dashboard pages
//
if (!userId) {
id = Meteor.setTimeout(validateUserId, 5000);
} else {
return roleCheck();
}

// default group to the shop or global if shop
// isn't defined for some reason.
if (checkGroup !== undefined && typeof checkGroup === "string") {
group = checkGroup;
}
if (!group) {
group = Roles.GLOBAL_GROUP;
}
}
// no specific permissions found returning false
// return false to be safe
return false;
},

Expand Down
11 changes: 6 additions & 5 deletions client/modules/core/subscriptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ Subscriptions.Account = Subscriptions.Manager.subscribe("Accounts", Meteor.userI
/**
* General Subscriptions
*/
Subscriptions.Shops = Meteor.subscribe("Shops");
Subscriptions.Shops = Subscriptions.Manager.subscribe("Shops");

Subscriptions.Packages = Meteor.subscribe("Packages");
Subscriptions.Packages = Subscriptions.Manager.subscribe("Packages");

Subscriptions.Tags = Meteor.subscribe("Tags");
Subscriptions.Tags = Subscriptions.Manager.subscribe("Tags");

Subscriptions.Media = Meteor.subscribe("Media");
Subscriptions.Media = Subscriptions.Manager.subscribe("Media");

// admin only
// todo should we put this inside autorun and detect user changes
Subscriptions.Inventory = Meteor.subscribe("Inventory");
Subscriptions.Inventory = Subscriptions.Manager.subscribe("Inventory");

/**
* Subscriptions that need to reload on new sessions
Expand Down Expand Up @@ -70,4 +70,5 @@ Tracker.autorun(() => {
sessionId = Session.get("sessionId");
});
Subscriptions.Cart = Meteor.subscribe("Cart", sessionId, Meteor.userId());
Subscriptions.UserProfile = Meteor.subscribe("UserProfile", Meteor.userId());
});
55 changes: 55 additions & 0 deletions client/modules/router/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

/**
* Route Hook Methods
*/
const Hooks = {
_hooks: {
onEnter: {},
onExit: {}
},

_addHook(type, routeName, callback) {
if (typeof this._hooks[type][routeName] === "undefined") {
this._hooks[type][routeName] = [];
}
this._hooks[type][routeName].push(callback);
},

onEnter(routeName, callback) {
// global onEnter callback
if (arguments.length === 1 && typeof arguments[0] === "function") {
const cb = routeName;
return this._addHook("onEnter", "GLOBAL", cb);
}
// route-specific onEnter callback
return this._addHook("onEnter", routeName, callback);
},

onExit(routeName, callback) {
// global onExit callback
if (arguments.length === 1 && typeof arguments[0] === "function") {
const cb = routeName;
return this._addHook("onExit", "GLOBAL", cb);
}
// route-specific onExit callback
return this._addHook("onExit", routeName, callback);
},

get(type, name) {
const group = this._hooks[type] || {};
const callbacks = group[name];
return (typeof callbacks !== "undefined" && !!callbacks.length) ? callbacks : [];
},

run(type, name, constant) {
const callbacks = this.get(type, name);
if (typeof callbacks !== "undefined" && !!callbacks.length) {
return callbacks.forEach((callback) => {
return callback(constant);
});
}
return null;
}
};

export default Hooks;
Loading

0 comments on commit cc13cef

Please sign in to comment.