From 43d723bcfb9e3da43d8eda742409d58efe2c06ae Mon Sep 17 00:00:00 2001 From: metbosch Date: Mon, 19 Jan 2015 23:34:49 +0100 Subject: [PATCH 1/7] Allowed scroll on binary-file container Set overflow in auto mode to allow large images. --- services/web/public/stylesheets/app/editor/binary-file.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/web/public/stylesheets/app/editor/binary-file.less b/services/web/public/stylesheets/app/editor/binary-file.less index 8e04d2112d..8e8467e5f9 100644 --- a/services/web/public/stylesheets/app/editor/binary-file.less +++ b/services/web/public/stylesheets/app/editor/binary-file.less @@ -2,6 +2,7 @@ padding: @line-height-computed / 2; background-color: @gray-lightest; text-align: center; + overflow: auto; img { max-width: 100%; max-height: 90%; @@ -17,4 +18,4 @@ color: @gray; } -} \ No newline at end of file +} From 6c387edbe20d8bb36b3b5ebbae5cdc528089f69c Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 5 Feb 2015 18:20:25 +0000 Subject: [PATCH 2/7] Remove Dropbox front end logic from main sharelatex repo --- .../Features/Dropbox/DropboxHandler.coffee | 81 --------------- .../Dropbox/DropboxProjectController.coffee | 12 --- .../Features/Dropbox/DropboxRouter.coffee | 18 ---- .../Dropbox/DropboxUserController.coffee | 26 ----- .../Dropbox/DropboxWebhookController.coffee | 21 ---- .../Dropbox/DropboxWebhookHandler.coffee | 48 --------- .../Features/Editor/EditorController.coffee | 3 - .../Subscription/SubscriptionHandler.coffee | 6 +- .../Features/User/UserPagesController.coffee | 17 ++-- .../app/coffee/infrastructure/Events.coffee | 2 + .../infrastructure/ExpressLocals.coffee | 1 + .../app/coffee/infrastructure/Modules.coffee | 3 + services/web/app/coffee/router.coffee | 13 --- services/web/app/views/project/editor.jade | 1 - .../web/app/views/project/editor/dropbox.jade | 41 -------- .../app/views/project/editor/left-menu.jade | 14 +-- services/web/app/views/user/settings.jade | 21 ---- .../controllers/DropboxController.coffee | 43 -------- .../public/coffee/ide/dropbox/index.coffee | 4 - .../coffee/Dropbox/DropboxHandlerTests.coffee | 83 ---------------- .../DropboxProjectControllerTests.coffee | 41 -------- .../Dropbox/DropboxUserControllerTests.coffee | 70 ------------- .../DropboxWebhookControllerTests.coffee | 51 ---------- .../Dropbox/DropboxWebhookHandlerTests.coffee | 99 ------------------- .../Editor/EditorControllerTests.coffee | 7 -- .../SubscriptionHandlerTests.coffee | 7 +- 26 files changed, 23 insertions(+), 710 deletions(-) delete mode 100644 services/web/app/coffee/Features/Dropbox/DropboxHandler.coffee delete mode 100644 services/web/app/coffee/Features/Dropbox/DropboxProjectController.coffee delete mode 100644 services/web/app/coffee/Features/Dropbox/DropboxRouter.coffee delete mode 100644 services/web/app/coffee/Features/Dropbox/DropboxUserController.coffee delete mode 100644 services/web/app/coffee/Features/Dropbox/DropboxWebhookController.coffee delete mode 100644 services/web/app/coffee/Features/Dropbox/DropboxWebhookHandler.coffee create mode 100644 services/web/app/coffee/infrastructure/Events.coffee delete mode 100644 services/web/app/views/project/editor/dropbox.jade delete mode 100644 services/web/public/coffee/ide/dropbox/controllers/DropboxController.coffee delete mode 100644 services/web/public/coffee/ide/dropbox/index.coffee delete mode 100644 services/web/test/UnitTests/coffee/Dropbox/DropboxHandlerTests.coffee delete mode 100644 services/web/test/UnitTests/coffee/Dropbox/DropboxProjectControllerTests.coffee delete mode 100644 services/web/test/UnitTests/coffee/Dropbox/DropboxUserControllerTests.coffee delete mode 100644 services/web/test/UnitTests/coffee/Dropbox/DropboxWebhookControllerTests.coffee delete mode 100644 services/web/test/UnitTests/coffee/Dropbox/DropboxWebhookHandlerTests.coffee diff --git a/services/web/app/coffee/Features/Dropbox/DropboxHandler.coffee b/services/web/app/coffee/Features/Dropbox/DropboxHandler.coffee deleted file mode 100644 index 33b9caf7b7..0000000000 --- a/services/web/app/coffee/Features/Dropbox/DropboxHandler.coffee +++ /dev/null @@ -1,81 +0,0 @@ -request = require('request') -settings = require('settings-sharelatex') -logger = require('logger-sharelatex') -Project = require('../../models/Project').Project -projectEntityHandler = require '../Project/ProjectEntityHandler' -_ = require('underscore') -async = require('async') - -module.exports = - - getUserRegistrationStatus: (user_id, callback)-> - logger.log user_id:user_id, "getting dropbox registration status from tpds" - opts = - url : "#{settings.apis.thirdPartyDataStore.url}/user/#{user_id}/dropbox/status" - timeout: 5000 - request.get opts, (err, response, body)-> - safelyGetResponse err, response, body, (err, body)-> - if err? - logger.err err:err, response:response, "getUserRegistrationStatus problem" - return callback err - logger.log status:body, "getting dropbox registration status for user #{user_id}" - callback err, body - - getDropboxRegisterUrl: (user_id, callback)-> - opts = - url: "#{settings.apis.thirdPartyDataStore.url}/user/#{user_id}/dropbox/register" - timeout: 5000 - request.get opts, (err, response, body)-> - safelyGetResponse err, response, body, (err, body)-> - if err? - logger.err err:err, response:response, "getUserRegistrationStatus problem" - return callback err - url = "#{body.authorize_url}&oauth_callback=#{settings.siteUrl}/dropbox/completeRegistration" - logger.log user_id:user_id, url:url, "starting dropbox register" - callback err, url - - completeRegistration: (user_id, callback)-> - opts = - url: "#{settings.apis.thirdPartyDataStore.url}/user/#{user_id}/dropbox/getaccesstoken" - timeout: 5000 - request.get opts, (err, response, body)=> - safelyGetResponse err, response, body, (err, body)=> - if err? - logger.err err:err, response:response, "getUserRegistrationStatus problem" - return callback err - success = body.success - logger.log user_id:user_id, success:body.success, "completing dropbox register" - if success - @flushUsersProjectToDropbox user_id - callback err, body.success - - - unlinkAccount: (user_id, callback)-> - opts = - url: "#{settings.apis.thirdPartyDataStore.url}/user/#{user_id}/dropbox" - timeout: 5000 - request.del opts, (err, response, body)=> - callback(err) - - flushUsersProjectToDropbox: (user_id, callback)-> - Project.findAllUsersProjects user_id, '_id', (err, projects = [], collabertions = [], readOnlyProjects = [])-> - projectList = [] - projectList = projectList.concat(projects) - projectList = projectList.concat(collabertions) - projectList = projectList.concat(readOnlyProjects) - projectIds = _.pluck(projectList, "_id") - logger.log projectIds:projectIds, user_id:user_id, "flushing all a users projects to tpds" - jobs = projectIds.map (project_id)-> - return (cb)-> - projectEntityHandler.flushProjectToThirdPartyDataStore project_id, cb - async.series jobs, callback - -safelyGetResponse = (err, res, body, callback)-> - statusCode = if res? then res.statusCode else 500 - if err? or statusCode != 200 - e = new Error("something went wrong getting response from dropbox, #{err}, #{statusCode}") - logger.err err:err - callback(e, []) - else - body = JSON.parse body - callback(null, body) diff --git a/services/web/app/coffee/Features/Dropbox/DropboxProjectController.coffee b/services/web/app/coffee/Features/Dropbox/DropboxProjectController.coffee deleted file mode 100644 index 0c6e804dbe..0000000000 --- a/services/web/app/coffee/Features/Dropbox/DropboxProjectController.coffee +++ /dev/null @@ -1,12 +0,0 @@ -DropboxHandler = require "./DropboxHandler" -ProjectGetter = require "../Project/ProjectGetter" - -module.exports = DropboxProjectController = - getStatus: (req, res, next) -> - project_id = req.params.Project_id - ProjectGetter.getProject project_id, {owner_ref: 1}, (error, project) -> - return next(error) if error? - DropboxHandler.getUserRegistrationStatus project.owner_ref, (error, status) -> - return next(error) if error? - res.json status - \ No newline at end of file diff --git a/services/web/app/coffee/Features/Dropbox/DropboxRouter.coffee b/services/web/app/coffee/Features/Dropbox/DropboxRouter.coffee deleted file mode 100644 index 91361685cd..0000000000 --- a/services/web/app/coffee/Features/Dropbox/DropboxRouter.coffee +++ /dev/null @@ -1,18 +0,0 @@ -DropboxUserController = require './DropboxUserController' -DropboxWebhookController = require './DropboxWebhookController' -DropboxProjectController = require "./DropboxProjectController" -SecurityManager = require "../../managers/SecurityManager" - -module.exports = - apply: (app) -> - app.get '/dropbox/beginAuth', DropboxUserController.redirectUserToDropboxAuth - app.get '/dropbox/completeRegistration', DropboxUserController.completeDropboxRegistration - app.get '/dropbox/unlink', DropboxUserController.unlinkDropbox - - app.get '/dropbox/webhook', DropboxWebhookController.verify - app.post '/dropbox/webhook', DropboxWebhookController.webhook - app.ignoreCsrf('post', '/dropbox/webhook') - - app.get '/project/:Project_id/dropbox/status', SecurityManager.requestIsOwner, DropboxProjectController.getStatus - - diff --git a/services/web/app/coffee/Features/Dropbox/DropboxUserController.coffee b/services/web/app/coffee/Features/Dropbox/DropboxUserController.coffee deleted file mode 100644 index 4e0e353194..0000000000 --- a/services/web/app/coffee/Features/Dropbox/DropboxUserController.coffee +++ /dev/null @@ -1,26 +0,0 @@ -dropboxHandler = require('./DropboxHandler') -logger = require('logger-sharelatex') - - -module.exports = - - redirectUserToDropboxAuth: (req, res, next)-> - user_id = req.session.user._id - dropboxHandler.getDropboxRegisterUrl user_id, (err, url)-> - return next(err) if err? - logger.log url:url, "redirecting user for dropbox auth" - res.redirect url - - completeDropboxRegistration: (req, res, next)-> - user_id = req.session.user._id - dropboxHandler.completeRegistration user_id, (err, success)-> - return next(err) if err? - res.redirect('/user/settings#dropboxSettings') - - unlinkDropbox: (req, res, next)-> - user_id = req.session.user._id - dropboxHandler.unlinkAccount user_id, (err, success)-> - return next(err) if err? - res.redirect('/user/settings#dropboxSettings') - - diff --git a/services/web/app/coffee/Features/Dropbox/DropboxWebhookController.coffee b/services/web/app/coffee/Features/Dropbox/DropboxWebhookController.coffee deleted file mode 100644 index cfd83ef2b2..0000000000 --- a/services/web/app/coffee/Features/Dropbox/DropboxWebhookController.coffee +++ /dev/null @@ -1,21 +0,0 @@ -logger = require("logger-sharelatex") -DropboxWebhookHandler = require("./DropboxWebhookHandler") - -module.exports = DropboxWebhookController = - verify: (req, res, next = (error) ->) -> - res.send(req.query.challenge) - req.session.destroy() - - webhook: (req, res, next = (error) ->) -> - dropbox_uids = req.body?.delta?.users - logger.log dropbox_uids: dropbox_uids, "received webhook request from Dropbox" - if !dropbox_uids? - return res.send(400) # Bad Request - - # Do this in the background so as not to keep Dropbox waiting - DropboxWebhookHandler.pollDropboxUids dropbox_uids, (error) -> - if error? - logger.error err: error, dropbox_uids: dropbox_uids, "error in webhook" - - res.send(200) - req.session.destroy() diff --git a/services/web/app/coffee/Features/Dropbox/DropboxWebhookHandler.coffee b/services/web/app/coffee/Features/Dropbox/DropboxWebhookHandler.coffee deleted file mode 100644 index 8fb5d1d9ae..0000000000 --- a/services/web/app/coffee/Features/Dropbox/DropboxWebhookHandler.coffee +++ /dev/null @@ -1,48 +0,0 @@ -logger = require("logger-sharelatex") -settings = require("settings-sharelatex") -async = require "async" -User = require("../../models/User").User -TpdsUpdateSender = require "../ThirdPartyDataStore/TpdsUpdateSender" - -redis = require("redis-sharelatex") -rclient = redis.createClient(settings.redis.web) - -module.exports = DropboxWebhookHandler = - pollDropboxUids: (dropbox_uids, callback = (error) ->) -> - jobs = [] - for uid in dropbox_uids - do (uid) -> - jobs.push (callback) -> - DropboxWebhookHandler.pollDropboxUid uid, callback - async.series jobs, callback - - pollDropboxUid: (dropbox_uid, callback = (error) ->) -> - DropboxWebhookHandler._delayAndBatchPoll dropbox_uid, (error, shouldPoll) -> - return callback(error) if error? - return callback() if !shouldPoll - User.find { - "dropbox.access_token.uid": dropbox_uid.toString() - "features.dropbox": true - }, (error, users = []) -> - return callback(error) if error? - user = users[0] - if !user? - logger.log dropbox_uid: dropbox_uid, "no sharelatex user found" - return callback() - TpdsUpdateSender.pollDropboxForUser user._id, callback - - POLL_DELAY_IN_MS: 5000 # 5 seconds - _delayAndBatchPoll: (dropbox_uid, callback = (error, shouldPoll) ->) -> - rclient.set( - "dropbox-poll-lock:#{dropbox_uid}", "LOCK", - "PX", DropboxWebhookHandler.POLL_DELAY_IN_MS, - "NX", - (error, gotLock) -> - return callback(error) if error? - if gotLock - setTimeout () -> - callback(null, true) - , DropboxWebhookHandler.POLL_DELAY_IN_MS - else - callback(null, false) - ) \ No newline at end of file diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee index 51896b4fe4..cbd8d3b91d 100644 --- a/services/web/app/coffee/Features/Editor/EditorController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorController.coffee @@ -151,9 +151,6 @@ module.exports = EditorController = return {_id:doc._id, path:path.substring(1)} callback(null, docList) - forceResyncOfDropbox: (project_id, callback)-> - ProjectEntityHandler.flushProjectToThirdPartyDataStore project_id, callback - notifyUsersProjectHasBeenDeletedOrRenamed: (project_id, callback)-> EditorRealTimeController.emitToRoom(project_id, 'projectRenamedOrDeletedByExternalSource') callback() diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionHandler.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionHandler.coffee index 4aa3310b89..4ff938240c 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionHandler.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionHandler.coffee @@ -6,7 +6,7 @@ logger = require('logger-sharelatex') SubscriptionUpdater = require("./SubscriptionUpdater") LimitationsManager = require('./LimitationsManager') EmailHandler = require("../Email/EmailHandler") -DropboxHandler = require("../Dropbox/DropboxHandler") +Events = require "../../infrastructure/Events" module.exports = @@ -52,8 +52,8 @@ module.exports = ONE_HOUR_IN_MS = 1000 * 60 * 60 setTimeout (-> EmailHandler.sendEmail "canceledSubscription", emailOpts ), ONE_HOUR_IN_MS - DropboxHandler.unlinkAccount user._id, -> - callback() + Events.emit "cancelSubscription", user._id + callback() else callback() diff --git a/services/web/app/coffee/Features/User/UserPagesController.coffee b/services/web/app/coffee/Features/User/UserPagesController.coffee index 20da921c28..6ffb8ecdb8 100644 --- a/services/web/app/coffee/Features/User/UserPagesController.coffee +++ b/services/web/app/coffee/Features/User/UserPagesController.coffee @@ -1,5 +1,4 @@ UserLocator = require("./UserLocator") -dropboxHandler = require('../Dropbox/DropboxHandler') logger = require("logger-sharelatex") Settings = require("settings-sharelatex") fs = require('fs') @@ -27,14 +26,12 @@ module.exports = title: 'login', redir: req.query.redir - settingsPage : (req, res)-> + settingsPage : (req, res, next)-> logger.log user: req.session.user, "loading settings page" UserLocator.findById req.session.user._id, (err, user)-> - dropboxHandler.getUserRegistrationStatus user._id, (err, status)-> - userIsRegisteredWithDropbox = !err? and status.registered - res.render 'user/settings', - title:'account_settings' - userIsRegisteredWithDropbox: userIsRegisteredWithDropbox - user: user, - languages: Settings.languages, - accountSettingsTabActive: true + return next(err) if err? + res.render 'user/settings', + title:'account_settings' + user: user, + languages: Settings.languages, + accountSettingsTabActive: true diff --git a/services/web/app/coffee/infrastructure/Events.coffee b/services/web/app/coffee/infrastructure/Events.coffee new file mode 100644 index 0000000000..a7ff219b7a --- /dev/null +++ b/services/web/app/coffee/infrastructure/Events.coffee @@ -0,0 +1,2 @@ +events = require "events" +module.exports = new events.EventEmitter() \ No newline at end of file diff --git a/services/web/app/coffee/infrastructure/ExpressLocals.coffee b/services/web/app/coffee/infrastructure/ExpressLocals.coffee index e0df597c69..856dcd51a7 100644 --- a/services/web/app/coffee/infrastructure/ExpressLocals.coffee +++ b/services/web/app/coffee/infrastructure/ExpressLocals.coffee @@ -157,5 +157,6 @@ module.exports = (app)-> if Settings.reloadModuleViewsOnEachRequest Modules.loadViewIncludes() res.locals.moduleIncludes = Modules.moduleIncludes + res.locals.moduleIncludesAvailable = Modules.moduleIncludesAvailable next() diff --git a/services/web/app/coffee/infrastructure/Modules.coffee b/services/web/app/coffee/infrastructure/Modules.coffee index 4c45e488e1..0aedf6bbf0 100644 --- a/services/web/app/coffee/infrastructure/Modules.coffee +++ b/services/web/app/coffee/infrastructure/Modules.coffee @@ -32,5 +32,8 @@ module.exports = Modules = compiler = jade.compile(partial, doctype: "html") html += compiler(locals) return html + + moduleIncludesAvailable: (view) -> + return (Modules.viewIncludes[view] or []).length > 0 Modules.loadModules() \ No newline at end of file diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index d1422998d6..18d0a5043a 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -33,8 +33,6 @@ StaticPagesRouter = require("./Features/StaticPages/StaticPagesRouter") ChatController = require("./Features/Chat/ChatController") BlogController = require("./Features/Blog/BlogController") WikiController = require("./Features/Wiki/WikiController") -DropboxRouter = require "./Features/Dropbox/DropboxRouter" -dropboxHandler = require "./Features/Dropbox/DropboxHandler" Modules = require "./infrastructure/Modules" RateLimiterMiddlewear = require('./Features/Security/RateLimiterMiddlewear') @@ -66,7 +64,6 @@ module.exports = class Router PasswordResetRouter.apply(app) StaticPagesRouter.apply(app) TemplatesRouter.apply(app) - DropboxRouter.apply(app) Modules.applyRouter(app) @@ -190,16 +187,6 @@ module.exports = class Router ), 10000 req.session.destroy() - app.get '/test', (req, res) -> - res.render "tests", - privilegeLevel: "owner" - project: - name: "test" - date: Date.now() - layout: false - userCanSeeDropbox: true - languages: [] - app.get "/ip", (req, res, next) -> res.send({ ip: req.ip diff --git a/services/web/app/views/project/editor.jade b/services/web/app/views/project/editor.jade index dc1403c909..94af094c2e 100644 --- a/services/web/app/views/project/editor.jade +++ b/services/web/app/views/project/editor.jade @@ -56,7 +56,6 @@ block content include ./editor/binary-file include ./editor/track-changes include ./editor/publish-template - include ./editor/dropbox .ui-layout-east include ./editor/chat diff --git a/services/web/app/views/project/editor/dropbox.jade b/services/web/app/views/project/editor/dropbox.jade deleted file mode 100644 index 5aa2e1b44b..0000000000 --- a/services/web/app/views/project/editor/dropbox.jade +++ /dev/null @@ -1,41 +0,0 @@ -script(type="text/ng-template", id="dropboxModalTemplate") - .modal-header - button.close( - type="button" - data-dismiss="modal" - ng-click="cancel()" - ) × - h3 #{translate("dropbox_sync")} - .modal-body.modal-body-share - - div(ng-show="dbState.gotLinkStatus") - div(ng-hide="dbState.userIsLinkedToDropbox || !dbState.hasDropboxFeature") - - span(ng-hide="dbState.startedLinkProcess") #{translate("account_not_linked_to_dropbox")} - |     - a(ng-click="linkToDropbox()").btn.btn-info #{translate("update_dropbox_settings")} - - p.small.text-center(ng-show="dbState.startedLinkProcess") - | #{translate("refresh_page_after_starting_free_trial")} - - - div(ng-show="dbState.hasDropboxFeature && dbState.userIsLinkedToDropbox") - p.small - | #{translate("this_project_will_appear_in_your_dropbox_folder_at")} - strong Dropbox/sharelatex/{{ project.name }} - div.text-center(ng-hide="dbState.hasDropboxFeature") - p #{translate("need_to_upgrade_for_dropbox")} - p(ng-controller="FreeTrialModalController") - a.btn(ng-click="startFreeTrial('dropbox')", ng-class="buttonClass") #{translate("start_free_trial")} - p.small(ng-show="startedFreeTrial") - | #{translate("refresh_page_after_starting_free_trial")} - - div(ng-hide="dbState.gotLinkStatus") - i.fa.fa-refresh.fa-spin - span.small   #{translate("checking_dropbox_status")} - - .modal-footer() - button.btn.btn-default( - ng-click="cancel()", - ) - span #{translate("dismiss")} diff --git a/services/web/app/views/project/editor/left-menu.jade b/services/web/app/views/project/editor/left-menu.jade index a68dbd586c..1e4d2ab43e 100644 --- a/services/web/app/views/project/editor/left-menu.jade +++ b/services/web/app/views/project/editor/left-menu.jade @@ -46,16 +46,10 @@ aside#left-menu.full-size( i.fa.fa-external-link.fa-fw |    #{translate("publish_as_template")} - div(ng-show="!anonymous") - h4() #{translate("sync")} - span(ng-controller="DropboxController") - ul.list-unstyled.nav() - li - a(ng-click="openDropboxModal()") - i.fa.fa-dropbox.fa-fw - |    Dropbox - - !{moduleIncludes("editorLeftMenu", locals)} + if (moduleIncludesAvailable("editorLeftMenu:sync")) + div(ng-show="!anonymous") + h4() #{translate("sync")} + !{moduleIncludes("editorLeftMenu:sync", locals)} h4(ng-show="!anonymous") #{translate("settings")} form.settings(ng-controller="SettingsController", ng-show="!anonymous") diff --git a/services/web/app/views/user/settings.jade b/services/web/app/views/user/settings.jade index d40f68c59c..d4a213aefb 100644 --- a/services/web/app/views/user/settings.jade +++ b/services/web/app/views/user/settings.jade @@ -96,27 +96,6 @@ block content ng-disabled="changePasswordForm.$invalid" ) #{translate("change")} - hr - - h3 #{translate("dropbox_integration")} - span.small - a(href='/help/kb/dropbox-2') (#{translate("learn_more")}) - - if(!user.features.dropbox) - p.small #{translate("dropbox_sync_description")} - .alert.alert-info - p #{translate("dropbox_is_premium")} - p - a.btn.btn-info(href='/user/subscription/plans') #{translate("upgrade")} - - else if(userIsRegisteredWithDropbox) - .alert.alert-success - | #{translate("account_is_linked")}. - | - a(href='/dropbox/unlink') #{translate("unlink_dropbox")} - - else - p.small #{translate("dropbox_sync_description")} - p - a.btn.btn-info(href='/dropbox/beginAuth') #{translate("link_to_dropbox")} - | !{moduleIncludes("userSettings", locals)} hr diff --git a/services/web/public/coffee/ide/dropbox/controllers/DropboxController.coffee b/services/web/public/coffee/ide/dropbox/controllers/DropboxController.coffee deleted file mode 100644 index 863b8a119f..0000000000 --- a/services/web/public/coffee/ide/dropbox/controllers/DropboxController.coffee +++ /dev/null @@ -1,43 +0,0 @@ -define [ - "base" - "ide/permissions/PermissionsManager" -], (App, PermissionsManager) -> - - POLLING_INTERVAL = 15 - ONE_MIN_MILI = 1000 * 60 - - cachedState = - gotLinkStatus: false - startedLinkProcess: false - userIsLinkedToDropbox: false - hasDropboxFeature: false - - - App.controller "DropboxController", ($scope, $modal, ide) -> - $scope.openDropboxModal = () -> - - $modal.open { - templateUrl: "dropboxModalTemplate" - controller: "DropboxModalController" - scope:$scope - } - - App.controller "DropboxModalController", ($scope, $modalInstance, ide, $timeout, $http) -> - user_id = ide.$scope.user.id - - $scope.dbState = cachedState - $scope.dbState.hasDropboxFeature = $scope.project.features.dropbox - - $http.get("/project/#{ide.project_id}/dropbox/status") - .success (status) -> - $scope.dbState.gotLinkStatus = true - if status.registered - $scope.dbState.userIsLinkedToDropbox = true - cachedState = $scope.dbState - - $scope.linkToDropbox = -> - window.open("/user/settings#dropboxSettings") - $scope.startedLinkProcess = true - - $scope.cancel = () -> - $modalInstance.dismiss() diff --git a/services/web/public/coffee/ide/dropbox/index.coffee b/services/web/public/coffee/ide/dropbox/index.coffee deleted file mode 100644 index 6041320724..0000000000 --- a/services/web/public/coffee/ide/dropbox/index.coffee +++ /dev/null @@ -1,4 +0,0 @@ -define [ - "ide/dropbox/controllers/DropboxController" -], () -> - diff --git a/services/web/test/UnitTests/coffee/Dropbox/DropboxHandlerTests.coffee b/services/web/test/UnitTests/coffee/Dropbox/DropboxHandlerTests.coffee deleted file mode 100644 index 7cad2ac9ff..0000000000 --- a/services/web/test/UnitTests/coffee/Dropbox/DropboxHandlerTests.coffee +++ /dev/null @@ -1,83 +0,0 @@ -SandboxedModule = require('sandboxed-module') -assert = require('assert') -require('chai').should() -sinon = require('sinon') -modulePath = require('path').join __dirname, '../../../../app/js/Features/Dropbox/DropboxHandler.js' - -thirdPartyDataStoreApiUrl = "http://third-party-json-store.herokuapp.com" -siteUrl = "www.sharelatex.com" - -describe 'third party data store', -> - user_id = "123nd3ijdks" - - beforeEach -> - @stubGet = sinon.stub() - @stubDel = sinon.stub() - @projectEntityHandler = flushProjectToThirdPartyDataStore:sinon.stub().callsArgWith(1) - @projectModel = findAllUsersProjects : sinon.stub() - @handler = SandboxedModule.require modulePath, requires: - "settings-sharelatex": {siteUrl:siteUrl, apis: {thirdPartyDataStore: {url: thirdPartyDataStoreApiUrl}}} - "../../models/Project":{Project:@projectModel} - '../Project/ProjectEntityHandler':@projectEntityHandler - "request": - get:@stubGet - del: @stubDel - 'logger-sharelatex': - log:-> - err:-> - - - it 'should be able to get userStatus', (done)-> - body = JSON.stringify({registered:true}) - opts = - url: "#{thirdPartyDataStoreApiUrl}/user/#{user_id}/dropbox/status" - timeout: 5000 - @stubGet.withArgs(opts).callsArgWith(1, null, {statusCode:200}, body) - @handler.getUserRegistrationStatus user_id, (err, status)-> - status.registered.should.equal true - done() - - it 'should be able to get auth url with callback url on it', (done)-> - url = "http://www.dropbox.com" - body = JSON.stringify({authorize_url:url}) - opts = - url: "#{thirdPartyDataStoreApiUrl}/user/#{user_id}/dropbox/register" - timeout: 5000 - @stubGet.withArgs(opts).callsArgWith(1, null, {statusCode:200}, body) - @handler.getDropboxRegisterUrl user_id, (err, returnedUrl)-> - returnedUrl.should.equal "#{url}&oauth_callback=#{siteUrl}/dropbox/completeRegistration" - done() - - it 'should be able to complete registration and get getAccessToken from dropbox', (done)-> - body = JSON.stringify({success:true}) - opts = - url: "#{thirdPartyDataStoreApiUrl}/user/#{user_id}/dropbox/getaccesstoken" - timeout: 5000 - @stubGet.withArgs(opts).callsArgWith(1, null, {statusCode:200}, body) - @handler.flushUsersProjectToDropbox = sinon.stub() - @handler.completeRegistration user_id, (err, successful)=> - @handler.flushUsersProjectToDropbox.called.should.equal true - successful.should.equal true - done() - - it 'should tell the tpds to unlink the account', (done)-> - opts = - url: "#{thirdPartyDataStoreApiUrl}/user/#{user_id}/dropbox" - timeout: 5000 - @stubDel.callsArgWith(1, null, {statusCode:200}) - @handler.unlinkAccount user_id, (err)=> - @stubDel.calledWith(opts).should.equal true - done() - - it 'should tell the project entity handler to flush project to tpds', (done)-> - user_id = "123u9oijllkj" - projectList = [{_id:"123lk"}, {_id:"12ji3ojio"}, {_id:"2jiojdoi"}] - collabProjectList = [{_id:"213ds"}] - @projectModel.findAllUsersProjects.callsArgWith(2, null, projectList, collabProjectList) - @handler.flushUsersProjectToDropbox user_id, => - @projectEntityHandler.flushProjectToThirdPartyDataStore.calledWith(projectList[0]._id).should.equal true - @projectEntityHandler.flushProjectToThirdPartyDataStore.calledWith(projectList[1]._id).should.equal true - @projectEntityHandler.flushProjectToThirdPartyDataStore.calledWith(projectList[2]._id).should.equal true - @projectEntityHandler.flushProjectToThirdPartyDataStore.calledWith(collabProjectList[0]._id).should.equal true - done() - diff --git a/services/web/test/UnitTests/coffee/Dropbox/DropboxProjectControllerTests.coffee b/services/web/test/UnitTests/coffee/Dropbox/DropboxProjectControllerTests.coffee deleted file mode 100644 index d230fff0ac..0000000000 --- a/services/web/test/UnitTests/coffee/Dropbox/DropboxProjectControllerTests.coffee +++ /dev/null @@ -1,41 +0,0 @@ -SandboxedModule = require('sandboxed-module') -assert = require('assert') -require('chai').should() -sinon = require('sinon') -modulePath = require('path').join __dirname, '../../../../app/js/Features/Dropbox/DropboxProjectController.js' - -describe 'DropboxProjectController', -> - beforeEach -> - @DropboxProjectController = SandboxedModule.require modulePath, requires: - './DropboxHandler': @DropboxHandler = {} - '../Project/ProjectGetter': @ProjectGetter = {} - 'logger-sharelatex': - log:-> - err:-> - - @project_id = "project-id-123" - @user_id = "user-id-123" - @req = {} - @res = - json: sinon.stub() - - describe "getStatus", -> - beforeEach -> - @req.params = - Project_id: @project_id - @ProjectGetter.getProject = sinon.stub().callsArgWith(2, null, { owner_ref: @user_id }) - @DropboxHandler.getUserRegistrationStatus = sinon.stub().callsArgWith(1, null, @status = {"mock": "status"}) - @DropboxProjectController.getStatus @req, @res - - it "should look up the project owner", -> - @ProjectGetter.getProject - .calledWith(@project_id, {owner_ref: 1}) - .should.equal true - - it "should get the owner's Dropbox status", -> - @DropboxHandler.getUserRegistrationStatus - .calledWith(@user_id) - .should.equal true - - it "should send the status to the client", -> - @res.json.calledWith(@status).should.equal true diff --git a/services/web/test/UnitTests/coffee/Dropbox/DropboxUserControllerTests.coffee b/services/web/test/UnitTests/coffee/Dropbox/DropboxUserControllerTests.coffee deleted file mode 100644 index 83e05afd65..0000000000 --- a/services/web/test/UnitTests/coffee/Dropbox/DropboxUserControllerTests.coffee +++ /dev/null @@ -1,70 +0,0 @@ -SandboxedModule = require('sandboxed-module') -assert = require('assert') -require('chai').should() -sinon = require('sinon') -modulePath = require('path').join __dirname, '../../../../app/js/Features/Dropbox/DropboxUserController.js' - - -describe 'DropboxUserController', -> - - beforeEach -> - @DropboxHandler = - getDropboxRegisterUrl: sinon.stub() - completeRegistration: sinon.stub() - unlinkAccount: sinon.stub() - - @controller = SandboxedModule.require modulePath, requires: - './DropboxHandler': @DropboxHandler - 'logger-sharelatex': - log:-> - err:-> - - @user_id = "23j21lk3j1312j321jkljkl" - @req = - session: - user: - _id: @user_id - @res = {} - - describe "redirectUserToDropboxAuth", -> - beforeEach -> - @dropboxUrl = "www.dropbox.com" - @DropboxHandler.getDropboxRegisterUrl.callsArgWith(1, null, @dropboxUrl) - - it "should call getDropboxRegisterUrl with the user id", (done)-> - - @res.redirect = (redirectUrl)=> - redirectUrl.should.equal @dropboxUrl - @DropboxHandler.getDropboxRegisterUrl.calledWith(@user_id).should.equal true - done() - - @controller.redirectUserToDropboxAuth @req, @res - - describe "completeDropboxRegistration", -> - beforeEach -> - @DropboxHandler.completeRegistration.callsArgWith(1) - - it "should call getDropboxRegisterUrl with the user id", (done)-> - - @res.redirect = (redirectUrl)=> - redirectUrl.should.equal "/user/settings#dropboxSettings" - @DropboxHandler.completeRegistration.calledWith(@user_id).should.equal true - done() - - @controller.completeDropboxRegistration @req, @res - - - describe "unlinkDropbox", -> - - beforeEach -> - @DropboxHandler.unlinkAccount.callsArgWith(1) - - it "should call getDropboxRegisterUrl with the user id", (done)-> - - @res.redirect = (redirectUrl)=> - redirectUrl.should.equal "/user/settings#dropboxSettings" - @DropboxHandler.unlinkAccount.calledWith(@user_id).should.equal true - done() - - @controller.unlinkDropbox @req, @res - diff --git a/services/web/test/UnitTests/coffee/Dropbox/DropboxWebhookControllerTests.coffee b/services/web/test/UnitTests/coffee/Dropbox/DropboxWebhookControllerTests.coffee deleted file mode 100644 index 10f2cdfbd4..0000000000 --- a/services/web/test/UnitTests/coffee/Dropbox/DropboxWebhookControllerTests.coffee +++ /dev/null @@ -1,51 +0,0 @@ -SandboxedModule = require('sandboxed-module') -assert = require('assert') -require('chai').should() -sinon = require('sinon') -modulePath = require('path').join __dirname, '../../../../app/js/Features/Dropbox/DropboxWebhookController.js' - -describe 'DropboxWebhookController', -> - beforeEach -> - @req = - session: - destroy: -> - - @DropboxWebhookController = SandboxedModule.require modulePath, requires: - "./DropboxWebhookHandler": @DropboxWebhookHandler = {} - 'logger-sharelatex': - log:-> - err:-> - - describe "verify", -> - beforeEach -> - @res = - send: sinon.stub() - @req.query = - challenge: @challenge = "foo" - @DropboxWebhookController.verify(@req, @res) - - it "should echo the challenge parameter back", -> - @res.send.calledWith(@challenge).should.equal true - - describe "webhook", -> - beforeEach -> - @req.body = - delta: - users: @dropbox_uids = [ - "123456", - "789123" - ] - @res.send = sinon.stub() - @DropboxWebhookHandler.pollDropboxUids = sinon.stub().callsArg(1) - @DropboxWebhookController.webhook(@req, @res) - - it "should poll the Dropbox uids", -> - @DropboxWebhookHandler.pollDropboxUids - .calledWith(@dropbox_uids) - .should.equal true - - it "should return success", -> - @res.send - .calledWith(200) - .should.equal true - diff --git a/services/web/test/UnitTests/coffee/Dropbox/DropboxWebhookHandlerTests.coffee b/services/web/test/UnitTests/coffee/Dropbox/DropboxWebhookHandlerTests.coffee deleted file mode 100644 index 7c6530961c..0000000000 --- a/services/web/test/UnitTests/coffee/Dropbox/DropboxWebhookHandlerTests.coffee +++ /dev/null @@ -1,99 +0,0 @@ -SandboxedModule = require('sandboxed-module') -assert = require('assert') -require('chai').should() -expect = require("chai").expect -sinon = require('sinon') -modulePath = require('path').join __dirname, '../../../../app/js/Features/Dropbox/DropboxWebhookHandler.js' - -describe 'DropboxWebhookHandler', -> - beforeEach -> - @DropboxWebhookHandler = SandboxedModule.require modulePath, requires: - "../../models/User": User: @User = {} - "../ThirdPartyDataStore/TpdsUpdateSender": @TpdsUpdateSender = {} - "redis-sharelatex": - createClient: () => @rclient = - auth: sinon.stub() - 'settings-sharelatex': redis: web: {} - 'logger-sharelatex': - log:-> - err:-> - @callback = sinon.stub() - - describe "pollDropboxUids", -> - beforeEach (done) -> - @dropbox_uids = [ - "123456", - "789123" - ] - @DropboxWebhookHandler.pollDropboxUid = sinon.stub().callsArg(1) - @DropboxWebhookHandler.pollDropboxUids @dropbox_uids, done - - it "should call pollDropboxUid for each uid", -> - for uid in @dropbox_uids - @DropboxWebhookHandler.pollDropboxUid - .calledWith(uid) - .should.equal true - - describe "pollDropboxUid", -> - beforeEach -> - @dropbox_uid = "dropbox-123456" - @user_id = "sharelatex-user-id" - @User.find = sinon.stub().callsArgWith(1, null, [ _id: @user_id ]) - @TpdsUpdateSender.pollDropboxForUser = sinon.stub().callsArg(1) - - describe "when there is already a poll in progress", () -> - beforeEach -> - @DropboxWebhookHandler._delayAndBatchPoll = sinon.stub().callsArgWith(1, null, false) - @DropboxWebhookHandler.pollDropboxUid @dropbox_uid, @callback - - it "should not go ahead with the poll", -> - @TpdsUpdateSender.pollDropboxForUser.called.should.equal false - - describe "when we are the one to do the delayed poll", () -> - beforeEach -> - @DropboxWebhookHandler._delayAndBatchPoll = sinon.stub().callsArgWith(1, null, true) - @DropboxWebhookHandler.pollDropboxUid @dropbox_uid, @callback - - it "should look up the user", -> - @User.find - .calledWith({ "dropbox.access_token.uid": @dropbox_uid, "features.dropbox": true }) - .should.equal true - - it "should poll the user's Dropbox", -> - @TpdsUpdateSender.pollDropboxForUser - .calledWith(@user_id) - .should.equal true - - it "should call the callback", -> - @callback.called.should.equal true - - describe "_delayAndBatchPoll", () -> - beforeEach -> - @dropbox_uid = "dropbox-uid-123" - @DropboxWebhookHandler.POLL_DELAY_IN_MS = 100 - - describe "when no one else is polling yet", -> - beforeEach (done) -> - @rclient.set = sinon.stub().callsArgWith(5, null, "OK") - @start = Date.now() - @DropboxWebhookHandler._delayAndBatchPoll @dropbox_uid, (error, @shouldPoll) => - @end = Date.now() - done() - - it "should set the lock", -> - @rclient.set - .calledWith("dropbox-poll-lock:#{@dropbox_uid}", "LOCK", "PX", @DropboxWebhookHandler.POLL_DELAY_IN_MS, "NX") - .should.equal true - - it "should return the callback after the delay with shouldPoll=true", -> - @shouldPoll.should.equal true - expect(@end - @start).to.be.at.least(@DropboxWebhookHandler.POLL_DELAY_IN_MS) - - describe "when someone else is already polling", -> - beforeEach -> - @rclient.set = sinon.stub().callsArgWith(5, null, null) - @DropboxWebhookHandler._delayAndBatchPoll @dropbox_uid, @callback - - it "should return the callback immediately with shouldPoll=false", -> - @callback.calledWith(null, false).should.equal true - diff --git a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee index 52e76e4374..adf30d781a 100644 --- a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee @@ -512,13 +512,6 @@ describe "EditorController", -> returnedDocs[1].path.should.equal "doc2.tex" done() - describe "forceResyncOfDropbox", -> - it 'should tell the project entity handler to flush to tpds', (done)-> - @ProjectEntityHandler.flushProjectToThirdPartyDataStore = sinon.stub().callsArgWith(1) - @EditorController.forceResyncOfDropbox @project_id, (err)=> - @ProjectEntityHandler.flushProjectToThirdPartyDataStore.calledWith(@project_id).should.equal true - done() - describe "notifyUsersProjectHasBeenDeletedOrRenamed", -> it 'should emmit a message to all users in a project', (done)-> @EditorRealTimeController.emitToRoom = sinon.stub() diff --git a/services/web/test/UnitTests/coffee/Subscription/SubscriptionHandlerTests.coffee b/services/web/test/UnitTests/coffee/Subscription/SubscriptionHandlerTests.coffee index f66a1813d6..7591aadebb 100644 --- a/services/web/test/UnitTests/coffee/Subscription/SubscriptionHandlerTests.coffee +++ b/services/web/test/UnitTests/coffee/Subscription/SubscriptionHandlerTests.coffee @@ -66,6 +66,7 @@ describe "Subscription Handler sanboxed", -> './LimitationsManager':@LimitationsManager "../Email/EmailHandler":@EmailHandler "../Dropbox/DropboxHandler":@DropboxHandler + "../../infrastructure/Events": @Events = {emit: sinon.stub()} @SubscriptionHandler.syncSubscriptionToUser = sinon.stub().callsArgWith(2) @@ -160,10 +161,8 @@ describe "Subscription Handler sanboxed", -> @RecurlyWrapper.cancelSubscription.called.should.equal true @RecurlyWrapper.cancelSubscription.calledWith(@subscription.recurlySubscription_id).should.equal true - - it "should unlink dropbox", -> - @DropboxHandler.unlinkAccount.called.should.equal true - @DropboxHandler.unlinkAccount.calledWith(@user._id).should.equal true + it "should trigger the cancel subscription event", -> + @Events.emit.calledWith("cancelSubscription", @user._id).should.equal true describe "reactiveRecurlySubscription", -> describe "with a user without a subscription", -> From 353e9c86a8d50a728600d8154c66c1bc036b47bc Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Mon, 9 Feb 2015 11:18:46 +0000 Subject: [PATCH 3/7] sample only 1% of pdf exceptions due to volume of requests to sentry --- .../web/public/coffee/ide/pdfng/directives/pdfRenderer.coffee | 4 ++-- .../web/public/coffee/ide/pdfng/directives/pdfViewer.coffee | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/web/public/coffee/ide/pdfng/directives/pdfRenderer.coffee b/services/web/public/coffee/ide/pdfng/directives/pdfRenderer.coffee index 7875faf886..a797c46865 100644 --- a/services/web/public/coffee/ide/pdfng/directives/pdfRenderer.coffee +++ b/services/web/public/coffee/ide/pdfng/directives/pdfRenderer.coffee @@ -145,7 +145,7 @@ define [ timedOut = false timer = $timeout () => - Raven?.captureMessage?('pdfng page load timed out after ' + @PAGE_LOAD_TIMEOUT + 'ms') + Raven?.captureMessage?('pdfng page load timed out after ' + @PAGE_LOAD_TIMEOUT + 'ms (1% sample)') if Math.random() < 0.01 # console.log 'page load timed out', pagenum timedOut = true clearTimeout(spinTimer) @@ -246,7 +246,7 @@ define [ timedOut = false timer = $timeout () => - Raven?.captureMessage?('pdfng page render timed out after ' + @PAGE_RENDER_TIMEOUT + 'ms') + Raven?.captureMessage?('pdfng page render timed out after ' + @PAGE_RENDER_TIMEOUT + 'ms (1% sample)') if Math.random() < 0.01 # console.log 'page render timed out', pagenum timedOut = true result.cancel() diff --git a/services/web/public/coffee/ide/pdfng/directives/pdfViewer.coffee b/services/web/public/coffee/ide/pdfng/directives/pdfViewer.coffee index 0f6c6d9bac..29e99fdd02 100644 --- a/services/web/public/coffee/ide/pdfng/directives/pdfViewer.coffee +++ b/services/web/public/coffee/ide/pdfng/directives/pdfViewer.coffee @@ -38,7 +38,7 @@ define [ loadedCallback: () -> $scope.$emit 'loaded' errorCallback: (error) -> - Raven?.captureMessage?('pdfng error ' + error) + Raven?.captureMessage?('pdfng error ' + error + ' (1% sample)') if Math.random() < 0.01 $scope.$emit 'pdf:error', error pageSizeChangeCallback: (pageNum, deltaH) -> $scope.$broadcast 'pdf:page:size-change', pageNum, deltaH From 001a5d751b31d51bb12804b6ee0ae8d1bc9bd192 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 10 Feb 2015 11:24:34 +0000 Subject: [PATCH 4/7] Pull out templates logic into its own module --- .../Templates/TemplatesController.coffee | 93 -------- .../Templates/TemplatesMiddlewear.coffee | 25 --- .../Templates/TemplatesPublisher.coffee | 36 --- .../Features/Templates/TemplatesRouter.coffee | 30 --- .../Templates/TemplatesWebController.coffee | 102 --------- services/web/app/coffee/router.coffee | 2 - services/web/app/views/templates/index.jade | 80 ------- services/web/app/views/templates/tag.jade | 31 --- .../web/app/views/templates/template.jade | 69 ------ .../Templates/TemplatesControllerTests.coffee | 209 ------------------ .../Templates/TemplatesPublisherTests.coffee | 64 ------ .../TemplatesWebControllerTests.coffee | 150 ------------- 12 files changed, 891 deletions(-) delete mode 100644 services/web/app/coffee/Features/Templates/TemplatesController.coffee delete mode 100644 services/web/app/coffee/Features/Templates/TemplatesMiddlewear.coffee delete mode 100644 services/web/app/coffee/Features/Templates/TemplatesPublisher.coffee delete mode 100644 services/web/app/coffee/Features/Templates/TemplatesRouter.coffee delete mode 100644 services/web/app/coffee/Features/Templates/TemplatesWebController.coffee delete mode 100644 services/web/app/views/templates/index.jade delete mode 100644 services/web/app/views/templates/tag.jade delete mode 100644 services/web/app/views/templates/template.jade delete mode 100644 services/web/test/UnitTests/coffee/Templates/TemplatesControllerTests.coffee delete mode 100644 services/web/test/UnitTests/coffee/Templates/TemplatesPublisherTests.coffee delete mode 100644 services/web/test/UnitTests/coffee/Templates/TemplatesWebControllerTests.coffee diff --git a/services/web/app/coffee/Features/Templates/TemplatesController.coffee b/services/web/app/coffee/Features/Templates/TemplatesController.coffee deleted file mode 100644 index 6e3ea5fe1e..0000000000 --- a/services/web/app/coffee/Features/Templates/TemplatesController.coffee +++ /dev/null @@ -1,93 +0,0 @@ -path = require('path') -ProjectUploadManager = require('../Uploads/ProjectUploadManager') -ProjectOptionsHandler = require("../Project/ProjectOptionsHandler") -ProjectDetailsHandler = require('../Project/ProjectDetailsHandler') -ProjectGetter = require('../Project/ProjectGetter') -EditorController = require('../Editor/EditorController') -TemplatesPublisher = require("./TemplatesPublisher") -settings = require('settings-sharelatex') -fs = require('fs') -request = require('request') -uuid = require('node-uuid') -logger = require('logger-sharelatex') -async = require("async") - - -module.exports = - - createProjectFromZipTemplate: (req, res)-> - logger.log body:req.session.templateData, "creating project from zip" - if !req.session.templateData? - return res.redirect "/project" - - dumpPath = "#{settings.path.dumpFolder}/#{uuid.v4()}" - writeStream = fs.createWriteStream(dumpPath) - zipUrl = req.session.templateData.zipUrl - if zipUrl.slice(0,12).indexOf("templates") == -1 - zipUrl = "#{settings.apis.web.url}#{zipUrl}" - else - zipUrl = "#{settings.apis.templates.url}#{zipUrl}" - zipReq = request(zipUrl) - zipReq.on "error", (error) -> - logger.error err: error, "error getting zip from template API" - zipReq.pipe(writeStream) - writeStream.on 'close', -> - ProjectUploadManager.createProjectFromZipArchive req.session.user._id, req.session.templateData.templateName, dumpPath, (err, project)-> - if err? - logger.err err:err, zipUrl:zipUrl, "problem building project from zip" - return res.send 500 - setCompiler project._id, req.session.templateData.compiler, -> - fs.unlink dumpPath, -> - delete req.session.templateData - res.redirect "/project/#{project._id}" - - publishProject: (req, res, next) -> - project_id = req.params.Project_id - ProjectGetter.getProject project_id, {owner_ref: 1}, (error, project) -> - return callback(error) if error? - user_id = project.owner_ref.toString() - logger.log user_id:user_id, project_id:project_id, "receiving request to publish project as template" - TemplatesPublisher.publish user_id, project_id, (error) -> - return next(error) if error? - res.send 204 - - unpublishProject: (req, res, next) -> - project_id = req.params.Project_id - ProjectGetter.getProject project_id, {owner_ref: 1}, (error, project) -> - return callback(error) if error? - user_id = project.owner_ref.toString() - logger.log user_id:user_id, project_id:project_id, "receiving request to unpublish project" - TemplatesPublisher.unpublish user_id, project_id, (error) -> - return next(error) if error? - res.send 204 - - updateProjectDescription: (req, res, next) -> - project_id = req.params.Project_id - {description} = req.body - EditorController.updateProjectDescription project_id, description, (error) -> - return next(error) if error? - res.send 204 - - getTemplateDetails: (req, res, next)-> - project_id = req.params.Project_id - ProjectGetter.getProject project_id, {owner_ref: 1}, (error, project) -> - return next(error) if error? - user_id = project.owner_ref.toString() - async.parallel { - details: (cb)-> - TemplatesPublisher.getTemplateDetails user_id, project_id, cb - description: (cb)-> - ProjectDetailsHandler.getProjectDescription project_id, cb - }, (err, results)-> - if err? - logger.err err:err, user_id:user_id, project_id:project_id, "something went wrong getting template details" - return next(err) - details = results.details - details.description = results.description - res.json details - -setCompiler = (project_id, compiler, callback)-> - if compiler? - ProjectOptionsHandler.setCompiler project_id, compiler, callback - else - callback() diff --git a/services/web/app/coffee/Features/Templates/TemplatesMiddlewear.coffee b/services/web/app/coffee/Features/Templates/TemplatesMiddlewear.coffee deleted file mode 100644 index d86ac09517..0000000000 --- a/services/web/app/coffee/Features/Templates/TemplatesMiddlewear.coffee +++ /dev/null @@ -1,25 +0,0 @@ -settings = require("settings-sharelatex") -logger = require("logger-sharelatex") - - -module.exports = - saveTemplateDataInSession: (req, res, next)-> - if req.query.templateName - req.session.templateData = req.query - next() - - id_or_tag_parse: (req, res, next)-> - tag_or_template_id = req.params.tag_or_template_id - if _isObjectId(tag_or_template_id) - req.params.template_id = tag_or_template_id - else - req.params.tag_name = tag_or_template_id - next() - - _isObjectId: _isObjectId = (tag_or_id)-> - checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$") - checkForHexRegExp.test(tag_or_id) - - insert_templates_user_id: (req, res, next)-> - req.params.user_id = settings.templates.user_id - next() diff --git a/services/web/app/coffee/Features/Templates/TemplatesPublisher.coffee b/services/web/app/coffee/Features/Templates/TemplatesPublisher.coffee deleted file mode 100644 index 526f631aeb..0000000000 --- a/services/web/app/coffee/Features/Templates/TemplatesPublisher.coffee +++ /dev/null @@ -1,36 +0,0 @@ -request = require("request") -settings = require("settings-sharelatex") -logger = require("logger-sharelatex") - -module.exports = - - publish : (user_id, project_id, callback)-> - url = buildUrl(user_id, project_id) - request.post url, (err)-> - if err? - logger.err err:err, "something went wrong publishing project as template" - callback err - - unpublish: (user_id, project_id, callback)-> - url = buildUrl(user_id, project_id) - request.del url, (err)-> - callback() - - - getTemplateDetails: (user_id, project_id, callback)-> - url = buildUrl(user_id, project_id)+"/details" - request.get url, (err, res, body)-> - if err? - logger.err err:err, user_id:user_id, project_id:project_id, body:body, "error getting template details" - return callback err - try - json = JSON.parse body - catch err - logger.err err:err, user_id:user_id, project_id:project_id, body:body, "error parsing project json details" - return callback err - logger.log json:json, user_id:user_id, project_id:project_id, "got template details" - callback(err, json) - - -buildUrl = (user_id, project_id)-> - url = "#{settings.apis.templates.url}/templates/user/#{user_id}/project/#{project_id}" diff --git a/services/web/app/coffee/Features/Templates/TemplatesRouter.coffee b/services/web/app/coffee/Features/Templates/TemplatesRouter.coffee deleted file mode 100644 index bc03ca799c..0000000000 --- a/services/web/app/coffee/Features/Templates/TemplatesRouter.coffee +++ /dev/null @@ -1,30 +0,0 @@ -SecurityManager = require("../../managers/SecurityManager") -AuthenticationController = require("../Authentication/AuthenticationController") -TemplatesWebController = require("./TemplatesWebController") -TemplatesController = require("./TemplatesController") -TemplatesMiddlewear = require('./TemplatesMiddlewear') -middleWear = require("./TemplatesMiddlewear") - -module.exports = - apply: (app)-> - - app.get "/templates", middleWear.insert_templates_user_id, TemplatesWebController.renderTemplatesIndexPage - app.get "/templates/user/:user_id", TemplatesWebController.renderTemplatesIndexPage - - app.get "/templates/:tag_or_template_id", middleWear.id_or_tag_parse, middleWear.insert_templates_user_id, TemplatesWebController.tagOrCanonicalPage - app.get "/templates/user/:user_id/:tag_or_template_id", middleWear.id_or_tag_parse, TemplatesWebController.tagOrCanonicalPage - - app.get "/templates/:tag_name/:template_name", middleWear.insert_templates_user_id, TemplatesWebController.renerTemplateInTag - app.get "/templates/user/:user_id/:tag_name/:template_name", TemplatesWebController.renerTemplateInTag - - app.get "/templates/:template_id/v/:version/:file_type", TemplatesWebController.proxyToTemplatesApi - - app.post "/project/:Project_id/template/publish", SecurityManager.requestIsOwner, TemplatesController.publishProject - app.post "/project/:Project_id/template/unpublish", SecurityManager.requestIsOwner, TemplatesController.unpublishProject - app.post "/project/:Project_id/template/description", SecurityManager.requestCanModifyProject, TemplatesController.updateProjectDescription - - # Make sure the /project/new/template route comes before the /project/:project_id/template route - # This is a get request so that it can be linked to. - app.get '/project/new/template', TemplatesMiddlewear.saveTemplateDataInSession, AuthenticationController.requireLogin(), TemplatesController.createProjectFromZipTemplate - - app.get "/project/:Project_id/template", SecurityManager.requestCanAccessProject, TemplatesController.getTemplateDetails \ No newline at end of file diff --git a/services/web/app/coffee/Features/Templates/TemplatesWebController.coffee b/services/web/app/coffee/Features/Templates/TemplatesWebController.coffee deleted file mode 100644 index 0185dfcfe8..0000000000 --- a/services/web/app/coffee/Features/Templates/TemplatesWebController.coffee +++ /dev/null @@ -1,102 +0,0 @@ -request = require("request") -settings = require("settings-sharelatex") -logger = require("logger-sharelatex") -ErrorController = require("../Errors/ErrorController") - -module.exports = TemplatesWebController = - - renderTemplatesIndexPage: (req, res)-> - logger.log "rendering index page of templates" - TemplatesWebController._getDataFromTemplatesApi "/user/#{req.params.user_id}", (err, data)-> - if err? or !data? - logger.err err:err, "something went wrong in renderTemplatesIndexPage" - return res.send 500 - data.title = "latex_templates" - res.render "templates/index", data - - renerTemplateInTag: (req, res)-> - {user_id, tag_name, template_name} = req.params - logger.log user_id:user_id, tag_name:tag_name, template_name:template_name, "rendering latex template page" - TemplatesWebController._getDataFromTemplatesApi "/user/#{user_id}/tag/#{tag_name}/template/#{template_name}", (err, data)-> - if err? and err == 404 - return ErrorController.notFound req, res - if err? or !data? - logger.err err:err, user_id:user_id, tag_name:tag_name, template_name:template_name, "something went wrong in renerTemplateInTag" - return res.send 500 - data.title = data?.template?.name - res.render "templates/template", data - - tagOrCanonicalPage: (req, res)-> - if req.params.template_id? - TemplatesWebController._renderCanonicalPage(req, res) - else if req.params.tag_name?.toLowerCase() == "all" - TemplatesWebController._renderAllTemplatesPage(req, res) - else if req.params.tag_name? - TemplatesWebController._renderTagPage(req, res) - else - logger.log params:req.params, "problem rendering tagOrCanonicalPage" - res.send 500 - - proxyToTemplatesApi: (req, res)-> - url = req.url - - name = req.query.name or "Template" - if req.query.inline? - disposition = "inline" - else - disposition = "attachment" - res.header({"content-disposition": "#{disposition}; filename=\"#{name.replace("\"", "-")}.#{req.params.file_type}\""}) - - logger.log url:url, template_name: name, disposition: disposition, "proxying request to templates api" - - getReq = request.get("#{settings.apis.templates.url}#{url}") - getReq.pipe(res) - getReq.on "error", (error) -> - logger.error err: error, "templates proxy API error" - res.send 500 - - _renderCanonicalPage: (req, res)-> - {user_id, template_id} = req.params - logger.log user_id:user_id, template_id:template_id, "rendering template page" - TemplatesWebController._getDataFromTemplatesApi "/user/#{user_id}/template/#{template_id}", (err, data)-> - if err? and err == 404 - return ErrorController.notFound req, res - if err? - logger.err err:err, user_id:user_id, template_id:template_id, "something went wrong in _renderCanonicalPage" - return res.send 500 - data.title = data?.template?.name - data.tag = null - res.render "templates/template", data - - _renderAllTemplatesPage: (req, res)-> - {user_id} = req.params - logger.log user_id:user_id, "rendering all templates page" - TemplatesWebController._getDataFromTemplatesApi "/user/#{user_id}/all", (err, data)-> - if err? and err == 404 - return ErrorController.notFound req, res - if err? - logger.err err:err, user_id:user_id, "something went wrong in _renderCanonicalPage" - return res.send 500 - data.title = "all_templates" - res.render "templates/tag", data - - _renderTagPage: (req, res)-> - {user_id, tag_name} = req.params - logger.log user_id:user_id, tag_name:tag_name, "rendinging tag page for templates" - TemplatesWebController._getDataFromTemplatesApi "/user/#{user_id}/tag/#{tag_name}", (err, data)-> - if err? and err == 404 - return ErrorController.notFound req, res - if err? - logger.err err:err, user_id:user_id, tag_name:tag_name, "something went wrong in _renderCanonicalPage" - return res.send 500 - data.title = data?.tag?.name - res.render "templates/tag", data - - _getDataFromTemplatesApi: (path, callback)-> - opts = - url: "#{settings.apis.templates.url}#{path}" - json:true - request.get opts, (err, response, data)-> - if response.statusCode == 404 - return callback 404 - callback err, data \ No newline at end of file diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index 18d0a5043a..8b58d205f6 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -14,7 +14,6 @@ UploadsRouter = require './Features/Uploads/UploadsRouter' metrics = require('./infrastructure/Metrics') ReferalController = require('./Features/Referal/ReferalController') ReferalMiddleware = require('./Features/Referal/ReferalMiddleware') -TemplatesRouter = require('./Features/Templates/TemplatesRouter') AuthenticationController = require('./Features/Authentication/AuthenticationController') TagsController = require("./Features/Tags/TagsController") CollaboratorsRouter = require('./Features/Collaborators/CollaboratorsRouter') @@ -63,7 +62,6 @@ module.exports = class Router UploadsRouter.apply(app) PasswordResetRouter.apply(app) StaticPagesRouter.apply(app) - TemplatesRouter.apply(app) Modules.applyRouter(app) diff --git a/services/web/app/views/templates/index.jade b/services/web/app/views/templates/index.jade deleted file mode 100644 index 2b64605c34..0000000000 --- a/services/web/app/views/templates/index.jade +++ /dev/null @@ -1,80 +0,0 @@ -extends ../layout - -block vars - - var meta = "Over 400 LaTeX templates for journal articles, theses, CV and resumes, posters, presentations, and much more" - -block content - .content.content-alt - .container - .row.template-page-header(ng-controller="SearchController") - - .col-md-2 - h2 - a(href="/templates") #{translate("templates")} - .col-md-8 - form.project-search.form-horizontal(role="form") - .form-group.has-feedback.has-feedback-left.col-md-12 - input.form-control.col-md-12(type='text', ng-model='searchQueryText', ng-keyup='search()', placeholder="Search template library....") - i.fa.fa-search.form-control-feedback-left - i.fa.fa-times.form-control-feedback( - ng-click="clearSearchText()", - style="cursor: pointer;", - ng-show="searchQueryText.length > 0" - ) - .col-md-2(ng-controller="MissingTemplateController") - a.btn.btn-primary(ng-click="showMissingTemplateModal()") #{translate("missing_template_question")} - .col-md-8(ng-cloak) - ul.list-unstyled - li(ng-repeat='hit in hits') - .thumbnail.searchResult - .row - a(ng-href='{{hit.url}}') - .col-md-3 - img(ng-src='{{hit.image_url}}') - .col-md-7 - h1(ng-bind-html='hit.name') - p(ng-bind-html='hit.description') - - - - - - .row - -each tag in tags - -if(tag.totalNumberOfTemplates > 0) - .template-section-header.col-md-12 - h2 - a(href=tag.tagPagePath) #{tag.name} - .row - -each template in tag.exampleTemplates - .col-md-3.template-thumbnail - a(href=template.templatePagePath ? template.templatePagePath : template.canonicalUrl).thumbnail - img(src=template.thumbnailUrl) - div.caption - h3.txt-middle #{template.name} - - -if(tag.totalNumberOfTemplates > 4) - .row - .col-md-12.text-center - a(href=tag.tagPagePath) View all #{tag.totalNumberOfTemplates} #{tag.name} templates » - - - - script(type="text/ng-template", id="missingTemplateModal") - .modal-header - button.close( - type="button" - data-dismiss="modal" - ng-click="cancel()" - ) × - h3 #{translate("missing_template_question")} - .modal-body #{translate("tell_us_about_the_template")} - .modal-footer - button.btn.btn-default( - ng-click="cancel()", - ) - span #{translate("dismiss")} - a.btn.btn-primary(href='mailto:team@sharelatex.com?Subject=template') #{translate("email_us")} - - - diff --git a/services/web/app/views/templates/tag.jade b/services/web/app/views/templates/tag.jade deleted file mode 100644 index 980794d04b..0000000000 --- a/services/web/app/views/templates/tag.jade +++ /dev/null @@ -1,31 +0,0 @@ -extends ../layout - -mixin template(template) - .template-thumbnail - a(href=template.templatePagePath ? template.templatePagePath : template.canonicalUrl).thumbnail - img(src=template.thumbnailUrl) - div.caption - h3 #{template.name} - -block content - .content.content-alt - .container - .row - .page-header - h2 - a(href="/templates") #{translate("templates")} - | › - a(href=tag.tagPagePath) #{tag.name} - - for (var row = 0; row <= Math.floor(templates.length / 4); row++) - .row - - for (var column = 0; column < 4; column++) - - if (templates[row*4 + column]) - .col-md-3 - +template(templates[row*4 + column]) - //- -each template in templates - //- a(href=template.templatePagePath || template.canonicalUrl) - //- .col-md-3.template-thumbnail - //- a(href=template.templatePagePath ? template.templatePagePath : template.canonicalUrl).thumbnail - //- img(src=template.thumbnailUrl) - //- div.caption - //- h3 #{template.name} diff --git a/services/web/app/views/templates/template.jade b/services/web/app/views/templates/template.jade deleted file mode 100644 index 0135d91a50..0000000000 --- a/services/web/app/views/templates/template.jade +++ /dev/null @@ -1,69 +0,0 @@ -extends ../layout - -block vars - - var meta = template.description - - title = title + " - LaTeX Template" - -block content - .content.content-alt - .container - .row - .page-header - h2 - a(href="/templates") #{translate("templates")} - | › - - if(tag) - a(href=tag.tagPagePath) #{tag.name} - | › - | #{template.name} - .row - .col-md-6 - .entry - .row - .col-md-12.template-large-pdf-preview - a(href="#{template.pdfUrl}?inline=true&name=#{template.name}") - img(src="#{template.previewUrl}") - - .col-md-6 - .template-details-section - h3 #{translate("about")} - div !{template.description} - div(ng-controller="openInSlController", ng-cloak).download-buttons - a.btn.btn-primary.btn-large(href=template.open_in_sharelatex_url, ng-click='open()', ng-disabled="isDisabled", rel='nofollow') {{openInSlText}} - |   - - a.btn.btn-default( - href="#{template.zipUrl}?name=#{template.name}", - rel='nofollow', - ng-click='downloadZip()', - tooltip-placement="bottom", - tooltip="#{translate('download_zip_file')}" - ) - i.fa.fa-cloud-download - .template-details-section.social_buttons - .addthis_toolbox.addthis_default_style.addthis_32x32_style - a.addthis_button_facebook - a.addthis_button_twitter - a.addthis_button_google_plusone_share - a.addthis_button_compact - script(type='text/javascript', src='//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-517c16586439faa7') - - h3 #{translate("comment")} - #disqus_thread - script(type='text/javascript'). - /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */ - var disqus_shortname = 'sharelatextemplates'; // required: replace example with your forum shortname - /* * * DON'T EDIT BELOW THIS LINE * * */ - (function() { - var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; - dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js'; - (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); - })(); - noscript - | Please enable JavaScript to view the - a(href='http://disqus.com/?ref_noscript') comments powered by Disqus. - a.dsq-brlink(href='http://disqus.com') - | comments powered by - span.logo-disqus Disqus - - diff --git a/services/web/test/UnitTests/coffee/Templates/TemplatesControllerTests.coffee b/services/web/test/UnitTests/coffee/Templates/TemplatesControllerTests.coffee deleted file mode 100644 index 8bf949c76a..0000000000 --- a/services/web/test/UnitTests/coffee/Templates/TemplatesControllerTests.coffee +++ /dev/null @@ -1,209 +0,0 @@ -should = require('chai').should() -SandboxedModule = require('sandboxed-module') -assert = require('assert') -path = require('path') -sinon = require('sinon') -modulePath = path.join __dirname, '../../../../app/js/Features/Templates/TemplatesController' - - -describe 'TemplatesController', -> - - project_id = "213432" - - beforeEach -> - @request = sinon.stub() - @request.returns { - pipe:-> - on:-> - } - @fs = { - unlink : sinon.stub() - createWriteStream : sinon.stub().returns(on:(_, cb)->cb()) - } - @ProjectUploadManager = {createProjectFromZipArchive : sinon.stub().callsArgWith(3, null, {_id:project_id})} - @dumpFolder = "dump/path" - @ProjectOptionsHandler = {setCompiler:sinon.stub().callsArgWith(2)} - @uuid = "1234" - @TemplatesPublisher = - publish: sinon.stub() - unpublish:sinon.stub() - getTemplateDetails: sinon.stub() - @ProjectDetailsHandler = - getProjectDescription:sinon.stub() - @controller = SandboxedModule.require modulePath, requires: - '../Uploads/ProjectUploadManager':@ProjectUploadManager - '../Project/ProjectOptionsHandler':@ProjectOptionsHandler - '../Project/ProjectDetailsHandler':@ProjectDetailsHandler - '../Project/ProjectGetter':@ProjectGetter = {} - '../Editor/EditorController': @EditorController = {} - './TemplatesPublisher':@TemplatesPublisher - "logger-sharelatex": - log:-> - err:-> - "settings-sharelatex": - path: - dumpFolder:@dumpFolder - siteUrl: "http://localhost:3000" - apis: - templates: - url: @templateApiUrl="http://templates.sharelatex.env" - web: - url: @webApiUrl="http://web-api.sharelatex.env" - "node-uuid":v4:=>@uuid - "request": @request - "fs":@fs - @zipUrl = "%2Ftemplates%2F52fb86a81ae1e566597a25f6%2Fv%2F4%2Fzip&templateName=Moderncv%20Banking&compiler=pdflatex" - @templateName = "project name here" - @user_id = "1234" - @req = - session: - user: _id:@user_id - templateData: - zipUrl: @zipUrl - templateName: @templateName - @redirect = {} - - describe 'reciving a request to create project from templates.sharelatex.com', -> - - it 'should take the zip url and write it to disk', (done)-> - redirect = => - @ProjectUploadManager.createProjectFromZipArchive.calledWith(@user_id, @templateName, "#{@dumpFolder}/#{@uuid}").should.equal true - @request.calledWith("#{@templateApiUrl}#{@zipUrl}").should.equal true - @fs.unlink.calledWith("#{@dumpFolder}/#{@uuid}").should.equal true - done() - res = redirect:redirect - @controller.createProjectFromZipTemplate @req, res - - - it "should go to the web api if the url does not contain templates", (done)-> - @req.session.templateData.zipUrl = @zipUrl = "/project/52fd24abf080d80a22000fbd/download/zip&templateName=Example_Project&compiler=xelatex" - redirect = => - @request.calledWith("#{@webApiUrl}#{@zipUrl}").should.equal true - done() - res = redirect:redirect - @controller.createProjectFromZipTemplate @req, res - - it "should go to the web api if the url has template futher down the string", (done)-> - @req.session.templateData.zipUrl = @zipUrl = "/project/52fd24abf080d80a22000fbd/download/zip&templateName=templates&compiler=xelatex" - redirect = => - @request.calledWith("#{@webApiUrl}#{@zipUrl}").should.equal true - done() - res = redirect:redirect - @controller.createProjectFromZipTemplate @req, res - - describe 'publishProject', -> - beforeEach -> - @user_id = "user-id-123" - @project_id = "project-id-123" - @res = - send: sinon.stub() - @req.params = - Project_id: @project_id - - @ProjectGetter.getProject = sinon.stub().callsArgWith(2, null, {owner_ref: @user_id}) - @TemplatesPublisher.publish = sinon.stub().callsArgWith(2) - @controller.publishProject @req, @res - - it "should look up the project owner", -> - @ProjectGetter.getProject - .calledWith(@project_id, { owner_ref: 1 }) - .should.equal true - - it "should publish the template", -> - @TemplatesPublisher.publish - .calledWith(@user_id, @project_id) - .should.equal true - - it "should return a success status", -> - @res.send.calledWith(204).should.equal true - - describe 'unpublishProject', -> - beforeEach -> - @user_id = "user-id-123" - @project_id = "project-id-123" - @res = - send: sinon.stub() - @req.params = - Project_id: @project_id - - @ProjectGetter.getProject = sinon.stub().callsArgWith(2, null, {owner_ref: @user_id}) - @TemplatesPublisher.unpublish = sinon.stub().callsArgWith(2) - @controller.unpublishProject @req, @res - - it "should look up the project owner", -> - @ProjectGetter.getProject - .calledWith(@project_id, { owner_ref: 1 }) - .should.equal true - - it "should publish the template", -> - @TemplatesPublisher.unpublish - .calledWith(@user_id, @project_id) - .should.equal true - - it "should return a success status", -> - @res.send.calledWith(204).should.equal true - - describe 'settings the compiler from the query string', -> - it 'should use the said compiler', (done)-> - @req.session.templateData.compiler = "xelatex" - redirect = => - @ProjectOptionsHandler.setCompiler.calledWith(project_id, "xelatex").should.equal true - done() - res = redirect:redirect - @controller.createProjectFromZipTemplate @req, res - - it 'should not call the options handler if there is not set compiler', (done)-> - redirect = => - @ProjectOptionsHandler.setCompiler.called.should.equal false - done() - res = redirect:redirect - @controller.createProjectFromZipTemplate @req, res - - describe "updateProjectDescription", -> - beforeEach -> - @EditorController.updateProjectDescription = sinon.stub().callsArg(2) - @res = - send: sinon.stub() - @req.params = - Project_id: @project_id = "project-id-123" - @req.body = - description: @description = "test description" - - @controller.updateProjectDescription @req, @res - - it "should update the project description", -> - @EditorController.updateProjectDescription - .calledWith(@project_id, @description) - .should.equal true - - it "should return a success code", -> - @res.send.calledWith(204).should.equal true - - describe 'getTemplateDetails', -> - beforeEach -> - @user_id = "user-id-123" - @project_id = "project-id-123" - @res = - json: sinon.stub() - @req.params = - Project_id: @project_id - - @ProjectGetter.getProject = sinon.stub().callsArgWith(2, null, {owner_ref: @user_id}) - @TemplatesPublisher.getTemplateDetails.callsArgWith(2, null, @details = {exists: true}) - @ProjectDetailsHandler.getProjectDescription.callsArgWith(1, null, @description = "test description") - - @controller.getTemplateDetails @req, @res - - it "should get the template details for the user_id and project_id", -> - @TemplatesPublisher.getTemplateDetails - .calledWith(@user_id, @project_id) - .should.equal true - - it "should return the details and description", -> - @res.json - .calledWith({ - exists: @details.exists - description: @description - }) - .should.equal true - diff --git a/services/web/test/UnitTests/coffee/Templates/TemplatesPublisherTests.coffee b/services/web/test/UnitTests/coffee/Templates/TemplatesPublisherTests.coffee deleted file mode 100644 index d7fe3845f3..0000000000 --- a/services/web/test/UnitTests/coffee/Templates/TemplatesPublisherTests.coffee +++ /dev/null @@ -1,64 +0,0 @@ -should = require('chai').should() -SandboxedModule = require('sandboxed-module') -assert = require('assert') -path = require('path') -sinon = require('sinon') -modulePath = path.join __dirname, '../../../../app/js/Features/Templates/TemplatesPublisher' -expect = require("chai").expect - -describe 'Templates publish', -> - - beforeEach -> - @request = - post: sinon.stub().callsArgWith(1) - del: sinon.stub().callsArgWith(1) - get: sinon.stub() - @settings = - apis: - templates: - url: "http://templates.sharelatex.env" - @TemplatesPublisher = SandboxedModule.require modulePath, requires: - "request": @request - "settings-sharelatex":@settings - "logger-sharelatex": - log:-> - err:-> - - @project_id = "12312132" - @user_id = "132jlkjdsaoij" - - describe "publish", -> - - it 'should post the project to the templates api', (done)-> - @TemplatesPublisher.publish @user_id, @project_id, => - uri = "#{@settings.apis.templates.url}/templates/user/#{@user_id}/project/#{@project_id}" - @request.post.calledWith(uri).should.equal true - done() - - - describe "unpublish", -> - - it "should make a DELETE request to templates api", (done)-> - @TemplatesPublisher.unpublish @user_id, @project_id, => - uri = "#{@settings.apis.templates.url}/templates/user/#{@user_id}/project/#{@project_id}" - @request.del.calledWith(uri).should.equal true - done() - - - describe "getTemplateDetails", -> - it "should make a get request to templates api", (done)-> - body = - exists:true - @request.get.callsArgWith(1, null, null, JSON.stringify(body)) - @TemplatesPublisher.getTemplateDetails @user_id, @project_id, (err, details)=> - uri = "#{@settings.apis.templates.url}/templates/user/#{@user_id}/project/#{@project_id}/details" - @request.get.calledWith(uri).should.equal true - assert.deepEqual details, body - done() - - - it "should catch an error thrown from trying to parse bad json", (done)-> - @request.get.callsArgWith(1, null, null, "") - @TemplatesPublisher.getTemplateDetails @user_id, @project_id, (err, details)=> - expect(err).to.exist - done() diff --git a/services/web/test/UnitTests/coffee/Templates/TemplatesWebControllerTests.coffee b/services/web/test/UnitTests/coffee/Templates/TemplatesWebControllerTests.coffee deleted file mode 100644 index 411ac437d7..0000000000 --- a/services/web/test/UnitTests/coffee/Templates/TemplatesWebControllerTests.coffee +++ /dev/null @@ -1,150 +0,0 @@ -should = require('chai').should() -SandboxedModule = require('sandboxed-module') -assert = require('assert') -path = require('path') -sinon = require('sinon') -modulePath = path.join __dirname, "../../../../app/js/Features/Templates/TemplatesWebController" -expect = require("chai").expect - -describe "TemplatesWebController", -> - - beforeEach -> - - @settings = - apis: - templates_api: - url:"templates.sharelatex.env" - @TemplatesWebController = SandboxedModule.require modulePath, requires: - "settings-sharelatex":@settings - "logger-sharelatex": - log:-> - err:-> - @stubbedApiData = - template:{_id:"12312321", name:"bob"} - tag: {name:"tag name"} - - @TemplatesWebController._getDataFromTemplatesApi = sinon.stub().callsArgWith(1, null, @stubbedApiData) - - @user_id = "12332lk3jlkj" - @tag_name = "tag-name-here" - @template_name = "template-name-here" - @template_id = "template_id_here" - @req = - params: - user_id: @user_id - @res = {} - - describe "renderTemplatesIndexPage", -> - - it "should get the data from the templates api", (done)-> - @res.render = (viewName, data)=> - @TemplatesWebController._getDataFromTemplatesApi.calledWith("/user/#{@user_id}").should.equal true - data.should.equal @stubbedApiData - done() - @TemplatesWebController.renderTemplatesIndexPage @req, @res - - - describe "renerTemplateInTag", -> - - it "should get the data from the templates api", (done)-> - @res.render = (viewName, data)=> - @TemplatesWebController._getDataFromTemplatesApi.calledWith("/user/#{@user_id}/tag/#{@tag_name}/template/#{@template_name}").should.equal true - data.should.equal @stubbedApiData - done() - - @req.params = - user_id:@user_id - template_name:@template_name - tag_name:@tag_name - - @TemplatesWebController.renerTemplateInTag @req, @res - - - describe "tagOrCanonicalPage", -> - - beforeEach -> - @TemplatesWebController._renderCanonicalPage = sinon.stub() - @TemplatesWebController._renderAllTemplatesPage = sinon.stub() - @TemplatesWebController._renderTagPage = sinon.stub() - - it "should call _renderCanonicalPage if there is a template id", ()-> - - @req.params = - template_id:@template_id - - @TemplatesWebController.tagOrCanonicalPage @req, @res - - @TemplatesWebController._renderCanonicalPage.called.should.equal true - @TemplatesWebController._renderAllTemplatesPage.called.should.equal false - @TemplatesWebController._renderTagPage.called.should.equal false - - it "should call _renderAllTemplatesPage the tag name is all", ()-> - - @req.params = - tag_name:"all" - - @TemplatesWebController.tagOrCanonicalPage @req, @res - - @TemplatesWebController._renderCanonicalPage.called.should.equal false - @TemplatesWebController._renderAllTemplatesPage.called.should.equal true - @TemplatesWebController._renderTagPage.called.should.equal false - - - it "should call _renderTagPage the tag name is set", ()-> - - @req.params = - tag_name:"some-tag" - - @TemplatesWebController.tagOrCanonicalPage @req, @res - - @TemplatesWebController._renderCanonicalPage.called.should.equal false - @TemplatesWebController._renderAllTemplatesPage.called.should.equal false - @TemplatesWebController._renderTagPage.called.should.equal true - - describe "_renderCanonicalPage", -> - - it "should get the data from the templates api", (done)-> - @res.render = (viewName, data)=> - @TemplatesWebController._getDataFromTemplatesApi.calledWith("/user/#{@user_id}/template/#{@template_id}").should.equal true - data.tag = null - data.should.equal @stubbedApiData - done() - - @req.params = - user_id:@user_id - template_id:@template_id - - @TemplatesWebController._renderCanonicalPage @req, @res - - - describe "_renderAllTemplatesPage", -> - - it "should get the data from the templates api", (done)-> - @res.render = (viewName, data)=> - @TemplatesWebController._getDataFromTemplatesApi.calledWith("/user/#{@user_id}/all").should.equal true - data.should.equal @stubbedApiData - done() - - @req.params = - user_id:@user_id - - @TemplatesWebController._renderAllTemplatesPage @req, @res - - - describe "_renderTagPage", -> - - it "should get the data from the templates api", (done)-> - @res.render = (viewName, data)=> - @TemplatesWebController._getDataFromTemplatesApi.calledWith("/user/#{@user_id}/tag/#{@tag_name}").should.equal true - data.should.equal @stubbedApiData - done() - - @req.params = - user_id:@user_id - tag_name:@tag_name - - @TemplatesWebController._renderTagPage @req, @res - - - - From b44e9b1dcb01c9687ccb321abaa832b260f4d32f Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 10 Feb 2015 13:02:43 +0000 Subject: [PATCH 5/7] Move template front end code to module --- .../app/views/project/editor/left-menu.jade | 5 +- services/web/public/coffee/ide.coffee | 1 - .../controllers/TemplatesController.coffee | 84 ------------------- .../public/coffee/ide/templates/index.coffee | 4 - 4 files changed, 1 insertion(+), 93 deletions(-) delete mode 100644 services/web/public/coffee/ide/templates/controllers/TemplatesController.coffee delete mode 100644 services/web/public/coffee/ide/templates/index.coffee diff --git a/services/web/app/views/project/editor/left-menu.jade b/services/web/app/views/project/editor/left-menu.jade index 1e4d2ab43e..479d501992 100644 --- a/services/web/app/views/project/editor/left-menu.jade +++ b/services/web/app/views/project/editor/left-menu.jade @@ -41,10 +41,7 @@ aside#left-menu.full-size( ) i.fa.fa-fw.fa-copy |    #{translate("copy_project")} - li(ng-controller="TemplatesController", ng-show="permissions.admin") - a(ng-click="openPublishTemplateModal()") - i.fa.fa-external-link.fa-fw - |    #{translate("publish_as_template")} + !{moduleIncludes("editorLeftMenu:actions", locals)} if (moduleIncludesAvailable("editorLeftMenu:sync")) div(ng-show="!anonymous") diff --git a/services/web/public/coffee/ide.coffee b/services/web/public/coffee/ide.coffee index 2bd1ae236f..a75e76bef8 100644 --- a/services/web/public/coffee/ide.coffee +++ b/services/web/public/coffee/ide.coffee @@ -12,7 +12,6 @@ define [ "ide/share/index" "ide/chat/index" "ide/clone/index" - "ide/templates/index" "ide/dropbox/index" "ide/hotkeys/index" "ide/directives/layout" diff --git a/services/web/public/coffee/ide/templates/controllers/TemplatesController.coffee b/services/web/public/coffee/ide/templates/controllers/TemplatesController.coffee deleted file mode 100644 index 10c6cf9000..0000000000 --- a/services/web/public/coffee/ide/templates/controllers/TemplatesController.coffee +++ /dev/null @@ -1,84 +0,0 @@ -define [ - "base" - "ide/permissions/PermissionsManager" -], (App, PermissionsManager) -> - - App.controller "TemplatesController", ($scope, $modal, ide) -> - $scope.openPublishTemplateModal = () -> - resetState = -> - $scope.problemTalkingToTemplateApi = false - - resetState() - - modal = $modal.open { - templateUrl: "publishProjectAsTemplateModalTemplate" - controller: "PublishProjectAsTemplateModalController" - scope:$scope - } - modal.result.then(resetState, resetState) - - App.controller "PublishProjectAsTemplateModalController", ($scope, $modalInstance, ide, $http) -> - user_id = ide.$scope.user.id - $scope.templateDetails = {exists:false} - - $scope.state = - publishInflight: false - unpublishInflight: false - - problemTalkingToTemplateApi = -> - $scope.problemTalkingToTemplateApi = true - - refreshPublishedStatus = -> - $http.get("/project/#{ide.project_id}/template") - .success (data) -> - $scope.templateDetails = data - $scope.templateDetails.publishedDate = moment(data.publishedDate).format("Do MMM YYYY, h:mm a") - $scope.templateDetails.description = data.description - .error () -> - problemTalkingToTemplateApi() - - refreshPublishedStatus() - $scope.$watch $scope.problemTalkingToTemplateApi, (value) -> - if value? - refreshPublishedStatus() - - updateProjectDescription = -> - $http.post("/project/#{ide.project_id}/template/description", { - description: $scope.templateDetails.description - _csrf: window.csrfToken - }) - - # Save the description on modal close - $modalInstance.result.finally () -> updateProjectDescription() - - $scope.publishTemplate = -> - $scope.state.publishInflight = true - updateProjectDescription() - .error () -> - problemTalkingToTemplateApi() - .success () -> - $http - .post("/project/#{ide.project_id}/template/publish", { - _csrf: window.csrfToken - }) - .error () -> - problemTalkingToTemplateApi() - .success () -> - refreshPublishedStatus() - $scope.state.publishInflight = false - - - $scope.unpublishTemplate = -> - $scope.state.unpublishInflight = true - $http - .post("/project/#{ide.project_id}/template/unpublish", { - _csrf: window.csrfToken - }) - .success () -> - refreshPublishedStatus() - $scope.state.unpublishInflight = false - .error () -> - problemTalkingToTemplateApi() - - $scope.cancel = () -> - $modalInstance.dismiss() diff --git a/services/web/public/coffee/ide/templates/index.coffee b/services/web/public/coffee/ide/templates/index.coffee deleted file mode 100644 index 10d7872e9c..0000000000 --- a/services/web/public/coffee/ide/templates/index.coffee +++ /dev/null @@ -1,4 +0,0 @@ -define [ - "ide/templates/controllers/TemplatesController" -], () -> - From bd5f3037129054047e3f91538b9cd613776097b9 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 10 Feb 2015 14:05:38 +0000 Subject: [PATCH 6/7] Remove dropbox js include --- services/web/public/coffee/ide.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/services/web/public/coffee/ide.coffee b/services/web/public/coffee/ide.coffee index a75e76bef8..87a8a984e2 100644 --- a/services/web/public/coffee/ide.coffee +++ b/services/web/public/coffee/ide.coffee @@ -12,7 +12,6 @@ define [ "ide/share/index" "ide/chat/index" "ide/clone/index" - "ide/dropbox/index" "ide/hotkeys/index" "ide/directives/layout" "ide/services/ide" From 18723c2e26edc6181c07f1d5c63b24417d051e68 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 10 Feb 2015 13:11:29 +0000 Subject: [PATCH 7/7] Bump version to 0.1.2 --- services/web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/package.json b/services/web/package.json index 5bce5af848..18b3e5ab5d 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -1,6 +1,6 @@ { "name": "web-sharelatex", - "version": "0.1.0", + "version": "0.1.2", "description": "The HTTP front end for ShareLaTeX", "repository": { "type": "git",