diff --git a/.eslintrc b/.eslintrc index 10faf997..28de5e75 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,8 +5,7 @@ "no-empty": [1], "no-lonely-if": [2], "no-inner-declarations": [2, "both"], - "space-after-keywords": [2], - "space-before-keywords": [2, "always"], + "keyword-spacing": [2, {"before": true, "after": true}], "space-before-blocks": [2], "space-before-function-paren": [2, "never"], "no-console": [0], @@ -21,7 +20,8 @@ "no-eq-null": [2], "no-return-assign": [2], "radix": [2], - "handle-callback-err": [2] + "handle-callback-err": [2], + "react/jsx-uses-vars": [2] }, "env": { "es6": true, @@ -36,12 +36,15 @@ "StripeCheckout" }, "extends": "eslint:recommended", - "ecmaFeatures": { + "parserOptions": { + "ecmaVersion": 8, + "sourceType": "module", + "ecmaFeatures": { "jsx": true, - "experimentalObjectRestSpread": true, - "modules": true + "experimentalObjectRestSpread": true + } }, "plugins": [ "react" ] -} \ No newline at end of file +} diff --git a/package.json b/package.json index 26e0ef31..12136c19 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "css-loader": "0.23.1", "enhanced-require": "0.5.0-beta6", "enzyme": "2.7.0", - "eslint": "1.10.3", + "eslint": "4.11.0", "eslint-loader": "1.1.1", "eslint-plugin-react": "3.14.0", "exports-loader": "0.6.2", diff --git a/server/routes/index.js b/server/routes/index.js index d15a62bb..fe78094b 100644 --- a/server/routes/index.js +++ b/server/routes/index.js @@ -548,38 +548,38 @@ var routes = { // kick off a Promise Chain Promise.resolve() - .then(function() { + .then(function() { // close the dispute automatically if it's not lost already - if (event === 'charge.dispute.created' && dispute.status === 'lost') { - return Promise.resolve(); - } - - return stripe.closeDispute(dispute.id) - .catch(function(closeDisputeError) { - if (closeDisputeError.message === 'This dispute is already closed') { - return console.log(closeDisputeError.message); + if (event === 'charge.dispute.created' && dispute.status === 'lost') { + return Promise.resolve(); } - return Promise.reject("Could not close the dispute"); - }); - }) - .then(function() { - basket.queue({ - event_type: event.type, - transaction_id: dispute.charge, - reason: dispute.reason, - status: dispute.status - }); + return stripe.closeDispute(dispute.id) + .catch(function(closeDisputeError) { + if (closeDisputeError.message === 'This dispute is already closed') { + return console.log(closeDisputeError.message); + } - reply("dispute processed"); - }) - .catch(function(err) { - if (err.isBoom) { - return reply(err); - } + return Promise.reject("Could not close the dispute"); + }); + }) + .then(function() { + basket.queue({ + event_type: event.type, + transaction_id: dispute.charge, + reason: dispute.reason, + status: dispute.status + }); - return reply(boom.badImplementation('An error occurred while handling the dispute webhook', err)); - }); + reply("dispute processed"); + }) + .catch(function(err) { + if (err.isBoom) { + return reply(err); + } + + return reply(boom.badImplementation('An error occurred while handling the dispute webhook', err)); + }); }, diff --git a/server/services.js b/server/services.js index 568d70bc..0ac12fac 100644 --- a/server/services.js +++ b/server/services.js @@ -44,7 +44,7 @@ var services = [ connectSrc: ['self', 'https://checkout.stripe.com', '206878104.log.optimizely.com', 'https://api.stripe.com', 'https://pontoon.mozilla.org'], fontSrc: ['self', 'https://fonts.gstatic.com', 'https://maxcdn.bootstrapcdn.com', 'https://pontoon.mozilla.org'], frameSrc: ['https://js.stripe.com', 'https://checkout.stripe.com', 'https://pontoon.mozilla.org', - 'https://app.optimizely.com'], + 'https://app.optimizely.com'], imgSrc: ['self', 'https://www.google-analytics.com', 'https://q.stripe.com', 'https://pontoon.mozilla.org', 'https://*.shpg.org/', 'https://cdn.optimizely.com'], scriptSrc: ['self', 'unsafe-inline', 'unsafe-eval', 'https://cdn.optimizely.com', 'https://app.optimizely.com', diff --git a/src/components/amount-buttons.js b/src/components/amount-buttons.js index 8699e604..b4eea2bb 100644 --- a/src/components/amount-buttons.js +++ b/src/components/amount-buttons.js @@ -18,7 +18,7 @@ var AmountButton = React.createClass({ category: "User Flow", action: "Changed Amount", label: e.currentTarget.value - }); + }); }, render: function() { @@ -31,12 +31,12 @@ var AmountButton = React.createClass({ ); @@ -68,7 +68,7 @@ var AmountOtherButton = React.createClass({ category: "User Flow", action: "Changed Amount", label: "Other" - }); + }); }, onInputClick: function() { document.querySelector("#amount-other").click(); @@ -85,13 +85,16 @@ var AmountOtherButton = React.createClass({ var inputValue = e.currentTarget.value; var amount = ""; - if (/^[\d]*[\.]?\d{0,2}$/.test(inputValue)) { + // TODO: This needs to be refactored to use regex replace + // and needs documentation for what they are matching. + // See https://github.com/mozilla/donate.mozilla.org/issues/1917 + if (/^[\d]*[.]?\d{0,2}$/.test(inputValue)) { amount = inputValue.replace(/,/g, ""); } else if (/^[\d]*[,]?\d{0,2}$/.test(inputValue)) { amount = inputValue.replace(/\./g, "").replace(",", "."); - } else if (/^[\d,]*[\.]?\d{0,2}$/.test(inputValue)) { + } else if (/^[\d,]*[.]?\d{0,2}$/.test(inputValue)) { amount = inputValue.replace(/,/g, ""); - } else if (/^[\d\.]*[,]?\d{0,2}$/.test(inputValue)) { + } else if (/^[\d.]*[,]?\d{0,2}$/.test(inputValue)) { amount = inputValue.replace(/\./g, "").replace(",", "."); } else { inputValue = this.state.inputValue; @@ -182,12 +185,12 @@ var AmountButtons = React.createClass({ values={{minAmount: { this.props.currency.code ? - : "" } + : "" } }} /> @@ -240,18 +243,18 @@ var AmountButtons = React.createClass({ }); module.exports = connect( -function(state) { - return { - amount: state.donateForm.amount, - presets: state.donateForm.presets, - currency: state.donateForm.currency, - amountError: state.donateForm.amountError - }; -}, -function(dispatch) { - return { - setAmount: function(data) { - dispatch(setAmount(data)); - } - }; -})(AmountButtons); + function(state) { + return { + amount: state.donateForm.amount, + presets: state.donateForm.presets, + currency: state.donateForm.currency, + amountError: state.donateForm.amountError + }; + }, + function(dispatch) { + return { + setAmount: function(data) { + dispatch(setAmount(data)); + } + }; + })(AmountButtons); diff --git a/src/components/currency-dropdown.js b/src/components/currency-dropdown.js index d678590f..57349e07 100644 --- a/src/components/currency-dropdown.js +++ b/src/components/currency-dropdown.js @@ -32,15 +32,15 @@ var CurrencyDropdown = React.createClass({ }); module.exports = connect( -function(state) { - return { - currency: state.donateForm.currency - }; -}, -function(dispatch) { - return { - setCurrency: function(data) { - dispatch(setCurrency(data)); - } - }; -})(CurrencyDropdown); + function(state) { + return { + currency: state.donateForm.currency + }; + }, + function(dispatch) { + return { + setCurrency: function(data) { + dispatch(setCurrency(data)); + } + }; + })(CurrencyDropdown); diff --git a/src/components/donate-button.js b/src/components/donate-button.js index b763864f..b2ceff01 100644 --- a/src/components/donate-button.js +++ b/src/components/donate-button.js @@ -29,9 +29,9 @@ var DonateButton = React.createClass({ }); module.exports = connect( -function(state) { - return { - amount: state.donateForm.amount, - currency: state.donateForm.currency - }; -})(DonateButton); + function(state) { + return { + amount: state.donateForm.amount, + currency: state.donateForm.currency + }; + })(DonateButton); diff --git a/src/components/donation-frequency.js b/src/components/donation-frequency.js index 30f60c27..91283e07 100644 --- a/src/components/donation-frequency.js +++ b/src/components/donation-frequency.js @@ -45,15 +45,15 @@ var DonationFrequency = React.createClass({ }); module.exports = connect( -function(state) { - return { - frequency: state.donateForm.frequency - }; -}, -function(dispatch) { - return { - setFrequency: function(data) { - dispatch(setFrequency(data)); - } - }; -})(DonationFrequency); + function(state) { + return { + frequency: state.donateForm.frequency + }; + }, + function(dispatch) { + return { + setFrequency: function(data) { + dispatch(setFrequency(data)); + } + }; + })(DonationFrequency); diff --git a/src/components/email-input.js b/src/components/email-input.js index 4eb1669c..823ca845 100644 --- a/src/components/email-input.js +++ b/src/components/email-input.js @@ -33,18 +33,18 @@ var EmailInput = React.createClass({ }); module.exports = connect( -function(state) { - return { - email: state.signupForm.email, - emailError: state.signupForm.emailError - }; -}, -function(dispatch) { - return { - setEmail: function(data) { - dispatch(setEmail(data)); - } - }; -}, null, { - withRef: true -})(EmailInput); + function(state) { + return { + email: state.signupForm.email, + emailError: state.signupForm.emailError + }; + }, + function(dispatch) { + return { + setEmail: function(data) { + dispatch(setEmail(data)); + } + }; + }, null, { + withRef: true + })(EmailInput); diff --git a/src/components/privacy-checkbox.js b/src/components/privacy-checkbox.js index 4d9fbbb2..28d0f897 100644 --- a/src/components/privacy-checkbox.js +++ b/src/components/privacy-checkbox.js @@ -26,16 +26,16 @@ var PrivacyPolicyCheckbox = React.createClass({ }); module.exports = connect( -function(state) { - return { - privacyPolicy: state.signupForm.privacyPolicy, - privacyPolicyError: state.signupForm.privacyPolicyError - }; -}, -function(dispatch) { - return { - setPrivacyPolicy: function(data) { - dispatch(setPrivacyPolicy(data)); - } - }; -})(PrivacyPolicyCheckbox); + function(state) { + return { + privacyPolicy: state.signupForm.privacyPolicy, + privacyPolicyError: state.signupForm.privacyPolicyError + }; + }, + function(dispatch) { + return { + setPrivacyPolicy: function(data) { + dispatch(setPrivacyPolicy(data)); + } + }; + })(PrivacyPolicyCheckbox); diff --git a/src/components/signup.js b/src/components/signup.js index 1f4c08b3..f82969b1 100644 --- a/src/components/signup.js +++ b/src/components/signup.js @@ -74,19 +74,19 @@ var Signup = React.createClass({ }); module.exports = connect( -function(state) { - return { - email: state.signupForm.email, - privacyPolicy: state.signupForm.privacyPolicy - }; -}, -function(dispatch) { - return { - setEmailError: function(data) { - dispatch(setEmailError(data)); - }, - setPrivacyPolicyError: function(data) { - dispatch(setPrivacyPolicyError(data)); - } - }; -})(Signup); + function(state) { + return { + email: state.signupForm.email, + privacyPolicy: state.signupForm.privacyPolicy + }; + }, + function(dispatch) { + return { + setEmailError: function(data) { + dispatch(setEmailError(data)); + }, + setPrivacyPolicyError: function(data) { + dispatch(setPrivacyPolicyError(data)); + } + }; + })(Signup); diff --git a/src/components/single-form.js b/src/components/single-form.js index 1bb6bb34..9b816dee 100644 --- a/src/components/single-form.js +++ b/src/components/single-form.js @@ -157,17 +157,17 @@ var singleForm = React.createClass({ }); module.exports = connect( -function(state) { - return { - currency: state.donateForm.currency, - amount: state.donateForm.amount, - frequency: state.donateForm.frequency - }; -}, -function(dispatch) { - return { - setAmountError: function(data) { - dispatch(setAmountError(data)); - } - }; -})(singleForm); + function(state) { + return { + currency: state.donateForm.currency, + amount: state.donateForm.amount, + frequency: state.donateForm.frequency + }; + }, + function(dispatch) { + return { + setAmountError: function(data) { + dispatch(setAmountError(data)); + } + }; + })(singleForm); diff --git a/src/components/thunderbird/signup.js b/src/components/thunderbird/signup.js index cc180474..ad39ae6e 100644 --- a/src/components/thunderbird/signup.js +++ b/src/components/thunderbird/signup.js @@ -75,19 +75,19 @@ var Signup = React.createClass({ }); module.exports = connect( -function(state) { - return { - email: state.signupForm.email, - privacyPolicy: state.signupForm.privacyPolicy - }; -}, -function(dispatch) { - return { - setEmailError: function(data) { - dispatch(setEmailError(data)); - }, - setPrivacyPolicyError: function(data) { - dispatch(setPrivacyPolicyError(data)); - } - }; -})(Signup); + function(state) { + return { + email: state.signupForm.email, + privacyPolicy: state.signupForm.privacyPolicy + }; + }, + function(dispatch) { + return { + setEmailError: function(data) { + dispatch(setEmailError(data)); + }, + setPrivacyPolicyError: function(data) { + dispatch(setPrivacyPolicyError(data)); + } + }; + })(Signup); diff --git a/src/lib/analytics.js b/src/lib/analytics.js index 60ed4e48..3dbaf7dc 100644 --- a/src/lib/analytics.js +++ b/src/lib/analytics.js @@ -11,7 +11,7 @@ module.exports = function() { // Search for PayPal Params var pp_tx_re = /tx=(\w+)/; - var pp_amt_re = /amt=([\w\.]+)/; + var pp_amt_re = /amt=([\w.]+)/; var pp_cc_re = /cc=(\w+)/; var pp_frequency_re = /frequency=(\w+)/; if (pp_tx_re.test(queryString) && pp_amt_re.test(queryString) && pp_cc_re.test(queryString)) { @@ -31,7 +31,7 @@ module.exports = function() { // Search for Coinbase Params var cb_tx_re = /order\[transaction\]\[id\]=(\w+)/; - var cb_amt_re = /order\[total_native\]\[cents\]=([\w\.]+)/; + var cb_amt_re = /order\[total_native\]\[cents\]=([\w.]+)/; var cb_cc_re = /order\[total_payout\]\[currency_iso\]=(\w+)/; if (cb_tx_re.test(queryString) && cb_amt_re.test(queryString) && cb_cc_re.test(queryString)) { tx = queryString.match(cb_tx_re)[1]; @@ -42,7 +42,7 @@ module.exports = function() { // Search for Stripe Params var str_tx_re = /str_id=(\w+)/; - var str_amt_re = /str_amount=([\w\.]+)/; + var str_amt_re = /str_amount=([\w.]+)/; var str_cc_re = /str_currency=(\w+)/; var str_frequency_re = /str_frequency=(\w+)/; if (str_tx_re.test(queryString) && str_amt_re.test(queryString) && str_cc_re.test(queryString)) { diff --git a/src/pages/jan-thank-you.js b/src/pages/jan-thank-you.js index 281c2ace..bd451d03 100644 --- a/src/pages/jan-thank-you.js +++ b/src/pages/jan-thank-you.js @@ -58,11 +58,11 @@ var ThankYou = React.createClass({
diff --git a/src/pages/paypal-donate.js b/src/pages/paypal-donate.js index 4318b3eb..e6a4d609 100644 --- a/src/pages/paypal-donate.js +++ b/src/pages/paypal-donate.js @@ -151,17 +151,17 @@ var simplePaypal = React.createClass({ }); module.exports = connect( -function(state) { - return { - currency: state.donateForm.currency, - amount: state.donateForm.amount, - frequency: state.donateForm.frequency - }; -}, -function(dispatch) { - return { - setAmountError: function(data) { - dispatch(setAmountError(data)); - } - }; -})(simplePaypal); + function(state) { + return { + currency: state.donateForm.currency, + amount: state.donateForm.amount, + frequency: state.donateForm.frequency + }; + }, + function(dispatch) { + return { + setAmountError: function(data) { + dispatch(setAmountError(data)); + } + }; + })(simplePaypal); diff --git a/webpack.config.js b/webpack.config.js index a6f21622..5a5f0f9f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -19,8 +19,8 @@ module.exports = { loaders: [ { test: /\.json$/, loaders: ['json-loader'], exclude: ['node_modules'] }, { test: /\.less$/, loader: ExtractTextPlugin.extract( - 'css?sourceMap!less?sourceMap' - ), exclude: ['node_modules'] } + 'css?sourceMap!less?sourceMap' + ), exclude: ['node_modules'] } ], preLoaders: [ { test: /\.jsx$/, loaders: ['eslint-loader'], exclude: ['node_modules'] }