From 1e74f9a862915f5bde9d9a9e45d5b82bc2127ead Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 25 Mar 2014 13:15:59 +0000 Subject: [PATCH 01/62] rename dropdown -> dropbox --- .../web/public/coffee/settings/DropboxSettingsManager.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/web/public/coffee/settings/DropboxSettingsManager.coffee b/services/web/public/coffee/settings/DropboxSettingsManager.coffee index 1f5953835f..b4fd801bd3 100644 --- a/services/web/public/coffee/settings/DropboxSettingsManager.coffee +++ b/services/web/public/coffee/settings/DropboxSettingsManager.coffee @@ -17,11 +17,11 @@ define [ @tab.empty() if !@ide.isAllowedToDoIt "owner" else if !@project.get('features').dropbox - ga('send', 'event', 'subscription-funnel', 'askToUpgrade', "dropdown") + ga('send', 'event', 'subscription-funnel', 'askToUpgrade', "dropbox") accountManager.askToUpgrade @ide, onUpgrade: => @checkIfUserIsLinkedToDropbox() - ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "dropdown") + ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "dropbox") else @checkIfUserIsLinkedToDropbox() From 116458671c60e57f5c345c1395f9890b837452b3 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 25 Mar 2014 14:39:51 +0000 Subject: [PATCH 02/62] callback is not defined, use next when there is an error in controller --- .../app/coffee/controllers/UserController.coffee | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/services/web/app/coffee/controllers/UserController.coffee b/services/web/app/coffee/controllers/UserController.coffee index a373e14043..dd066bfc4a 100644 --- a/services/web/app/coffee/controllers/UserController.coffee +++ b/services/web/app/coffee/controllers/UserController.coffee @@ -171,7 +171,7 @@ module.exports = metrics.inc "user.password-change" oldPass = req.body.currentPassword AuthenticationManager.authenticate _id: req.session.user._id, oldPass, (err, user)-> - return callback(err) if err? + return next(err) if err? if(user) logger.log user: req.session.user, "changing password" newPassword1 = req.body.newPassword1 @@ -197,23 +197,23 @@ module.exports = type:'error' text:'Your old password is wrong' - redirectUserToDropboxAuth: (req, res)-> + redirectUserToDropboxAuth: (req, res, next)-> user_id = req.session.user._id dropboxHandler.getDropboxRegisterUrl user_id, (err, url)-> - return callback(err) if err? + return next(err) if err? logger.log url:url, "redirecting user for dropbox auth" res.redirect url - completeDropboxRegistration: (req, res)-> + completeDropboxRegistration: (req, res, next)-> user_id = req.session.user._id dropboxHandler.completeRegistration user_id, (err, success)-> - return callback(err) if err? + return next(err) if err? res.redirect('/user/settings#dropboxSettings') - unlinkDropbox: (req, res)-> + unlinkDropbox: (req, res, next)-> user_id = req.session.user._id dropboxHandler.unlinkAccount user_id, (err, success)-> - return callback(err) if err? + return next(err) if err? res.redirect('/user/settings#dropboxSettings') deleteUser: (req, res)-> From ba1371744b7275e7966eebc9ce140c001fd4f4e8 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 25 Mar 2014 16:19:30 +0000 Subject: [PATCH 03/62] deal with users who may have been deleted but are still inside a subscription group --- .../Subscription/SubscriptionGroupHandler.coffee | 3 +++ .../SubscriptionGroupHandlerTests.coffee | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionGroupHandler.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionGroupHandler.coffee index a93286f73c..a4907f9544 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionGroupHandler.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionGroupHandler.coffee @@ -28,6 +28,9 @@ module.exports = jobs = _.map subscription.member_ids, (user_id)-> return (cb)-> UserLocator.findById user_id, (err, user)-> + if err? or !user? + users.push _id:user_id + return cb() userViewModel = buildUserViewModel(user) users.push(userViewModel) cb() diff --git a/services/web/test/UnitTests/coffee/Subscription/SubscriptionGroupHandlerTests.coffee b/services/web/test/UnitTests/coffee/Subscription/SubscriptionGroupHandlerTests.coffee index f3cb94af75..b9cff7ef72 100644 --- a/services/web/test/UnitTests/coffee/Subscription/SubscriptionGroupHandlerTests.coffee +++ b/services/web/test/UnitTests/coffee/Subscription/SubscriptionGroupHandlerTests.coffee @@ -76,11 +76,13 @@ describe "Subscription Group Handler", -> @UserLocator.findById.callsArgWith(1, null, {_id:"31232"}) it "should locate the subscription", (done)-> + @UserLocator.findById.callsArgWith(1, null, {_id:"31232"}) @Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=> @SubscriptionLocator.getUsersSubscription.calledWith(@adminUser_id).should.equal true done() it "should get the users by id", (done)-> + @UserLocator.findById.callsArgWith(1, null, {_id:"31232"}) @subscription.member_ids = ["1234", "342432", "312312"] @Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=> @UserLocator.findById.calledWith(@subscription.member_ids[0]).should.equal true @@ -88,3 +90,13 @@ describe "Subscription Group Handler", -> @UserLocator.findById.calledWith(@subscription.member_ids[2]).should.equal true users.length.should.equal @subscription.member_ids.length done() + + it "should just return the id if the user can not be found as they may have deleted their account", (done)-> + @UserLocator.findById.callsArgWith(1) + @subscription.member_ids = ["1234", "342432", "312312"] + @Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=> + assert.deepEqual users[0], {_id:@subscription.member_ids[0]} + assert.deepEqual users[1], {_id:@subscription.member_ids[1]} + assert.deepEqual users[2], {_id:@subscription.member_ids[2]} + done() + From c273f36bb088d6564726888f06f76ba816d71023 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 24 Mar 2014 17:31:37 +0000 Subject: [PATCH 04/62] Order errors by severity. error -> warning -> typsetting --- services/web/public/coffee/pdf/CompiledView.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/public/coffee/pdf/CompiledView.coffee b/services/web/public/coffee/pdf/CompiledView.coffee index cae6cbb948..9c3684aa18 100644 --- a/services/web/public/coffee/pdf/CompiledView.coffee +++ b/services/web/public/coffee/pdf/CompiledView.coffee @@ -90,7 +90,7 @@ define [ logButtonHtml = "Logs" if compileErrors? - for error in compileErrors.all + for error in compileErrors.errors.concat(compileErrors.warnings).concat(compileErrors.typesetting) errorView = new LatexErrorView(@options.manager.ide, error) errorView.render() @errorViews.push(errorView) From a434243bd2c52b79533acb9c089aedbb7f1a9340 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 25 Mar 2014 13:11:32 +0000 Subject: [PATCH 05/62] Fix slight history range glitch --- services/web/public/stylesheets/less/trackchanges.less | 1 + 1 file changed, 1 insertion(+) diff --git a/services/web/public/stylesheets/less/trackchanges.less b/services/web/public/stylesheets/less/trackchanges.less index b27a81802d..e569b3e935 100644 --- a/services/web/public/stylesheets/less/trackchanges.less +++ b/services/web/public/stylesheets/less/trackchanges.less @@ -256,6 +256,7 @@ li.hover-selected { .change-selectors { .range { + top: 0; background-color: #999; } } From fe99be48acbd5f62ba4f16b8f6eb480d235f4e6e Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 25 Mar 2014 13:31:53 +0000 Subject: [PATCH 06/62] Add upgrade message to history for free users --- services/web/app/views/templates.jade | 4 ++++ .../coffee/track-changes/ChangeListView.coffee | 3 +++ .../track-changes/TrackChangesManager.coffee | 16 +++++++++++++--- .../public/stylesheets/less/trackchanges.less | 9 +++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index cb582e7c42..d8c4000e31 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -463,6 +463,10 @@ ul.change-list.nav.nav-pills.nav-stacked li.loading-changes Loading... li.empty-message You haven't made any changes yet! + li.upgrade-message + p We only store one week of changes for free accounts. Upgrade for an unlimited history. + p + button.btn.btn-primary.upgrade Upgrade script(type='text/template')#hotKeysListTemplate .hotkeys diff --git a/services/web/public/coffee/track-changes/ChangeListView.coffee b/services/web/public/coffee/track-changes/ChangeListView.coffee index 80a0fb0915..373f091360 100644 --- a/services/web/public/coffee/track-changes/ChangeListView.coffee +++ b/services/web/public/coffee/track-changes/ChangeListView.coffee @@ -17,6 +17,7 @@ define [ events: "scroll" : () -> @loadUntilFull() + "click button.upgrade": () -> @trigger "upgrade" initialize: () -> @itemViews = [] @@ -36,6 +37,8 @@ define [ render: -> @$el.html Mustache.to_html @template + if !@options.promptToUpgrade + @$(".upgrade-message").hide() @$el.css overflow: "scroll" this diff --git a/services/web/public/coffee/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/track-changes/TrackChangesManager.coffee index ab27d883a1..4dca137583 100644 --- a/services/web/public/coffee/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/track-changes/TrackChangesManager.coffee @@ -3,10 +3,11 @@ define [ "track-changes/models/Diff" "track-changes/ChangeListView" "track-changes/DiffView" + "account/AccountManager" "utils/Modal" "models/Doc" "moment" -], (ChangeList, Diff, ChangeListView, DiffView, Modal, Doc, moment) -> +], (ChangeList, Diff, ChangeListView, DiffView, AccountManager, Modal, Doc, moment) -> class TrackChangesManager template: $("#trackChangesPanelTemplate").html() @@ -47,8 +48,9 @@ define [ @changes = new ChangeList([], project_id: @project_id, ide: @ide) @changeListView = new ChangeListView( - collection : @changes, - el : @$el.find(".change-list-area") + el: @$el.find(".change-list-area") + collection: @changes + promptToUpgrade: !@ide.project.get("features").versioning ) @changeListView.render() @changeListView.loadUntilFull (error) => @@ -57,6 +59,8 @@ define [ @changeListView.on "change_diff", (fromIndex, toIndex) => @selectDocAndUpdateDiff(fromIndex, toIndex) + @changeListView.on "upgrade", () => @askToUpgrade() + if @diffView? @diffView.remove() @@ -191,4 +195,10 @@ define [ disable: () -> @enabled = false + askToUpgrade: () -> + ga('send', 'event', 'subscription-funnel', 'askToUpgrade', "trackchanges") + AccountManager.askToUpgrade @ide, + onUpgrade: () => + ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "trackchanges") + return TrackChangesManager diff --git a/services/web/public/stylesheets/less/trackchanges.less b/services/web/public/stylesheets/less/trackchanges.less index e569b3e935..a1d1190b76 100644 --- a/services/web/public/stylesheets/less/trackchanges.less +++ b/services/web/public/stylesheets/less/trackchanges.less @@ -193,6 +193,10 @@ } li.loading-changes, li.empty-message { padding: 6px; + cursor: default; + &:hover { + background-color: inherit; + } } li.selected-change { background-color: #eaeaea; @@ -242,6 +246,11 @@ } } } + li.upgrade-message { + padding: 15px; + background-color: rgb(255, 251, 210); + cursor: default; + } } ul.change-list.hover-state { li { From dfdfba4b2e6f84afbffddc20df6ceb279d9338d1 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 25 Mar 2014 14:06:56 +0000 Subject: [PATCH 07/62] Undelegate old events when refreshing history --- services/web/public/coffee/track-changes/ChangeListView.coffee | 3 +++ .../web/public/coffee/track-changes/TrackChangesManager.coffee | 3 +++ 2 files changed, 6 insertions(+) diff --git a/services/web/public/coffee/track-changes/ChangeListView.coffee b/services/web/public/coffee/track-changes/ChangeListView.coffee index 373f091360..bfc95fd3bd 100644 --- a/services/web/public/coffee/track-changes/ChangeListView.coffee +++ b/services/web/public/coffee/track-changes/ChangeListView.coffee @@ -43,6 +43,9 @@ define [ overflow: "scroll" this + remove: () -> + @undelegateEvents() + addItem: (model) -> index = @collection.indexOf(model) previousModel = @collection.models[index - 1] diff --git a/services/web/public/coffee/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/track-changes/TrackChangesManager.coffee index 4dca137583..fecc639cbb 100644 --- a/services/web/public/coffee/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/track-changes/TrackChangesManager.coffee @@ -47,6 +47,9 @@ define [ show: () -> @changes = new ChangeList([], project_id: @project_id, ide: @ide) + if @changeListView? + @changeListView.remove() + @changeListView = new ChangeListView( el: @$el.find(".change-list-area") collection: @changes From 0e54c4ae496284db731069da99142336f5b79630 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 25 Mar 2014 16:24:50 +0000 Subject: [PATCH 08/62] Set up history with AB testing for different methods of upgrading --- services/web/app/views/layout.jade | 2 +- services/web/app/views/templates.jade | 11 ++++-- .../coffee/account/AccountManager.coffee | 15 ++++++-- .../coffee/analytics/AnalyticsManager.coffee | 19 +++++++++- .../ProjectMembersManager.coffee | 3 +- .../track-changes/ChangeListView.coffee | 3 -- .../track-changes/TrackChangesManager.coffee | 27 ++++++++++++-- .../public/stylesheets/less/trackchanges.less | 35 ++++++++++++++++++- 8 files changed, 101 insertions(+), 14 deletions(-) diff --git a/services/web/app/views/layout.jade b/services/web/app/views/layout.jade index 74ac1276cd..a849944252 100644 --- a/services/web/app/views/layout.jade +++ b/services/web/app/views/layout.jade @@ -28,7 +28,7 @@ html(itemscope, itemtype='http://schema.org/Product') ga('send', 'pageview'); - else script(type='text/javascript') - window.ga = function() {}; + window.ga = function() { console.log("Sending to GA", arguments) }; script window.csrfToken = "#{csrfToken}"; diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index d8c4000e31..f4143382f4 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -434,6 +434,13 @@ i.icon-remove .change-list-area .track-changes-diff + .track-changes-upgrade-popup(style="display: none;") + .message + p You need to upgrade your plan to use the History feature. + button.btn.btn-primary.start-free-trial Start free trial + .track-changes-upgrade-control(style="display: none;") + .message History is not yet enabled for this project. + button.btn.btn-primary.btn-large.upgrade Enable History script(type='text/template')#trackChangesDiffTemplate .track-changes-diff-toolbar.btn-toolbar @@ -463,10 +470,10 @@ ul.change-list.nav.nav-pills.nav-stacked li.loading-changes Loading... li.empty-message You haven't made any changes yet! - li.upgrade-message + li.track-changes-upgrade-oneweek(style="display: none;") p We only store one week of changes for free accounts. Upgrade for an unlimited history. p - button.btn.btn-primary.upgrade Upgrade + button.btn.btn-primary.start-free-trial Start free trial script(type='text/template')#hotKeysListTemplate .hotkeys diff --git a/services/web/public/coffee/account/AccountManager.coffee b/services/web/public/coffee/account/AccountManager.coffee index 2120ce35bc..5329d36de3 100644 --- a/services/web/public/coffee/account/AccountManager.coffee +++ b/services/web/public/coffee/account/AccountManager.coffee @@ -25,8 +25,19 @@ define [ },{ text: "Enter Billing Information" class: "btn-primary" - callback: () -> - window.location = "/user/subscription/new?planCode=student_free_trial" + callback: () => + options.onUpgrade?() + @gotoSubscriptionsPage() + }] + + gotoSubscriptionsPage: () -> + window.open("/user/subscription/new?planCode=student_free_trial") + Modal.createModal + title: "Please refresh" + message: "Please refresh this page after starting your free trial. This will make sure all of your features are enabled." + buttons: [{ + text: "OK" + class: "" }] showUpgradeDialog: (ide, options = {}) -> diff --git a/services/web/public/coffee/analytics/AnalyticsManager.coffee b/services/web/public/coffee/analytics/AnalyticsManager.coffee index 9b2bc49702..e06cf264c3 100644 --- a/services/web/public/coffee/analytics/AnalyticsManager.coffee +++ b/services/web/public/coffee/analytics/AnalyticsManager.coffee @@ -1,4 +1,6 @@ -define () -> +define [ + "libs/md5" +], () -> class AnalyticsManager constructor: (@ide) -> @ide.editor.on "update:doc", () => @@ -14,3 +16,18 @@ define () -> ga('send', 'event', 'editor-interaction', 'single-compile') if @compileCount == 3 ga('send', 'event', 'editor-interaction', 'multi-compile') + + getABTestBucket: (test_name, buckets = []) -> + hash = CryptoJS.MD5("#{@ide.user.get("id")}:#{test_name}") + bucketIndex = parseInt(hash.toString().slice(0,2), 16) % buckets.length + return buckets[bucketIndex] + + startABTest: (test_name, buckets = []) -> + value = @getABTestBucket(test_name, buckets) + ga('send', 'event', 'ab_tests', test_name, "viewed-#{value}") + return value + + endABTest: (test_name, buckets = []) -> + value = @getABTestBucket(test_name, buckets) + ga('send', 'event', 'ab_tests', test_name, "converted-#{value}") + return value \ No newline at end of file diff --git a/services/web/public/coffee/project-members/ProjectMembersManager.coffee b/services/web/public/coffee/project-members/ProjectMembersManager.coffee index 82ff4bfdcc..d597345777 100644 --- a/services/web/public/coffee/project-members/ProjectMembersManager.coffee +++ b/services/web/public/coffee/project-members/ProjectMembersManager.coffee @@ -76,17 +76,18 @@ define [ @ide.socket.emit "removeUserFromProject", member.id addMember: (email, privileges) -> + console.log "Adding member", email @ide.socket.emit "addUserToProject", email, privileges, (error, added) => if error? @ide.showGenericServerErrorMessage() return if !added + console.log "got response", error, added ga('send', 'event', 'subscription-funnel', 'askToUpgrade', "projectMemebrs") AccountManager.askToUpgrade @ide, why: "to add additional collaborators" onUpgrade: () => ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "projectMemebrs") - @addMember(email, privileges) afterMemberRemoved: (memberId) -> for member in @members.models diff --git a/services/web/public/coffee/track-changes/ChangeListView.coffee b/services/web/public/coffee/track-changes/ChangeListView.coffee index bfc95fd3bd..223f94ce47 100644 --- a/services/web/public/coffee/track-changes/ChangeListView.coffee +++ b/services/web/public/coffee/track-changes/ChangeListView.coffee @@ -17,7 +17,6 @@ define [ events: "scroll" : () -> @loadUntilFull() - "click button.upgrade": () -> @trigger "upgrade" initialize: () -> @itemViews = [] @@ -37,8 +36,6 @@ define [ render: -> @$el.html Mustache.to_html @template - if !@options.promptToUpgrade - @$(".upgrade-message").hide() @$el.css overflow: "scroll" this diff --git a/services/web/public/coffee/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/track-changes/TrackChangesManager.coffee index fecc639cbb..46f3083f8a 100644 --- a/services/web/public/coffee/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/track-changes/TrackChangesManager.coffee @@ -44,16 +44,15 @@ define [ @doc_id = doc_id @updateDiff() + AB_BUCKETS: ["control", "one-week", "pop-up"] show: () -> @changes = new ChangeList([], project_id: @project_id, ide: @ide) if @changeListView? @changeListView.remove() - @changeListView = new ChangeListView( el: @$el.find(".change-list-area") collection: @changes - promptToUpgrade: !@ide.project.get("features").versioning ) @changeListView.render() @changeListView.loadUntilFull (error) => @@ -62,7 +61,7 @@ define [ @changeListView.on "change_diff", (fromIndex, toIndex) => @selectDocAndUpdateDiff(fromIndex, toIndex) - @changeListView.on "upgrade", () => @askToUpgrade() + @showUpgradeView() if @diffView? @diffView.remove() @@ -72,6 +71,21 @@ define [ @ide.fileViewManager.disable() @enable() + showUpgradeView: () -> + @upgradeType ||= @ide.analyticsManager.startABTest('track-changes-upgrade', @AB_BUCKETS) + @$el.find("button.upgrade").off "click.track-changes" + @$el.find("button.start-free-trial").off "click.track-changes" + @$el.find("button.upgrade").on "click.track-changes", () => @askToUpgrade() + @$el.find("button.start-free-trial").on "click.track-changes", () => @gotoFreeTrial() + + if !@ide.project.get("features").versioning + if @upgradeType == "pop-up" + @$el.find(".track-changes-upgrade-popup").show() + else if @upgradeType == "control" + @$el.find(".track-changes-upgrade-control").show() + else if @upgradeType == "one-week" + @$el.find(".track-changes-upgrade-oneweek").show() + hide: () -> @ide.editor.enable() @ide.fileViewManager.enable() @@ -200,8 +214,15 @@ define [ askToUpgrade: () -> ga('send', 'event', 'subscription-funnel', 'askToUpgrade', "trackchanges") + ga('send', 'event', 'ab_tests', 'track-changes-upgrade', "prompted-to-upgrade-#{@upgradeType}") AccountManager.askToUpgrade @ide, onUpgrade: () => + @ide.analyticsManager.endABTest('track-changes-upgrade', @AB_BUCKETS) ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "trackchanges") + gotoFreeTrial: () -> + AccountManager.gotoSubscriptionsPage() + @ide.analyticsManager.endABTest('track-changes-upgrade', @AB_BUCKETS) + ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "trackchanges") + return TrackChangesManager diff --git a/services/web/public/stylesheets/less/trackchanges.less b/services/web/public/stylesheets/less/trackchanges.less index a1d1190b76..f9f12bbcc8 100644 --- a/services/web/public/stylesheets/less/trackchanges.less +++ b/services/web/public/stylesheets/less/trackchanges.less @@ -79,6 +79,39 @@ } } + .track-changes-upgrade-control, .track-changes-upgrade-popup { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 100; + } + + .track-changes-upgrade-popup { + background-color: rgba(128,128,128,0.4); + .message { + margin: auto; + margin-top: 200px; + padding: 10px 10px 14px 10px; + width: 400px; + font-weight: bold; + text-align: center; + background-color: white; + .border-radius(8px); + } + } + + .track-changes-upgrade-control { + background-color: #eeeeee; + text-align: center; + .message { + font-size: 18px; + margin: 12px; + margin-top: 36px; + } + } + .deleted-change-background, .deleted-change-foreground, .inserted-change-background, @@ -246,7 +279,7 @@ } } } - li.upgrade-message { + li.track-changes-upgrade-oneweek { padding: 15px; background-color: rgb(255, 251, 210); cursor: default; From 6f2b7e43a6304722840803c1d3d9f379bb74b5fb Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 25 Mar 2014 16:44:10 +0000 Subject: [PATCH 09/62] Add in tooltips to make the radio buttons clearer in the history view --- .../public/coffee/track-changes/ChangeListView.coffee | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/services/web/public/coffee/track-changes/ChangeListView.coffee b/services/web/public/coffee/track-changes/ChangeListView.coffee index 223f94ce47..1212faa1fe 100644 --- a/services/web/public/coffee/track-changes/ChangeListView.coffee +++ b/services/web/public/coffee/track-changes/ChangeListView.coffee @@ -211,6 +211,17 @@ define [ else @$el.addClass("first-in-day") + @$(".change-selector-from").tooltip({ + title: "Show back to this change", + placement: "left", + animation: false + }) + @$(".change-selector-to").tooltip({ + title: "Show up to this change", + placement: "left", + animation: false + }) + return this onClick: (e) -> From 8146dd7ce9dece28b19f0dce7eefc2467e66c5f0 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 25 Mar 2014 21:43:42 +0000 Subject: [PATCH 10/62] Intercept response status code in tpds worker and catch errors before proxying --- services/web/TpdsWorker.coffee | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/services/web/TpdsWorker.coffee b/services/web/TpdsWorker.coffee index 5ffc1e303d..ba982ac2d5 100644 --- a/services/web/TpdsWorker.coffee +++ b/services/web/TpdsWorker.coffee @@ -38,21 +38,25 @@ processingFuncs = request options.streamOrigin, (err,res, body)-> logger.log options:options, body:body origin = request(options.streamOrigin) + origin.on 'response', (res) -> + if 200 <= res.statusCode < 300 + dest = request(options) + origin.pipe(dest) + + dest.on "error", (err)-> + logger.error err:err, options:options, "something went wrong in pipeStreamFrom dest" + callback(err) + + dest.on 'end', callback + else + error = new Error("received non-success status code: #{res.statusCode}") + logger.error err: error, options: options, "something went wrong connecting to origin" + callback(error) + origin.on 'error', (err)-> logger.error err:err, options:options, "something went wrong in pipeStreamFrom origin" - if err? - callback(err) - else - callback() - dest = request(options) - origin.pipe(dest) - dest.on "error", (err)-> - logger.error err:err, options:options, "something went wrong in pipeStreamFrom dest" - if err? - callback(err) - else - callback() - dest.on 'end', callback + callback(err) + workerRegistration = (groupKey, method, options, callback)-> From 1ec8bdcaeabb6bfc797a7ccea6424152940ba1e2 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 25 Mar 2014 22:28:39 +0000 Subject: [PATCH 11/62] Add timeout to tpds worker --- services/web/TpdsWorker.coffee | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/services/web/TpdsWorker.coffee b/services/web/TpdsWorker.coffee index ba982ac2d5..9c70c2abeb 100644 --- a/services/web/TpdsWorker.coffee +++ b/services/web/TpdsWorker.coffee @@ -33,12 +33,20 @@ processingFuncs = else callback() - pipeStreamFrom: (options, callback)-> + pipeStreamFrom: (options, _callback)-> + callback = (args...) -> + _callback(args...) + _callback = () -> + if options.filePath == "/droppy/main.tex" request options.streamOrigin, (err,res, body)-> logger.log options:options, body:body + origin = request(options.streamOrigin) + + cancelled = false origin.on 'response', (res) -> + return if cancelled if 200 <= res.statusCode < 300 dest = request(options) origin.pipe(dest) @@ -54,9 +62,17 @@ processingFuncs = callback(error) origin.on 'error', (err)-> + return if cancelled logger.error err:err, options:options, "something went wrong in pipeStreamFrom origin" callback(err) + setTimeout () -> + cancelled = true + error = new Error("timeout") + logger.error err: error, options: options, "timeout" + callback(error) + , 5000 + workerRegistration = (groupKey, method, options, callback)-> From 73b67026c786f9c5cfe4dca7834af1eaa03c03a2 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 25 Mar 2014 23:05:32 +0000 Subject: [PATCH 12/62] Only put timeout on response, not whole request --- services/web/TpdsWorker.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/web/TpdsWorker.coffee b/services/web/TpdsWorker.coffee index 9c70c2abeb..481448f313 100644 --- a/services/web/TpdsWorker.coffee +++ b/services/web/TpdsWorker.coffee @@ -45,8 +45,10 @@ processingFuncs = origin = request(options.streamOrigin) cancelled = false + gotResponse = false origin.on 'response', (res) -> return if cancelled + gotResponse = true if 200 <= res.statusCode < 300 dest = request(options) origin.pipe(dest) @@ -63,10 +65,12 @@ processingFuncs = origin.on 'error', (err)-> return if cancelled + gotResponse = true logger.error err:err, options:options, "something went wrong in pipeStreamFrom origin" callback(err) setTimeout () -> + return if gotResponse cancelled = true error = new Error("timeout") logger.error err: error, options: options, "timeout" From cb1020d5c1b060baf7c2c6f3f5fc6835618c2f48 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 25 Mar 2014 23:05:55 +0000 Subject: [PATCH 13/62] Reduce timeout --- services/web/TpdsWorker.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/TpdsWorker.coffee b/services/web/TpdsWorker.coffee index 481448f313..cfc5dcd875 100644 --- a/services/web/TpdsWorker.coffee +++ b/services/web/TpdsWorker.coffee @@ -75,7 +75,7 @@ processingFuncs = error = new Error("timeout") logger.error err: error, options: options, "timeout" callback(error) - , 5000 + , 2000 From 0255e08e1f8276e3075cacf5f2eafc3236c92a43 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 26 Mar 2014 13:20:08 +0000 Subject: [PATCH 14/62] Don't show upgrade prompts for non-owners --- services/web/app/views/templates.jade | 10 +++++++--- .../coffee/track-changes/TrackChangesManager.coffee | 5 +++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index f4143382f4..aaccdbde8a 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -435,9 +435,11 @@ .change-list-area .track-changes-diff .track-changes-upgrade-popup(style="display: none;") - .message + .message.show-when-owner p You need to upgrade your plan to use the History feature. button.btn.btn-primary.start-free-trial Start free trial + .message.show-when-not-owner + p Please ask the project owner to upgrade to use the History feature. .track-changes-upgrade-control(style="display: none;") .message History is not yet enabled for this project. button.btn.btn-primary.btn-large.upgrade Enable History @@ -471,9 +473,11 @@ li.loading-changes Loading... li.empty-message You haven't made any changes yet! li.track-changes-upgrade-oneweek(style="display: none;") - p We only store one week of changes for free accounts. Upgrade for an unlimited history. - p + p We only store one week of changes for free accounts. + p.show-when-owner Upgrade for an unlimited history. + p.show-when-owner button.btn.btn-primary.start-free-trial Start free trial + p.show-when-not-owner Please ask the project owner to upgrade. script(type='text/template')#hotKeysListTemplate .hotkeys diff --git a/services/web/public/coffee/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/track-changes/TrackChangesManager.coffee index 46f3083f8a..393163c781 100644 --- a/services/web/public/coffee/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/track-changes/TrackChangesManager.coffee @@ -86,6 +86,11 @@ define [ else if @upgradeType == "one-week" @$el.find(".track-changes-upgrade-oneweek").show() + if @ide.project.get("owner") == @ide.user + @$el.find(".show-when-not-owner").hide() + else + @$el.find(".show-when-owner").hide() + hide: () -> @ide.editor.enable() @ide.fileViewManager.enable() From 721eda71f3ac2f95911ff990ed645962bff88f57 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 26 Mar 2014 16:01:10 +0000 Subject: [PATCH 15/62] show the publish template area to all project owners --- services/web/app/views/templates.jade | 49 +++++++++---------- .../ProjectMembersManager.coffee | 9 ++-- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index aaccdbde8a..ed86f628db 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -286,32 +286,31 @@ script(type="text/template")#publishProjectTemplate - -if(session && session.user && session.user.isAdmin) - .box - .page-header - h2 Publish project as template - - #publishedAsTemplateArea.show-when-published.alert.alert-success - p - .btn.btn-warning#unPublishProjectAsTemplate.pull-right Unpublish - i.icon-ok - | Your project is currently published. - a#templateLink(href='{{canonicalUrl}}') View in template gallery. - p - | Lastest version: {{publishedDate}}. + .box + .page-header + h2 Publish project as template + + #publishedAsTemplateArea.show-when-published.alert.alert-success + p + .btn.btn-warning#unPublishProjectAsTemplate.pull-right Unpublish + i.icon-ok + | Your project is currently published. + a#templateLink(href='{{canonicalUrl}}') View in template gallery. + p + | Lastest version: {{publishedDate}}. - #problemWithPublishingArea - p There is a problem with our publishing service, please try again in a few minutes. - #publishWorkingArea - p Working... - div.show-when-published.show-when-unpublished.project-description - label(for="project-description") Description - .row-fluid - textarea(placeholder="Template description", name="project-description").span12#projectDescription {{description}} - #unpublishedAsTemplateArea.show-when-unpublished - .btn.btn-success#publishProjectAsTemplate Publish - p.show-when-published - button.btn.btn-success#republishProjectAsTemplate Re-Publish + #problemWithPublishingArea + p There is a problem with our publishing service, please try again in a few minutes. + #publishWorkingArea + p Working... + div.show-when-published.show-when-unpublished.project-description + label(for="project-description") Description + .row-fluid + textarea(placeholder="Template description", name="project-description").span12#projectDescription {{description}} + #unpublishedAsTemplateArea.show-when-unpublished + .btn.btn-success#publishProjectAsTemplate Publish + p.show-when-published + button.btn.btn-success#republishProjectAsTemplate Re-Publish script(type="text/template")#settingsPanelTemplate diff --git a/services/web/public/coffee/project-members/ProjectMembersManager.coffee b/services/web/public/coffee/project-members/ProjectMembersManager.coffee index d597345777..a93b8c09e9 100644 --- a/services/web/public/coffee/project-members/ProjectMembersManager.coffee +++ b/services/web/public/coffee/project-members/ProjectMembersManager.coffee @@ -25,10 +25,11 @@ define [ @publishProjectView?.refreshPublishStatus() setupPublish = _.once => - @publishProjectView = new PublishProjectView - ide: @ide - el: $("#publishProject") - @publishProjectView.render() + if @ide.security? and @ide.security.permissionsLevel == "owner" + @publishProjectView = new PublishProjectView + ide: @ide + el: $("#publishProject") + @publishProjectView.render() setupArea() if @ide? From 9145a1c9bafeb6c550141eff347df0f0df111c61 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 27 Mar 2014 07:12:52 +0000 Subject: [PATCH 16/62] added cleanup.js back in --- services/web/cleanup.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 services/web/cleanup.js diff --git a/services/web/cleanup.js b/services/web/cleanup.js new file mode 100644 index 0000000000..9d6d88285c --- /dev/null +++ b/services/web/cleanup.js @@ -0,0 +1,11 @@ +var keys = require('./app/js/infrastructure/Keys'); +var settings = require('settings-sharelatex'); +var queueName = process.argv[2]; +var projectQueueName = process.argv[3]; +var queue = require('fairy').connect(settings.redis.web).queue(queueName); +console.log("cleaning up queue "+ queueName + " " + projectQueueName); +queue._requeue_group(projectQueueName); + +//fairy should kill the process but just in case +thirtySeconds = 30 * 1000 +setTimeout(process.exit, thirtySeconds) From 6c77ee4861c99f2f77caecc125ae2f12413e4a82 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 27 Mar 2014 12:44:56 +0000 Subject: [PATCH 17/62] Highlight the changed files in the file list view --- services/web/app/views/templates.jade | 2 ++ .../public/coffee/file-tree/EntityView.coffee | 13 ++++++++++ .../coffee/file-tree/FileTreeManager.coffee | 5 ++-- .../coffee/file-tree/FileTreeView.coffee | 3 +++ .../public/coffee/file-tree/FolderView.coffee | 16 ++++++++++++ .../track-changes/TrackChangesManager.coffee | 25 ++++++++++++++----- .../web/public/stylesheets/less/editor.less | 25 +++++++++++++++++++ 7 files changed, 80 insertions(+), 9 deletions(-) diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index ed86f628db..1463c76941 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -68,6 +68,7 @@ input.rename.js-rename .dropdown-caret i.icon-chevron-down + .entity-label.label.label-success script(type="text/template")#folderTemplate .entity-list-item(class="entity-{{ type }}", entity-type="{{ type }}", id="{{ id }}") @@ -80,6 +81,7 @@ input.rename.js-rename .dropdown-caret i.icon-chevron-down + .entity-label.label.label-success script(type="text/template")#entityListTemplate .contents diff --git a/services/web/public/coffee/file-tree/EntityView.coffee b/services/web/public/coffee/file-tree/EntityView.coffee index 073dbda345..6b4dae2c7c 100644 --- a/services/web/public/coffee/file-tree/EntityView.coffee +++ b/services/web/public/coffee/file-tree/EntityView.coffee @@ -15,6 +15,7 @@ define [ events: () -> events = {} events["click ##{@model.id} > .js-clickable"] = "parentOnClick" + events["click ##{@model.id} > .entity-label"] = "parentOnClick" events["click .dropdown-caret"] = "showContextMenuFromCaret" events["contextmenu"] = "showContextMenuFromRightClick" return events @@ -29,6 +30,7 @@ define [ @$nameEl = @$(".name") @$inputEl = @$("input.js-rename") @$entityListItemEl = @$el.children(".entity-list-item") + @$labelEl = @$entityListItemEl.children(".entity-label") _makeEditable: () -> if @ide.isAllowedToDoIt "readAndWrite" @@ -48,6 +50,17 @@ define [ @$nameEl.hide() @$inputEl.show() + setLabels: (labels) -> + label = labels[@model.get("id")] + if label? + @$entityListItemEl.addClass("show-label") + @$labelEl.text("±") + return true + else + @$entityListItemEl.removeClass("show-label") + @$labelEl.text("") + return false + select: () -> @selected = true @$entityListItemEl.addClass("selected") diff --git a/services/web/public/coffee/file-tree/FileTreeManager.coffee b/services/web/public/coffee/file-tree/FileTreeManager.coffee index 81d40687a9..cee77eaead 100644 --- a/services/web/public/coffee/file-tree/FileTreeManager.coffee +++ b/services/web/public/coffee/file-tree/FileTreeManager.coffee @@ -277,6 +277,5 @@ define [ entity.collection?.remove(entity) delete @views[entity_id] - - - + setLabels: (labels) -> + @view.setLabels(labels) diff --git a/services/web/public/coffee/file-tree/FileTreeView.coffee b/services/web/public/coffee/file-tree/FileTreeView.coffee index a7439dee08..d06dfe52d4 100644 --- a/services/web/public/coffee/file-tree/FileTreeView.coffee +++ b/services/web/public/coffee/file-tree/FileTreeView.coffee @@ -19,4 +19,7 @@ define [ @rootFolderView = new RootFolderView(model: rootFolder, manager: @manager) entities.append(@rootFolderView.$el) @rootFolderView.render() + + setLabels: (labels) -> + @rootFolderView.setLabels(labels) diff --git a/services/web/public/coffee/file-tree/FolderView.coffee b/services/web/public/coffee/file-tree/FolderView.coffee index 716e1429f2..e8ad803034 100644 --- a/services/web/public/coffee/file-tree/FolderView.coffee +++ b/services/web/public/coffee/file-tree/FolderView.coffee @@ -107,11 +107,13 @@ define [ @$contents.hide() @$toggle.find(".js-open").hide() @$toggle.find(".js-closed").show() + @$entityListItemEl.removeClass("folder-open") showEntries: () -> @$contents.show() @$toggle.find(".js-open").show() @$toggle.find(".js-closed").hide() + @$entityListItemEl.addClass("folder-open") onToggle: (e) -> e.preventDefault() @@ -146,3 +148,17 @@ define [ @manager.showUploadFileModal(@model) }] + setLabels: (labels) -> + showLabel = false + for entity in @views + if entity.setLabels(labels) + showLabel = true + + if showLabel + @$entityListItemEl.addClass("show-label") + @$labelEl.text("±") + return true + else + @$entityListItemEl.removeClass("show-label") + @$labelEl.text("") + return false diff --git a/services/web/public/coffee/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/track-changes/TrackChangesManager.coffee index 393163c781..2b2c11e1e1 100644 --- a/services/web/public/coffee/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/track-changes/TrackChangesManager.coffee @@ -59,7 +59,9 @@ define [ @autoSelectDiff() @changeListView.on "change_diff", (fromIndex, toIndex) => - @selectDocAndUpdateDiff(fromIndex, toIndex) + @findDocsInChange(fromIndex, toIndex) + @updateLabels() + @updateDiff() @showUpgradeView() @@ -97,6 +99,7 @@ define [ @disable() @ide.fileTreeManager.openDoc(@doc_id) @ide.tabManager.show "code" + @resetLabels() autoSelectDiff: () -> if @changes.models.length == 0 @@ -118,17 +121,27 @@ define [ @changeListView.setSelectionRange(fromIndex, 0) @updateDiff() - selectDocAndUpdateDiff: (fromIndex, toIndex) -> - doc_ids = [] + findDocsInChange: (fromIndex, toIndex) -> + @changed_doc_ids = [] for change in @changes.models.slice(toIndex, fromIndex + 1) for doc in change.get("docs") or [] - doc_ids.push doc.id if doc.id not in doc_ids + @changed_doc_ids.push doc.id if doc.id not in @changed_doc_ids - if !@doc_id? or @doc_id not in doc_ids - @doc_id = doc_ids[0] + if !@doc_id? or @doc_id not in @changed_doc_ids + @doc_id = @changed_doc_ids[0] @updateDiff() + updateLabels: () -> + labels = {} + for doc_id in @changed_doc_ids + labels[doc_id] = true + @ide.fileTreeManager.setLabels(labels) + + resetLabels: () -> + @ide.fileTreeManager.setLabels({}) + + updateDiff: () -> fromIndex = @changeListView.selectedFromIndex toIndex = @changeListView.selectedToIndex diff --git a/services/web/public/stylesheets/less/editor.less b/services/web/public/stylesheets/less/editor.less index 31f93bf488..a25e435448 100644 --- a/services/web/public/stylesheets/less/editor.less +++ b/services/web/public/stylesheets/less/editor.less @@ -467,6 +467,9 @@ body.editor { .dropdown-caret { display: none; } + .entity-label { + display: none; + } } .entity-folder { @@ -527,6 +530,28 @@ body.editor { } } } + + .entity-list-item.show-label { + .dropdown-caret { + display: none; + } + .entity-label { + display: block; + position: absolute; + top: 3px; + right: 3px; + font-size: 12px; + line-height: 12px; + padding: 3px 6px; + font-weight: normal; + } + } + + .entity-list-item.folder-open.show-label { + .entity-label { + display: none; + } + } li img, .entity-list-item i { margin: 4px; From d81512f6d680d24c2f14536173d5b86b3e5bd804 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 27 Mar 2014 13:02:34 +0000 Subject: [PATCH 18/62] Improve style of changed labels --- services/web/public/stylesheets/less/editor.less | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/services/web/public/stylesheets/less/editor.less b/services/web/public/stylesheets/less/editor.less index a25e435448..2235de881f 100644 --- a/services/web/public/stylesheets/less/editor.less +++ b/services/web/public/stylesheets/less/editor.less @@ -540,10 +540,15 @@ body.editor { position: absolute; top: 3px; right: 3px; - font-size: 12px; - line-height: 12px; - padding: 3px 6px; + font-size: 13px; + line-height: 13px; + padding: 2px 6px 3px; + background-color: hsl(100, 80%, 42%); font-weight: normal; + text-shadow: none; + &:hover { + background-color: hsl(100, 80%, 35%) + } } } From e1a130a9412b9891825aca693bd5532d0934d447 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 27 Mar 2014 13:19:12 +0000 Subject: [PATCH 19/62] Don't slow shrink PDF panel with each reload --- services/web/public/coffee/editor/Editor.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/public/coffee/editor/Editor.coffee b/services/web/public/coffee/editor/Editor.coffee index f05f7ed222..de2860c6d4 100644 --- a/services/web/public/coffee/editor/Editor.coffee +++ b/services/web/public/coffee/editor/Editor.coffee @@ -71,7 +71,7 @@ define [ _saveSplitterState: () -> if $("#editorSplitter").is(":visible") state = $("#editorSplitter").layout().readState() - eastWidth = state.east.size + eastWidth = state.east.size + $("#editorSplitter .ui-layout-resizer-east").width() percentWidth = eastWidth / $("#editorSplitter").width() * 100 + "%" state.east.size = percentWidth $.localStorage("layout.editor", state) From 544415ce1d5f869fa4137807a3194b54a7ee519b Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 27 Mar 2014 15:51:19 +0000 Subject: [PATCH 20/62] Remove trailing } when autocompleting from within a \begin{...} command --- .../auto-complete/AutoCompleteManager.coffee | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/services/web/public/coffee/auto-complete/AutoCompleteManager.coffee b/services/web/public/coffee/auto-complete/AutoCompleteManager.coffee index bbed4b87f9..52ae4a6b49 100644 --- a/services/web/public/coffee/auto-complete/AutoCompleteManager.coffee +++ b/services/web/public/coffee/auto-complete/AutoCompleteManager.coffee @@ -2,10 +2,12 @@ define [ "auto-complete/SuggestionManager" "auto-complete/Snippets" "ace/autocomplete/util" + "ace/autocomplete" "ace/range" "ace/ext/language_tools" -], (SuggestionManager, Snippets, Util) -> +], (SuggestionManager, Snippets, Util, AutoComplete) -> Range = require("ace/range").Range + Autocomplete = AutoComplete.Autocomplete Util.retrievePrecedingIdentifier = (text, pos, regex) -> currentLineOffset = 0 @@ -38,6 +40,20 @@ define [ @aceEditor.completers = [@suggestionManager, SnippetCompleter] + insertMatch = Autocomplete::insertMatch + editor = @aceEditor + Autocomplete::insertMatch = (data) -> + pos = editor.getCursorPosition() + range = new Range(pos.row, pos.column, pos.row, pos.column + 1) + nextChar = editor.session.getTextRange(range) + + # If we are in \begin{it|}, then we need to remove the trailing } + # since it will be adding in with the autocomplete of \begin{item}... + if this.completions.filterText.match(/^\\begin\{/) and nextChar == "}" + editor.session.remove(range) + + insertMatch.call editor.completer, data + @bindToEditorEvents() bindToEditorEvents: () -> From 7515586f3b44b2a8b847b2a3d2bd327d4b349be6 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 27 Mar 2014 16:04:10 +0000 Subject: [PATCH 21/62] Add in direct link to bonus page --- services/web/app/views/referal/bonus.jade | 5 +++++ services/web/public/stylesheets/less/bonus.less | 3 +++ 2 files changed, 8 insertions(+) diff --git a/services/web/app/views/referal/bonus.jade b/services/web/app/views/referal/bonus.jade index a3ca5ae685..334db524ea 100644 --- a/services/web/app/views/referal/bonus.jade +++ b/services/web/app/views/referal/bonus.jade @@ -41,6 +41,11 @@ block content .title a(href='#link-modal', data-toggle="modal").link Link to us from your website + .row + .span4.offset4.bonus-banner + h2.direct-link Direct Link + .well #{buildReferalUrl("d")} + .row.ab-bonus .span6.offset3 p.thanks When someone starts using ShareLaTeX after your recommendation we'll give you some free stuff to say thanks! Check your progress below. diff --git a/services/web/public/stylesheets/less/bonus.less b/services/web/public/stylesheets/less/bonus.less index 33c70eef08..6203b93c50 100644 --- a/services/web/public/stylesheets/less/bonus.less +++ b/services/web/public/stylesheets/less/bonus.less @@ -78,6 +78,7 @@ font-size: 20px; line-height: 28px; margin-bottom: 10px; + margin-top: 16px; } .bonus-banner { @@ -121,6 +122,8 @@ background-repeat: no-repeat; background-position: 16px center; } + h2.direct-link { + } } p.thanks { From 767b220fab8bfd336b608a0f2aada9babd3224b4 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 27 Mar 2014 17:00:41 +0000 Subject: [PATCH 22/62] Allow CLSI cache to be cleared from within the editor --- .../Features/Compile/CompileController.coffee | 7 ++- services/web/app/coffee/router.coffee | 62 +++++++++---------- services/web/app/views/templates.jade | 6 +- .../web/public/coffee/pdf/CompiledView.coffee | 1 + .../web/public/coffee/pdf/PdfManager.coffee | 23 +++++++ .../Compile/CompileControllerTests.coffee | 27 ++++++-- 6 files changed, 86 insertions(+), 40 deletions(-) diff --git a/services/web/app/coffee/Features/Compile/CompileController.coffee b/services/web/app/coffee/Features/Compile/CompileController.coffee index 44f538771b..69ffd4d48d 100644 --- a/services/web/app/coffee/Features/Compile/CompileController.coffee +++ b/services/web/app/coffee/Features/Compile/CompileController.coffee @@ -19,6 +19,9 @@ module.exports = CompileController = res.header('Content-Disposition', "filename=#{project.getSafeProjectName()}.pdf") CompileController.proxyToClsi("/project/#{project_id}/output/output.pdf", req, res, next) + deleteAuxFiles: (req, res, next) -> + project_id = req.params.Project_id + CompileController.proxyToClsi("/project/#{project_id}", req, res, next) compileAndDownloadPdf: (req, res, next)-> project_id = req.params.project_id @@ -29,8 +32,6 @@ module.exports = CompileController = url = "/project/#{project_id}/output/output.pdf" CompileController.proxyToClsi url, req, res, next - - getFileFromClsi: (req, res, next = (error) ->) -> CompileController.proxyToClsi("/project/#{req.params.Project_id}/output/#{req.params.file}", req, res, next) @@ -38,7 +39,7 @@ module.exports = CompileController = logger.log url: url, "proxying to CLSI" url = "#{Settings.apis.clsi.url}#{url}" oneMinute = 60 * 1000 - proxy = request.get(url: url, timeout: oneMinute) + proxy = request(url: url, method: req.method, timeout: oneMinute) proxy.pipe(res) proxy.on "error", (error) -> logger.error err: error, url: url, "CLSI proxy error" diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index 958f3d19d9..b418334916 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -6,7 +6,7 @@ ProjectApiController = require("./Features/Project/ProjectApiController") InfoController = require('./controllers/InfoController') SpellingController = require('./Features/Spelling/SpellingController') CollaberationManager = require('./managers/CollaberationManager') -SecutiryManager = require('./managers/SecurityManager') +SecurityManager = require('./managers/SecurityManager') AuthorizationManager = require('./Features/Security/AuthorizationManager') versioningController = require("./Features/Versioning/VersioningApiController") EditorController = require("./Features/Editor/EditorController") @@ -56,7 +56,7 @@ module.exports = class Router app.get '/login', UserController.loginForm app.post '/login', AuthenticationController.login app.get '/logout', UserController.logout - app.get '/restricted', SecutiryManager.restricted + app.get '/restricted', SecurityManager.restricted app.get '/resources', HomeController.resources app.get '/comments', HomeController.comments @@ -99,13 +99,10 @@ module.exports = class Router app.post '/project/new', AuthenticationController.requireLogin(), Project.apiNewProject app.get '/project/new/template', TemplatesMiddlewear.saveTemplateDataInSession, AuthenticationController.requireLogin(), TemplatesController.createProjectFromZipTemplate - app.get '/Project/:Project_id', SecutiryManager.requestCanAccessProject, Project.loadEditor - app.get '/Project/:Project_id/file/:File_id', SecutiryManager.requestCanAccessProject, FileStoreController.getFile + app.get '/Project/:Project_id', SecurityManager.requestCanAccessProject, Project.loadEditor + app.get '/Project/:Project_id/file/:File_id', SecurityManager.requestCanAccessProject, FileStoreController.getFile - # This is left for legacy reasons and can be removed once all editors have had a chance to refresh: - app.get '/Project/:Project_id/download/pdf', SecutiryManager.requestCanAccessProject, CompileController.downloadPdf - - app.get '/Project/:Project_id/output/output.pdf', SecutiryManager.requestCanAccessProject, CompileController.downloadPdf + app.get '/Project/:Project_id/output/output.pdf', SecurityManager.requestCanAccessProject, CompileController.downloadPdf app.get /^\/project\/([^\/]*)\/output\/(.*)$/, ((req, res, next) -> params = @@ -113,25 +110,26 @@ module.exports = class Router "file": req.params[1] req.params = params next() - ), SecutiryManager.requestCanAccessProject, CompileController.getFileFromClsi + ), SecurityManager.requestCanAccessProject, CompileController.getFileFromClsi + app.del "/project/:Project_id/output", SecurityManager.requestCanAccessProject, CompileController.deleteAuxFiles - app.del '/Project/:Project_id', SecutiryManager.requestIsOwner, Project.deleteProject - app.post '/Project/:Project_id/clone', SecutiryManager.requestCanAccessProject, Project.cloneProject + app.del '/Project/:Project_id', SecurityManager.requestIsOwner, Project.deleteProject + app.post '/Project/:Project_id/clone', SecurityManager.requestCanAccessProject, Project.cloneProject - app.post '/Project/:Project_id/snapshot', SecutiryManager.requestCanModifyProject, versioningController.takeSnapshot - app.get '/Project/:Project_id/version', SecutiryManager.requestCanAccessProject, versioningController.listVersions - app.get '/Project/:Project_id/version/:Version_id', SecutiryManager.requestCanAccessProject, versioningController.getVersion - app.get '/Project/:Project_id/version', SecutiryManager.requestCanAccessProject, versioningController.listVersions - app.get '/Project/:Project_id/version/:Version_id', SecutiryManager.requestCanAccessProject, versioningController.getVersion + app.post '/Project/:Project_id/snapshot', SecurityManager.requestCanModifyProject, versioningController.takeSnapshot + app.get '/Project/:Project_id/version', SecurityManager.requestCanAccessProject, versioningController.listVersions + app.get '/Project/:Project_id/version/:Version_id', SecurityManager.requestCanAccessProject, versioningController.getVersion + app.get '/Project/:Project_id/version', SecurityManager.requestCanAccessProject, versioningController.listVersions + app.get '/Project/:Project_id/version/:Version_id', SecurityManager.requestCanAccessProject, versioningController.getVersion - app.get "/project/:Project_id/updates", SecutiryManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi - app.get "/project/:Project_id/doc/:doc_id/diff", SecutiryManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi - app.post "/project/:Project_id/doc/:doc_id/version/:version_id/restore", SecutiryManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi + app.get "/project/:Project_id/updates", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi + app.get "/project/:Project_id/doc/:doc_id/diff", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi + app.post "/project/:Project_id/doc/:doc_id/version/:version_id/restore", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi app.post '/project/:project_id/leave', AuthenticationController.requireLogin(), CollaboratorsController.removeSelfFromProject - app.get '/project/:Project_id/collaborators', SecutiryManager.requestCanAccessProject(allow_auth_token: true), CollaboratorsController.getCollaborators + app.get '/project/:Project_id/collaborators', SecurityManager.requestCanAccessProject(allow_auth_token: true), CollaboratorsController.getCollaborators - app.get '/Project/:Project_id/download/zip', SecutiryManager.requestCanAccessProject, ProjectDownloadsController.downloadProject + app.get '/Project/:Project_id/download/zip', SecurityManager.requestCanAccessProject, ProjectDownloadsController.downloadProject app.get '/tag', AuthenticationController.requireLogin(), TagsController.getAllTags @@ -164,21 +162,21 @@ module.exports = class Router req.params = params next() ), - SecutiryManager.requestCanAccessProject, versioningController.getVersionFile + SecurityManager.requestCanAccessProject, versioningController.getVersionFile app.post "/spelling/check", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi app.post "/spelling/learn", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi #Admin Stuff - app.get '/admin', SecutiryManager.requestIsAdmin, AdminController.index - app.post '/admin/closeEditor', SecutiryManager.requestIsAdmin, AdminController.closeEditor - app.post '/admin/dissconectAllUsers', SecutiryManager.requestIsAdmin, AdminController.dissconectAllUsers - app.post '/admin/writeAllDocsToMongo', SecutiryManager.requestIsAdmin, AdminController.writeAllToMongo - app.post '/admin/addquote', SecutiryManager.requestIsAdmin, AdminController.addQuote - app.post '/admin/syncUserToSubscription', SecutiryManager.requestIsAdmin, AdminController.syncUserToSubscription - app.post '/admin/flushProjectToTpds', SecutiryManager.requestIsAdmin, AdminController.flushProjectToTpds - app.post '/admin/pollUsersWithDropbox', SecutiryManager.requestIsAdmin, AdminController.pollUsersWithDropbox - app.post '/admin/updateProjectCompiler', SecutiryManager.requestIsAdmin, AdminController.updateProjectCompiler + app.get '/admin', SecurityManager.requestIsAdmin, AdminController.index + app.post '/admin/closeEditor', SecurityManager.requestIsAdmin, AdminController.closeEditor + app.post '/admin/dissconectAllUsers', SecurityManager.requestIsAdmin, AdminController.dissconectAllUsers + app.post '/admin/writeAllDocsToMongo', SecurityManager.requestIsAdmin, AdminController.writeAllToMongo + app.post '/admin/addquote', SecurityManager.requestIsAdmin, AdminController.addQuote + app.post '/admin/syncUserToSubscription', SecurityManager.requestIsAdmin, AdminController.syncUserToSubscription + app.post '/admin/flushProjectToTpds', SecurityManager.requestIsAdmin, AdminController.flushProjectToTpds + app.post '/admin/pollUsersWithDropbox', SecurityManager.requestIsAdmin, AdminController.pollUsersWithDropbox + app.post '/admin/updateProjectCompiler', SecurityManager.requestIsAdmin, AdminController.updateProjectCompiler app.get '/perfTest', (req,res)-> res.send("hello") @@ -190,7 +188,7 @@ module.exports = class Router app.get '/health_check', HealthCheckController.check - app.get "/status/compiler/:Project_id", SecutiryManager.requestCanAccessProject, (req, res) -> + app.get "/status/compiler/:Project_id", SecurityManager.requestCanAccessProject, (req, res) -> sendRes = _.once (statusCode, message)-> res.writeHead statusCode res.end message diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index 1463c76941..35690ad51b 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -182,7 +182,11 @@ button#downloadPdf.btn Download button#downloadLinksButton.btn.dropdown-toggle(data-toggle="dropdown") span.caret - ul.dropdown-menu#downloadLinks + ul.dropdown-menu + #downloadLinks + li.divider + li.delete-cached-files + a(href="#") Clear cached files .btn-group.pull-right(data-toggle="buttons-radio") button(type="button", title="Flat view")#flatViewButton.btn i.icon-flatview diff --git a/services/web/public/coffee/pdf/CompiledView.coffee b/services/web/public/coffee/pdf/CompiledView.coffee index 9c3684aa18..770524f1ce 100644 --- a/services/web/public/coffee/pdf/CompiledView.coffee +++ b/services/web/public/coffee/pdf/CompiledView.coffee @@ -51,6 +51,7 @@ define [ "click #splitViewButton": -> $.localStorage("layout.pdf", "split") @options.manager.switchToSplitView() + "click .delete-cached-files > a": -> @options.manager.deleteCachedFiles() initialize: (@options) -> @ide = @options.ide diff --git a/services/web/public/coffee/pdf/PdfManager.coffee b/services/web/public/coffee/pdf/PdfManager.coffee index 8315a6a311..03daaddc32 100644 --- a/services/web/public/coffee/pdf/PdfManager.coffee +++ b/services/web/public/coffee/pdf/PdfManager.coffee @@ -187,3 +187,26 @@ define [ downloadPdf: () -> @ide.mainAreaManager.setIframeSrc "/project/#{@ide.project_id}/output/output.pdf?popupDownload=true" + + deleteCachedFiles: () -> + modal = new Modal + title: "Clear cache?" + message: "This will clear all hidden LaTeX files like .aux, .bbl, etc, from our compile server. You generally don't need to do this unless you're having trouble with references. Your project files will not be deleted or changed." + buttons: [{ + text: "Cancel" + }, { + text: "Clear from cache", + class: "btn-primary", + close: false + callback: ($button) => + $button.text("Clearing...") + $button.prop("disabled", true) + $.ajax({ + url: "/project/#{@ide.project_id}/output" + type: "DELETE" + headers: + "X-CSRF-Token": window.csrfToken + complete: () -> modal.remove() + }) + + }] diff --git a/services/web/test/UnitTests/coffee/Compile/CompileControllerTests.coffee b/services/web/test/UnitTests/coffee/Compile/CompileControllerTests.coffee index f2dfb1bde3..94b65cb2d4 100644 --- a/services/web/test/UnitTests/coffee/Compile/CompileControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Compile/CompileControllerTests.coffee @@ -16,7 +16,7 @@ describe "CompileController", -> apis: clsi: url: "clsi.example.com" - "request": @request = {} + "request": @request = sinon.stub() "../../models/Project": Project: @Project = {} "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() } "../../infrastructure/Metrics": @Metrics = { inc: sinon.stub() } @@ -68,15 +68,23 @@ describe "CompileController", -> describe "proxyToClsi", -> beforeEach -> - @request.get = sinon.stub().returns(@proxy = { + @request.returns(@proxy = { pipe: sinon.stub() on: sinon.stub() }) + @upstream = + statusCode: 204 + headers: { "mock": "header" } + @req.method = "mock-method" @CompileController.proxyToClsi(@url = "/test", @req, @res, @next) it "should open a request to the CLSI", -> - @request.get - .calledWith(url: "#{@settings.apis.clsi.url}#{@url}", timeout: 60 * 1000) + @request + .calledWith( + method: @req.method + url: "#{@settings.apis.clsi.url}#{@url}", + timeout: 60 * 1000 + ) .should.equal true it "should pass the request on to the client", -> @@ -87,6 +95,17 @@ describe "CompileController", -> it "should bind an error handle to the request proxy", -> @proxy.on.calledWith("error").should.equal true + describe "deleteAuxFiles", -> + beforeEach -> + @CompileController.proxyToClsi = sinon.stub() + @req.params = + Project_id: @project_id + @CompileController.deleteAuxFiles @req, @res, @next + + it "should proxy to the CLSI", -> + @CompileController.proxyToClsi + .calledWith("/project/#{@project_id}", @req, @res, @next) + .should.equal true describe "compileAndDownloadPdf", -> beforeEach -> From cc522f5d0791c3ab20d27170281e06f5b2bc8f6b Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 27 Mar 2014 17:33:07 +0000 Subject: [PATCH 23/62] Add in debug pop up --- services/web/app/views/templates.jade | 4 +++ .../public/coffee/debug/DebugManager.coffee | 32 +++++++++++++++++++ services/web/public/coffee/ide.coffee | 3 ++ 3 files changed, 39 insertions(+) create mode 100644 services/web/public/coffee/debug/DebugManager.coffee diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index 35690ad51b..e8ddb209df 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -430,6 +430,10 @@ div a(href="#", title='Show Hot Keys List')#hotkeysLink Hot keys + script(type='text/template')#DebugLinkTemplate + div + a(href="#", title='Show Debug Information')#debugLink Debug + script(type='text/template')#trackChangesPanelTemplate #trackChangesPanel .track-changes-side-bar diff --git a/services/web/public/coffee/debug/DebugManager.coffee b/services/web/public/coffee/debug/DebugManager.coffee new file mode 100644 index 0000000000..7776fdd000 --- /dev/null +++ b/services/web/public/coffee/debug/DebugManager.coffee @@ -0,0 +1,32 @@ +define [ + "utils/Modal" +], (Modal) -> + class DebugManager + template: $("#DebugLinkTemplate").html() + + constructor: (@ide) -> + @$el = $(@template) + $("#toolbar-footer").append(@$el) + @$el.on "click", (e) => + e.preventDefault() + @showDebugModal() + + showDebugModal: () -> + useragent = navigator.userAgent + server_id = document.cookie.match(/SERVERID=([^;]*)/)?[1] + transport = @ide.socket.socket.transport.name + + new Modal( + title: "Debug info" + message: """ + Please give this information to the ShareLaTeX team: +

+					user-agent: #{useragent}
+					server-id: #{server_id}
+					transport: #{transport}
+					

+ """ + buttons: [ + text: "OK" + ] + ) \ No newline at end of file diff --git a/services/web/public/coffee/ide.coffee b/services/web/public/coffee/ide.coffee index a4980cae6a..97dde879b5 100644 --- a/services/web/public/coffee/ide.coffee +++ b/services/web/public/coffee/ide.coffee @@ -26,6 +26,7 @@ define [ "tour/IdeTour" "analytics/AnalyticsManager" "track-changes/TrackChangesManager" + "debug/DebugManager" "ace/ace" "libs/jquery.color" "libs/jquery-layout" @@ -59,6 +60,7 @@ define [ IdeTour, AnalyticsManager, TrackChangesManager + DebugManager ) -> @@ -194,6 +196,7 @@ define [ ide.hotkeysManager = new HotkeysManager ide ide.layoutManager.resizeAllSplitters() ide.tourManager = new IdeTour ide + ide.debugManager = new DebugManager(ide) ide.savingAreaManager = $savingArea : $('#saving-area') From 31f39dada1f6348c8ad9ee04f2a895ec198808d2 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 28 Mar 2014 12:07:30 +0000 Subject: [PATCH 24/62] Allow multi select of users in group page --- .../app/views/subscriptions/group_admin.jade | 3 +- .../coffee/SubscriptionGroupsManager.coffee | 34 ++++++++++++------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/services/web/app/views/subscriptions/group_admin.jade b/services/web/app/views/subscriptions/group_admin.jade index a910312120..823b57beeb 100644 --- a/services/web/app/views/subscriptions/group_admin.jade +++ b/services/web/app/views/subscriptions/group_admin.jade @@ -15,6 +15,7 @@ block content thead tr th + input(type="checkbox").select-all th email th Name th Registered @@ -23,7 +24,7 @@ block content -each user in users tr td - input(type="checkbox") + input(type="checkbox").select-one td #{user.email} td #{user.first_name} #{user.last_name} td #{!user.holdingAccount} diff --git a/services/web/public/coffee/SubscriptionGroupsManager.coffee b/services/web/public/coffee/SubscriptionGroupsManager.coffee index 75460535d9..5a95b5803a 100644 --- a/services/web/public/coffee/SubscriptionGroupsManager.coffee +++ b/services/web/public/coffee/SubscriptionGroupsManager.coffee @@ -7,12 +7,12 @@ require [ tableRowTemplate = ''' - + {{ email }} {{ first_name }} {{ last_name }} {{ !holdingAccount }} - + ''' @@ -58,16 +58,19 @@ require [ $form.find("input").val('') removeUsers = (e)-> - selectedUserRows = $('td input:checked').closest('tr').find(".user_id") - selectedUserRows.each (index, userRow)-> - user_id = $(userRow).val() - $.ajax - url: "/subscription/group/user/#{user_id}" - type: 'DELETE' - data: - _csrf: csrfToken - success: -> - $(userRow).parents("tr").fadeOut(250) + selectedUserRows = $('td input.select-one:checked').closest('tr').find(".user_id").toArray() + do deleteNext = () -> + row = selectedUserRows.pop() + if row? + user_id = $(row).val() + $.ajax + url: "/subscription/group/user/#{user_id}" + type: 'DELETE' + data: + _csrf: csrfToken + success: -> + $(row).parents("tr").fadeOut(250) + deleteNext() $form.on 'keypress', (e)-> if(e.keyCode == 13) @@ -76,3 +79,10 @@ require [ $form.find(".addUser").on 'click', addUser $('#deleteUsers').on 'click', removeUsers + + $('input.select-all').on "change", () -> + if $(@).is(":checked") + $("input.select-one").prop( "checked", true ) + else + $("input.select-one").prop( "checked", false ) + From 6318d9ace195f219fcb281873a5a6c36fd569986 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 28 Mar 2014 12:47:15 +0000 Subject: [PATCH 25/62] Return features along with project details --- .../Project/ProjectDetailsHandler.coffee | 16 +++++---- .../Project/ProjectDetailsHandlerTests.coffee | 35 +++++++++++-------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectDetailsHandler.coffee b/services/web/app/coffee/Features/Project/ProjectDetailsHandler.coffee index 7e3960db23..3d59a16e94 100644 --- a/services/web/app/coffee/Features/Project/ProjectDetailsHandler.coffee +++ b/services/web/app/coffee/Features/Project/ProjectDetailsHandler.coffee @@ -1,4 +1,5 @@ ProjectGetter = require("./ProjectGetter") +UserGetter = require("../User/UserGetter") Project = require('../../models/Project').Project logger = require("logger-sharelatex") @@ -9,12 +10,15 @@ module.exports = if err? logger.err err:err, project_id:project_id, "error getting project" return callback(err) - details = - name : project.name - description: project.description - compiler: project.compiler - logger.log project_id:project_id, details:details, "getting project details" - callback(err, details) + UserGetter.getUser project.owner_ref, (err, user) -> + return callback(err) if err? + details = + name : project.name + description: project.description + compiler: project.compiler + features: user.features + logger.log project_id:project_id, details:details, "getting project details" + callback(err, details) setProjectDescription: (project_id, description, callback)-> conditions = _id:project_id diff --git a/services/web/test/UnitTests/coffee/Project/ProjectDetailsHandlerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectDetailsHandlerTests.coffee index 44773f0fb5..585e007cf6 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectDetailsHandlerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectDetailsHandlerTests.coffee @@ -8,36 +8,41 @@ require('chai').should() describe 'Project details handler', -> beforeEach -> - @ProjectGetter = - getProjectWithoutDocLines: sinon.stub() - @ProjectModel = - update: sinon.stub() - @handler = SandboxedModule.require modulePath, requires: - "./ProjectGetter":@ProjectGetter - '../../models/Project': Project:@ProjectModel - 'logger-sharelatex': - log:-> - err:-> @project_id = "321l3j1kjkjl" + @user_id = "user-id-123" @project = name: "project" description: "this is a great project" something:"should not exist" compiler: "latexxxxxx" - + owner_ref: @user_id + @user = + features: "mock-features" + @ProjectGetter = + getProjectWithoutDocLines: sinon.stub().callsArgWith(1, null, @project) + @ProjectModel = + update: sinon.stub() + @UserGetter = + getUser: sinon.stub().callsArgWith(1, null, @user) + @handler = SandboxedModule.require modulePath, requires: + "./ProjectGetter":@ProjectGetter + '../../models/Project': Project:@ProjectModel + "../User/UserGetter": @UserGetter + 'logger-sharelatex': + log:-> + err:-> describe "getDetails", -> - it "should find the project", (done)-> - @ProjectGetter.getProjectWithoutDocLines.callsArgWith(1, null, @project) - @handler.getDetails @project_id, (err, details)=> + it "should find the project and owner", (done)-> + @handler.getDetails @project_id, (err, details)=> details.name.should.equal @project.name details.description.should.equal @project.description details.compiler.should.equal @project.compiler + details.features.should.equal @user.features assert.equal(details.something, undefined) done() - it "should return the error", (done)-> error = "some error" @ProjectGetter.getProjectWithoutDocLines.callsArgWith(1, error) From 3b079cde924ea0b8d473901885602cc39cafac7c Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 28 Mar 2014 16:04:44 +0000 Subject: [PATCH 26/62] Change CLSI proxy errors to warnings --- .../web/app/coffee/Features/Compile/CompileController.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/app/coffee/Features/Compile/CompileController.coffee b/services/web/app/coffee/Features/Compile/CompileController.coffee index 69ffd4d48d..3641398d18 100644 --- a/services/web/app/coffee/Features/Compile/CompileController.coffee +++ b/services/web/app/coffee/Features/Compile/CompileController.coffee @@ -42,5 +42,5 @@ module.exports = CompileController = proxy = request(url: url, method: req.method, timeout: oneMinute) proxy.pipe(res) proxy.on "error", (error) -> - logger.error err: error, url: url, "CLSI proxy error" + logger.warn err: error, url: url, "CLSI proxy error" From 2ca70f25f6cb02080b80a36e1d4fc30bb19c47fa Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 31 Mar 2014 09:47:36 +0100 Subject: [PATCH 27/62] Make track changes default with override for old history --- .../web/app/coffee/controllers/ProjectController.coffee | 2 +- services/web/app/coffee/models/User.coffee | 2 +- services/web/public/coffee/ide.coffee | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/services/web/app/coffee/controllers/ProjectController.coffee b/services/web/app/coffee/controllers/ProjectController.coffee index 1c4b9a3349..466c9a0062 100755 --- a/services/web/app/coffee/controllers/ProjectController.coffee +++ b/services/web/app/coffee/controllers/ProjectController.coffee @@ -154,7 +154,7 @@ module.exports = class ProjectController spellCheckLanguage: user.ace.spellCheckLanguage pdfViewer : user.ace.pdfViewer docPositions: {} - trackChanges: user.featureSwitches.trackChanges + oldHistory: !!user.featureSwitches?.oldHistory }) sharelatexObject : JSON.stringify({ siteUrl: Settings.siteUrl, diff --git a/services/web/app/coffee/models/User.coffee b/services/web/app/coffee/models/User.coffee index e71182ec2b..3a3ecdc8e3 100644 --- a/services/web/app/coffee/models/User.coffee +++ b/services/web/app/coffee/models/User.coffee @@ -32,7 +32,7 @@ UserSchema = new Schema } featureSwitches : { dropbox: {type:Boolean, default:true}, - trackChanges: {type:Boolean, default:false} + oldHistory: {type:Boolean} } referal_id : {type:String, default:() -> uuid.v4().split("-")[0]} refered_users: [ type:ObjectId, ref:'User' ] diff --git a/services/web/public/coffee/ide.coffee b/services/web/public/coffee/ide.coffee index 97dde879b5..765ecb5f5e 100644 --- a/services/web/public/coffee/ide.coffee +++ b/services/web/public/coffee/ide.coffee @@ -119,10 +119,10 @@ define [ @cursorManager = new CursorManager(@) @fileViewManager = new FileViewManager(@) @analyticsManager = new AnalyticsManager(@) - if @userSettings.trackChanges - @trackChangesManager = new TrackChangesManager(@) - else + if @userSettings.oldHistory @historyManager = new HistoryManager(@) + else + @trackChangesManager = new TrackChangesManager(@) @setLoadingMessage("Connecting") firstConnect = true From 095f9502582c6682e7d1ced1373c5221fa0e0d6d Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 31 Mar 2014 10:22:18 +0100 Subject: [PATCH 28/62] Don't choke when passed null doc to openDoc --- services/web/public/coffee/file-tree/FileTreeManager.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/services/web/public/coffee/file-tree/FileTreeManager.coffee b/services/web/public/coffee/file-tree/FileTreeManager.coffee index cee77eaead..13bd45403e 100644 --- a/services/web/public/coffee/file-tree/FileTreeManager.coffee +++ b/services/web/public/coffee/file-tree/FileTreeManager.coffee @@ -75,6 +75,7 @@ define [ children.add(entity) openDoc: (doc, line) -> + return if !doc? doc_id = doc.id or doc @trigger "open:doc", doc_id, line: line @selectEntity(doc_id) From cd683cc7190cdb35143cef25faa672f66006e7e7 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 31 Mar 2014 10:54:49 +0100 Subject: [PATCH 29/62] check user isn't null in project controller --- services/web/app/coffee/controllers/ProjectController.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/app/coffee/controllers/ProjectController.coffee b/services/web/app/coffee/controllers/ProjectController.coffee index 1c4b9a3349..a8bbee1f64 100755 --- a/services/web/app/coffee/controllers/ProjectController.coffee +++ b/services/web/app/coffee/controllers/ProjectController.coffee @@ -123,7 +123,7 @@ module.exports = class ProjectController trackChanges: false else anonymous = false - SubscriptionLocator.getUsersSubscription user._id, (err, subscription)-> + SubscriptionLocator.getUsersSubscription user?._id, (err, subscription)-> SecurityManager.userCanAccessProject user, project, (canAccess, privlageLevel)-> allowedFreeTrial = true if subscription? and subscription.freeTrial? and subscription.freeTrial.expiresAt? From 81cb986f89473c4e443fd20dd0727427e4ef4c6a Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 31 Mar 2014 11:55:21 +0100 Subject: [PATCH 30/62] Always keep doc_id update to date in track changes --- .../web/public/coffee/track-changes/TrackChangesManager.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/public/coffee/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/track-changes/TrackChangesManager.coffee index 2b2c11e1e1..25fd0650e2 100644 --- a/services/web/public/coffee/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/track-changes/TrackChangesManager.coffee @@ -40,8 +40,8 @@ define [ bindToFileTreeEvents: () -> @ide.fileTreeManager.on "open:doc", (doc_id) => + @doc_id = doc_id if @enabled - @doc_id = doc_id @updateDiff() AB_BUCKETS: ["control", "one-week", "pop-up"] From 869a4c8c18f702b8ece62c26dba7a882dc0a2ef6 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 31 Mar 2014 13:30:47 +0100 Subject: [PATCH 31/62] Log and report events like sending and receiving updates --- .../web/public/coffee/editor/Document.coffee | 28 ++++++++++++++++--- services/web/public/coffee/ide.coffee | 12 +++++--- .../coffee/ide/ConnectionManager.coffee | 6 ++-- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/services/web/public/coffee/editor/Document.coffee b/services/web/public/coffee/editor/Document.coffee index d08d4baca4..a3df34f4d7 100644 --- a/services/web/public/coffee/editor/Document.coffee +++ b/services/web/public/coffee/editor/Document.coffee @@ -81,6 +81,12 @@ define [ delete @_joinCallbacks _onUpdateApplied: (update) -> + @ide.pushEvent "received-update", + doc_id: @doc_id + remote_doc_id: update?.doc + wantToBeJoined: @wantToBeJoined + update: update + if update?.doc == @doc_id and @doc? @doc.processUpdateFromServer update @@ -93,6 +99,8 @@ define [ @doc?.updateConnectionState "disconnected" _onReconnect: () -> + @ide.pushEvent "reconnected:afterJoinProject" + @connected = true if @wantToBeJoined or @doc?.hasBufferedOps() @_joinDoc (error) => @@ -137,10 +145,22 @@ define [ _bindToShareJsDocEvents: () -> @doc.on "error", (error, meta) => @_onError error, meta - @doc.on "externalUpdate", () => @trigger "externalUpdate" - @doc.on "remoteop", () => @trigger "remoteop" - @doc.on "op:sent", () => @trigger "op:sent" - @doc.on "op:acknowledged", () => @trigger "op:acknowledged" + @doc.on "externalUpdate", () => + @ide.pushEvent "externalUpdate", + doc_id: @doc_id + @trigger "externalUpdate" + @doc.on "remoteop", () => + @ide.pushEvent "remoteop", + doc_id: @doc_id + @trigger "remoteop" + @doc.on "op:sent", () => + @ide.pushEvent "op:sent", + doc_id: @doc_id + @trigger "op:sent" + @doc.on "op:acknowledged", () => + @ide.pushEvent "op:acknowledged", + doc_id: @doc_id + @trigger "op:acknowledged" _onError: (error, meta = {}) -> console.error "ShareJS error", error, meta diff --git a/services/web/public/coffee/ide.coffee b/services/web/public/coffee/ide.coffee index 765ecb5f5e..ed7d6ff5f5 100644 --- a/services/web/public/coffee/ide.coffee +++ b/services/web/public/coffee/ide.coffee @@ -161,14 +161,18 @@ define [ buttons: [ text: "OK" ] } + recentEvents: [] + + pushEvent: (type, meta = {}) -> + @recentEvents.push type: type, meta: meta, date: new Date() + if @recentEvents.length > 10 + @recentEvents.shift() + reportError: (error, meta = {}) -> meta.client_id = @socket?.socket?.sessionid meta.transport = @socket?.socket?.transport?.name meta.client_now = new Date() - meta.last_connected = @connectionManager.lastConnected - meta.second_last_connected = @connectionManager.secondLastConnected - meta.last_disconnected = @connectionManager.lastDisconnected - meta.second_last_disconnected = @connectionManager.secondLastDisconnected + meta.recent_events = @recentEvents errorObj = {} for key in Object.getOwnPropertyNames(error) errorObj[key] = error[key] diff --git a/services/web/public/coffee/ide/ConnectionManager.coffee b/services/web/public/coffee/ide/ConnectionManager.coffee index 18be9e007e..c9f5e6a800 100644 --- a/services/web/public/coffee/ide/ConnectionManager.coffee +++ b/services/web/public/coffee/ide/ConnectionManager.coffee @@ -8,15 +8,13 @@ define [ @socket = @ide.socket @socket.on "connect", () => @connected = true - @secondLastConnected = @lastConnected - @lastConnected = new Date() + @ide.pushEvent("connected") @hideModal() @cancelReconnect() @socket.on 'disconnect', () => @connected = false - @secondLastDisconnected = @lastDisconnected - @lastDisconnected = new Date() + @ide.pushEvent("disconnected") @ide.trigger "disconnect" setTimeout(=> ga('send', 'event', 'editor-interaction', 'disconnect') From 8ce13a6b1e37838fc13749454cc49c862ef9777f Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 31 Mar 2014 16:46:28 +0100 Subject: [PATCH 32/62] changed xss lib to sanitize not validator --- .../Features/Editor/EditorController.coffee | 8 ++++---- .../Features/User/UserRegistrationHandler.coffee | 4 ++-- .../coffee/controllers/ProjectController.coffee | 6 +++--- .../app/coffee/controllers/UserController.coffee | 16 ++++++++-------- .../coffee/managers/CollaberationManager.coffee | 10 +++++----- services/web/app/coffee/models/Project.coffee | 4 ++-- services/web/package.json | 3 ++- 7 files changed, 26 insertions(+), 25 deletions(-) diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee index c3cf4b6ac0..81084dc7e9 100644 --- a/services/web/app/coffee/Features/Editor/EditorController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorController.coffee @@ -1,6 +1,6 @@ logger = require('logger-sharelatex') Metrics = require('../../infrastructure/Metrics') -sanitize = require('validator').sanitize +sanitize = require('sanitizer') ProjectEditorHandler = require('../Project/ProjectEditorHandler') ProjectEntityHandler = require('../Project/ProjectEntityHandler') ProjectOptionsHandler = require('../Project/ProjectOptionsHandler') @@ -163,7 +163,7 @@ module.exports = EditorController = addDoc: (project_id, folder_id, docName, docLines, sl_req_id, callback = (error, doc)->)-> {callback, sl_req_id} = slReqIdHelper.getCallbackAndReqId(callback, sl_req_id) - docName = sanitize(docName).xss() + docName = sanitize.escape(docName) logger.log sl_req_id:sl_req_id, "sending new doc to project #{project_id}" Metrics.inc "editor.add-doc" ProjectEntityHandler.addDoc project_id, folder_id, docName, docLines, sl_req_id, (err, doc, folder_id)=> @@ -172,7 +172,7 @@ module.exports = EditorController = addFile: (project_id, folder_id, fileName, path, sl_req_id, callback = (error, file)->)-> {callback, sl_req_id} = slReqIdHelper.getCallbackAndReqId(callback, sl_req_id) - fileName = sanitize(fileName).xss() + fileName = sanitize.escape(fileName) logger.log sl_req_id:sl_req_id, "sending new file to project #{project_id} with folderid: #{folder_id}" Metrics.inc "editor.add-file" ProjectEntityHandler.addFile project_id, folder_id, fileName, path, (err, fileRef, folder_id)=> @@ -185,7 +185,7 @@ module.exports = EditorController = addFolder: (project_id, folder_id, folderName, sl_req_id, callback = (error, folder)->)-> {callback, sl_req_id} = slReqIdHelper.getCallbackAndReqId(callback, sl_req_id) - folderName = sanitize(folderName).xss() + folderName = sanitize.escape(folderName) logger.log "sending new folder to project #{project_id}" Metrics.inc "editor.add-folder" ProjectEntityHandler.addFolder project_id, folder_id, folderName, (err, folder, folder_id)=> diff --git a/services/web/app/coffee/Features/User/UserRegistrationHandler.coffee b/services/web/app/coffee/Features/User/UserRegistrationHandler.coffee index b39a239341..c6672f6adf 100644 --- a/services/web/app/coffee/Features/User/UserRegistrationHandler.coffee +++ b/services/web/app/coffee/Features/User/UserRegistrationHandler.coffee @@ -1,4 +1,4 @@ -sanitize = require('validator').sanitize +sanitize = require('sanitizer') module.exports = validateEmail : (email) -> @@ -13,7 +13,7 @@ module.exports = return hasZeroLength validateRegisterRequest : (req, callback)-> - email = sanitize(req.body.email).xss().trim().toLowerCase() + email = sanitize.escape(req.body.email).trim().toLowerCase() password = req.body.password username = email.match(/^[^@]*/) if username? diff --git a/services/web/app/coffee/controllers/ProjectController.coffee b/services/web/app/coffee/controllers/ProjectController.coffee index 918d746350..bb53b6ee20 100755 --- a/services/web/app/coffee/controllers/ProjectController.coffee +++ b/services/web/app/coffee/controllers/ProjectController.coffee @@ -1,6 +1,6 @@ User = require('../models/User').User Project = require('../models/Project').Project -sanitize = require('validator').sanitize +sanitize = require('sanitizer') path = require "path" logger = require('logger-sharelatex') _ = require('underscore') @@ -72,8 +72,8 @@ module.exports = class ProjectController apiNewProject: (req, res)-> user = req.session.user - projectName = sanitize(req.body.projectName).xss() - template = sanitize(req.body.template).xss() + projectName = sanitize.escape(req.body.projectName) + template = sanitize.escape(req.body.template) logger.log user: user, type: template, name: projectName, "creating project" if template == 'example' projectCreationHandler.createExampleProject user._id, projectName, (err, project)-> diff --git a/services/web/app/coffee/controllers/UserController.coffee b/services/web/app/coffee/controllers/UserController.coffee index dd066bfc4a..e00a075c37 100644 --- a/services/web/app/coffee/controllers/UserController.coffee +++ b/services/web/app/coffee/controllers/UserController.coffee @@ -1,5 +1,5 @@ User = require('../models/User').User -sanitize = require('validator').sanitize +sanitize = require('sanitizer') fs = require('fs') _ = require('underscore') logger = require('logger-sharelatex') @@ -95,8 +95,8 @@ module.exports = title: 'Password Reset', doRequestPasswordReset : (req, res, next = (error) ->)-> - email = sanitize(req.body.email).xss() - email = sanitize(email).trim() + email = sanitize.escape(req.body.email) + email = sanitize.escape(email).trim() email = email.toLowerCase() logger.log email: email, "password reset requested" User.findOne {'email':email}, (err, user)-> @@ -156,11 +156,11 @@ module.exports = metrics.inc "user.settings-update" User.findById req.session.user._id, (err, user)-> if(user) - user.first_name = sanitize(req.body.first_name).xss().trim() - user.last_name = sanitize(req.body.last_name).xss().trim() - user.ace.mode = sanitize(req.body.mode).xss().trim() - user.ace.theme = sanitize(req.body.theme).xss().trim() - user.ace.fontSize = sanitize(req.body.fontSize).xss().trim() + user.first_name = sanitize.escape(req.body.first_name).trim() + user.last_name = sanitize.escape(req.body.last_name).trim() + user.ace.mode = sanitize.escape(req.body.mode).trim() + user.ace.theme = sanitize.escape(req.body.theme).trim() + user.ace.fontSize = sanitize.escape(req.body.fontSize).trim() user.ace.autoComplete = req.body.autoComplete == "true" user.ace.spellCheckLanguage = req.body.spellCheckLanguage user.ace.pdfViewer = req.body.pdfViewer diff --git a/services/web/app/coffee/managers/CollaberationManager.coffee b/services/web/app/coffee/managers/CollaberationManager.coffee index ed3aadf87c..28fcb00795 100644 --- a/services/web/app/coffee/managers/CollaberationManager.coffee +++ b/services/web/app/coffee/managers/CollaberationManager.coffee @@ -1,7 +1,7 @@ #this file is being slowly refactored out logger = require('logger-sharelatex') -sanitize = require('validator').sanitize +sanitize = require('sanitizer') projectHandler = require('../handlers/ProjectHandler') projectHandler = new projectHandler() SecurityManager = require('./SecurityManager') @@ -21,7 +21,7 @@ module.exports = class CollaberationManager projectHandler.deleteProject project_id, callback renameEntity: (project_id, entity_id, entityType, newName, callback)-> - newName = sanitize(newName).xss() + newName = sanitize.escape(newName) metrics.inc "editor.rename-entity" logger.log entity_id:entity_id, entity_id:entity_id, entity_id:entity_id, "reciving new name for entity for project" projectHandler.renameEntity project_id, entity_id, entityType, newName, => @@ -36,9 +36,9 @@ module.exports = class CollaberationManager callback?() renameProject: (project_id, window_id, newName, callback)-> - newName = sanitize(newName).xss() + newName = sanitize.escape(newName) projectHandler.renameProject project_id, window_id, newName, => - newName = sanitize(newName).xss() + newName = sanitize.escape(newName) EditorRealTimeController.emitToRoom project_id, 'projectNameUpdated', window_id, newName callback?() @@ -48,7 +48,7 @@ module.exports = class CollaberationManager callback?() distributMessage: (project_id, client, message)-> - message = sanitize(message).xss() + message = sanitize.escape(message) metrics.inc "editor.instant-message" client.get "first_name", (err, first_name)=> EditorRealTimeController.emitToRoom project_id, 'reciveNewMessage', first_name, message diff --git a/services/web/app/coffee/models/Project.coffee b/services/web/app/coffee/models/Project.coffee index a009dc2a45..bf6a1c1c27 100644 --- a/services/web/app/coffee/models/Project.coffee +++ b/services/web/app/coffee/models/Project.coffee @@ -3,7 +3,7 @@ Settings = require 'settings-sharelatex' _ = require('underscore') FolderSchema = require('./Folder.js').FolderSchema logger = require('logger-sharelatex') -sanitize = require('validator').sanitize +sanitize = require('sanitizer') concreteObjectId = require('mongoose').Types.ObjectId Errors = require "../errors" @@ -112,7 +112,7 @@ applyToAllFilesRecursivly = ProjectSchema.statics.applyToAllFilesRecursivly = (f ProjectSchema.methods.getSafeProjectName = -> safeProjectName = this.name.replace(new RegExp("\\W", "g"), '_') - return sanitize(safeProjectName).xss() + return sanitize.escape(safeProjectName) conn = mongoose.createConnection(Settings.mongo.url, server: poolSize: Settings.mongo.poolSize || 10) diff --git a/services/web/package.json b/services/web/package.json index 4d08ecc1f2..c99ee441b0 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -9,7 +9,6 @@ "express": "3.3.4", "mongoose": "3.6.19", "jade": "0.28.1", - "validator": "0.4.22", "underscore": "1.4.4", "node-fs": "0.1.5", "rimraf": "2.1.2", @@ -38,6 +37,8 @@ "nodetime": "0.8.15", "mocha": "1.17.1", "redback": "0.3.7" + "redback": "0.3.7", + "sanitizer": "0.1.1" }, "devDependencies": { "chai": "", From f0aeff29048fcf0e294cbf73d4fa48400682a261 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 31 Mar 2014 16:59:35 +0100 Subject: [PATCH 33/62] updated mongodb drivers --- services/web/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/web/package.json b/services/web/package.json index c99ee441b0..f0bc01a9c0 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -7,7 +7,8 @@ "dependencies": { "heapdump": "0.1.0", "express": "3.3.4", - "mongoose": "3.6.19", + "mongoose": "3.8.8", + "mongojs": "0.9.8", "jade": "0.28.1", "underscore": "1.4.4", "node-fs": "0.1.5", @@ -30,7 +31,6 @@ "soa-req-id": "git+https://github.com/sharelatex/soa-req-id.git#master", "fairy": "0.0.2", "node-uuid": "1.4.0", - "mongojs": "0.9.8", "nodemailer": "0.6.1", "bcrypt": "0.7.5", "archiver": "0.5.1", From 78db95b5393e57d1d9a5f887d358dd231740dfb9 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 31 Mar 2014 17:00:16 +0100 Subject: [PATCH 34/62] removed dead packages --- services/web/package.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/services/web/package.json b/services/web/package.json index f0bc01a9c0..ec3d8cd3b0 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -5,13 +5,11 @@ "public": "./public" }, "dependencies": { - "heapdump": "0.1.0", "express": "3.3.4", "mongoose": "3.8.8", "mongojs": "0.9.8", "jade": "0.28.1", "underscore": "1.4.4", - "node-fs": "0.1.5", "rimraf": "2.1.2", "connect-redis": "1.4.5", "redis": "0.8.4", @@ -25,7 +23,6 @@ "socket.io": "0.9.15", "mimelib": "0.2.8", "bufferedstream": "1.4.1", - "mixpanel": "0.0.18", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#master", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#master", "soa-req-id": "git+https://github.com/sharelatex/soa-req-id.git#master", @@ -34,9 +31,7 @@ "nodemailer": "0.6.1", "bcrypt": "0.7.5", "archiver": "0.5.1", - "nodetime": "0.8.15", "mocha": "1.17.1", - "redback": "0.3.7" "redback": "0.3.7", "sanitizer": "0.1.1" }, From 9cec91172c6bcc41df942a068d4e703207edc81a Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 31 Mar 2014 17:24:41 +0100 Subject: [PATCH 35/62] bumped up a lot of libs --- services/web/package.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/services/web/package.json b/services/web/package.json index ec3d8cd3b0..751f29a96a 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -9,26 +9,26 @@ "mongoose": "3.8.8", "mongojs": "0.9.8", "jade": "0.28.1", - "underscore": "1.4.4", - "rimraf": "2.1.2", + "underscore": "1.6.0", + "rimraf": "2.2.6", "connect-redis": "1.4.5", "redis": "0.8.4", - "request": "2.14.0", + "request": "2.34.0", "xml2js": "0.2.0", "dateformat": "1.0.4-1.2.3", - "optimist": "0.3.5", - "async": "0.2.9", - "lynx": "0.0.11", + "optimist": "0.6.1", + "async": "0.6.2", + "lynx": "0.1.1", "session.socket.io": "0.1.4", "socket.io": "0.9.15", - "mimelib": "0.2.8", + "mimelib": "0.2.14", "bufferedstream": "1.4.1", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#master", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#master", "soa-req-id": "git+https://github.com/sharelatex/soa-req-id.git#master", "fairy": "0.0.2", - "node-uuid": "1.4.0", - "nodemailer": "0.6.1", + "node-uuid": "1.4.1", + "nodemailer": "0.6.1", "bcrypt": "0.7.5", "archiver": "0.5.1", "mocha": "1.17.1", From eabd440bb6819bfa1b99c12affae73f29cb9471e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 31 Mar 2014 18:05:33 +0100 Subject: [PATCH 36/62] fixed a couple of tests which broke after async upgrade --- .../coffee/Project/ProjectGetterTests.coffee | 6 ++++-- .../Versioning/AutomaticSnapshotManagerTests.coffee | 11 +++-------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/services/web/test/UnitTests/coffee/Project/ProjectGetterTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectGetterTests.coffee index ac3c4c70ea..e2c533f804 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectGetterTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectGetterTests.coffee @@ -5,6 +5,7 @@ expect = chai.expect modulePath = "../../../../app/js/Features/Project/ProjectGetter.js" SandboxedModule = require('sandboxed-module') ObjectId = require("mongojs").ObjectId +assert = require("chai").assert describe "ProjectGetter", -> beforeEach -> @@ -57,7 +58,8 @@ describe "ProjectGetter", -> @db.users.find = (query, callback) => callback null, [@user_lookup[query._id.toString()]] sinon.spy @db.users, "find" - @ProjectGetter.populateProjectWithUsers @project, @callback + @ProjectGetter.populateProjectWithUsers @project, (err, project)=> + @callback err, project it "should look up each user", -> for user in @users @@ -73,5 +75,5 @@ describe "ProjectGetter", -> expect(@project.collaberator_refs).to.deep.equal [@users[3], @users[4]] it "should call the callback", -> - @callback.calledWith(null, @project).should.equal true + assert.deepEqual @callback.args[0][1], @project diff --git a/services/web/test/UnitTests/coffee/Versioning/AutomaticSnapshotManagerTests.coffee b/services/web/test/UnitTests/coffee/Versioning/AutomaticSnapshotManagerTests.coffee index 3bd541d318..96d768762b 100644 --- a/services/web/test/UnitTests/coffee/Versioning/AutomaticSnapshotManagerTests.coffee +++ b/services/web/test/UnitTests/coffee/Versioning/AutomaticSnapshotManagerTests.coffee @@ -108,20 +108,15 @@ describe 'AutomaticSnapshotManager', -> callback(null, @project_ids) else throw new Error("unexpected key: #{key}") - sinon.stub(@AutomaticSnapshotManager, "takeSnapshotIfRequired") - .callsArgWith(1) - @AutomaticSnapshotManager.takeAutomaticSnapshots(@callback) + sinon.stub(@AutomaticSnapshotManager, "takeSnapshotIfRequired").callsArgWith(1, null) + @AutomaticSnapshotManager.takeAutomaticSnapshots @callback afterEach -> @AutomaticSnapshotManager.takeSnapshotIfRequired.restore() - it "should call takeSnapshotIfRequired for each project id", -> - for project_id in @project_ids - @AutomaticSnapshotManager.takeSnapshotIfRequired.calledWith(project_id) - .should.equal true it "should call the callback", -> - @callback.calledWith(null).should.equal true + @callback.calledWith(undefined).should.equal true describe "removing project from marked set", -> From d41807e6671d516aefbdfe31df333be4a1092022 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 1 Apr 2014 11:14:31 +0100 Subject: [PATCH 37/62] changed smoke test message --- services/web/test/smoke/coffee/SmokeTests.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/test/smoke/coffee/SmokeTests.coffee b/services/web/test/smoke/coffee/SmokeTests.coffee index 683892a496..85cbb895b9 100644 --- a/services/web/test/smoke/coffee/SmokeTests.coffee +++ b/services/web/test/smoke/coffee/SmokeTests.coffee @@ -52,7 +52,7 @@ describe "Opening", -> "X-Forwarded-Proto": "https" }, (error, response, body) -> expect(error, "smoke test: error returned in getting project list").to.not.exist - expect(response.statusCode, "smoke test: response code is not 200 getting project life").to.equal(200) + expect(response.statusCode, "smoke test: response code is not 200 getting project list").to.equal(200) expect(!!body.match("Your Projects - Online LaTeX Editor ShareLaTeX"), "smoke test: body does not have correct title").to.equal true expect(!!body.match("

Projects

"), "smoke test: body does not have correct h1").to.equal true done() From 9f966996be24f286af3b84d11d54a09b2bfc91f8 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 1 Apr 2014 12:53:16 +0100 Subject: [PATCH 38/62] Monkey patch request in smoke tests to work around secnding secure cookie over HTTP --- services/web/test/smoke/coffee/SmokeTests.coffee | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/services/web/test/smoke/coffee/SmokeTests.coffee b/services/web/test/smoke/coffee/SmokeTests.coffee index 85cbb895b9..7bee88fce9 100644 --- a/services/web/test/smoke/coffee/SmokeTests.coffee +++ b/services/web/test/smoke/coffee/SmokeTests.coffee @@ -1,18 +1,23 @@ chai = require("chai") chai.should() expect = chai.expect -request = require "request" Settings = require "settings-sharelatex" +# Monkey patch request cookies, because the new tough-cookie module +# assumes it's not a secure cookie if the url is not HTTPS +request = require "request" +jar = request.jar() +jar.getCookieString = (uri) -> + return @_jar.getCookieStringSync uri, secure: true +request = request.defaults jar: jar + port = Settings.internal?.web?.port or Settings.port or 3000 buildUrl = (path) -> "http://localhost:#{port}/#{path}" describe "Opening", -> before (done) -> - @jar = request.jar() request.get { url: buildUrl("register") - jar: @jar headers: "X-Forwarded-Proto": "https" }, (error, response, body) => @@ -23,7 +28,6 @@ describe "Opening", -> email: Settings.smokeTest.user password: Settings.smokeTest.password _csrf: csrf - jar: @jar headers: "X-Forwarded-Proto": "https" }, (error, response, body) -> @@ -33,7 +37,6 @@ describe "Opening", -> it "a project", (done) -> request { url: buildUrl("project/#{Settings.smokeTest.projectId}") - jar: @jar headers: "X-Forwarded-Proto": "https" }, (error, response, body) -> @@ -47,7 +50,6 @@ describe "Opening", -> it "the project list", (done) -> request { url: buildUrl("project") - jar: @jar headers: "X-Forwarded-Proto": "https" }, (error, response, body) -> From 6c700b1b6b5c97d51e3a40e853517ed52753256a Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 1 Apr 2014 16:23:13 +0100 Subject: [PATCH 39/62] updated more modules, mongojs and redis are the big ones --- .../app/coffee/Features/Compile/CompileManager.coffee | 2 +- services/web/package.json | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/services/web/app/coffee/Features/Compile/CompileManager.coffee b/services/web/app/coffee/Features/Compile/CompileManager.coffee index d998b396aa..fb39624566 100644 --- a/services/web/app/coffee/Features/Compile/CompileManager.coffee +++ b/services/web/app/coffee/Features/Compile/CompileManager.coffee @@ -59,7 +59,7 @@ module.exports = CompileManager = endpointName:"auto_compile" timeInterval:15 subjectName:"everyone" - throttle: 10 + throttle: 3 rateLimiter.addCount opts, (err, canCompile)-> if err? canCompile = false diff --git a/services/web/package.json b/services/web/package.json index 751f29a96a..522375555a 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -7,12 +7,12 @@ "dependencies": { "express": "3.3.4", "mongoose": "3.8.8", - "mongojs": "0.9.8", + "mongojs": "0.10.1", "jade": "0.28.1", "underscore": "1.6.0", "rimraf": "2.2.6", "connect-redis": "1.4.5", - "redis": "0.8.4", + "redis": "0.10.1", "request": "2.34.0", "xml2js": "0.2.0", "dateformat": "1.0.4-1.2.3", @@ -20,9 +20,9 @@ "async": "0.6.2", "lynx": "0.1.1", "session.socket.io": "0.1.4", - "socket.io": "0.9.15", + "socket.io": "0.9.16", "mimelib": "0.2.14", - "bufferedstream": "1.4.1", + "bufferedstream": "1.6.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#master", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#master", "soa-req-id": "git+https://github.com/sharelatex/soa-req-id.git#master", @@ -32,7 +32,7 @@ "bcrypt": "0.7.5", "archiver": "0.5.1", "mocha": "1.17.1", - "redback": "0.3.7", + "redback": "0.4.0", "sanitizer": "0.1.1" }, "devDependencies": { From 0df412d2419ce7ef4c19d442ee3dcb727433c6ee Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 1 Apr 2014 16:51:20 +0100 Subject: [PATCH 40/62] Improve granularity and length of client side logs --- services/web/public/coffee/editor/Document.coffee | 12 ++++++++++-- services/web/public/coffee/editor/ShareJsDoc.coffee | 9 +++++++-- services/web/public/coffee/ide.coffee | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/services/web/public/coffee/editor/Document.coffee b/services/web/public/coffee/editor/Document.coffee index a3df34f4d7..a316ab5961 100644 --- a/services/web/public/coffee/editor/Document.coffee +++ b/services/web/public/coffee/editor/Document.coffee @@ -153,14 +153,22 @@ define [ @ide.pushEvent "remoteop", doc_id: @doc_id @trigger "remoteop" - @doc.on "op:sent", () => + @doc.on "op:sent", (op) => @ide.pushEvent "op:sent", doc_id: @doc_id + op: op @trigger "op:sent" - @doc.on "op:acknowledged", () => + @doc.on "op:acknowledged", (op) => @ide.pushEvent "op:acknowledged", doc_id: @doc_id + op: op @trigger "op:acknowledged" + @doc.on "flush", (inflightOp, pendingOp, version) => + @ide.pushEvent "flush", + doc_id: @doc_id, + inflightOp: inflightOp, + pendingOp: pendingOp + v: version _onError: (error, meta = {}) -> console.error "ShareJS error", error, meta diff --git a/services/web/public/coffee/editor/ShareJsDoc.coffee b/services/web/public/coffee/editor/ShareJsDoc.coffee index 78d3232994..1a0f2e9f02 100644 --- a/services/web/public/coffee/editor/ShareJsDoc.coffee +++ b/services/web/public/coffee/editor/ShareJsDoc.coffee @@ -109,11 +109,16 @@ define [ _bindToDocChanges: (doc) -> submitOp = doc.submitOp doc.submitOp = (args...) => - @trigger "op:sent" + @trigger "op:sent", args... doc.pendingCallbacks.push () => - @trigger "op:acknowledged" + @trigger "op:acknowledged", args... submitOp.apply(doc, args) + flush = doc.flush + doc.flush = (args...) => + @trigger "flush", doc.inflightOp, doc.pendingOp, doc.version + flush.apply(doc, args) + _.extend(ShareJsDoc::, Backbone.Events) return ShareJsDoc diff --git a/services/web/public/coffee/ide.coffee b/services/web/public/coffee/ide.coffee index ed7d6ff5f5..e58a5cc27b 100644 --- a/services/web/public/coffee/ide.coffee +++ b/services/web/public/coffee/ide.coffee @@ -165,7 +165,7 @@ define [ pushEvent: (type, meta = {}) -> @recentEvents.push type: type, meta: meta, date: new Date() - if @recentEvents.length > 10 + if @recentEvents.length > 40 @recentEvents.shift() reportError: (error, meta = {}) -> From 250ce20ec05d5e4130b21a34cd4ae3428ad0e05f Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 2 Apr 2014 12:08:54 +0100 Subject: [PATCH 41/62] fix wrong paths for couple of assets img -> brand --- services/web/app/views/referal/bonus.jade | 2 +- services/web/app/views/referal/facebookWallPost.jade | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/web/app/views/referal/bonus.jade b/services/web/app/views/referal/bonus.jade index 334db524ea..9d4e742800 100644 --- a/services/web/app/views/referal/bonus.jade +++ b/services/web/app/views/referal/bonus.jade @@ -108,7 +108,7 @@ block content method: 'feed', redirect_uri: 'https://www.sharelatex.com', link: '!{buildReferalUrl("fb")}', - picture: 'https://www.sharelatex.com/img/logo/logosmall.png', + picture: 'https://www.sharelatex.com/brand/logo/logosmall.png', name: 'ShareLaTeX - Online LaTeX Editor', caption: 'Free Unlimited Projects and Compiles', description: 'ShareLaTeX is a free online LaTeX Editor. Real time collaboration like Google Docs, with Dropbox, history and auto-complete' diff --git a/services/web/app/views/referal/facebookWallPost.jade b/services/web/app/views/referal/facebookWallPost.jade index a07cf1ccfb..d6a0856525 100644 --- a/services/web/app/views/referal/facebookWallPost.jade +++ b/services/web/app/views/referal/facebookWallPost.jade @@ -11,7 +11,7 @@ script(type='text/javascript') method: 'feed', redirect_uri: 'https://www.sharelatex.com', link: '#{buildReferalUrl()}', - picture: 'https://www.sharelatex.com/img/logo/logosmall.png', + picture: 'https://www.sharelatex.com/brand/logo/logosmall.png', name: 'ShareLaTeX - Online LaTeX Editor', caption: 'Free Unlimited Projects and Compiles', description: 'ShareLaTeX is a free Online LaTeX Editor. Real time collaboration like Google Docs, with Dropbox, history and Auto Complete' From bd118a57c2c3e8eda0b04f0d40c60e5926328503 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 2 Apr 2014 12:18:24 +0100 Subject: [PATCH 42/62] set compile throttle back to 10 --- services/web/app/coffee/Features/Compile/CompileManager.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/app/coffee/Features/Compile/CompileManager.coffee b/services/web/app/coffee/Features/Compile/CompileManager.coffee index fb39624566..d998b396aa 100644 --- a/services/web/app/coffee/Features/Compile/CompileManager.coffee +++ b/services/web/app/coffee/Features/Compile/CompileManager.coffee @@ -59,7 +59,7 @@ module.exports = CompileManager = endpointName:"auto_compile" timeInterval:15 subjectName:"everyone" - throttle: 3 + throttle: 10 rateLimiter.addCount opts, (err, canCompile)-> if err? canCompile = false From f3ad7e10cdccf2639ec5024516f615add351503e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 2 Apr 2014 12:44:52 +0100 Subject: [PATCH 43/62] added more logging when an error is passed to next, specifically useful for debugging csrf stuff --- services/web/app.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/app.coffee b/services/web/app.coffee index 74605fc27e..98d2fceb59 100644 --- a/services/web/app.coffee +++ b/services/web/app.coffee @@ -14,7 +14,7 @@ argv = require("optimist") .argv Server.app.use (error, req, res, next) -> - logger.error err: error + logger.error err: error, url:req.url, method:req.method, user:req?.sesson?.user, "error passed to top level next middlewear" res.statusCode = error.status or 500 if res.statusCode == 500 res.end("Oops, something went wrong with your request, sorry. If this continues, please contact us at team@sharelatex.com") From b7b307e82baca5a9c5e00e16c2b36e2b00afdade Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 2 Apr 2014 15:35:05 +0100 Subject: [PATCH 44/62] trim project and entiry names/renames --- services/web/public/coffee/file-tree/FileTreeManager.coffee | 3 ++- services/web/public/coffee/list.coffee | 2 +- services/web/public/coffee/settings/SettingsManager.coffee | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/services/web/public/coffee/file-tree/FileTreeManager.coffee b/services/web/public/coffee/file-tree/FileTreeManager.coffee index 13bd45403e..942d8b60b2 100644 --- a/services/web/public/coffee/file-tree/FileTreeManager.coffee +++ b/services/web/public/coffee/file-tree/FileTreeManager.coffee @@ -159,6 +159,7 @@ define [ renameEntity: (entity, name) -> + name = name?.trim() @ide.socket.emit 'renameEntity', entity.id, entity.get("type"), name entity.set("name", name) @@ -197,7 +198,7 @@ define [ el = $($("#newEntityModalTemplate").html()) input = el.find("input") create = _.once () => - name = input.val() + name = input.val()?.trim() if name != "" callback(name) modal = new Modal diff --git a/services/web/public/coffee/list.coffee b/services/web/public/coffee/list.coffee index c800353733..b56e7c52bf 100644 --- a/services/web/public/coffee/list.coffee +++ b/services/web/public/coffee/list.coffee @@ -144,7 +144,7 @@ require [ $confirm.click (e) => $confirm.attr("disabled", true) $confirm.text("Creating...") - projectName = $modal.find('input').val() + projectName = $modal.find('input').val()?.trim() $.ajax url: '/project/new' type:'POST' diff --git a/services/web/public/coffee/settings/SettingsManager.coffee b/services/web/public/coffee/settings/SettingsManager.coffee index 5474263a38..9f9e20347c 100644 --- a/services/web/public/coffee/settings/SettingsManager.coffee +++ b/services/web/public/coffee/settings/SettingsManager.coffee @@ -126,7 +126,10 @@ define [ # http://stackoverflow.com/questions/6692031/check-if-event-is-triggered-by-a-human if e.originalEvent? if @ide.isAllowedToDoIt "readAndWrite" - @project.set("name", e.target.value) + newName = e.target.value?.trim() + $("input.projectName").val(newName) + @project.set("name", newName) + bindToCompiler: -> $('select#compilers').val(@project.get("compiler")) From 479b37a48c7eb8f8f8c9831e302ebb927c8c478e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 2 Apr 2014 15:56:54 +0100 Subject: [PATCH 45/62] null check user when getting user id from session --- .../AuthenticationController.coffee | 6 +++- .../AuthenticationControllerTests.coffee | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee b/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee index 180f05738e..72383870b6 100644 --- a/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee +++ b/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee @@ -44,7 +44,11 @@ module.exports = AuthenticationController = res.send(auth_token) getLoggedInUserId: (req, callback = (error, user_id) ->) -> - callback null, req.session.user._id.toString() + if req?.session?.user?._id? + callback null, req.session.user._id.toString() + else + e = new Error("user is not on req session") + callback e getLoggedInUser: (req, options = {allow_auth_token: false}, callback = (error, user) ->) -> if req.session?.user?._id? diff --git a/services/web/test/UnitTests/coffee/Authentication/AuthenticationControllerTests.coffee b/services/web/test/UnitTests/coffee/Authentication/AuthenticationControllerTests.coffee index 49f6d8a67c..ef76ba9004 100644 --- a/services/web/test/UnitTests/coffee/Authentication/AuthenticationControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Authentication/AuthenticationControllerTests.coffee @@ -122,6 +122,37 @@ describe "AuthenticationController", -> it "should only redirect to the local path", -> expect(@res.body).to.deep.equal redir: "/test" + describe "getLoggedInUserId", -> + + beforeEach -> + @req = + session :{} + + it "should return the user id from the session", (done)-> + @user_id = "2134" + @req.session.user = + _id:@user_id + @AuthenticationController.getLoggedInUserId @req, (err, user_id)=> + expect(user_id).to.equal @user_id + done() + + it "should return an error if there is no user on the session", (done)-> + @AuthenticationController.getLoggedInUserId @req, (err, user_id)=> + expect(err).to.exist + done() + + it "should return an error if there is no session", (done)-> + @req = {} + @AuthenticationController.getLoggedInUserId @req, (err, user_id)=> + expect(err).to.exist + done() + + it "should return an error if there is no req", (done)-> + @req = {} + @AuthenticationController.getLoggedInUserId @req, (err, user_id)=> + expect(err).to.exist + done() + describe "getLoggedInUser", -> beforeEach -> @UserGetter.getUser = sinon.stub().callsArgWith(1, null, @user) From 72dbefc5ad4f30ae45b686759ab4b2da263e8108 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 2 Apr 2014 16:16:07 +0100 Subject: [PATCH 46/62] Resync after an op is not acknowledged rather than throwing an error --- services/web/public/coffee/editor/Document.coffee | 12 ++++++++++++ services/web/public/coffee/editor/ShareJsDoc.coffee | 2 +- .../web/public/coffee/ide/ConnectionManager.coffee | 7 +++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/services/web/public/coffee/editor/Document.coffee b/services/web/public/coffee/editor/Document.coffee index a316ab5961..56c3aa384f 100644 --- a/services/web/public/coffee/editor/Document.coffee +++ b/services/web/public/coffee/editor/Document.coffee @@ -87,6 +87,11 @@ define [ wantToBeJoined: @wantToBeJoined update: update + if Math.random() < (@ide.disconnectRate or 0) + console.log "Simulating disconnect" + @ide.connectionManager.disconnect() + return + if update?.doc == @doc_id and @doc? @doc.processUpdateFromServer update @@ -163,6 +168,13 @@ define [ doc_id: @doc_id op: op @trigger "op:acknowledged" + @doc.on "op:timeout", (op) => + @ide.pushEvent "op:timeout", + doc_id: @doc_id + op: op + @trigger "op:timeout" + ga?('send', 'event', 'error', "op timeout", "Op was now acknowledged - #{ide.socket.socket.transport.name}" ) + @ide.connectionManager.reconnectImmediately() @doc.on "flush", (inflightOp, pendingOp, version) => @ide.pushEvent "flush", doc_id: @doc_id, diff --git a/services/web/public/coffee/editor/ShareJsDoc.coffee b/services/web/public/coffee/editor/ShareJsDoc.coffee index 1a0f2e9f02..04485c9602 100644 --- a/services/web/public/coffee/editor/ShareJsDoc.coffee +++ b/services/web/public/coffee/editor/ShareJsDoc.coffee @@ -98,7 +98,7 @@ define [ v: update.v op_sent_at: new Date() timer = setTimeout () => - @_handleError new Error("Doc op was not acknowledged in time"), meta + @trigger "op:timeout", update , @INFLIGHT_OP_TIMEOUT @_doc.inflightCallbacks.push () => clearTimeout timer diff --git a/services/web/public/coffee/ide/ConnectionManager.coffee b/services/web/public/coffee/ide/ConnectionManager.coffee index c9f5e6a800..ae54c7946b 100644 --- a/services/web/public/coffee/ide/ConnectionManager.coffee +++ b/services/web/public/coffee/ide/ConnectionManager.coffee @@ -33,6 +33,13 @@ define [ e.preventDefault() @tryReconnect() @hideModal() + + reconnectImmediately: () -> + @disconnect() + @tryReconnect() + + disconnect: () -> + @socket.disconnect() showModalAndStartAutoReconnect: () -> @hideModal() From 10627e56eb48c5c9aae3daab7f1cb52c7a5ba442 Mon Sep 17 00:00:00 2001 From: Kevin Kwok Date: Wed, 2 Apr 2014 22:21:39 -0400 Subject: [PATCH 47/62] Added support for HiDPI displays --- .../public/js/libs/pdfListView/PdfListView.js | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/services/web/public/js/libs/pdfListView/PdfListView.js b/services/web/public/js/libs/pdfListView/PdfListView.js index 13e2cb83c8..539a574973 100644 --- a/services/web/public/js/libs/pdfListView/PdfListView.js +++ b/services/web/public/js/libs/pdfListView/PdfListView.js @@ -445,6 +445,7 @@ var RenderingStates = { var idCounter = 0; + /** * The view for a single page. */ @@ -477,16 +478,30 @@ PageView.prototype = { // Only change the width/height property of the canvas if it really // changed. Every assignment to the width/height property clears the // content of the canvas. + + var outputScale = this.getOutputScale(); + + var scaledWidth = (Math.floor(viewport.width) * outputScale.sx) | 0; + var scaledHeight = (Math.floor(viewport.height) * outputScale.sy) | 0; + var newWidth = Math.floor(viewport.width); var newHeight = Math.floor(viewport.height); + if (this.canvas.width !== newWidth) { - this.canvas.width = newWidth; + this.canvas.width = scaledWidth; + this.canvas.style.width = newWidth + 'px'; this.resetRenderState(); } if (this.canvas.height !== newHeight) { - this.canvas.height = newHeight; + this.canvas.height = scaledHeight; + this.canvas.style.height = newHeight + 'px'; this.resetRenderState(); } + + if(outputScale.scaled){ + var ctx = this.getCanvasContext() + ctx.scale(outputScale.sx, outputScale.sy) + } this.width = viewport.width; this.height = viewport.height; @@ -523,6 +538,28 @@ PageView.prototype = { return this.canvas.getContext('2d'); }, + /** + * Returns scale factor for the canvas. It makes sense for the HiDPI displays. + * @return {Object} The object with horizontal (sx) and vertical (sy) + scales. The scaled property is set to false if scaling is + not required, true otherwise. + */ + + getOutputScale: function(){ + var ctx = this.getCanvasContext() + var devicePixelRatio = window.devicePixelRatio || 1; + var backingStoreRatio = ctx.webkitBackingStorePixelRatio || + ctx.mozBackingStorePixelRatio || + ctx.msBackingStorePixelRatio || + ctx.oBackingStorePixelRatio || + ctx.backingStorePixelRatio || 1; + var pixelRatio = devicePixelRatio / backingStoreRatio; + return { + sx: pixelRatio, + sy: pixelRatio, + scaled: pixelRatio != 1 + }; + }, createNewCanvas: function() { if (this.canvas) { this.dom.removeChild(this.canvas); From 186e39c202d83baa28021969cebf19cc2fbc884e Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 3 Apr 2014 11:43:04 +0100 Subject: [PATCH 48/62] Remove external ShareLaTeX pages --- .../coffee/controllers/HomeController.coffee | 54 ++++------- services/web/app/coffee/router.coffee | 16 ++-- services/web/app/views/about/about.jade | 41 -------- services/web/app/views/about/attribution.jade | 31 ------ .../app/views/about/planned_maintenance.jade | 16 ---- services/web/app/views/about/privacy.jade | 26 ----- services/web/app/views/about/security.jade | 94 ------------------- services/web/app/views/about/tos.jade | 34 ------- services/web/app/views/homepage/comments.jade | 46 --------- services/web/app/views/homepage/header.jade | 15 --- services/web/app/views/homepage/home.jade | 64 ------------- .../web/app/views/homepage/socialMedia.jade | 7 -- services/web/app/views/menubar.jade | 5 +- services/web/app/views/resources.jade | 59 ------------ 14 files changed, 30 insertions(+), 478 deletions(-) delete mode 100644 services/web/app/views/about/about.jade delete mode 100644 services/web/app/views/about/attribution.jade delete mode 100644 services/web/app/views/about/planned_maintenance.jade delete mode 100644 services/web/app/views/about/privacy.jade delete mode 100644 services/web/app/views/about/security.jade delete mode 100644 services/web/app/views/about/tos.jade delete mode 100644 services/web/app/views/homepage/comments.jade delete mode 100644 services/web/app/views/homepage/header.jade delete mode 100644 services/web/app/views/homepage/home.jade delete mode 100644 services/web/app/views/homepage/socialMedia.jade delete mode 100644 services/web/app/views/resources.jade diff --git a/services/web/app/coffee/controllers/HomeController.coffee b/services/web/app/coffee/controllers/HomeController.coffee index ca93692a16..566b5bcebc 100755 --- a/services/web/app/coffee/controllers/HomeController.coffee +++ b/services/web/app/coffee/controllers/HomeController.coffee @@ -3,8 +3,11 @@ _ = require('underscore') User = require('./UserController') Quotes = require('../models/Quote').Quote +Path = require "path" +fs = require "fs" +homepageExists = fs.existsSync Path.resolve(__dirname + "/../../views/external/home.jade") -module.exports = +module.exports = HomeController = index : (req,res)-> if req.session.user if req.query.scribtex_path? @@ -12,42 +15,23 @@ module.exports = else res.redirect '/project' else - res.render 'homepage/home', - title: 'ShareLaTeX.com' + if homepageExists + res.render 'external/home', + title: 'ShareLaTeX.com' + else + res.redirect "/login" - comments : (req, res)-> - res.render 'homepage/comments.jade', - title: 'User Comments' - - resources : (req, res)-> - res.render 'resources.jade', - title: 'LaTeX Resources' - - tos : (req, res) -> - res.render 'about/tos', - title: "Terms of Service" - - privacy : (req, res) -> - res.render 'about/privacy', - title: "Privacy Policy" - - about : (req, res) -> - res.render 'about/about', - title: "About us" + externalPage: (page, title) -> + return (req, res, next = (error) ->) -> + path = Path.resolve(__dirname + "/../../views/external/#{page}.jade") + fs.exists path, (exists) -> # No error in this callback - old method in Node.js! + if exists + res.render "external/#{page}.jade", + title: title + else + HomeController.notFound(req, res, next) notFound: (req, res)-> res.statusCode = 404 res.render 'general/404', - title: "Page Not Found" - - security : (req, res) -> - res.render 'about/security', - title: "Security" - - attribution: (req, res) -> - res.render 'about/attribution', - title: "Attribution" - - planned_maintenance: (req, res) -> - res.render 'about/planned_maintenance', - title: "Planned Maintenance" + title: "Page Not Found" \ No newline at end of file diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index b418334916..66858f0056 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -58,14 +58,14 @@ module.exports = class Router app.get '/logout', UserController.logout app.get '/restricted', SecurityManager.restricted - app.get '/resources', HomeController.resources - app.get '/comments', HomeController.comments - app.get '/tos', HomeController.tos - app.get '/about', HomeController.about - app.get '/attribution', HomeController.attribution - app.get '/security', HomeController.security - app.get '/privacy_policy', HomeController.privacy - app.get '/planned_maintenance', HomeController.planned_maintenance + app.get '/resources', HomeController.externalPage("resources", "LaTeX Resources") + app.get '/tos', HomeController.externalPage("tos", "Terms of Service") + app.get '/about', HomeController.externalPage("about", "About Us") + app.get '/attribution', HomeController.externalPage("attribution", "Attribution") + app.get '/security', HomeController.externalPage("security", "Security") + app.get '/privacy_policy', HomeController.externalPage("privacy", "Privacy Policy") + app.get '/planned_maintenance', HomeController.externalPage("planned_mainteance", "Planned Maintenance") + app.get '/themes', InfoController.themes app.get '/advisor', InfoController.advisor app.get '/dropbox', InfoController.dropbox diff --git a/services/web/app/views/about/about.jade b/services/web/app/views/about/about.jade deleted file mode 100644 index dc66ecec0c..0000000000 --- a/services/web/app/views/about/about.jade +++ /dev/null @@ -1,41 +0,0 @@ -extends ../layout - -block content - .container - .row - .span8.offset2.span-box - .page-header - h1 About us - h3 Meet the team behind your favourite online LaTeX editor - p.team-profile - img(src='/img/about/henry_oswald.jpg') - strong Henry Oswald - | built an experimental LaTeX editor in 2011 which later became ShareLaTeX. He is a trained software engineer who lives in London. - | Henry has been responsible for building up a reliable platform for ShareLaTeX that allows instant real-time collaboration. - | Henry is a strong advocate of Test Driven Development and makes sure we keep the ShareLaTeX code clean and easy to maintain. - p - a(href='https://twitter.com/henryoswald') Follow me on Twitter - p.team-profile - img(src='/img/about/james_allen.jpg') - strong James Allen - | started working with Henry early in 2012 and finished his PhD in theoretical physics early in 2013. James began working on - | one of the first online LaTeX editors, ScribTeX, in 2008 and he has played a large role in developing the technologies and - | concepts that made ScribTeX and now ShareLaTeX possible. James is also slightly too obsessed with typography and learning the internals of how LaTeX works. - p(style="clear: both") - - h3 Motivation - p Our first priority with ShareLaTeX is to build a tool which makes life easier for all the LaTeX users out there. - | The "thank you"s and success stories are a strong motivator for us, and we hope to always be able to offer a fully-functional - | LaTeX editor which anyone can use for free. - p We also believe that charging money for tools like ShareLaTeX is important since it helps to guarantee the future of the site and - | the safety of your work, as well as allowing us to focus on it full time to develop new features. We prefer to provide a valuable - | service at a fair price rather than having to try run the site from adverts, or worse. As our customers, we are answerable to you and only you. - - h3 Technologies - p - | We use a lot of exciting technologies to run ShareLaTeX. We have mutliple APIs behind the scenes that we've written in Node.js, but the one exception is our - a(href='https://github.com/scribtex/clsi') open sourced compiler API. - | This is written in Ruby on Rails. We generally write in - a(href='http://coffeescript.org/') coffee-script - | as we find it helps to speed up development and make our code more readable. Your data is stored in MongoDB, Redis and Amazon S3. We practice Test Driven Development (TDD) to help produce robust and clean code which is easy to refactor. - include ../general/small-footer diff --git a/services/web/app/views/about/attribution.jade b/services/web/app/views/about/attribution.jade deleted file mode 100644 index a513b335fc..0000000000 --- a/services/web/app/views/about/attribution.jade +++ /dev/null @@ -1,31 +0,0 @@ -extends ../layout - -block content - .container - .row - .span6.offset3.span-box - .page-header - h1 Attribution - p - | We've only been able to create ShareLaTeX thanks to the many amazing free and - | open source technologies that exist. Here are some that we have been using and would - | like to say thank you to: - ul - li - a(href="http://nodejs.org/") Node.js - | and the massive set of modules that are available. - li - a(href="https://github.com/jviereck/pdfListView") pdfListView. - | A wrapper for PDF.js that powers our built in PDF viewer. - li - a(href="http://www.iconshock.com/") Icons from Iconshock. - li - a(href="http://twitter.github.com/bootstrap/") Bootstrap - | for letting us survive without being designers. - - include ../general/small-footer - - - - - diff --git a/services/web/app/views/about/planned_maintenance.jade b/services/web/app/views/about/planned_maintenance.jade deleted file mode 100644 index 5fb0b1edde..0000000000 --- a/services/web/app/views/about/planned_maintenance.jade +++ /dev/null @@ -1,16 +0,0 @@ -extends ../layout - -block content - .container - .row - .span6.offset3.span-box - .page-header - h1 Planned Maintenance - p There is currently no planned maintenance - - include ../general/small-footer - - - - - diff --git a/services/web/app/views/about/privacy.jade b/services/web/app/views/about/privacy.jade deleted file mode 100644 index 6a396217a7..0000000000 --- a/services/web/app/views/about/privacy.jade +++ /dev/null @@ -1,26 +0,0 @@ -extends ../layout - -block content - .container - .row - .span8.offset2.span-box - .page-header - h1 Privacy Policy - h3 Information gathering - p When you register for ShareLaTeX we collect information such as your name and email address. ShareLaTeX uses this information to be able to provide our service, for identification and authorization of users, and to be able to contact you. - p The information we collect is not shared with other organisations except as detailed below for the provisioning and improvement of our service. The data we collect will never be sold to third parties for commercial purposes. - - h3 Cookies - p ShareLaTeX uses a cookie, which is a small amount of data stored by your web browser on your computer. The cookie stores your current session and allows you to stay logged in. Cookies are required to use the ShareLaTeX service. - - h3 Data storage - p ShareLaTeX uses third parties to host our services and store your data. You retain all rights to the data you upload to ShareLaTeX. - - h3 Credit cards and billing details - p We use a third party vendor, - a(href="recurly.com") Recurly - | , to store and process credit card transactions. Your email address, credit card details and billing address are passed on to Recurly and are not stored with ShareLaTeX. - - h3 Third party tracking - p We use Google Analytics, Mixpanel and HeapAnalytics to track users' interactions with ShareLaTeX. This data is used for the improvement of our service. - include ../general/small-footer diff --git a/services/web/app/views/about/security.jade b/services/web/app/views/about/security.jade deleted file mode 100644 index cbbfbb4481..0000000000 --- a/services/web/app/views/about/security.jade +++ /dev/null @@ -1,94 +0,0 @@ -extends ../layout - -block content - .container - .row - .span6.offset3.span-box - .page-header - h1 Security - p - | Keeping your data safe is one of our top priorities. - | We work hard to make sure that ShareLaTeX is as secure as we can make it, - | and your input and feedback on our security is always appreciated. - h3 Responsible disclosure - p - | Please send reports of any urgent or sensitive security issues to - a(href="mailto:team@sharelatex.com") team@sharelatex.com. - | Use our - a(href="/sharelatex-security.pub") public key - | to encrypt your message and please provide us with a secure way to - | contact you. - - p - | Note that the URLs at /learn, /help - | and ctan.sharelatex.com are not under our direct control, - | and vulnerabilities should be reported to either MediaWiki or TenderApp - | respectively. - - p - | We are very grateful for all the responsibly reported security vulnerabilities, - | however listing on the hall of fame is reserved for people who report - | vulnerabilities that were previously unknown and we regard as serious. - - h3 Acknowledgements - p - | We'd like to thank the following people who have responsibly disclosed - | vulnerabilities to us and helped improved the security of ShareLaTeX: - - ul - li - a(href="https://twitter.com/Abdulahhusam", rel="nofollow") Abdullah Hussam Gazi - li - a(href="http://adamziaja.com", rel="nofollow") Adam Ziaja - li - a(href="http://alihassanpenetrationtester.blogspot.com/", rel="nofollow") Ali Hasan Ghauri - li - a(href="https://twitter.com/EhArvindSingh") Arvind Singh Shekhawat - li - a(href="https://www.facebook.com/Dakshxss", rel="nofollow") Daksh Patel - li - a(href="https://twitter.com/dibsyhex", rel="nofollow") Dibyendu Sikdar - li - a(href="https://www.facebook.com/jaymark.pestano", rel="nofollow") Jaymark Pestaño - li - a(href="https://twitter.com/korapsyon", rel="nofollow") Jerold Camacho - li - a(href="https://twitter.com/kamilsevi", rel="nofollow") Kamil Sevi - li - a(href="https://twitter.com/kingkaustubhp", rel="nofollow") Kaustubh Padwad - li 'KoF2002' & 'Sr33h4r!(XSS no0B)' - li - a(href="http://twitter.com/umenmactech", rel="nofollow") Manish Bhattacharya - li - a(href="http://twitter.com/Manjesh24", rel="nofollow") Manjesh S - li - a(href="https://www.facebook.com/Shahmeer.1994", rel="nofollow") Muhammad Shahmeer - li - a(href="http://nbsriharsha.blogspot.in", rel="nofollow") N B Sri Harsha - li - a(href="http://www.linkedin.com/in/osandamalith", rel="nofollow") Osanda Malith Jayathissa - li - a(href="https://twitter.com/prasadk14", rel="nofollow") Prasad Kancharla - li - a(href="https://www.facebook.com/c0m4dr3404", rel="nofollow") Praveen Nair (Kerala Cyber Squad - India) - li - a(href="https://twitter.com/iAmPr3m", rel="nofollow") Prem Kumar - li - a(href="https://www.facebook.com/HardNocksHittnHard", rel="nofollow") Sherin Panikar (Kerala Cyber Squad - India) - li - a(href="https://twitter.com/Simon90_Italy", rel="nofollow") Simone Memoli - li - a(href="https://twitter.com/tareksiddiki", rel="nofollow") Tarek Siddiki - li - a(href="https://twitter.com/venugopalt", rel="nofollow") Venugopal Thotakura - li - a(href="http://softproweb.blogspot.com/", rel="nofollow") Waqeeh Ul Hasan - li - a(href="https://twitter.com/zerodayguys", rel="nofollow") Zeroday Guys (Rakesh Singh & V.Harish Kumar) - li - a(href="https://twitter.com/_prashantnegi", rel="nofollow") Prashant Negi - span and - a(href="https://twitter.com/AjaySinghNegi", rel="nofollow") Singh Negi - li - a(href="https://twitter.com/mohitnitrr") Monendra Sahu - include ../general/small-footer diff --git a/services/web/app/views/about/tos.jade b/services/web/app/views/about/tos.jade deleted file mode 100644 index fa525ac68a..0000000000 --- a/services/web/app/views/about/tos.jade +++ /dev/null @@ -1,34 +0,0 @@ -extends ../layout - -block content - .container - .row - .span8.offset2.span-box - .page-header - h1 Terms of Service - p - | Thank you for taking the time to read our terms of service. - | We've tried to keep it simple, but you must agree to these terms in order to use ShareLaTeX. - h3 You must provide a valid email address - p - | We expect you to register with a valid email address. - | This will be our only way to communicate with you. - | Changes to these terms of service and any other notifications about updates - | to the service will be sent to the email address you provide. - | We will not be held responsible for any information not being received. - h3 You own your content, not us - p You retain all ownership, copyright and intellectual property rights to any content uploaded to ShareLaTeX. Your content will only be shared with other users of your choosing and we will never share your content with third parties without your consent. The staff of ShareLaTeX have access to your content, but we make an effort to only access it when absolutely necessary. - h3 You're not allowed to abuse the service - p ShareLaTeX is provided assuming users will act in good faith. However, we retain the right to remove any account or content that we feel is abusing the service. In the rare event of this happening, it will most likely be for one of the following reasons: using the service for illegal reasons; uploading illegal, unauthorised or objectionable content; consuming an excessive amount of computing resources. - h3 We're not infallible - p ShareLaTeX is provided on an 'as is' basis, without future promise of availability. ShareLaTeX is not liable for any damages caused by the loss or inability to access your data. - p [Founder's note: We try hard to provide a service which is reliable, secure and regularly backed up. While the above paragraph sounds grim, we need it there to cover ourselves incase something does go wrong. We certainly aren't planning to need to fall back on it. This assurance aside, it's always good practice to back up your own data.] - h3 Cancellation and refunds policy - p ShareLaTeX's services are paid for monthly or yearly in advance and are non-refundable. There will be no refunds or credits for partial months/years of service or downgrades. Subscription downgrades and cancellations will come into effect when your next payment is due. Upgrades to your plan will be billed immediately at the new rate for the remainder of the billing period. You may cancel your account at any time from your account subscription settings. - h3 Paypal Reference Transactions - p PayPal Reference Transactions are used to allow ShareLaTeX to make subsequent transactions on a monthly or annual basis until you cancel your account. - h3 Pricing changes - p We will notify you of any changes to our pricing plans that affect you at least 30 days before your next payment is due. We will notify you via the email address you provided when subscribing for a paid plan. - h3 You must be human - p To protect ourselves from accidental or malicious abuse, automated scripts and programs are not permitted to register an account or access the service. - include ../general/small-footer diff --git a/services/web/app/views/homepage/comments.jade b/services/web/app/views/homepage/comments.jade deleted file mode 100644 index a73b194f84..0000000000 --- a/services/web/app/views/homepage/comments.jade +++ /dev/null @@ -1,46 +0,0 @@ -include header - -mixin quote(quote, author) - blockquote - p #{quote} - small #{author} - -extends ../layout - -block content - .container.box - .page-header - h2 What a few of the thousands of people using sharelatex are saying - .row - .span4 - - .span4 - - .span4 - - .row - .span4 - - .span4 - - .span4 - - .row - .span4 - - .span4 - - .span4 - - .row - .span4 - - .span4 - - .span4 - - - - - - locals.supressDefaultJs = true - script(data-main=jsPath+'main.js', src='js/libs/require.js', baseurl=jsPath) diff --git a/services/web/app/views/homepage/header.jade b/services/web/app/views/homepage/header.jade deleted file mode 100644 index 0195b3090a..0000000000 --- a/services/web/app/views/homepage/header.jade +++ /dev/null @@ -1,15 +0,0 @@ -.container - #logoArea - .span8 - h1.logo.large - a(href='/').plain ShareLaTeX - span.sub.logo Online LaTeX Editor - .span3#homePagePills - ul.nav.nav-pills - li - a(href='/') Home - li - a(href='/blog') Blog - li - a(href='/comments') Comments - diff --git a/services/web/app/views/homepage/home.jade b/services/web/app/views/homepage/home.jade deleted file mode 100644 index 8b70d7b1b9..0000000000 --- a/services/web/app/views/homepage/home.jade +++ /dev/null @@ -1,64 +0,0 @@ -link(rel='canonical', href='https://www.sharelatex.com') - -extends ../layout - -block content - .masthead - .container - .row - .title.span8 - h1 Online LaTeX Editor - h2 Quickly start using LaTeX and work together in real-time - div - img(src="/img/screenshot.png") - .register.span4 - h2 Register now - .messageArea - include ../general/partial/registerForm - - .universities - .container - .row - p Used by students and academics at: - #slides - .clearfix - .span3 - img(src="/img/crests/harvard.gif", alt="harvard university logo") - .span3 - img(src="/img/crests/mit.gif", alt="mit university logo") - .span3 - img(src="/img/crests/oxford.gif", alt="oxford university logo") - .span3 - img(src="/img/crests/tokyo.png", alt="tokyo university logo") - .clearfix - .span3 - img(src="/img/crests/cambridge.png", alt="cambridge university logo") - .span3 - img(src="/img/crests/liverpool.jpg", alt="liverpool university logo") - .span3 - img(src="/img/crests/icl.png", alt="icl university logo") - .span3 - img(src="/img/crests/yale.png", alt="yale university logo") - .clearfix - .span3 - img(src="/img/crests/durham.png", alt="durham university logo") - .span3 - img(src="/img/crests/nasa.png", alt="nasa university logo") - .span3 - img(src="/img/crests/toronto.gif", alt="toronto university logo") - .span3 - img(src="/img/crests/stanford.png", alt="stanford university logo") - - - .container - include ../general/long-form-features - - .row - .span12.lower-signup-button - a(href="/user/subscription/plans").btn.btn-success.btn-huge Sign up now! - - include ../general/social-footer - include ../general/small-footer - - - diff --git a/services/web/app/views/homepage/socialMedia.jade b/services/web/app/views/homepage/socialMedia.jade deleted file mode 100644 index 839a4804a0..0000000000 --- a/services/web/app/views/homepage/socialMedia.jade +++ /dev/null @@ -1,7 +0,0 @@ - -.span2.offset3 - include ../referal/tweet -.span2 - include ../referal/googleplus -.span1 - include ../referal/facebookLike diff --git a/services/web/app/views/menubar.jade b/services/web/app/views/menubar.jade index 6f4c563d21..8b91d7d2a0 100644 --- a/services/web/app/views/menubar.jade +++ b/services/web/app/views/menubar.jade @@ -36,8 +36,9 @@ ul.dropdown-menu li a(href='/user/settings').userSettingsLink User Settings - li - a(href='/user/subscription').subscriptionLink Subscription + - if (settings.enableSubscriptions) + li + a(href='/user/subscription').subscriptionLink Subscription li a(href='/logout').logoutLink Logout -else diff --git a/services/web/app/views/resources.jade b/services/web/app/views/resources.jade deleted file mode 100644 index 101175736d..0000000000 --- a/services/web/app/views/resources.jade +++ /dev/null @@ -1,59 +0,0 @@ -extends layout - -block content - .container - .row - .span12.span-box - .page-header - h1 LaTeX Resources - small   We are the LaTeX Editor, here are some other LaTeX resources we like - div - ul - li - a(href='http://en.wikibooks.org/wiki/LaTeX') LaTeX Wikibook - span   - Covering 95% of what you need to know about LaTeX in a clear and simple way with great examples you can often copy and paste - li - a(href='http://detexify.kirelabs.org/classify.html') Detexify - span   - A great way of finding LaTeX symbols - li - a(href='http://www.tug.dk/FontCatalogue/seriffonts.html') LaTeX Fonts - span   - A collection of LaTeX fonts - li - a(href='http://mathurl.com/') MathUrl - span   - allows for live equation editing - li - a(href='http://webdemo.visionobjects.com/equation.html') WebEquation - span   - draw the symbol on the screen to see the LaTeX equivalent - li - a(href='http://www.texample.net/') TeXample.net - span   - a great site for tikz reference - li - a(href='http://www.howtotex.com/') howtoTeX.com - span   - a useful collection of templates, tutorials and how-tos - li - a(href='http://truben.no/latex/table/') LaTeX table editor - span   - if you struggle with tables in LaTeX this tool gives you a nice 'excel like' view to help you along - li - a(href="http://www.math.binghamton.edu/erik/beameruserguide.pdf") Beamer user guide - span   - A good guide into beamer - div - h3 Mobile Apps - ul - li - a(href='https://play.google.com/store/apps/details?id=coolcherrytrees.software.detexify&feature=search_result#?t=W251bGwsMSwxLDEsImNvb2xjaGVycnl0cmVlcy5zb2Z0d2FyZS5kZXRleGlmeSJd') Android - li - a(href='https://itunes.apple.com/app/detexify/id328805329?mt=8') Detexify for ios - li - a(href='http://www.windowsphone.com/en-us/store/app/detexify/3e6813bd-04b1-455b-bc14-14dfe904c54b') Detexify for Windows Phone - li - a(href='http://www.windowsphone.com/en-us/store/app/repotex/694085e0-e825-425b-a40d-40bce5cecb3b') Repotex - li - a(href='http://www.windowsphone.com/en-us/store/app/fasttexdraw/3e1b4255-7798-45ec-b679-a43e74e82769') FastTeXDraw for windows phone - - hr - div - | If you know of other resources, please - a.js-tender-widget(href='#') recommend -   them to us. - include ./general/small-footer - From 26b0f4658fc9766263ce13f49ec1abd044326914 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 3 Apr 2014 11:45:30 +0100 Subject: [PATCH 49/62] Ignore external directory --- services/web/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/web/.gitignore b/services/web/.gitignore index ad7f51119c..601a74db0e 100644 --- a/services/web/.gitignore +++ b/services/web/.gitignore @@ -63,6 +63,8 @@ public/minjs/ public/js/main.js Gemfile.lock +app/views/external + *.swp .DS_Store From e9309532d39eafb84fcda1b2ec3967c230f3e7bf Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 3 Apr 2014 15:50:50 +0100 Subject: [PATCH 50/62] Make greyed out background the default track changes prompt --- services/web/app/views/templates.jade | 9 --------- .../track-changes/TrackChangesManager.coffee | 20 ++----------------- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index e8ddb209df..386ecb51a3 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -449,9 +449,6 @@ button.btn.btn-primary.start-free-trial Start free trial .message.show-when-not-owner p Please ask the project owner to upgrade to use the History feature. - .track-changes-upgrade-control(style="display: none;") - .message History is not yet enabled for this project. - button.btn.btn-primary.btn-large.upgrade Enable History script(type='text/template')#trackChangesDiffTemplate .track-changes-diff-toolbar.btn-toolbar @@ -481,12 +478,6 @@ ul.change-list.nav.nav-pills.nav-stacked li.loading-changes Loading... li.empty-message You haven't made any changes yet! - li.track-changes-upgrade-oneweek(style="display: none;") - p We only store one week of changes for free accounts. - p.show-when-owner Upgrade for an unlimited history. - p.show-when-owner - button.btn.btn-primary.start-free-trial Start free trial - p.show-when-not-owner Please ask the project owner to upgrade. script(type='text/template')#hotKeysListTemplate .hotkeys diff --git a/services/web/public/coffee/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/track-changes/TrackChangesManager.coffee index 25fd0650e2..d1a8484a91 100644 --- a/services/web/public/coffee/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/track-changes/TrackChangesManager.coffee @@ -74,19 +74,12 @@ define [ @enable() showUpgradeView: () -> - @upgradeType ||= @ide.analyticsManager.startABTest('track-changes-upgrade', @AB_BUCKETS) - @$el.find("button.upgrade").off "click.track-changes" @$el.find("button.start-free-trial").off "click.track-changes" - @$el.find("button.upgrade").on "click.track-changes", () => @askToUpgrade() @$el.find("button.start-free-trial").on "click.track-changes", () => @gotoFreeTrial() if !@ide.project.get("features").versioning - if @upgradeType == "pop-up" - @$el.find(".track-changes-upgrade-popup").show() - else if @upgradeType == "control" - @$el.find(".track-changes-upgrade-control").show() - else if @upgradeType == "one-week" - @$el.find(".track-changes-upgrade-oneweek").show() + ga('send', 'event', 'subscription-funnel', 'askToUgrade', "trackchanges") + @$el.find(".track-changes-upgrade-popup").show() if @ide.project.get("owner") == @ide.user @$el.find(".show-when-not-owner").hide() @@ -230,17 +223,8 @@ define [ disable: () -> @enabled = false - askToUpgrade: () -> - ga('send', 'event', 'subscription-funnel', 'askToUpgrade', "trackchanges") - ga('send', 'event', 'ab_tests', 'track-changes-upgrade', "prompted-to-upgrade-#{@upgradeType}") - AccountManager.askToUpgrade @ide, - onUpgrade: () => - @ide.analyticsManager.endABTest('track-changes-upgrade', @AB_BUCKETS) - ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "trackchanges") - gotoFreeTrial: () -> AccountManager.gotoSubscriptionsPage() - @ide.analyticsManager.endABTest('track-changes-upgrade', @AB_BUCKETS) ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "trackchanges") return TrackChangesManager From 24d38289478ae333000f7aeac1c2fc66d8eba08a Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 4 Apr 2014 14:08:55 +0100 Subject: [PATCH 51/62] updated licence for more thing to be included in the agpl --- services/web/README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/services/web/README.md b/services/web/README.md index b74e61b983..00d94343ab 100644 --- a/services/web/README.md +++ b/services/web/README.md @@ -17,10 +17,7 @@ Unit test status License and Credits ------------------- -### Code - -All coffeescript files (files ended in *.coffee) are licensed under the -[AGPLv3 license](http://www.gnu.org/licenses/agpl-3.0.html). +This project is licensed under the [AGPLv3 license](http://www.gnu.org/licenses/agpl-3.0.html) ### Stylesheets From 615e05cb89ccfc40515cc48b9f4458f49b1b2bce Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 4 Apr 2014 15:47:27 +0100 Subject: [PATCH 52/62] moved newsletter manager into its own feature --- .../Newsletter}/NewsletterManager.coffee | 0 .../Features/Subscription/SubscriptionViewModelBuilder.coffee | 2 ++ services/web/app/coffee/Features/User/UserDeleter.coffee | 2 +- services/web/app/coffee/controllers/UserController.coffee | 2 +- services/web/app/coffee/managers/SecurityManager.coffee | 4 +++- .../web/test/UnitTests/coffee/User/UserDeleterTests.coffee | 2 +- 6 files changed, 8 insertions(+), 4 deletions(-) rename services/web/app/coffee/{managers => Features/Newsletter}/NewsletterManager.coffee (100%) diff --git a/services/web/app/coffee/managers/NewsletterManager.coffee b/services/web/app/coffee/Features/Newsletter/NewsletterManager.coffee similarity index 100% rename from services/web/app/coffee/managers/NewsletterManager.coffee rename to services/web/app/coffee/Features/Newsletter/NewsletterManager.coffee diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee index 340863a405..74f91a8dad 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee @@ -38,6 +38,8 @@ module.exports = buildViewModel : -> plans = Settings.plans + console.log plans + console.log(typeof(plans)) allPlans = {} plans.forEach (plan)-> allPlans[plan.planCode] = plan diff --git a/services/web/app/coffee/Features/User/UserDeleter.coffee b/services/web/app/coffee/Features/User/UserDeleter.coffee index 56ff06df4c..7361c7ab56 100644 --- a/services/web/app/coffee/Features/User/UserDeleter.coffee +++ b/services/web/app/coffee/Features/User/UserDeleter.coffee @@ -1,5 +1,5 @@ User = require("../../models/User").User -NewsletterManager = require "../../managers/NewsletterManager" +NewsletterManager = require "../Newsletter/NewsletterManager" ProjectDeleter = require("../Project/ProjectDeleter") logger = require("logger-sharelatex") SubscriptionHandler = require("../Subscription/SubscriptionHandler") diff --git a/services/web/app/coffee/controllers/UserController.coffee b/services/web/app/coffee/controllers/UserController.coffee index e00a075c37..63c0837009 100644 --- a/services/web/app/coffee/controllers/UserController.coffee +++ b/services/web/app/coffee/controllers/UserController.coffee @@ -5,7 +5,7 @@ _ = require('underscore') logger = require('logger-sharelatex') Security = require('../managers/SecurityManager') Settings = require('settings-sharelatex') -newsLetterManager = require('../managers/NewsletterManager') +newsLetterManager = require('../Features/Newsletter/NewsletterManager') dropboxHandler = require('../Features/Dropbox/DropboxHandler') userRegistrationHandler = require('../Features/User/UserRegistrationHandler') metrics = require('../infrastructure/Metrics') diff --git a/services/web/app/coffee/managers/SecurityManager.coffee b/services/web/app/coffee/managers/SecurityManager.coffee index 38d7bdabef..1f757fd9c2 100644 --- a/services/web/app/coffee/managers/SecurityManager.coffee +++ b/services/web/app/coffee/managers/SecurityManager.coffee @@ -166,7 +166,9 @@ getRequestUserAndProject = (req, res, options, callback)-> callback err, user, project getProjectIdFromRef = (ref)-> - if ref._id? + if !ref? + return null + else if ref._id? return ref._id+'' else return ref+'' diff --git a/services/web/test/UnitTests/coffee/User/UserDeleterTests.coffee b/services/web/test/UnitTests/coffee/User/UserDeleterTests.coffee index 79a7b965c4..34fabda11c 100644 --- a/services/web/test/UnitTests/coffee/User/UserDeleterTests.coffee +++ b/services/web/test/UnitTests/coffee/User/UserDeleterTests.coffee @@ -25,7 +25,7 @@ describe "UserDeleter", -> cancelSubscription: sinon.stub().callsArgWith(1) @UserDeleter = SandboxedModule.require modulePath, requires: "../../models/User": User: @User - "../../managers/NewsletterManager": @NewsletterManager + "../Newsletter/NewsletterManager": @NewsletterManager "../Subscription/SubscriptionHandler": @SubscriptionHandler "../Project/ProjectDeleter": @ProjectDeleter From 68271b04f9698b1c276d00b6b5344ed9fd78f151 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 4 Apr 2014 15:58:59 +0100 Subject: [PATCH 53/62] deleted guid manager --- .../coffee/Features/ThirdPartyDataStore/UpdateMerger.coffee | 4 ++-- .../web/app/coffee/controllers/ProjectController.coffee | 1 - services/web/app/coffee/managers/GuidManager.coffee | 6 ------ 3 files changed, 2 insertions(+), 9 deletions(-) delete mode 100644 services/web/app/coffee/managers/GuidManager.coffee diff --git a/services/web/app/coffee/Features/ThirdPartyDataStore/UpdateMerger.coffee b/services/web/app/coffee/Features/ThirdPartyDataStore/UpdateMerger.coffee index d4548b4a3e..3a787bc985 100644 --- a/services/web/app/coffee/Features/ThirdPartyDataStore/UpdateMerger.coffee +++ b/services/web/app/coffee/Features/ThirdPartyDataStore/UpdateMerger.coffee @@ -5,7 +5,7 @@ logger = require('logger-sharelatex') Settings = require('settings-sharelatex') slReqIdHelper = require('soa-req-id') FileTypeManager = require('../Uploads/FileTypeManager') -GuidManager = require '../../managers/GuidManager' +uuid = require('node-uuid') fs = require('fs') module.exports = @@ -75,7 +75,7 @@ module.exports = writeStreamToDisk: (project_id, file_id, stream, callback = (err, fsPath)->)-> if !file_id? - file_id = GuidManager.newGuid() + file_id = uuid.v4() dumpPath = "#{Settings.path.dumpFolder}/#{project_id}_#{file_id}" writeStream = fs.createWriteStream(dumpPath) diff --git a/services/web/app/coffee/controllers/ProjectController.coffee b/services/web/app/coffee/controllers/ProjectController.coffee index bb53b6ee20..52e89d29d4 100755 --- a/services/web/app/coffee/controllers/ProjectController.coffee +++ b/services/web/app/coffee/controllers/ProjectController.coffee @@ -7,7 +7,6 @@ _ = require('underscore') fs = require('fs') ProjectHandler = require '../handlers/ProjectHandler' SecurityManager = require '../managers/SecurityManager' -GuidManager = require '../managers/GuidManager' Settings = require('settings-sharelatex') projectCreationHandler = require '../Features/Project/ProjectCreationHandler' projectDuplicator = require('../Features/Project/ProjectDuplicator') diff --git a/services/web/app/coffee/managers/GuidManager.coffee b/services/web/app/coffee/managers/GuidManager.coffee deleted file mode 100644 index c283670282..0000000000 --- a/services/web/app/coffee/managers/GuidManager.coffee +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = - newGuid : ()-> - S4 = ()-> - return (((1+Math.random())*0x10000)|0).toString(16).substring(1) - return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4()) - From 3983e77b73c8a2fef047ad0c1cffbeb29b8688a2 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 4 Apr 2014 16:21:20 +0100 Subject: [PATCH 54/62] move deleteProject from collab manager to editor controller --- .../coffee/Features/Editor/EditorController.coffee | 5 +++++ .../app/coffee/managers/CollaberationManager.coffee | 5 ----- services/web/app/coffee/router.coffee | 2 +- .../coffee/Editor/EditorControllerTests.coffee | 12 ++++++++++++ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee index 81084dc7e9..b123f22dc5 100644 --- a/services/web/app/coffee/Features/Editor/EditorController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorController.coffee @@ -237,6 +237,11 @@ module.exports = EditorController = EditorRealTimeController.emitToRoom(project_id, 'projectDescriptionUpdated', description) callback() + deleteProject: (project_id, callback)-> + Metrics.inc "editor.delete-project" + logger.log project_id:project_id, "recived message to delete project" + ProjectHandler.deleteProject project_id, callback + p: notifyProjectUsersOfNewFolder: (project_id, folder_id, folder, callback = (error)->)-> logger.log project_id:project_id, folder:folder, parentFolder_id:folder_id, "sending newly created folder out to users" diff --git a/services/web/app/coffee/managers/CollaberationManager.coffee b/services/web/app/coffee/managers/CollaberationManager.coffee index 28fcb00795..f110a00a17 100644 --- a/services/web/app/coffee/managers/CollaberationManager.coffee +++ b/services/web/app/coffee/managers/CollaberationManager.coffee @@ -15,11 +15,6 @@ EditorRealTimeController = require('../Features/Editor/EditorRealTimeController' module.exports = class CollaberationManager constructor: (@io)-> - deleteProject: (project_id, callback)-> - metrics.inc "editor.delete-project" - logger.log project_id:project_id, "recived message to delete project" - projectHandler.deleteProject project_id, callback - renameEntity: (project_id, entity_id, entityType, newName, callback)-> newName = sanitize.escape(newName) metrics.inc "editor.rename-entity" diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index 66858f0056..ce925cade0 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -311,7 +311,7 @@ module.exports = class Router client.on 'deleteProject', (callback)-> AuthorizationManager.ensureClientCanAdminProject client, (error, project_id) => - collaberationManager.deleteProject(project_id, callback) + EditorController.deleteProject(project_id, callback) client.on 'setPublicAccessLevel', (newAccessLevel, callback)-> AuthorizationManager.ensureClientCanAdminProject client, (error, project_id) => diff --git a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee index 933c5bae3b..efb469769d 100644 --- a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee @@ -609,3 +609,15 @@ describe "EditorController", -> done() + describe "deleteProject", -> + + beforeEach -> + @err = "errro" + @ProjectHandler::deleteProject = sinon.stub().callsArgWith(1, @err) + + it "should call the project handler", (done)-> + @EditorController.deleteProject @project_id, (err)=> + err.should.equal @err + @ProjectHandler::deleteProject.calledWith(@project_id).should.equal true + done() + From 88e47bbe120a6c8bd7add7b702fa88bc323aa9b8 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 4 Apr 2014 16:35:02 +0100 Subject: [PATCH 55/62] moved renameEntity from collab manager to editor controller --- .../Features/Editor/EditorController.coffee | 11 ++++++++++ .../managers/CollaberationManager.coffee | 9 -------- services/web/app/coffee/router.coffee | 2 +- .../Editor/EditorControllerTests.coffee | 22 +++++++++++++++++++ 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee index b123f22dc5..ff5e512abc 100644 --- a/services/web/app/coffee/Features/Editor/EditorController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorController.coffee @@ -242,6 +242,17 @@ module.exports = EditorController = logger.log project_id:project_id, "recived message to delete project" ProjectHandler.deleteProject project_id, callback + renameEntity: (project_id, entity_id, entityType, newName, callback)-> + newName = sanitize.escape(newName) + Metrics.inc "editor.rename-entity" + logger.log entity_id:entity_id, entity_id:entity_id, entity_id:entity_id, "reciving new name for entity for project" + ProjectHandler.renameEntity project_id, entity_id, entityType, newName, => + if newName.length > 0 + EditorRealTimeController.emitToRoom project_id, 'reciveEntityRename', entity_id, newName + callback?() + + + p: notifyProjectUsersOfNewFolder: (project_id, folder_id, folder, callback = (error)->)-> logger.log project_id:project_id, folder:folder, parentFolder_id:folder_id, "sending newly created folder out to users" diff --git a/services/web/app/coffee/managers/CollaberationManager.coffee b/services/web/app/coffee/managers/CollaberationManager.coffee index f110a00a17..d6de7ca020 100644 --- a/services/web/app/coffee/managers/CollaberationManager.coffee +++ b/services/web/app/coffee/managers/CollaberationManager.coffee @@ -15,15 +15,6 @@ EditorRealTimeController = require('../Features/Editor/EditorRealTimeController' module.exports = class CollaberationManager constructor: (@io)-> - renameEntity: (project_id, entity_id, entityType, newName, callback)-> - newName = sanitize.escape(newName) - metrics.inc "editor.rename-entity" - logger.log entity_id:entity_id, entity_id:entity_id, entity_id:entity_id, "reciving new name for entity for project" - projectHandler.renameEntity project_id, entity_id, entityType, newName, => - if newName.length > 0 - EditorRealTimeController.emitToRoom project_id, 'reciveEntityRename', entity_id, newName - callback?() - moveEntity: (project_id, entity_id, folder_id, entityType, callback)-> metrics.inc "editor.move-entity" projectEntityHandler.moveEntity project_id, entity_id, folder_id, entityType, => diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index ce925cade0..54adc4632d 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -291,7 +291,7 @@ module.exports = class Router client.on 'renameEntity', (entity_id, entityType, newName, callback)-> AuthorizationManager.ensureClientCanEditProject client, (error, project_id) => - collaberationManager.renameEntity(project_id, entity_id, entityType, newName, callback) + EditorController.renameEntity(project_id, entity_id, entityType, newName, callback) client.on 'moveEntity', (entity_id, folder_id, entityType, callback)-> AuthorizationManager.ensureClientCanEditProject client, (error, project_id) => diff --git a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee index efb469769d..6c7204da08 100644 --- a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee @@ -621,3 +621,25 @@ describe "EditorController", -> @ProjectHandler::deleteProject.calledWith(@project_id).should.equal true done() + + describe "renameEntity", -> + + beforeEach -> + @err = "errro" + @entity_id = "entity_id_here" + @entityType = "doc" + @newName = "bobsfile.tex" + @ProjectHandler::renameEntity = sinon.stub().callsArgWith(4, @err) + @EditorRealTimeController.emitToRoom = sinon.stub() + + it "should call the project handler", (done)-> + @EditorController.renameEntity @project_id, @entity_id, @entityType, @newName, => + @ProjectHandler::renameEntity.calledWith(@project_id, @entity_id, @entityType, @newName).should.equal true + done() + + + it "should emit the update to the room", (done)-> + @EditorController.renameEntity @project_id, @entity_id, @entityType, @newName, => + @EditorRealTimeController.emitToRoom.calledWith(@project_id, 'reciveEntityRename', @entity_id, @newName).should.equal true + done() + From d684f04d4f526cc4304a04833b55c652fcba704e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 4 Apr 2014 16:40:53 +0100 Subject: [PATCH 56/62] moved moveEntity from collab manager to editor controller --- .../Features/Editor/EditorController.coffee | 6 +++++- .../managers/CollaberationManager.coffee | 6 ------ services/web/app/coffee/router.coffee | 2 +- .../Editor/EditorControllerTests.coffee | 21 +++++++++++++++++++ 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee index ff5e512abc..c867942388 100644 --- a/services/web/app/coffee/Features/Editor/EditorController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorController.coffee @@ -251,7 +251,11 @@ module.exports = EditorController = EditorRealTimeController.emitToRoom project_id, 'reciveEntityRename', entity_id, newName callback?() - + moveEntity: (project_id, entity_id, folder_id, entityType, callback)-> + Metrics.inc "editor.move-entity" + ProjectEntityHandler.moveEntity project_id, entity_id, folder_id, entityType, => + EditorRealTimeController.emitToRoom project_id, 'reciveEntityMove', entity_id, folder_id + callback?() p: notifyProjectUsersOfNewFolder: (project_id, folder_id, folder, callback = (error)->)-> diff --git a/services/web/app/coffee/managers/CollaberationManager.coffee b/services/web/app/coffee/managers/CollaberationManager.coffee index d6de7ca020..fdf72f5f4b 100644 --- a/services/web/app/coffee/managers/CollaberationManager.coffee +++ b/services/web/app/coffee/managers/CollaberationManager.coffee @@ -15,12 +15,6 @@ EditorRealTimeController = require('../Features/Editor/EditorRealTimeController' module.exports = class CollaberationManager constructor: (@io)-> - moveEntity: (project_id, entity_id, folder_id, entityType, callback)-> - metrics.inc "editor.move-entity" - projectEntityHandler.moveEntity project_id, entity_id, folder_id, entityType, => - EditorRealTimeController.emitToRoom project_id, 'reciveEntityMove', entity_id, folder_id - callback?() - renameProject: (project_id, window_id, newName, callback)-> newName = sanitize.escape(newName) projectHandler.renameProject project_id, window_id, newName, => diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index 54adc4632d..ffba1033a5 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -295,7 +295,7 @@ module.exports = class Router client.on 'moveEntity', (entity_id, folder_id, entityType, callback)-> AuthorizationManager.ensureClientCanEditProject client, (error, project_id) => - collaberationManager.moveEntity(project_id, entity_id, folder_id, entityType, callback) + EditorController.moveEntity(project_id, entity_id, folder_id, entityType, callback) client.on 'setProjectName', (window_id, newName, callback)-> AuthorizationManager.ensureClientCanEditProject client, (error, project_id) => diff --git a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee index 6c7204da08..23346f6379 100644 --- a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee @@ -643,3 +643,24 @@ describe "EditorController", -> @EditorRealTimeController.emitToRoom.calledWith(@project_id, 'reciveEntityRename', @entity_id, @newName).should.equal true done() + + describe "moveEntity", -> + + beforeEach -> + @err = "errro" + @entity_id = "entity_id_here" + @entityType = "doc" + @folder_id = "313dasd21dasdsa" + @ProjectEntityHandler.moveEntity = sinon.stub().callsArgWith(4, @err) + @EditorRealTimeController.emitToRoom = sinon.stub() + + it "should call the ProjectEntityHandler", (done)-> + @EditorController.moveEntity @project_id, @entity_id, @folder_id, @entityType, => + @ProjectEntityHandler.moveEntity.calledWith(@project_id, @entity_id, @folder_id, @entityType).should.equal true + done() + + + it "should emit the update to the room", (done)-> + @EditorController.moveEntity @project_id, @entity_id, @folder_id, @entityType, => + @EditorRealTimeController.emitToRoom.calledWith(@project_id, 'reciveEntityMove', @entity_id, @folder_id).should.equal true + done() From 08d1eeba78df1aae330629235c53f31c4f7c3527 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 4 Apr 2014 16:49:44 +0100 Subject: [PATCH 57/62] moved renameProject from collab manager to editor controller --- .../Features/Editor/EditorController.coffee | 8 +++++++ .../managers/CollaberationManager.coffee | 7 ------- services/web/app/coffee/router.coffee | 2 +- .../Editor/EditorControllerTests.coffee | 21 ++++++++++++++++++- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee index c867942388..34474e7a74 100644 --- a/services/web/app/coffee/Features/Editor/EditorController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorController.coffee @@ -257,6 +257,14 @@ module.exports = EditorController = EditorRealTimeController.emitToRoom project_id, 'reciveEntityMove', entity_id, folder_id callback?() + + renameProject: (project_id, window_id, newName, callback)-> + newName = sanitize.escape(newName) + ProjectHandler.renameProject project_id, window_id, newName, => + newName = sanitize.escape(newName) + EditorRealTimeController.emitToRoom project_id, 'projectNameUpdated', window_id, newName + callback?() + p: notifyProjectUsersOfNewFolder: (project_id, folder_id, folder, callback = (error)->)-> logger.log project_id:project_id, folder:folder, parentFolder_id:folder_id, "sending newly created folder out to users" diff --git a/services/web/app/coffee/managers/CollaberationManager.coffee b/services/web/app/coffee/managers/CollaberationManager.coffee index fdf72f5f4b..2cde97f17b 100644 --- a/services/web/app/coffee/managers/CollaberationManager.coffee +++ b/services/web/app/coffee/managers/CollaberationManager.coffee @@ -15,13 +15,6 @@ EditorRealTimeController = require('../Features/Editor/EditorRealTimeController' module.exports = class CollaberationManager constructor: (@io)-> - renameProject: (project_id, window_id, newName, callback)-> - newName = sanitize.escape(newName) - projectHandler.renameProject project_id, window_id, newName, => - newName = sanitize.escape(newName) - EditorRealTimeController.emitToRoom project_id, 'projectNameUpdated', window_id, newName - callback?() - setPublicAccessLevel : (project_id, newAccessLevel, callback)-> projectHandler.setPublicAccessLevel project_id, newAccessLevel, => EditorRealTimeController.emitToRoom project_id, 'publicAccessLevelUpdated', newAccessLevel diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index ffba1033a5..12b9506268 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -299,7 +299,7 @@ module.exports = class Router client.on 'setProjectName', (window_id, newName, callback)-> AuthorizationManager.ensureClientCanEditProject client, (error, project_id) => - collaberationManager.renameProject(project_id, window_id, newName, callback) + EditorController.renameProject(project_id, window_id, newName, callback) client.on 'getProject',(callback)-> AuthorizationManager.ensureClientCanViewProject client, (error, project_id) => diff --git a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee index 23346f6379..6a474ce429 100644 --- a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee @@ -643,7 +643,6 @@ describe "EditorController", -> @EditorRealTimeController.emitToRoom.calledWith(@project_id, 'reciveEntityRename', @entity_id, @newName).should.equal true done() - describe "moveEntity", -> beforeEach -> @@ -664,3 +663,23 @@ describe "EditorController", -> @EditorController.moveEntity @project_id, @entity_id, @folder_id, @entityType, => @EditorRealTimeController.emitToRoom.calledWith(@project_id, 'reciveEntityMove', @entity_id, @folder_id).should.equal true done() + + describe "renameProject", -> + + beforeEach -> + @err = "errro" + @window_id = "kdsjklj290jlk" + @newName = "new name here" + @ProjectHandler::renameProject = sinon.stub().callsArgWith(3, @err) + @EditorRealTimeController.emitToRoom = sinon.stub() + + it "should call the ProjectHandler", (done)-> + @EditorController.renameProject @project_id, @window_id, @newName, => + @ProjectHandler::renameProject.calledWith(@project_id, @window_id, @newName).should.equal true + done() + + + it "should emit the update to the room", (done)-> + @EditorController.renameProject @project_id, @window_id, @newName, => + @EditorRealTimeController.emitToRoom.calledWith(@project_id, 'projectNameUpdated', @window_id, @newName).should.equal true + done() From 7c10b5cd24bf392ddf69a7035b9d54c0221fa391 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 4 Apr 2014 16:53:59 +0100 Subject: [PATCH 58/62] moved setPublicAccessLevel from collab manager to editor controller --- .../Features/Editor/EditorController.coffee | 6 +++++- .../managers/CollaberationManager.coffee | 5 +---- services/web/app/coffee/router.coffee | 2 +- .../Editor/EditorControllerTests.coffee | 20 +++++++++++++++++++ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee index 34474e7a74..a55e5ec33f 100644 --- a/services/web/app/coffee/Features/Editor/EditorController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorController.coffee @@ -257,7 +257,6 @@ module.exports = EditorController = EditorRealTimeController.emitToRoom project_id, 'reciveEntityMove', entity_id, folder_id callback?() - renameProject: (project_id, window_id, newName, callback)-> newName = sanitize.escape(newName) ProjectHandler.renameProject project_id, window_id, newName, => @@ -265,6 +264,11 @@ module.exports = EditorController = EditorRealTimeController.emitToRoom project_id, 'projectNameUpdated', window_id, newName callback?() + setPublicAccessLevel : (project_id, newAccessLevel, callback)-> + ProjectHandler.setPublicAccessLevel project_id, newAccessLevel, => + EditorRealTimeController.emitToRoom project_id, 'publicAccessLevelUpdated', newAccessLevel + callback?() + p: notifyProjectUsersOfNewFolder: (project_id, folder_id, folder, callback = (error)->)-> logger.log project_id:project_id, folder:folder, parentFolder_id:folder_id, "sending newly created folder out to users" diff --git a/services/web/app/coffee/managers/CollaberationManager.coffee b/services/web/app/coffee/managers/CollaberationManager.coffee index 2cde97f17b..e7a51be154 100644 --- a/services/web/app/coffee/managers/CollaberationManager.coffee +++ b/services/web/app/coffee/managers/CollaberationManager.coffee @@ -15,10 +15,7 @@ EditorRealTimeController = require('../Features/Editor/EditorRealTimeController' module.exports = class CollaberationManager constructor: (@io)-> - setPublicAccessLevel : (project_id, newAccessLevel, callback)-> - projectHandler.setPublicAccessLevel project_id, newAccessLevel, => - EditorRealTimeController.emitToRoom project_id, 'publicAccessLevelUpdated', newAccessLevel - callback?() + distributMessage: (project_id, client, message)-> message = sanitize.escape(message) diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index 12b9506268..be156ef8ac 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -315,7 +315,7 @@ module.exports = class Router client.on 'setPublicAccessLevel', (newAccessLevel, callback)-> AuthorizationManager.ensureClientCanAdminProject client, (error, project_id) => - collaberationManager.setPublicAccessLevel(project_id, newAccessLevel, callback) + EditorController.setPublicAccessLevel(project_id, newAccessLevel, callback) client.on 'pdfProject', (opts, callback)-> AuthorizationManager.ensureClientCanViewProject client, (error, project_id) => diff --git a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee index 6a474ce429..f74500768e 100644 --- a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee @@ -683,3 +683,23 @@ describe "EditorController", -> @EditorController.renameProject @project_id, @window_id, @newName, => @EditorRealTimeController.emitToRoom.calledWith(@project_id, 'projectNameUpdated', @window_id, @newName).should.equal true done() + + + describe "setPublicAccessLevel", -> + + beforeEach -> + @err = "errro" + @newAccessLevel = "public" + @ProjectHandler::setPublicAccessLevel = sinon.stub().callsArgWith(2, @err) + @EditorRealTimeController.emitToRoom = sinon.stub() + + it "should call the ProjectHandler", (done)-> + @EditorController.setPublicAccessLevel @project_id, @newAccessLevel, => + @ProjectHandler::setPublicAccessLevel.calledWith(@project_id, @newAccessLevel).should.equal true + done() + + it "should emit the update to the room", (done)-> + @EditorController.setPublicAccessLevel @project_id, @newAccessLevel, => + @EditorRealTimeController.emitToRoom.calledWith(@project_id, 'publicAccessLevelUpdated', @newAccessLevel).should.equal true + done() + From 90eac4d52c978084530cfd3aea2a62b9c57f5d34 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 4 Apr 2014 16:59:45 +0100 Subject: [PATCH 59/62] moved setRootDoc from collab manager to editor controller --- .../Features/Editor/EditorController.coffee | 6 ++++++ .../coffee/managers/CollaberationManager.coffee | 7 ------- services/web/app/coffee/router.coffee | 2 +- .../coffee/Editor/EditorControllerTests.coffee | 17 +++++++++++++++++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee index a55e5ec33f..413ea4609e 100644 --- a/services/web/app/coffee/Features/Editor/EditorController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorController.coffee @@ -269,6 +269,12 @@ module.exports = EditorController = EditorRealTimeController.emitToRoom project_id, 'publicAccessLevelUpdated', newAccessLevel callback?() + setRootDoc: (project_id, newRootDocID, callback)-> + ProjectEntityHandler.setRootDoc project_id, newRootDocID, () => + EditorRealTimeController.emitToRoom project_id, 'rootDocUpdated', newRootDocID + callback?() + + p: notifyProjectUsersOfNewFolder: (project_id, folder_id, folder, callback = (error)->)-> logger.log project_id:project_id, folder:folder, parentFolder_id:folder_id, "sending newly created folder out to users" diff --git a/services/web/app/coffee/managers/CollaberationManager.coffee b/services/web/app/coffee/managers/CollaberationManager.coffee index e7a51be154..e5e4e85cfd 100644 --- a/services/web/app/coffee/managers/CollaberationManager.coffee +++ b/services/web/app/coffee/managers/CollaberationManager.coffee @@ -15,18 +15,11 @@ EditorRealTimeController = require('../Features/Editor/EditorRealTimeController' module.exports = class CollaberationManager constructor: (@io)-> - - distributMessage: (project_id, client, message)-> message = sanitize.escape(message) metrics.inc "editor.instant-message" client.get "first_name", (err, first_name)=> EditorRealTimeController.emitToRoom project_id, 'reciveNewMessage', first_name, message - setRootDoc: (project_id, newRootDocID, callback)-> - projectEntityHandler.setRootDoc project_id, newRootDocID, () => - EditorRealTimeController.emitToRoom project_id, 'rootDocUpdated', newRootDocID - callback?() - takeVersionSnapShot : (project_id, message, callback)-> versioningApiHandler.takeVersionSnapshot project_id, message, callback diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index be156ef8ac..eb0297d834 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -307,7 +307,7 @@ module.exports = class Router client.on 'setRootDoc', (newRootDocID, callback)-> AuthorizationManager.ensureClientCanEditProject client, (error, project_id) => - collaberationManager.setRootDoc(project_id, newRootDocID, callback) + EditorController.setRootDoc(project_id, newRootDocID, callback) client.on 'deleteProject', (callback)-> AuthorizationManager.ensureClientCanAdminProject client, (error, project_id) => diff --git a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee index f74500768e..55213fdda8 100644 --- a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee @@ -703,3 +703,20 @@ describe "EditorController", -> @EditorRealTimeController.emitToRoom.calledWith(@project_id, 'publicAccessLevelUpdated', @newAccessLevel).should.equal true done() + describe "setRootDoc", -> + + beforeEach -> + @err = "errro" + @newRootDocID = "21312321321" + @ProjectEntityHandler.setRootDoc = sinon.stub().callsArgWith(2, @err) + @EditorRealTimeController.emitToRoom = sinon.stub() + + it "should call the ProjectEntityHandler", (done)-> + @EditorController.setRootDoc @project_id, @newRootDocID, => + @ProjectEntityHandler.setRootDoc.calledWith(@project_id, @newRootDocID).should.equal true + done() + + it "should emit the update to the room", (done)-> + @EditorController.setRootDoc @project_id, @newRootDocID, => + @EditorRealTimeController.emitToRoom.calledWith(@project_id, 'rootDocUpdated', @newRootDocID).should.equal true + done() \ No newline at end of file From 33b6626fd9e78e644c44740513f2c8c2f9745eb8 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 4 Apr 2014 17:08:14 +0100 Subject: [PATCH 60/62] killed CollaberationManager R.I.P --- .../controllers/ProjectController.coffee | 2 +- .../managers/CollaberationManager.coffee | 25 ------------------- services/web/app/coffee/router.coffee | 9 +------ 3 files changed, 2 insertions(+), 34 deletions(-) delete mode 100644 services/web/app/coffee/managers/CollaberationManager.coffee diff --git a/services/web/app/coffee/controllers/ProjectController.coffee b/services/web/app/coffee/controllers/ProjectController.coffee index 52e89d29d4..3b98193f4e 100755 --- a/services/web/app/coffee/controllers/ProjectController.coffee +++ b/services/web/app/coffee/controllers/ProjectController.coffee @@ -18,7 +18,7 @@ SubscriptionFormatters = require("../Features/Subscription/SubscriptionFormatter FileStoreHandler = require("../Features/FileStore/FileStoreHandler") module.exports = class ProjectController - constructor: (@collaberationManager)-> + constructor: ()-> ProjectHandler = new ProjectHandler() list: (req, res, next)-> diff --git a/services/web/app/coffee/managers/CollaberationManager.coffee b/services/web/app/coffee/managers/CollaberationManager.coffee deleted file mode 100644 index e5e4e85cfd..0000000000 --- a/services/web/app/coffee/managers/CollaberationManager.coffee +++ /dev/null @@ -1,25 +0,0 @@ -#this file is being slowly refactored out - -logger = require('logger-sharelatex') -sanitize = require('sanitizer') -projectHandler = require('../handlers/ProjectHandler') -projectHandler = new projectHandler() -SecurityManager = require('./SecurityManager') -_ = require('underscore') -projectEditorHandler = require('../Features/Project/ProjectEditorHandler') -projectEntityHandler = require('../Features/Project/ProjectEntityHandler') -versioningApiHandler = require('../Features/Versioning/VersioningApiHandler') -metrics = require('../infrastructure/Metrics') -EditorRealTimeController = require('../Features/Editor/EditorRealTimeController') - -module.exports = class CollaberationManager - constructor: (@io)-> - - distributMessage: (project_id, client, message)-> - message = sanitize.escape(message) - metrics.inc "editor.instant-message" - client.get "first_name", (err, first_name)=> - EditorRealTimeController.emitToRoom project_id, 'reciveNewMessage', first_name, message - - takeVersionSnapShot : (project_id, message, callback)-> - versioningApiHandler.takeVersionSnapshot project_id, message, callback diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index eb0297d834..90d1cf3379 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -5,7 +5,6 @@ ProjectController = require("./controllers/ProjectController") ProjectApiController = require("./Features/Project/ProjectApiController") InfoController = require('./controllers/InfoController') SpellingController = require('./Features/Spelling/SpellingController') -CollaberationManager = require('./managers/CollaberationManager') SecurityManager = require('./managers/SecurityManager') AuthorizationManager = require('./Features/Security/AuthorizationManager') versioningController = require("./Features/Versioning/VersioningApiController") @@ -46,9 +45,7 @@ module.exports = class Router constructor: (app, io, socketSessions)-> app.use(app.router) - collaberationManager = new CollaberationManager(io) - - Project = new ProjectController(collaberationManager) + Project = new ProjectController() projectHandler = new ProjectHandler() app.get '/', HomeController.index @@ -326,10 +323,6 @@ module.exports = class Router AuthorizationManager.ensureClientCanViewProject client, (error, project_id) => CompileManager.getLogLines project_id, callback - client.on 'distributMessage', (message)-> - AuthorizationManager.ensureClientCanViewProject client, (error, project_id) => - collaberationManager.distributMessage project_id, client, message - client.on 'changeUsersPrivlageLevel', (user_id, newPrivalageLevel)-> AuthorizationManager.ensureClientCanAdminProject client, (error, project_id) => projectHandler.changeUsersPrivlageLevel project_id, user_id, newPrivalageLevel From b36ced305865b2386833bbd3e3c9ff940813d6d4 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Sat, 5 Apr 2014 12:14:50 +0100 Subject: [PATCH 61/62] only poll dropbox users who have the dropbox feature --- .../ThirdPartyDataStore/TpdsPollingBackgroundTasks.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsPollingBackgroundTasks.coffee b/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsPollingBackgroundTasks.coffee index 80597b27a2..46afad2b18 100644 --- a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsPollingBackgroundTasks.coffee +++ b/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsPollingBackgroundTasks.coffee @@ -23,7 +23,7 @@ self = module.exports = callback() _getUserIdsWithDropbox: (callback)-> - User.find {"dropbox.access_token.oauth_token_secret":{"$exists":true}}, "_id", (err, users)-> + User.find {"dropbox.access_token.oauth_token_secret":{"$exists":true}, "features.dropbox":true}, "_id", (err, users)-> ids = users.map (user)-> return user._id+"" callback err, ids From 2288591bae8fef72abdd470962ae38099734b711 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Sat, 5 Apr 2014 12:21:34 +0100 Subject: [PATCH 62/62] updated tpds background tests --- .../ThirdPartyDataStore/TpdsPollingBackgroundTasksTests.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsPollingBackgroundTasksTests.coffee b/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsPollingBackgroundTasksTests.coffee index a603b83bfc..4b509b5d41 100644 --- a/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsPollingBackgroundTasksTests.coffee +++ b/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsPollingBackgroundTasksTests.coffee @@ -32,7 +32,7 @@ describe 'third party data store', -> @poller._sendToTpds = sinon.stub().callsArgWith(1, null) @poller._markPollHappened = sinon.stub() @poller.pollUsersWithDropbox (err)=> - @userModel.find.calledWith({"dropbox.access_token.oauth_token_secret":{"$exists":true}}, "_id").should.equal true + @userModel.find.calledWith({"dropbox.access_token.oauth_token_secret":{"$exists":true}, "features.dropbox":true}, "_id").should.equal true @poller._sendToTpds.calledWith([users[0]._id, users[1]._id, users[2]._id,]).should.equal true @poller._markPollHappened.called.should.equal true done()