From 81d0edf71672dca20852acf3b00adf5bb777d7b4 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 16 Aug 2016 15:19:36 +0100 Subject: [PATCH 01/15] Improve error handling --- .../SubscriptionController.coffee | 45 ++++++++++++------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee index ca932ffab3..fbc72a277e 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee @@ -22,6 +22,7 @@ module.exports = SubscriptionController = viewName = "#{viewName}_#{req.query.v}" logger.log viewName:viewName, "showing plans page" GeoIpLookup.getCurrencyCode req.query?.ip || req.ip, (err, recomendedCurrency)-> + return next(err) if err? res.render viewName, title: "plans_and_pricing" plans: plans @@ -71,12 +72,13 @@ module.exports = SubscriptionController = AuthenticationController.getLoggedInUser req, (error, user) => return next(error) if error? LimitationsManager.userHasSubscriptionOrIsGroupMember user, (err, hasSubOrIsGroupMember, subscription)-> + return next(err) if err? groupLicenceInviteUrl = SubscriptionDomainHandler.getDomainLicencePage(user) if subscription?.customAccount logger.log user: user, "redirecting to custom account page" res.redirect "/user/subscription/custom_account" else if groupLicenceInviteUrl? and !hasSubOrIsGroupMember - logger.log user:user, "redirecting to group subscription invite page" + logger.log user:user, "redirecting to group subscription invite page" res.redirect groupLicenceInviteUrl else if !hasSubOrIsGroupMember logger.log user: user, "redirecting to plans" @@ -99,7 +101,9 @@ module.exports = SubscriptionController = userCustomSubscriptionPage: (req, res, next)-> AuthenticationController.getLoggedInUser req, (error, user) -> + return next(error) if error? LimitationsManager.userHasSubscriptionOrIsGroupMember user, (err, hasSubOrIsGroupMember, subscription)-> + return next(err) if err? if !subscription? err = new Error("subscription null for custom account, user:#{user?._id}") logger.warn err:err, "subscription is null for custom accounts page" @@ -113,6 +117,7 @@ module.exports = SubscriptionController = AuthenticationController.getLoggedInUser req, (error, user) -> return next(error) if error? LimitationsManager.userHasSubscription user, (err, hasSubscription)-> + return next(err) if err? if !hasSubscription res.redirect "/user/subscription" else @@ -142,23 +147,26 @@ module.exports = SubscriptionController = return res.sendStatus 500 res.sendStatus 201 - successful_subscription: (req, res)-> + successful_subscription: (req, res, next)-> AuthenticationController.getLoggedInUser req, (error, user) => + return next(error) if error? SubscriptionViewModelBuilder.buildUsersSubscriptionViewModel user, (error, subscription) -> + return next(error) if error? res.render "subscriptions/successful_subscription", title: "thank_you" subscription:subscription cancelSubscription: (req, res, next) -> AuthenticationController.getLoggedInUser req, (error, user) -> - logger.log user_id:user._id, "canceling subscription" return next(error) if error? + logger.log user_id:user._id, "canceling subscription" SubscriptionHandler.cancelSubscription user, (err)-> if err? logger.err err:err, user_id:user._id, "something went wrong canceling subscription" + return next(err) res.redirect "/user/subscription" - - updateSubscription: (req, res)-> + + updateSubscription: (req, res, next)-> AuthenticationController.getLoggedInUser req, (error, user) -> return next(error) if error? planCode = req.body.plan_code @@ -166,30 +174,35 @@ module.exports = SubscriptionController = SubscriptionHandler.updateSubscription user, planCode, null, (err)-> if err? logger.err err:err, user_id:user._id, "something went wrong updating subscription" + return next(err) res.redirect "/user/subscription" - reactivateSubscription: (req, res)-> + reactivateSubscription: (req, res, next)-> AuthenticationController.getLoggedInUser req, (error, user) -> - logger.log user_id:user._id, "reactivating subscription" return next(error) if error? + logger.log user_id:user._id, "reactivating subscription" SubscriptionHandler.reactivateSubscription user, (err)-> if err? logger.err err:err, user_id:user._id, "something went wrong reactivating subscription" + return next(err) res.redirect "/user/subscription" - recurlyCallback: (req, res)-> + recurlyCallback: (req, res, next)-> logger.log data: req.body, "received recurly callback" # we only care if a subscription has exipired if req.body? and req.body["expired_subscription_notification"]? recurlySubscription = req.body["expired_subscription_notification"].subscription - SubscriptionHandler.recurlyCallback recurlySubscription, -> + SubscriptionHandler.recurlyCallback recurlySubscription, (err)-> + return next(err) if err? res.sendStatus 200 else res.sendStatus 200 - renderUpgradeToAnnualPlanPage: (req, res)-> + renderUpgradeToAnnualPlanPage: (req, res, next)-> AuthenticationController.getLoggedInUser req, (error, user) -> + return next(error) if error? LimitationsManager.userHasSubscription user, (err, hasSubscription, subscription)-> + return next(err) if err? planCode = subscription?.planCode.toLowerCase() if planCode?.indexOf("annual") != -1 planName = "annual" @@ -204,8 +217,9 @@ module.exports = SubscriptionController = title: "Upgrade to annual" planName: planName - processUpgradeToAnnualPlan: (req, res)-> + processUpgradeToAnnualPlan: (req, res, next)-> AuthenticationController.getLoggedInUser req, (error, user) -> + return next(error) if error? {planName} = req.body coupon_code = Settings.coupon_codes.upgradeToAnnualPromo[planName] annualPlanName = "#{planName}-annual" @@ -213,13 +227,14 @@ module.exports = SubscriptionController = SubscriptionHandler.updateSubscription user, annualPlanName, coupon_code, (err)-> if err? logger.err err:err, user_id:user._id, "error updating subscription" - res.sendStatus 500 - else - res.sendStatus 200 + return next(err) + res.sendStatus 200 - extendTrial: (req, res)-> + extendTrial: (req, res, next)-> AuthenticationController.getLoggedInUser req, (error, user) -> + return next(error) if error? LimitationsManager.userHasSubscription user, (err, hasSubscription, subscription)-> + return next(err) if err? SubscriptionHandler.extendTrial subscription, 14, (err)-> if err? res.send 500 From fc068b62a26a67f1255b9181f604c340502a689b Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 17 Aug 2016 08:51:35 +0100 Subject: [PATCH 02/15] defend against undefined plan_code --- .../Features/Subscription/SubscriptionController.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee index fbc72a277e..d4521981e4 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee @@ -170,6 +170,10 @@ module.exports = SubscriptionController = AuthenticationController.getLoggedInUser req, (error, user) -> return next(error) if error? planCode = req.body.plan_code + if !planCode? + err = new Error('plan_code not defined') + logger.err {user_id: user._id, err}, "error updating subscription" + return next(err) logger.log planCode: planCode, user_id:user._id, "updating subscription" SubscriptionHandler.updateSubscription user, planCode, null, (err)-> if err? From 090f10e3be90555a5a770a43566b88547191f4d1 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Thu, 18 Aug 2016 09:47:57 +0100 Subject: [PATCH 03/15] add log hints for new chktex messages --- .../HumanReadableLogsRules.coffee | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee index c61c61506b..7d31bf3f43 100644 --- a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee +++ b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee @@ -102,5 +102,22 @@ define -> [ humanReadableHint: """ You have used an open bracket without a corresponding close bracket. """ - + , ruleId: "hint_mismatched_environment2" + regexToMatch: /Error: `\\end\{([^\}]+)\})' expected but found `\\end\{([^\}]+)\}'.*/ + newMessage: "Error: environment does not match \\begin{$1} ... \\end{$2}" + humanReadableHint: """ + You have used \\begin{...} without a corresponding \\end{...}. + """ + , ruleId: "hint_mismatched_environment3" + regexToMatch: /Error: No matching \\end found for `\\begin\{([^\}]+)\}'.*/ + newMessage: "Error: No matching \\end found for \\begin{$1}" + humanReadableHint: """ + You have used \\begin{...} without a corresponding \\end{...}. + """ + , ruleId: "hint_mismatched_environment3" + regexToMatch: /Error: Found `\\end\{([^\}]+)\}' without corresponding \\begin.*/ + newMessage: "Error: Found \\end{$1} without a corresponding \\begin{$1}" + humanReadableHint: """ + You have used \\begin{...} without a corresponding \\end{...}. + """ ] From 109e79db9930ba32e8a7f86a4da9483380ed8f87 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Thu, 18 Aug 2016 13:21:27 +0100 Subject: [PATCH 04/15] track cascading errors in Human Readable Log Hints --- .../human-readable-logs/HumanReadableLogs.coffee | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogs.coffee b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogs.coffee index e59e35a40c..61cc1b7df7 100644 --- a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogs.coffee +++ b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogs.coffee @@ -11,6 +11,8 @@ define [ _getRule = (logMessage) -> return rule for rule in ruleset when rule.regexToMatch.test logMessage + seenErrorTypes = {} # keep track of types of errors seen + for entry in parsedLogEntries.all ruleDetails = _getRule entry.message @@ -21,8 +23,20 @@ define [ entry.ruleId = 'hint_' + ruleDetails.regexToMatch.toString().replace(/\s/g, '_').slice(1, -1) if ruleDetails.newMessage? entry.message = entry.message.replace ruleDetails.regexToMatch, ruleDetails.newMessage + # suppress any entries that are known to cascade from previous error types + if ruleDetails.cascadesFrom? + for type in ruleDetails.cascadesFrom + entry.suppressed = true if seenErrorTypes[type] + # record the types of errors seen + if ruleDetails.types? + for type in ruleDetails.types + seenErrorTypes[type] = true entry.humanReadableHint = ruleDetails.humanReadableHint if ruleDetails.humanReadableHint? entry.extraInfoURL = ruleDetails.extraInfoURL if ruleDetails.extraInfoURL? - + + # filter out the suppressed errors (from the array entries in parsedLogEntries) + for key, errors of parsedLogEntries when typeof errors is 'object' and errors.length > 0 + parsedLogEntries[key] = (err for err in errors when not err.suppressed) + return parsedLogEntries From 133250c15092be0ca8c4935a950530a299c2bb60 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Thu, 18 Aug 2016 13:28:47 +0100 Subject: [PATCH 05/15] extend log hints for more chktex errors --- .../HumanReadableLogsRules.coffee | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee index 7d31bf3f43..9436d0705d 100644 --- a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee +++ b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee @@ -90,6 +90,7 @@ define -> [ """ , ruleId: "hint_mismatched_environment" + types: ['environment'] regexToMatch: /Error: `([^']{2,})' expected, found `([^']{2,})'.*/ newMessage: "Error: environment does not match \\begin{$1} ... \\end{$2}" humanReadableHint: """ @@ -97,27 +98,35 @@ define -> [ """ , ruleId: "hint_mismatched_brackets" + types: ['environment'] regexToMatch: /Error: `([^a-zA-Z0-9])' expected, found `([^a-zA-Z0-9])'.*/ newMessage: "Error: brackets do not match, found '$2' instead of '$1'" humanReadableHint: """ You have used an open bracket without a corresponding close bracket. """ - , ruleId: "hint_mismatched_environment2" - regexToMatch: /Error: `\\end\{([^\}]+)\})' expected but found `\\end\{([^\}]+)\}'.*/ - newMessage: "Error: environment does not match \\begin{$1} ... \\end{$2}" + , + ruleId: "hint_mismatched_environment2" + types: ['environment'] + regexToMatch: /Error: `\\end\{([^\}]+)\}' expected but found `\\end\{([^\}]+)\}'.*/ + newMessage: "Error: environments do not match: \\begin{$1} ... \\end{$2}" humanReadableHint: """ - You have used \\begin{...} without a corresponding \\end{...}. + You have used \\begin{} without a corresponding \\end{}. """ - , ruleId: "hint_mismatched_environment3" - regexToMatch: /Error: No matching \\end found for `\\begin\{([^\}]+)\}'.*/ - newMessage: "Error: No matching \\end found for \\begin{$1}" + , + ruleId: "hint_mismatched_environment3" + types: ['environment'] + regexToMatch: /Warning: No matching \\end found for `\\begin\{([^\}]+)\}'.*/ + newMessage: "Warning: No matching \\end found for \\begin{$1}" humanReadableHint: """ - You have used \\begin{...} without a corresponding \\end{...}. + You have used \\begin{} without a corresponding \\end{}. """ - , ruleId: "hint_mismatched_environment3" - regexToMatch: /Error: Found `\\end\{([^\}]+)\}' without corresponding \\begin.*/ - newMessage: "Error: Found \\end{$1} without a corresponding \\begin{$1}" + , + ruleId: "hint_mismatched_environment4" + types: ['environment'] + cascadesFrom: ['environment'] + regexToMatch: /Error: Found `\\end\{([^\}]+)\}' without corresponding \\begin.*/ + newMessage: "Error: found \\end{$1} without a corresponding \\begin{$1}" humanReadableHint: """ - You have used \\begin{...} without a corresponding \\end{...}. + You have used \\begin{} without a corresponding \\end{}. """ ] From 07cd75cd64cf9b8973adb3e48ec45d48386ac55f Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 19 Aug 2016 11:52:04 +0100 Subject: [PATCH 06/15] Add an `expect404` option to apiRequest. Suppress error generation when 404 response is encountered. --- .../Features/Subscription/RecurlyWrapper.coffee | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/services/web/app/coffee/Features/Subscription/RecurlyWrapper.coffee b/services/web/app/coffee/Features/Subscription/RecurlyWrapper.coffee index 059c5fb02c..2be1fc35c7 100644 --- a/services/web/app/coffee/Features/Subscription/RecurlyWrapper.coffee +++ b/services/web/app/coffee/Features/Subscription/RecurlyWrapper.coffee @@ -29,13 +29,15 @@ module.exports = RecurlyWrapper = RecurlyWrapper.apiRequest({ url: "accounts/#{user._id}" method: "GET" + expect404: true }, (error, response, responseBody) -> if error - if response.statusCode == 404 # actually not an error in this case, just no existing account - cache.userExists = false - return next(null, cache) logger.error {error, user_id: user._id, recurly_token_id}, "error response from recurly while checking account" return next(error) + if response.statusCode == 404 # actually not an error in this case, just no existing account + logger.log {user_id: user._id, recurly_token_id}, "user does not currently exist in recurly, proceed" + cache.userExists = false + return next(null, cache) logger.log {user_id: user._id, recurly_token_id}, "user appears to exist in recurly" RecurlyWrapper._parseAccountXml responseBody, (err, account) -> if err @@ -236,10 +238,14 @@ module.exports = RecurlyWrapper = "Authorization" : "Basic " + new Buffer(Settings.apis.recurly.apiKey).toString("base64") "Accept" : "application/xml" "Content-Type" : "application/xml; charset=utf-8" + expect404 = options.expect404 + delete options.expect404 request options, (error, response, body) -> - unless error? or response.statusCode == 200 or response.statusCode == 201 or response.statusCode == 204 + unless error? or response.statusCode == 200 or response.statusCode == 201 or response.statusCode == 204 or (response.statusCode == 404 and expect404) logger.err err:error, body:body, options:options, statusCode:response?.statusCode, "error returned from recurly" error = "Recurly API returned with status code: #{response.statusCode}" + if response.statusCode == 404 and expect404 + logger.log {url: options.url, method: options.method}, "got 404 response from recurly, expected as valid response" callback(error, response, body) sign : (parameters, callback) -> From c02854c9d8fc2852b654d9734f6b6c950c27e48a Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 19 Aug 2016 11:52:50 +0100 Subject: [PATCH 07/15] Improve log messages --- .../Features/Subscription/SubscriptionController.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee index d4521981e4..8b36e28e1d 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee @@ -171,8 +171,8 @@ module.exports = SubscriptionController = return next(error) if error? planCode = req.body.plan_code if !planCode? - err = new Error('plan_code not defined') - logger.err {user_id: user._id, err}, "error updating subscription" + err = new Error('plan_code is not defined') + logger.err {user_id: user._id, err, planCode}, "[Subscription] error in updateSubscription form" return next(err) logger.log planCode: planCode, user_id:user._id, "updating subscription" SubscriptionHandler.updateSubscription user, planCode, null, (err)-> From a904427531b2ab16b9f8b428792bdf04bd221203 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 19 Aug 2016 11:57:44 +0100 Subject: [PATCH 08/15] Fix broken test --- .../UnitTests/coffee/Subscription/RecurlyWrapperTests.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/test/UnitTests/coffee/Subscription/RecurlyWrapperTests.coffee b/services/web/test/UnitTests/coffee/Subscription/RecurlyWrapperTests.coffee index 5a5e9fc40c..eda02ccf72 100644 --- a/services/web/test/UnitTests/coffee/Subscription/RecurlyWrapperTests.coffee +++ b/services/web/test/UnitTests/coffee/Subscription/RecurlyWrapperTests.coffee @@ -728,7 +728,7 @@ describe "RecurlyWrapper", -> describe 'when the account does not exist', -> beforeEach -> - @apiRequest.callsArgWith(1, new Error('not found'), {statusCode: 404}, '') + @apiRequest.callsArgWith(1, null, {statusCode: 404}, '') it 'should not produce an error', (done) -> @call (err, result) => From 03aa9b87f14115f0355156d92b5855601c11ddb5 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Mon, 22 Aug 2016 10:09:54 +0100 Subject: [PATCH 09/15] Add debug query string `origin` to invocations of the updateSubscription endpoint. --- .../Features/Subscription/SubscriptionController.coffee | 3 ++- .../web/app/views/subscriptions/edit-billing-details.jade | 2 +- .../web/public/coffee/main/subscription-dashboard.coffee | 5 ++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee index 8b36e28e1d..3d2ba910d0 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee @@ -167,12 +167,13 @@ module.exports = SubscriptionController = res.redirect "/user/subscription" updateSubscription: (req, res, next)-> + _origin = req?.query?.origin || null AuthenticationController.getLoggedInUser req, (error, user) -> return next(error) if error? planCode = req.body.plan_code if !planCode? err = new Error('plan_code is not defined') - logger.err {user_id: user._id, err, planCode}, "[Subscription] error in updateSubscription form" + logger.err {user_id: user._id, err, planCode, origin: _origin, body: req.body}, "[Subscription] error in updateSubscription form" return next(err) logger.log planCode: planCode, user_id:user._id, "updating subscription" SubscriptionHandler.updateSubscription user, planCode, null, (err)-> diff --git a/services/web/app/views/subscriptions/edit-billing-details.jade b/services/web/app/views/subscriptions/edit-billing-details.jade index f0b6671bcd..caf204b79d 100644 --- a/services/web/app/views/subscriptions/edit-billing-details.jade +++ b/services/web/app/views/subscriptions/edit-billing-details.jade @@ -19,7 +19,7 @@ block content Recurly.config(!{recurlyConfig}) Recurly.buildBillingInfoUpdateForm({ target : "#billingDetailsForm", - successURL : "#{successURL}?_csrf=#{csrfToken}", + successURL : "#{successURL}?_csrf=#{csrfToken}&origin=editBillingDetails", signature : "!{signature}", accountCode : "#{user.id}" }); diff --git a/services/web/public/coffee/main/subscription-dashboard.coffee b/services/web/public/coffee/main/subscription-dashboard.coffee index 63eec0d65a..69d030ed3b 100644 --- a/services/web/public/coffee/main/subscription-dashboard.coffee +++ b/services/web/public/coffee/main/subscription-dashboard.coffee @@ -62,8 +62,7 @@ define [ $scope.inflight = true - - $http.post(SUBSCRIPTION_URL, body) + $http.post("#{SUBSCRIPTION_URL}?origin=confirmChangePlan", body) .success -> location.reload() .error -> @@ -124,7 +123,7 @@ define [ plan_code: 'student' _csrf : window.csrfToken $scope.inflight = true - $http.post(SUBSCRIPTION_URL, body) + $http.post("#{SUBSCRIPTION_URL}?origin=downgradeToStudent", body) .success -> location.reload() .error -> From a9095ccde8dff48dd090a1bf9f1096a9d7919c6f Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Mon, 22 Aug 2016 14:54:07 +0100 Subject: [PATCH 10/15] Disable filter which wraps long words, still buggy. --- services/web/app/views/project/editor/chat.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/app/views/project/editor/chat.jade b/services/web/app/views/project/editor/chat.jade index 86842c36de..538a5b9d37 100644 --- a/services/web/app/views/project/editor/chat.jade +++ b/services/web/app/views/project/editor/chat.jade @@ -45,7 +45,7 @@ aside.chat( mathjax, ng-repeat="content in message.contents track by $index" ) - span(ng-bind-html="content | linky:'_blank' | wrapLongWords") + span(ng-bind-html="content | linky:'_blank'") .new-message textarea( From 2f93a102fde5a0eca893003aca0115c14f569e55 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Mon, 22 Aug 2016 16:12:29 +0100 Subject: [PATCH 11/15] Fix layout to support scrollable messages. --- services/web/app/views/project/editor/chat.jade | 11 ++++++----- services/web/public/stylesheets/app/editor/chat.less | 10 ++++++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/services/web/app/views/project/editor/chat.jade b/services/web/app/views/project/editor/chat.jade index 538a5b9d37..47a1752834 100644 --- a/services/web/app/views/project/editor/chat.jade +++ b/services/web/app/views/project/editor/chat.jade @@ -41,11 +41,12 @@ aside.chat( }" ) .arrow(ng-style="{'border-color': 'hsl({{ hue(message.user) }}, 70%, 70%)'}") - p( - mathjax, - ng-repeat="content in message.contents track by $index" - ) - span(ng-bind-html="content | linky:'_blank'") + .message-content + p( + mathjax, + ng-repeat="content in message.contents track by $index" + ) + span(ng-bind-html="content | linky:'_blank'") .new-message textarea( diff --git a/services/web/public/stylesheets/app/editor/chat.less b/services/web/public/stylesheets/app/editor/chat.less index 592d39ecf4..0a35fdc1c2 100644 --- a/services/web/public/stylesheets/app/editor/chat.less +++ b/services/web/public/stylesheets/app/editor/chat.less @@ -47,6 +47,7 @@ } .message-wrapper { margin-left: 50px + @line-height-computed/2; + .name { font-size: 12px; color: @gray-light; @@ -54,12 +55,17 @@ min-height: 16px; } .message { - padding: @line-height-computed / 2; border-left: 3px solid transparent; - position: relative; font-size: 14px; box-shadow: -1px 2px 3px #ddd; border-raduis: @border-radius-base; + position: relative; + + .message-content { + padding: @line-height-computed / 2; + overflow-x: scroll; + } + .arrow { right: 100%; top: @line-height-computed / 4; From 861022aff06eb8854370e619c6f7217afa53766d Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Mon, 22 Aug 2016 16:32:59 +0100 Subject: [PATCH 12/15] Make scrollbar only visible when needed. --- services/web/public/stylesheets/app/editor/chat.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/public/stylesheets/app/editor/chat.less b/services/web/public/stylesheets/app/editor/chat.less index 0a35fdc1c2..d702a225fe 100644 --- a/services/web/public/stylesheets/app/editor/chat.less +++ b/services/web/public/stylesheets/app/editor/chat.less @@ -63,7 +63,7 @@ .message-content { padding: @line-height-computed / 2; - overflow-x: scroll; + overflow-x: auto; } .arrow { From 290b1ad13443c94e94803c11200c0481e5c525c3 Mon Sep 17 00:00:00 2001 From: MCribbin Date: Mon, 22 Aug 2016 16:33:07 +0100 Subject: [PATCH 13/15] Update HumanReadableLogsRules.coffee Added corrections to new hints: -Double subscript -Double superscript -LaTeX Error: Something's wrong--perhaps a missing \item -Misplaced \noalign --- .../HumanReadableLogsRules.coffee | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee index c61c61506b..6882d2814d 100644 --- a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee +++ b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee @@ -102,5 +102,52 @@ define -> [ humanReadableHint: """ You have used an open bracket without a corresponding close bracket. """ - + , + regexToMatch: /LaTeX Error: Can be used only in preamble/ + extraInfoURL: "https://www.sharelatex.com/learn/Errors/LaTeX_Error:_Can_be_used_only_in_preamble" + humanReadableHint: """ + You have used a command in the main body of your document which should be used in the preamble. Make sure that \\documentclass[\u2026]{\u2026} and all \\usepackage{\u2026} commands are written before \\begin{document}. + """ + , + regexToMatch: /Missing \\right inserted/ + extraInfoURL: "https://www.sharelatex.com/learn/Errors/Missing_%5Cright_insertede" + humanReadableHint: """ + You have started an expression with a \\left command, but have not included a corresponding \\right command. Make sure that your \\left and \\right commands balance everywhere, or else try using \\Biggl and \\Biggr commands instead as shown here. + """ + , + regexToMatch: /Double superscript/ + extraInfoURL: "https://www.sharelatex.com/learn/Errors/Double_superscript" + humanReadableHint: """ + You have written a double superscript incorrectly as a^b^c, or else you have written a prime with a superscript. Remember to include { and } when using multiple superscripts. Try a^{b^c} instead. + """ + , + regexToMatch: /Double subscript/ + extraInfoURL: "https://www.sharelatex.com/learn/Errors/Double_subscript" + humanReadableHint: """ + You have written a double subscript incorrectly as a_b_c. Remember to include { and } when using multiple subscripts. Try a_{b_c} instead. + """ + , + regexToMatch: /No \\author given/ + extraInfoURL: "https://www.sharelatex.com/learn/Errors/No_%5Cauthor_given" + humanReadableHint: """ + You have used the \\maketitle command, but have not specified any \\author. To fix this, include an author in your preamble using the \\author{\u2026} command. + """ + , + regexToMatch: /LaTeX Error: Environment .+ undefined/ + extraInfoURL: "https://www.sharelatex.com/learn/Errors%2FLaTeX%20Error%3A%20Environment%20XXX%20undefined" + humanReadableHint: """ + You have created an environment (using \\begin{\u2026} and \\end{\u2026} commands) which is not recognized. Make sure you have included the required package for that environment in your preamble, and that the environment is spelled correctly. + """ + , + regexToMatch: /LaTeX Error: Something's wrong--perhaps a missing \\item/ + extraInfoURL: "https://www.sharelatex.com/learn/Errors/LaTeX_Error:_Something%27s_wrong--perhaps_a_missing_%5Citem" + humanReadableHint: """ + There are no entries found in a list you have created. Make sure you label list entries using the \\item command, and that you have not used a list inside a table. + """ + , + regexToMatch: /Misplaced \\noalign/ + extraInfoURL: "https://www.sharelatex.com/learn/Errors/Misplaced_%5Cnoalign" + humanReadableHint: """ + You have used a \\hline command in the wrong place, probably outside a table. If the \\hline command is written inside a table, try including \\\ before it. + """ ] From bcc8bfbe6cbfb598c1b982cc6b1fa9bbb90405a2 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 22 Aug 2016 17:36:33 +0100 Subject: [PATCH 14/15] Redirect to working update billing details end point that shows a nice message --- .../Features/Subscription/SubscriptionController.coffee | 7 +++++-- .../coffee/Features/Subscription/SubscriptionRouter.coffee | 1 + services/web/app/views/subscriptions/dashboard.jade | 5 +++++ .../coffee/Subscription/SubscriptionControllerTests.coffee | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee index 3d2ba910d0..943c78f62d 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee @@ -97,7 +97,7 @@ module.exports = SubscriptionController = groupSubscriptions: groupSubscriptions subscriptionTabActive: true user:user - + saved_billing_details: req.query.saved_billing_details? userCustomSubscriptionPage: (req, res, next)-> AuthenticationController.getLoggedInUser req, (error, user) -> @@ -131,9 +131,12 @@ module.exports = SubscriptionController = currency: "USD" subdomain: Settings.apis.recurly.subdomain signature : signature - successURL : "#{Settings.siteUrl}/user/subscription/update" + successURL : "#{Settings.siteUrl}/user/subscription/billing-details/update" user : id : user._id + + updateBillingDetails: (req, res, next) -> + res.redirect "/user/subscription?saved_billing_details=true" createSubscription: (req, res, next)-> AuthenticationController.getLoggedInUser req, (error, user) -> diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionRouter.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionRouter.coffee index f2d66c30c5..62d4d306ab 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionRouter.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionRouter.coffee @@ -16,6 +16,7 @@ module.exports = webRouter.get '/user/subscription/new', AuthenticationController.requireLogin(), SubscriptionController.paymentPage webRouter.get '/user/subscription/billing-details/edit', AuthenticationController.requireLogin(), SubscriptionController.editBillingDetailsPage + webRouter.post '/user/subscription/billing-details/update', AuthenticationController.requireLogin(), SubscriptionController.updateBillingDetails webRouter.get '/user/subscription/thank-you', AuthenticationController.requireLogin(), SubscriptionController.successful_subscription diff --git a/services/web/app/views/subscriptions/dashboard.jade b/services/web/app/views/subscriptions/dashboard.jade index 9b9464419e..34493e5a8c 100644 --- a/services/web/app/views/subscriptions/dashboard.jade +++ b/services/web/app/views/subscriptions/dashboard.jade @@ -40,6 +40,11 @@ block content .container(ng-controller="UserSubscriptionController") .row .col-md-8.col-md-offset-2 + if saved_billing_details + .alert.alert-success + i.fa.fa-check + |   + | #{translate("your_billing_details_were_saved")} .card(ng-if="view == 'overview'") .page-header h1 #{translate("your_subscription")} diff --git a/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee b/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee index 27e9e571d1..db5e4e8c1c 100644 --- a/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee @@ -109,7 +109,7 @@ describe "SubscriptionController sanboxed", -> it "should set the correct variables for the template", -> should.exist @res.renderedVariables.signature - @res.renderedVariables.successURL.should.equal "#{@settings.siteUrl}/user/subscription/update" + @res.renderedVariables.successURL.should.equal "#{@settings.siteUrl}/user/subscription/billing-details/update" @res.renderedVariables.user.id.should.equal @user._id describe "with a user without subscription", -> From 4b50505ec9ddd9e640205db6a11321c23b2f871e Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Tue, 23 Aug 2016 11:27:27 +0100 Subject: [PATCH 15/15] suppress all cascading chktex environment errors --- .../ide/human-readable-logs/HumanReadableLogsRules.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee index ffd46fb0c7..164e78ce66 100644 --- a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee +++ b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee @@ -155,6 +155,7 @@ define -> [ , ruleId: "hint_mismatched_environment2" types: ['environment'] + cascadesFrom: ['environment'] regexToMatch: /Error: `\\end\{([^\}]+)\}' expected but found `\\end\{([^\}]+)\}'.*/ newMessage: "Error: environments do not match: \\begin{$1} ... \\end{$2}" humanReadableHint: """ @@ -163,6 +164,7 @@ define -> [ , ruleId: "hint_mismatched_environment3" types: ['environment'] + cascadesFrom: ['environment'] regexToMatch: /Warning: No matching \\end found for `\\begin\{([^\}]+)\}'.*/ newMessage: "Warning: No matching \\end found for \\begin{$1}" humanReadableHint: """