From 1e101c66a8a5797ee2b974368b210d322d90d581 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 8 Feb 2014 14:44:47 +0000 Subject: [PATCH 001/525] Initial commit with web-sharelatex and document-updater-sharelatex --- server-ce/.gitignore | 1 + server-ce/Gruntfile.coffee | 51 ++++++++++++++++++++++++++++++++++++++ server-ce/package.json | 18 ++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 server-ce/.gitignore create mode 100644 server-ce/Gruntfile.coffee create mode 100644 server-ce/package.json diff --git a/server-ce/.gitignore b/server-ce/.gitignore new file mode 100644 index 0000000000..3c3629e647 --- /dev/null +++ b/server-ce/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee new file mode 100644 index 0000000000..2e3e5695c4 --- /dev/null +++ b/server-ce/Gruntfile.coffee @@ -0,0 +1,51 @@ +module.exports = (grunt) -> + grunt.loadNpmTasks 'grunt-bunyan' + grunt.loadNpmTasks 'grunt-execute' + grunt.loadNpmTasks 'grunt-available-tasks' + grunt.loadNpmTasks 'grunt-concurrent' + + grunt.initConfig + execute: + web: + src: "node_modules/web-sharelatex/app.js" + 'document-updater': + src: "node_modules/document-updater-sharelatex/app.js" + + concurrent: + all: + tasks: ['run:web', 'run:document-updater'] + options: + logConcurrentOutput: true + + availabletasks: + tasks: + options: + filter: 'exclude', + tasks: [ + 'coffee' + 'execute' + 'bunyan' + 'availabletasks' + ] + groups: + "Compile tasks": [ + "compile:server" + "compile" + ] + "Run tasks": [ + "run" + "default" + ] + "Misc": [ + "help" + ] + + grunt.registerTask 'help', 'Display this help list', 'availabletasks' + + grunt.registerTask 'run:web', "Run web-sharelatex, the ShareLaTeX web server", ["bunyan", "execute:web"] + grunt.registerTask 'run:document-updater', "Run document-updater-sharelatex, the real-time document server", ["bunyan", "execute:document-updater"] + + grunt.registerTask 'run', "Run all of the sharelatex processes", ['concurrent:all'] + + grunt.registerTask 'default', 'run' + diff --git a/server-ce/package.json b/server-ce/package.json new file mode 100644 index 0000000000..4dbb4eddd8 --- /dev/null +++ b/server-ce/package.json @@ -0,0 +1,18 @@ +{ + "name": "sharelatex", + "description": "An online collaborative LaTeX editor", + "dependencies": { + "logger-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/logger-sharelatex.git#bunyan", + "web-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/web-sharelatex.git#master", + "document-updater-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/documentupdater-sharelatex.git#master", + "coffee-script": "~1.7.1" + }, + "devDependencies": { + "grunt": "~0.4.2", + "bunyan": "~0.22.1", + "grunt-bunyan": "~0.5.0", + "grunt-execute": "~0.1.5", + "grunt-available-tasks": "~0.4.1", + "grunt-concurrent": "~0.4.3" + } +} From 29a038e6331b4971c02ab24b1466501ba1fc9459 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 8 Feb 2014 19:40:56 +0000 Subject: [PATCH 002/525] Add README and CONTRIBUTING --- server-ce/CONTRIBUTING.md | 36 +++++++++++++++++++++++++ server-ce/README.md | 57 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 server-ce/CONTRIBUTING.md create mode 100644 server-ce/README.md diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md new file mode 100644 index 0000000000..8d0079d288 --- /dev/null +++ b/server-ce/CONTRIBUTING.md @@ -0,0 +1,36 @@ +Contributing to ShareLaTeX +========================== + +Thank you for reading this! If you've found a bug, or have a new feature in mind, +then here are some notes on how to best report issues or implement changes. + +Security +-------- + +Please do not publish security vulnerabilities publicly until we've had a chance +to address them. All security related issues/patches should be sent directly to +security@sharelatex.com where we will attempt to address them quickly. If you're +unsure whether something is a security issue or not, then please be cautious and +contact us at security@sharelatex.com first. + +Reporting bugs +-------------- + +If you've found a bug then please: + +1. Check if there is an existing issue for it. If there is then please add + any more information that you have, or give it a "+1". +2. If there is there is no issue, then please open one. +3. Please describe the issue as clearly as possible, including how to + reproduce the bug, which situations it appears in, what you expected to + happen, and what actually happens. +4. Please include a screenshot for front end issues if you can. + +Pull Requests +------------- + +We love pull requests, so be bold with them! Don't be afraid of going ahead +and changing something, or adding a new feature. If you're setting of to make +a big change then opening an issue (or commenting on an existing one) is the +best way to discuss your ideas first. + diff --git a/server-ce/README.md b/server-ce/README.md new file mode 100644 index 0000000000..663dfea432 --- /dev/null +++ b/server-ce/README.md @@ -0,0 +1,57 @@ +ShareLaTeX is a web based collaborative LaTeX editor. There are two versions of it, +the online version that anyone can sign up to at www.sharelatex.com, and this open source +version which allows anyone to run a local installation of ShareLaTeX. + +This repository pulls together all of the different services in ShareLaTeX's service +orientied architecture (SOA). + +Installation +============ + +First, check out a local copy of this repository: + + $ git clone git@github.com:sharelatex/sharelatex.git + $ cd sharelatex + +Next run `npm install` to download all of the dependencies and services +(you need Node.js installed, version 0.10.0 or later): + + $ npm install + +This can take a while, so now would be a good time for a cup of tea. +When that has finished, run ShareLaTeX with + + $ grunt run + +ShareLaTeX should now be running at http://localhost:3000. + +Dependencies +============ + +You need a local instance of Redis and Mongodb running on their standard ports. + +Other repositories +================== + +ShareLaTeX consists of many separate services, each with their own Node.js process +and source code repository. These are all downloaded when you run `npm install` and +they are run when you run `grunt run`. + +The different services are: + +web-sharelatex +-------------- + +The front facing web server that serves all the HTML pages, CSS and javascript +to the client. Also contains a lot of logic around creating and editing +projects, and account management. + +document-updater-sharelatex +--------------------------- + +Process updates that come in from the editor when users modify documents. Ensures that +the updates are applied in the right order, and that only one operation is modifying +the document at a time. Also caches the documents in redis for very fast but persistent +modifications. + + From 93024e5b2edddca7c21b06e0d403bbe41608ab67 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 8 Feb 2014 21:52:45 +0000 Subject: [PATCH 003/525] Update Gruntfile --- server-ce/Gruntfile.coffee | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 2e3e5695c4..03f7c85e04 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -22,18 +22,17 @@ module.exports = (grunt) -> options: filter: 'exclude', tasks: [ - 'coffee' + 'concurrent' 'execute' 'bunyan' 'availabletasks' ] groups: - "Compile tasks": [ - "compile:server" - "compile" - ] "Run tasks": [ "run" + "run:all" + "run:web" + "run:document-updater" "default" ] "Misc": [ @@ -46,6 +45,7 @@ module.exports = (grunt) -> grunt.registerTask 'run:document-updater', "Run document-updater-sharelatex, the real-time document server", ["bunyan", "execute:document-updater"] grunt.registerTask 'run', "Run all of the sharelatex processes", ['concurrent:all'] + grunt.registerTask 'run:all', 'run' grunt.registerTask 'default', 'run' From fd14f6d9f5844c8593aca20f009a41b140bc4216 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 8 Feb 2014 21:53:07 +0000 Subject: [PATCH 004/525] Add in settings module --- server-ce/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/package.json b/server-ce/package.json index 4dbb4eddd8..0bbfab7d78 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -3,6 +3,7 @@ "description": "An online collaborative LaTeX editor", "dependencies": { "logger-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/logger-sharelatex.git#bunyan", + "settings-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/settings-sharelatex.git#master", "web-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/web-sharelatex.git#master", "document-updater-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/documentupdater-sharelatex.git#master", "coffee-script": "~1.7.1" From b1ae5cb7aabc0db7fcbfcc15578707c7677fc2bc Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 10 Feb 2014 12:26:34 +0000 Subject: [PATCH 005/525] Add commented settings file --- server-ce/config/settings.testing.coffee | 194 +++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 server-ce/config/settings.testing.coffee diff --git a/server-ce/config/settings.testing.coffee b/server-ce/config/settings.testing.coffee new file mode 100644 index 0000000000..8c2eb5a33d --- /dev/null +++ b/server-ce/config/settings.testing.coffee @@ -0,0 +1,194 @@ +Path = require('path') +http = require('http') +http.globalAgent.maxSockets = 300 + +# Make time interval config easier. +seconds = 1000 +minutes = 60 * seconds + +# These credentials are used for authenticating api requests +# between services that may need to go over public channels +httpAuthUser = "sharelatex" +httpAuthPass = "password" +httpAuthUsers = {} +httpAuthUsers[httpAuthUser] = httpAuthPass + +sessionSecret = "secret-please-change" + +module.exports = + # File storage + # ------------ + # + # ShareLaTeX stores binary files like images in S3. + # Fill in your Amazon S3 credential below. + s3: + key: "" + secret: "" + bucketName : "" + + # Databases + # --------- + mongo: + url : 'mongodb://127.0.0.1/sharelatexTesting' + + redis: + web: + host: "localhost" + port: "6379" + password: "" + + api: + host: "localhost" + port: "6379" + password: "" + + # Service locations + # ----------------- + + # Configure which ports to run each service on. Generally you + # can leave these as they are unless you have some other services + # running which conflict, or want to run the web process on port 80. + internal: + web: + port: webPort = 3000 + documentupdater: + port: docUpdaterPort = 3003 + + # Tell each service where to find the other services. If everything + # is running locally then this is easy, but they exist as separate config + # options incase you want to run some services on remote hosts. + apis: + web: + url: "http://localhost:#{webPort}" + user: httpAuthUser + pass: httpAuthPass + documentupdater: + url : "http://localhost:#{docUpdaterPort}" + thirdPartyDataStore: + url : "http://localhost:3002" + emptyProjectFlushDelayMiliseconds: 5 * seconds + tags: + url :"http://localhost:3012" + spelling: + url : "http://localhost:3005" + versioning: + snapshotwaitms:3000 + url: "http://localhost:4000" + username: httpAuthUser + password: httpAuthPass + recurly: + privateKey: "" + apiKey: "" + subdomain: "" + chat: + url: "http://localhost:3010" + templates: + port: 3007 + blog: + port: 3008 + filestore: + url: "http://localhost:3009" + clsi: + url: "http://localhost:3013" + templates_api: + url: "http://localhost:3014" + + # Where your instance of ShareLaTeX can be found publically. Used in emails + # that are sent out, generated links, etc. + siteUrl : 'http://localhost:3000' + + # Same, but with http auth credentials. + httpAuthSiteUrl: 'http://#{httpAuthUser}:#{httpAuthPass}@localhost:3000' + + # Security + # -------- + security: + sessionSecret: sessionSecret + + httpAuthUsers: httpAuthUsers + + # Default features + # ---------------- + # + # You can select the features that are enabled by default for new + # new users. + plans: plans = [{ + planCode: "personal" + name: "Personal" + price: 0 + features: + collaborators: -1 + dropbox: true + versioning: true + }] + + # Spelling languages + # ------------------ + # + # You must have the corresponding aspell package installed to + # be able to use a language. + languages: [ + {name: "English", code: "en"} + ] + + # Third party services + # -------------------- + # + # ShareLaTeX's regular newsletter is managed by Markdown mail. Add your + # credentials here to integrate with this. + # markdownmail: + # secret: "" + # list_id: "" + # + # Fill in your unique token from various analytics services to enable + # them. + # analytics: + # mixpanel: + # token: "" + # ga: + # token: "" + # heap: + # token: "" + # + # ShareLaTeX's help desk is provided by tenderapp.com + # tenderUrl: "" + # + # ShareLaTeX uses Amazon's SES api to send transactional emails. + # Uncomment these lines and provide your credentials to be able to send emails. + # ses: + # "key":"" + # "secret":"" + + # Production Settings + # ------------------- + + # Should javascript assets be served minified or not. Note that you will + # need to run `grunt compile:minify` within the web-sharelatex directory + # to generate these. + useMinifiedJs: false + + # Should static assets be sent with a header to tell the browser to cache + # them. + cacheStaticAssets: false + + # If you are running ShareLaTeX over https, set this to true to send the + # cookie with a secure flag (recommended). + secureCookie: false + + + # Internal configs + # ---------------- + path: + commonFolder: Path.resolve "common" + dumpFolder: Path.resolve "data/dumpFolder" + zippedProjects: Path.resolve "data/zippedProjects" + unzippedProjects: Path.resolve "data/unzippedProjects" + + automaticSnapshots: + maxTimeBetweenSnapshots: 30 * minutes + waitTimeAfterLastEdit: 5 * minutes + + smokeTest: + user: "team+smoketest@sharelatex.com" + password: "smoketest" + projectId: "52b18a70249683c0a9000007" From 543c9f2878bd8fdfa1652b148c757054e5b4418f Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 12 Feb 2014 10:21:20 +0000 Subject: [PATCH 006/525] Import web and doc updater as git repos, not npm modules --- server-ce/.gitignore | 3 + server-ce/Gruntfile.coffee | 106 ++++++++++++++---- ...ing.coffee => settings.development.coffee} | 32 ++++-- server-ce/package.json | 2 - 4 files changed, 110 insertions(+), 33 deletions(-) rename server-ce/config/{settings.testing.coffee => settings.development.coffee} (85%) diff --git a/server-ce/.gitignore b/server-ce/.gitignore index 3c3629e647..a8b670e583 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -1 +1,4 @@ node_modules + +web +document-updater diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 03f7c85e04..d25f63af96 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -1,3 +1,11 @@ +fs = require "fs" +exec = require("child_process").exec +spawn = require("child_process").spawn + +WEB_REPO = "git@bitbucket.org:sharelatex/web-sharelatex.git" +DOC_UPDATER_REPO = "git@bitbucket.org:sharelatex/documentupdater-sharelatex.git" + + module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-bunyan' grunt.loadNpmTasks 'grunt-execute' @@ -7,9 +15,9 @@ module.exports = (grunt) -> grunt.initConfig execute: web: - src: "node_modules/web-sharelatex/app.js" + src: "web/app.js" 'document-updater': - src: "node_modules/document-updater-sharelatex/app.js" + src: "document-updater/app.js" concurrent: all: @@ -20,25 +28,39 @@ module.exports = (grunt) -> availabletasks: tasks: options: - filter: 'exclude', - tasks: [ - 'concurrent' - 'execute' - 'bunyan' - 'availabletasks' - ] - groups: - "Run tasks": [ - "run" - "run:all" - "run:web" - "run:document-updater" - "default" - ] - "Misc": [ - "help" - ] + filter: 'exclude', + tasks: [ + 'concurrent' + 'execute' + 'bunyan' + 'availabletasks' + ] + groups: + "Run tasks": [ + "run" + "run:all" + "run:web" + "run:document-updater" + "default" + ] + "Misc": [ + "help" + ] + grunt.registerTask 'install:web', "Download and set up the web-sharelatex service", () -> + done = @async() + Helpers.installService(WEB_REPO, "web", done) + grunt.registerTask 'install:document-updater', "Download and set up the document-updater-sharelatex service", () -> + done = @async() + Helpers.installService(DOC_UPDATER_REPO, "document-updater", done) + + grunt.registerTask 'update:web', "Checkout and update the web-sharelatex service", () -> + done = @async() + Helpers.updateService("web", done) + grunt.registerTask 'update:document-updater', "Checkout and update the document-updater-sharelatex service", () -> + done = @async() + Helpers.updateService("document-updater", done) + grunt.registerTask 'help', 'Display this help list', 'availabletasks' grunt.registerTask 'run:web', "Run web-sharelatex, the ShareLaTeX web server", ["bunyan", "execute:web"] @@ -49,3 +71,47 @@ module.exports = (grunt) -> grunt.registerTask 'default', 'run' +Helpers = + installService: (repo_src, dir, callback = (error) ->) -> + Helpers.cloneGitRepo repo_src, dir, (error) -> + return callback(error) if error? + Helpers.installNpmModules dir, (error) -> + return callback(error) if error? + Helpers.runGruntInstall dir, (error) -> + return callback(error) if error? + callback() + + updateService: (dir, callback = (error) ->) -> + Helpers.updateGitRepo dir, (error) -> + return callback(error) if error? + Helpers.installNpmModules dir, (error) -> + return callback(error) if error? + Helpers.runGruntInstall dir, (error) -> + return callback(error) if error? + callback() + + cloneGitRepo: (repo_src, dir, callback = (error) ->) -> + if !fs.existsSync(dir) + proc = spawn "git", ["clone", repo_src, dir], stdio: "inherit" + proc.on "close", () -> + callback() + else + console.log "#{dir} already installed, skipping." + callback() + + updateGitRepo: (dir, callback = (error) ->) -> + proc = spawn "git", ["checkout", "master"], cwd: dir, stdio: "inherit" + proc.on "close", () -> + proc = spawn "git", ["pull"], cwd: dir, stdio: "inherit" + proc.on "close", () -> + callback() + + installNpmModules: (dir, callback = (error) ->) -> + proc = spawn "npm", ["install"], stdio: "inherit", cwd: dir + proc.on "close", () -> + callback() + + runGruntInstall: (dir, callback = (error) ->) -> + proc = spawn "grunt", ["install"], stdio: "inherit", cwd: dir + proc.on "close", () -> + callback() diff --git a/server-ce/config/settings.testing.coffee b/server-ce/config/settings.development.coffee similarity index 85% rename from server-ce/config/settings.testing.coffee rename to server-ce/config/settings.development.coffee index 8c2eb5a33d..46d8ce0da8 100644 --- a/server-ce/config/settings.testing.coffee +++ b/server-ce/config/settings.development.coffee @@ -20,7 +20,7 @@ module.exports = # ------------ # # ShareLaTeX stores binary files like images in S3. - # Fill in your Amazon S3 credential below. + # Fill in your Amazon S3 credentials below. s3: key: "" secret: "" @@ -29,7 +29,7 @@ module.exports = # Databases # --------- mongo: - url : 'mongodb://127.0.0.1/sharelatexTesting' + url : 'mongodb://127.0.0.1/sharelatex' redis: web: @@ -175,20 +175,30 @@ module.exports = # cookie with a secure flag (recommended). secureCookie: false - # Internal configs # ---------------- path: - commonFolder: Path.resolve "common" + # If we ever need to write something to disk (e.g. incoming requests + # that need processing but may be too big for memory, then write + # them to disk here). dumpFolder: Path.resolve "data/dumpFolder" - zippedProjects: Path.resolve "data/zippedProjects" - unzippedProjects: Path.resolve "data/unzippedProjects" + # Automatic Snapshots + # ------------------- automaticSnapshots: - maxTimeBetweenSnapshots: 30 * minutes + # How long should we wait after the user last edited to + # take a snapshot? waitTimeAfterLastEdit: 5 * minutes + # Even if edits are still taking place, this is maximum + # time to wait before taking another snapshot. + maxTimeBetweenSnapshots: 30 * minutes - smokeTest: - user: "team+smoketest@sharelatex.com" - password: "smoketest" - projectId: "52b18a70249683c0a9000007" + # Smoke test + # ---------- + # Provide log in credentials and a project to be able to run + # some basic smoke tests to check the core functionality. + # + # smokeTest: + # user: "" + # password: "" + # projectId: "" diff --git a/server-ce/package.json b/server-ce/package.json index 0bbfab7d78..bb2ab4e1aa 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -4,8 +4,6 @@ "dependencies": { "logger-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/logger-sharelatex.git#bunyan", "settings-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/settings-sharelatex.git#master", - "web-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/web-sharelatex.git#master", - "document-updater-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/documentupdater-sharelatex.git#master", "coffee-script": "~1.7.1" }, "devDependencies": { From a6e998da7cda52e594c0ac7a6104bb8ed8643e04 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 12 Feb 2014 11:18:25 +0000 Subject: [PATCH 007/525] Use git repos --- server-ce/Gruntfile.coffee | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index d25f63af96..555185cd19 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -2,8 +2,13 @@ fs = require "fs" exec = require("child_process").exec spawn = require("child_process").spawn -WEB_REPO = "git@bitbucket.org:sharelatex/web-sharelatex.git" -DOC_UPDATER_REPO = "git@bitbucket.org:sharelatex/documentupdater-sharelatex.git" +SERVICES = [{ + name: "web" + repo: "git@github.com:sharelatex/web-sharelatex.git" +}, { + name: "document-updater" + repo: "git@github.com:sharelatex/document-updater-sharelatex.git" +}] module.exports = (grunt) -> @@ -46,21 +51,21 @@ module.exports = (grunt) -> "Misc": [ "help" ] + "Install tasks": ("install:#{service.name}" for service in SERVICES).concat("install:all") + "Update tasks": ("update:#{service.name}" for service in SERVICES).concat("update:all") - grunt.registerTask 'install:web', "Download and set up the web-sharelatex service", () -> - done = @async() - Helpers.installService(WEB_REPO, "web", done) - grunt.registerTask 'install:document-updater', "Download and set up the document-updater-sharelatex service", () -> - done = @async() - Helpers.installService(DOC_UPDATER_REPO, "document-updater", done) + for service in SERVICES + do (service) -> + grunt.registerTask "install:#{service.name}", "Download and set up the #{service.name} service", () -> + done = @async() + Helpers.installService(service.repo, service.name, done) + grunt.registerTask "update:#{service.name}", "Checkout and update the #{service.name} service", () -> + done = @async() + Helpers.updateService(service.name, done) + + grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", ("install:#{service.name}" for service in SERVICES) + grunt.registerTask 'update:all', "Checkout and update all ShareLaTeX services", ("update:#{service.name}" for service in SERVICES) - grunt.registerTask 'update:web', "Checkout and update the web-sharelatex service", () -> - done = @async() - Helpers.updateService("web", done) - grunt.registerTask 'update:document-updater', "Checkout and update the document-updater-sharelatex service", () -> - done = @async() - Helpers.updateService("document-updater", done) - grunt.registerTask 'help', 'Display this help list', 'availabletasks' grunt.registerTask 'run:web', "Run web-sharelatex, the ShareLaTeX web server", ["bunyan", "execute:web"] From b9a7cb6c30c4d05d76d9829e14482a427d7edab2 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 12 Feb 2014 11:24:13 +0000 Subject: [PATCH 008/525] Update installation details --- server-ce/Gruntfile.coffee | 10 ++++------ server-ce/README.md | 26 +++++++++++++++----------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 555185cd19..f517e166fc 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -62,18 +62,16 @@ module.exports = (grunt) -> grunt.registerTask "update:#{service.name}", "Checkout and update the #{service.name} service", () -> done = @async() Helpers.updateService(service.name, done) + grunt.registerTask 'run:#{service.name}', "Run the ShareLaTeX #{service.name} service", ["bunyan", "execute:web"] grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", ("install:#{service.name}" for service in SERVICES) + grunt.registerTask 'install', 'install:all' grunt.registerTask 'update:all', "Checkout and update all ShareLaTeX services", ("update:#{service.name}" for service in SERVICES) - - grunt.registerTask 'help', 'Display this help list', 'availabletasks' - - grunt.registerTask 'run:web', "Run web-sharelatex, the ShareLaTeX web server", ["bunyan", "execute:web"] - grunt.registerTask 'run:document-updater', "Run document-updater-sharelatex, the real-time document server", ["bunyan", "execute:document-updater"] - + grunt.registerTask 'update', 'update:all' grunt.registerTask 'run', "Run all of the sharelatex processes", ['concurrent:all'] grunt.registerTask 'run:all', 'run' + grunt.registerTask 'help', 'Display this help list', 'availabletasks' grunt.registerTask 'default', 'run' Helpers = diff --git a/server-ce/README.md b/server-ce/README.md index 663dfea432..7e5eafb553 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,3 +1,6 @@ +ShareLaTeX +========== + ShareLaTeX is a web based collaborative LaTeX editor. There are two versions of it, the online version that anyone can sign up to at www.sharelatex.com, and this open source version which allows anyone to run a local installation of ShareLaTeX. @@ -6,19 +9,18 @@ This repository pulls together all of the different services in ShareLaTeX's ser orientied architecture (SOA). Installation -============ +------------ First, check out a local copy of this repository: $ git clone git@github.com:sharelatex/sharelatex.git $ cd sharelatex -Next run `npm install` to download all of the dependencies and services -(you need Node.js installed, version 0.10.0 or later): +Next install all the Node modules and ShareLaTeX services: $ npm install + $ grunt install -This can take a while, so now would be a good time for a cup of tea. When that has finished, run ShareLaTeX with $ grunt run @@ -26,12 +28,16 @@ When that has finished, run ShareLaTeX with ShareLaTeX should now be running at http://localhost:3000. Dependencies -============ +------------ -You need a local instance of Redis and Mongodb running on their standard ports. +You need: + +* Node.js 0.10 or greater +* Grunt command line tools (Run `npm install -g grunt-cli` to install them) +* A local instance of Redis and Mongodb running on their standard ports. Other repositories -================== +------------------ ShareLaTeX consists of many separate services, each with their own Node.js process and source code repository. These are all downloaded when you run `npm install` and @@ -39,15 +45,13 @@ they are run when you run `grunt run`. The different services are: -web-sharelatex --------------- +### web-sharelatex The front facing web server that serves all the HTML pages, CSS and javascript to the client. Also contains a lot of logic around creating and editing projects, and account management. -document-updater-sharelatex ---------------------------- +### document-updater-sharelatex Process updates that come in from the editor when users modify documents. Ensures that the updates are applied in the right order, and that only one operation is modifying From 4625d7126f688f62825a2eb7bb65e18583acfbdf Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 12 Feb 2014 12:11:58 +0000 Subject: [PATCH 009/525] Allow custom configs to be installed via git --- server-ce/.gitignore | 3 +++ server-ce/Gruntfile.coffee | 24 ++++++++++++++++++++---- server-ce/package.json | 3 ++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/server-ce/.gitignore b/server-ce/.gitignore index a8b670e583..2d01c63836 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -1,4 +1,7 @@ +config +config-local node_modules web document-updater + diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index f517e166fc..bb35b07b5c 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -1,6 +1,6 @@ fs = require "fs" -exec = require("child_process").exec spawn = require("child_process").spawn +rimraf = require "rimraf" SERVICES = [{ name: "web" @@ -51,8 +51,9 @@ module.exports = (grunt) -> "Misc": [ "help" ] - "Install tasks": ("install:#{service.name}" for service in SERVICES).concat("install:all") - "Update tasks": ("update:#{service.name}" for service in SERVICES).concat("update:all") + "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install"]) + "Update tasks": ("update:#{service.name}" for service in SERVICES).concat(["update:all", "update"]) + "Config tasks": ["install:config"] for service in SERVICES do (service) -> @@ -62,7 +63,7 @@ module.exports = (grunt) -> grunt.registerTask "update:#{service.name}", "Checkout and update the #{service.name} service", () -> done = @async() Helpers.updateService(service.name, done) - grunt.registerTask 'run:#{service.name}', "Run the ShareLaTeX #{service.name} service", ["bunyan", "execute:web"] + grunt.registerTask "run:#{service.name}", "Run the ShareLaTeX #{service.name} service", ["bunyan", "execute:web"] grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", ("install:#{service.name}" for service in SERVICES) grunt.registerTask 'install', 'install:all' @@ -71,6 +72,9 @@ module.exports = (grunt) -> grunt.registerTask 'run', "Run all of the sharelatex processes", ['concurrent:all'] grunt.registerTask 'run:all', 'run' + grunt.registerTask 'install:config', "Install a custom config from a git repository (set SHARELATEX_CONFIG_REPO to the repository location)", () -> + Helpers.installCustomConfig @async() + grunt.registerTask 'help', 'Display this help list', 'availabletasks' grunt.registerTask 'default', 'run' @@ -118,3 +122,15 @@ Helpers = proc = spawn "grunt", ["install"], stdio: "inherit", cwd: dir proc.on "close", () -> callback() + + installCustomConfig: (callback = (error) ->) -> + if !process.env.SHARELATEX_CONFIG_REPO? + return callback(new Error("Please set the SHARELATEX_CONFIG_REPO enviroment variable to point to a git repository.")) + + rimraf "config-local", (error) -> + Helpers.cloneGitRepo process.env.SHARELATEX_CONFIG_REPO, "config-local", (error) -> + return callback(error) if error? + for file in fs.readdirSync("config-local") + unless file == ".git" + fs.symlinkSync("config-local/#{file}", "config/#{file}") + callback() diff --git a/server-ce/package.json b/server-ce/package.json index bb2ab4e1aa..29813532b2 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -4,7 +4,8 @@ "dependencies": { "logger-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/logger-sharelatex.git#bunyan", "settings-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/settings-sharelatex.git#master", - "coffee-script": "~1.7.1" + "coffee-script": "~1.7.1", + "rimraf": "~2.2.6" }, "devDependencies": { "grunt": "~0.4.2", From b492c0d5c98988cbd449f76a1cb75d0a8e71d573 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 12 Feb 2014 12:15:47 +0000 Subject: [PATCH 010/525] Fix up some Gruntfile errors --- server-ce/Gruntfile.coffee | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index bb35b07b5c..62e45a1a99 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -1,6 +1,7 @@ fs = require "fs" spawn = require("child_process").spawn rimraf = require "rimraf" +Path = require "path" SERVICES = [{ name: "web" @@ -63,7 +64,7 @@ module.exports = (grunt) -> grunt.registerTask "update:#{service.name}", "Checkout and update the #{service.name} service", () -> done = @async() Helpers.updateService(service.name, done) - grunt.registerTask "run:#{service.name}", "Run the ShareLaTeX #{service.name} service", ["bunyan", "execute:web"] + grunt.registerTask "run:#{service.name}", "Run the ShareLaTeX #{service.name} service", ["bunyan", "execute:#{service.name}"] grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", ("install:#{service.name}" for service in SERVICES) grunt.registerTask 'install', 'install:all' @@ -132,5 +133,5 @@ Helpers = return callback(error) if error? for file in fs.readdirSync("config-local") unless file == ".git" - fs.symlinkSync("config-local/#{file}", "config/#{file}") + fs.symlinkSync(Path.resolve("config-local/#{file}"), "config/#{file}") callback() From 4d4d048c73c827c10cfdf48a6d05b44311df2807 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 13 Feb 2014 12:37:47 +0000 Subject: [PATCH 011/525] Add CLSI to known repos --- server-ce/Gruntfile.coffee | 21 +++++++++++--------- server-ce/config/settings.development.coffee | 19 ++++++++++++++++-- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 62e45a1a99..63222b4773 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -9,6 +9,9 @@ SERVICES = [{ }, { name: "document-updater" repo: "git@github.com:sharelatex/document-updater-sharelatex.git" +}, { + name: "clsi" + repo: "git@github.com:sharelatex/clsi-sharelatex.git" }] @@ -18,17 +21,19 @@ module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-available-tasks' grunt.loadNpmTasks 'grunt-concurrent' + execute = {} + for service in SERVICES + execute[service.name] = + src: "#{service.name}/app.js" + grunt.initConfig - execute: - web: - src: "web/app.js" - 'document-updater': - src: "document-updater/app.js" + execute: execute concurrent: all: - tasks: ['run:web', 'run:document-updater'] + tasks: ("run:#{service.name}" for service in SERVICES) options: + limit: SERVICES.length logConcurrentOutput: true availabletasks: @@ -45,10 +50,8 @@ module.exports = (grunt) -> "Run tasks": [ "run" "run:all" - "run:web" - "run:document-updater" "default" - ] + ].concat ("run:#{service.name}" for service in SERVICES) "Misc": [ "help" ] diff --git a/server-ce/config/settings.development.coffee b/server-ce/config/settings.development.coffee index 46d8ce0da8..f75f555d4f 100644 --- a/server-ce/config/settings.development.coffee +++ b/server-ce/config/settings.development.coffee @@ -42,6 +42,12 @@ module.exports = port: "6379" password: "" + mysql: + clsi: + database: "clsi" + username: "clsi" + password: "" + # Service locations # ----------------- @@ -51,8 +57,13 @@ module.exports = internal: web: port: webPort = 3000 + host: "localhost" documentupdater: port: docUpdaterPort = 3003 + host: "localhost" + clsi: + port: clsiPort = 3013 + host: "localhost" # Tell each service where to find the other services. If everything # is running locally then this is easy, but they exist as separate config @@ -64,6 +75,8 @@ module.exports = pass: httpAuthPass documentupdater: url : "http://localhost:#{docUpdaterPort}" + clsi: + url: "http://localhost:#{clsiPort}" thirdPartyDataStore: url : "http://localhost:3002" emptyProjectFlushDelayMiliseconds: 5 * seconds @@ -88,8 +101,6 @@ module.exports = port: 3008 filestore: url: "http://localhost:3009" - clsi: - url: "http://localhost:3013" templates_api: url: "http://localhost:3014" @@ -182,6 +193,10 @@ module.exports = # that need processing but may be too big for memory, then write # them to disk here). dumpFolder: Path.resolve "data/dumpFolder" + # Where to write the project to disk before running LaTeX on it + compilesDir: Path.resolve(__dirname + "/../compiles") + # Where to cache downloaded URLs for the CLSI + clsiCacheDir: Path.resolve(__dirname + "/../cache") # Automatic Snapshots # ------------------- From a7b3c2a557de709ff5bcdc988edb042033d695d3 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 13 Feb 2014 13:07:03 +0000 Subject: [PATCH 012/525] Update README.md --- server-ce/README.md | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 7e5eafb553..f3c79ca880 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,12 +1,14 @@ ShareLaTeX ========== -ShareLaTeX is a web based collaborative LaTeX editor. There are two versions of it, -the online version that anyone can sign up to at www.sharelatex.com, and this open source -version which allows anyone to run a local installation of ShareLaTeX. +ShareLaTeX is a web-based collaborative LaTeX editor. We run a hosted service at +https://www.sharelatex.com and this repository contains the open source code that +powers it and allows you to run a local installation. -This repository pulls together all of the different services in ShareLaTeX's service -orientied architecture (SOA). +ShareLaTeX uses a service orientied architecture (SOA) where we have lots of small +APIs that talk to each other over HTTP and Redis pub-sub channels. This repository +pulls together all of the different services and allows you to set up and run +them quickly. Installation ------------ @@ -16,7 +18,7 @@ First, check out a local copy of this repository: $ git clone git@github.com:sharelatex/sharelatex.git $ cd sharelatex -Next install all the Node modules and ShareLaTeX services: +Next install all the node modules and ShareLaTeX services: $ npm install $ grunt install @@ -33,29 +35,45 @@ Dependencies You need: * Node.js 0.10 or greater -* Grunt command line tools (Run `npm install -g grunt-cli` to install them) +* The grunt command line tools (Run `npm install -g grunt-cli` to install them) * A local instance of Redis and Mongodb running on their standard ports. +Config +------ + +ShareLaTeX should mostly run out of the box, although it uses Amazon S3 for storing binary +files like images. You will need to configure ShareLaTeX to use your own S3 access key +which can be done by editing the file at `config/settings.development.coffee` + Other repositories ------------------ ShareLaTeX consists of many separate services, each with their own Node.js process -and source code repository. These are all downloaded when you run `npm install` and -they are run when you run `grunt run`. +and source code repository. These are all downloaded and set upwhen you run +`grunt install` The different services are: -### web-sharelatex +### [web](http://github.com/sharelatex/web-sharelatex) The front facing web server that serves all the HTML pages, CSS and javascript to the client. Also contains a lot of logic around creating and editing projects, and account management. -### document-updater-sharelatex +### [document-updater](http://github.com/sharelatex/document-updater-sharelatex) Process updates that come in from the editor when users modify documents. Ensures that the updates are applied in the right order, and that only one operation is modifying the document at a time. Also caches the documents in redis for very fast but persistent modifications. +### [CLSI](http://github.com/sharelatex/clsi-sharelatex) + +The Common LaTeX Service Interface (CLSI) which provides an API for compiling LaTeX +documents. + +Contributing +------------ + +Please see the [CONTRIBUTING](https://github.com/sharelatex/sharelatex/blob/master/CONTRIBUTING.md) file for information on contributing to the development of ShareLaTeX. From e8b4d4e8a93e82bb6cd276df568a94ee1cea2fae Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 13 Feb 2014 13:21:36 +0000 Subject: [PATCH 013/525] Update CONTRIBUTING.md --- server-ce/CONTRIBUTING.md | 57 +++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index 8d0079d288..613660f31e 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -1,8 +1,40 @@ Contributing to ShareLaTeX ========================== -Thank you for reading this! If you've found a bug, or have a new feature in mind, -then here are some notes on how to best report issues or implement changes. +Thank you for reading this! If you'd like to report a bug or join in the development +of ShareLaTeX, then here are some notes on how to do that. + +Reporting bugs and opening issues +--------------------------------- + +If you'd like a report a bug or open an issue then please: + +1. **Find the correct repository.** ShareLaTeX is split across multiple different repositories, each containing a different service (you can find a list [here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories)). If you know the bug only applies to one service, then please open an issue in that repository. For general bugs and issues that span more than one service, please open an issue in the [sharelatex/sharelatex](https://github.com/sharelatex/sharelatex) repository. +2. **Check if there is an existing issue.** If there is then please add + any more information that you have, or give it a "+1" in the comments. + +When submitting an issue please describe the issue as clearly as possible, including how to +reproduce the bug, which situations it appears in, what you expected to happen, and what actually happens. +If you can include a screenshot for front end issues that is very helpful. + +Pull Requests +------------- + +We love pull requests, so be bold with them! Don't be afraid of going ahead +and changing something, or adding a new feature. We're very happy to work with you +to get your changes merged into ShareLaTeX. + +If you've got an idea for a change then please discuss it in the open first, +either by opening an issue, or by joining us in our +[development chat room](http://www.hipchat.com/g1nJMcj7b). + +Developer Chat Room +------------------- + +If you want to ask any questions in real-time, or get a feel for what's going on +then please drop into our [development chat room](http://www.hipchat.com/g1nJMcj7b). +If no one is online then you can still leave a message that will hopefully get a reply +when we return. Security -------- @@ -13,24 +45,3 @@ security@sharelatex.com where we will attempt to address them quickly. If you're unsure whether something is a security issue or not, then please be cautious and contact us at security@sharelatex.com first. -Reporting bugs --------------- - -If you've found a bug then please: - -1. Check if there is an existing issue for it. If there is then please add - any more information that you have, or give it a "+1". -2. If there is there is no issue, then please open one. -3. Please describe the issue as clearly as possible, including how to - reproduce the bug, which situations it appears in, what you expected to - happen, and what actually happens. -4. Please include a screenshot for front end issues if you can. - -Pull Requests -------------- - -We love pull requests, so be bold with them! Don't be afraid of going ahead -and changing something, or adding a new feature. If you're setting of to make -a big change then opening an issue (or commenting on an existing one) is the -best way to discuss your ideas first. - From f4fbe3ad0fbd6478ef2fcc2c0f702f1437d82556 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 14 Feb 2014 17:30:43 +0000 Subject: [PATCH 014/525] Add in filestore --- server-ce/.gitignore | 5 +++++ server-ce/Gruntfile.coffee | 3 +++ server-ce/config/settings.development.coffee | 18 +++++++++++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/server-ce/.gitignore b/server-ce/.gitignore index 2d01c63836..957755e331 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -4,4 +4,9 @@ node_modules web document-updater +clsi +filestore + +compiles +cache diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 63222b4773..906f8999d5 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -12,6 +12,9 @@ SERVICES = [{ }, { name: "clsi" repo: "git@github.com:sharelatex/clsi-sharelatex.git" +}, { + name: "filestore" + repo: "git@github.com:sharelatex/filestore-sharelatex.git" }] diff --git a/server-ce/config/settings.development.coffee b/server-ce/config/settings.development.coffee index f75f555d4f..099e74a7c4 100644 --- a/server-ce/config/settings.development.coffee +++ b/server-ce/config/settings.development.coffee @@ -24,7 +24,9 @@ module.exports = s3: key: "" secret: "" - bucketName : "" + buckets: + # The S3 bucket name to store binary files in + user_files: "" # Databases # --------- @@ -64,6 +66,9 @@ module.exports = clsi: port: clsiPort = 3013 host: "localhost" + filestore: + port: filestorePort = 3009 + host: "localhost" # Tell each service where to find the other services. If everything # is running locally then this is easy, but they exist as separate config @@ -77,6 +82,8 @@ module.exports = url : "http://localhost:#{docUpdaterPort}" clsi: url: "http://localhost:#{clsiPort}" + filestore: + url: "http://localhost:#{filestorePort}" thirdPartyDataStore: url : "http://localhost:3002" emptyProjectFlushDelayMiliseconds: 5 * seconds @@ -99,8 +106,6 @@ module.exports = port: 3007 blog: port: 3008 - filestore: - url: "http://localhost:3009" templates_api: url: "http://localhost:3014" @@ -217,3 +222,10 @@ module.exports = # user: "" # password: "" # projectId: "" + + # Filestore health check + # ---------------------- + # Project and file details to check in filestore when calling /health_check + # health_check: + # project_id: "" + # file_id: "" From 6735187ac255c70f5fd3eb9bf4d5c14e5f421337 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 15 Feb 2014 18:31:12 +0000 Subject: [PATCH 015/525] Update CONTRIBUTING.md --- server-ce/CONTRIBUTING.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index 613660f31e..b1ae5a4936 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -4,12 +4,16 @@ Contributing to ShareLaTeX Thank you for reading this! If you'd like to report a bug or join in the development of ShareLaTeX, then here are some notes on how to do that. +*Note that ShareLaTeX is actually made up of many seperate repositories (a list is available +[here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories)).* +[CLICK HERE for an overview of all issues and pull requests in all the ShareLaTeX repositories](https://github.com/organizations/sharelatex/dashboard/issues) + Reporting bugs and opening issues --------------------------------- If you'd like a report a bug or open an issue then please: -1. **Find the correct repository.** ShareLaTeX is split across multiple different repositories, each containing a different service (you can find a list [here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories)). If you know the bug only applies to one service, then please open an issue in that repository. For general bugs and issues that span more than one service, please open an issue in the [sharelatex/sharelatex](https://github.com/sharelatex/sharelatex) repository. +1. **Find the correct repository.** ShareLaTeX is split across multiple different repositories, each containing a different service (you can find a list of [all repositories here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories), and [all issues here](https://github.com/organizations/sharelatex/dashboard/issues)). If you know the bug only applies to one service, then please open an issue in that repository. For general bugs and issues that span more than one service, please open an issue in the [sharelatex/sharelatex](https://github.com/sharelatex/sharelatex) repository. 2. **Check if there is an existing issue.** If there is then please add any more information that you have, or give it a "+1" in the comments. From 68c1a153c7b75dcdfb97dec2186e25282e3acc95 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 17 Feb 2014 20:01:21 +0000 Subject: [PATCH 016/525] Updated readme to have authors name at the bottom I like to follow/look into the people behind a project sometimes, just making it easier for them. --- server-ce/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index f3c79ca880..f2923e424c 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -77,3 +77,8 @@ Contributing Please see the [CONTRIBUTING](https://github.com/sharelatex/sharelatex/blob/master/CONTRIBUTING.md) file for information on contributing to the development of ShareLaTeX. +Authors +--- + +- [Henry Oswald](twitter.com/henryoswald) +- James Allen From aa00aa25c23caabf1f1bdb6f810dff772d7af4f8 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 18 Feb 2014 16:28:24 +0000 Subject: [PATCH 017/525] Update README --- server-ce/README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index f2923e424c..27198bf9cc 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -54,24 +54,29 @@ and source code repository. These are all downloaded and set upwhen you run The different services are: -### [web](http://github.com/sharelatex/web-sharelatex) +### [web](https://github.com/sharelatex/web-sharelatex) The front facing web server that serves all the HTML pages, CSS and javascript to the client. Also contains a lot of logic around creating and editing projects, and account management. -### [document-updater](http://github.com/sharelatex/document-updater-sharelatex) +### [document-updater](https://github.com/sharelatex/document-updater-sharelatex) -Process updates that come in from the editor when users modify documents. Ensures that +Processes updates that come in from the editor when users modify documents. Ensures that the updates are applied in the right order, and that only one operation is modifying the document at a time. Also caches the documents in redis for very fast but persistent modifications. -### [CLSI](http://github.com/sharelatex/clsi-sharelatex) +### [CLSI](https://github.com/sharelatex/clsi-sharelatex) The Common LaTeX Service Interface (CLSI) which provides an API for compiling LaTeX documents. +### [filestore](https://github.com/sharelatex/filestore-sharelatex) + +An API for perform CRUD (Create, Read, Update and Delete) operations on binary files +(like images) stored in ShareLaTeX. + Contributing ------------ @@ -80,5 +85,5 @@ Please see the [CONTRIBUTING](https://github.com/sharelatex/sharelatex/blob/mast Authors --- -- [Henry Oswald](twitter.com/henryoswald) -- James Allen +- [Henry Oswald](http://twitter.com/henryoswald) +- [James Allen](http://twitter.com/thejpallen) From 74650cf678f0b8054623d47ddb7a63f8ca1aa98c Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 18 Feb 2014 17:40:23 +0000 Subject: [PATCH 018/525] Configure CLSI to use sqllite --- server-ce/.gitignore | 1 + server-ce/cache/.gitignore | 0 server-ce/config/settings.development.coffee | 2 ++ 3 files changed, 3 insertions(+) create mode 100644 server-ce/cache/.gitignore diff --git a/server-ce/.gitignore b/server-ce/.gitignore index 957755e331..b9433f478a 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -10,3 +10,4 @@ filestore compiles cache +db.sqlite diff --git a/server-ce/cache/.gitignore b/server-ce/cache/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/server-ce/config/settings.development.coffee b/server-ce/config/settings.development.coffee index 099e74a7c4..698b171ba4 100644 --- a/server-ce/config/settings.development.coffee +++ b/server-ce/config/settings.development.coffee @@ -49,6 +49,8 @@ module.exports = database: "clsi" username: "clsi" password: "" + dialect: "sqlite" + storage: Path.resolve(__dirname + "/../db.sqlite") # Service locations # ----------------- From a012cabcf7c271968bad1d216b7062fc321c8cce Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 19 Feb 2014 13:23:49 +0000 Subject: [PATCH 019/525] Remove old method of installing local settings --- server-ce/Gruntfile.coffee | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 906f8999d5..9ebfbfd218 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -79,9 +79,6 @@ module.exports = (grunt) -> grunt.registerTask 'run', "Run all of the sharelatex processes", ['concurrent:all'] grunt.registerTask 'run:all', 'run' - grunt.registerTask 'install:config', "Install a custom config from a git repository (set SHARELATEX_CONFIG_REPO to the repository location)", () -> - Helpers.installCustomConfig @async() - grunt.registerTask 'help', 'Display this help list', 'availabletasks' grunt.registerTask 'default', 'run' @@ -130,14 +127,3 @@ Helpers = proc.on "close", () -> callback() - installCustomConfig: (callback = (error) ->) -> - if !process.env.SHARELATEX_CONFIG_REPO? - return callback(new Error("Please set the SHARELATEX_CONFIG_REPO enviroment variable to point to a git repository.")) - - rimraf "config-local", (error) -> - Helpers.cloneGitRepo process.env.SHARELATEX_CONFIG_REPO, "config-local", (error) -> - return callback(error) if error? - for file in fs.readdirSync("config-local") - unless file == ".git" - fs.symlinkSync(Path.resolve("config-local/#{file}"), "config/#{file}") - callback() From 476bf88c2a1afad3cb520de258af10b501886528 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 19 Feb 2014 13:24:52 +0000 Subject: [PATCH 020/525] Update README with new settings details --- server-ce/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 27198bf9cc..858b0161dd 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -45,6 +45,11 @@ ShareLaTeX should mostly run out of the box, although it uses Amazon S3 for stor files like images. You will need to configure ShareLaTeX to use your own S3 access key which can be done by editing the file at `config/settings.development.coffee` +A local settings file can be specified by setting the `SHARELATEX_CONFIG` environment variable +to point to your own settings file. E.g. + + $ export SHARELATEX_CONFIG=/home/james/config/settings.development.coffee + Other repositories ------------------ From ddb1bbc7f0c7d8515c090374facf42a8c76cae20 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 19 Feb 2014 15:37:47 +0000 Subject: [PATCH 021/525] Update dependencies --- server-ce/README.md | 8 ++++---- server-ce/package.json | 3 --- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 858b0161dd..abdc702589 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -32,11 +32,11 @@ ShareLaTeX should now be running at http://localhost:3000. Dependencies ------------ -You need: +ShareLaTeX should run on OS X and Linux. You need: -* Node.js 0.10 or greater -* The grunt command line tools (Run `npm install -g grunt-cli` to install them) -* A local instance of Redis and Mongodb running on their standard ports. +* [Node.js](http://nodejs.org/) 0.10 or greater +* The [grunt](http://gruntjs.com/) command line tools (Run `npm install -g grunt-cli` to install them) +* A local instance of [Redis](http://redis.io/) and [MongoDB](http://www.mongodb.org/) running on their standard ports. Config ------ diff --git a/server-ce/package.json b/server-ce/package.json index 29813532b2..ca6cb7b4f5 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -2,9 +2,6 @@ "name": "sharelatex", "description": "An online collaborative LaTeX editor", "dependencies": { - "logger-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/logger-sharelatex.git#bunyan", - "settings-sharelatex": "git+ssh://git@bitbucket.org:sharelatex/settings-sharelatex.git#master", - "coffee-script": "~1.7.1", "rimraf": "~2.2.6" }, "devDependencies": { From e84928f03a521c2f0aa07063fbf848155671b46e Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 20 Feb 2014 16:36:39 +0000 Subject: [PATCH 022/525] Create LICENSE --- server-ce/LICENSE | 661 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 661 insertions(+) create mode 100644 server-ce/LICENSE diff --git a/server-ce/LICENSE b/server-ce/LICENSE new file mode 100644 index 0000000000..dba13ed2dd --- /dev/null +++ b/server-ce/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. From b2fa78d338b1e31fe30b729bd8fb6eeb50b87bd6 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 20 Feb 2014 16:37:34 +0000 Subject: [PATCH 023/525] Update README.md --- server-ce/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index abdc702589..af8bc00413 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -92,3 +92,10 @@ Authors - [Henry Oswald](http://twitter.com/henryoswald) - [James Allen](http://twitter.com/thejpallen) + +License +---- + +The code in this repository is released under the GNU AFFERO GENERAL PUBLIC LICENSE, version 3. A copy can be found in the `LICENSE` file. + +Copyright (c) ShareLaTeX, 2014. From cd02addffbd6ac0f40e019e9c8ca7d356baa4887 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 21 Feb 2014 10:18:33 +0000 Subject: [PATCH 024/525] Update README.md --- server-ce/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index af8bc00413..1eeff8b103 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,18 +1,19 @@ ShareLaTeX ========== -ShareLaTeX is a web-based collaborative LaTeX editor. We run a hosted service at -https://www.sharelatex.com and this repository contains the open source code that -powers it and allows you to run a local installation. +[ShareLaTeX](https://www.sharelatex.com) is now open source! ShareLaTeX is an online real-time collaborative LaTeX editor, and you can now run your own local version where you can host, edit, collaborate in real-time, and compile your LaTeX documents. We’re still 100% focused on running the hosted version at http://www.sharelatex.com, but we want to be more flexible in how you can use ShareLaTeX, and give something back to our wonderful community. + +**[Read more on our blog](https://www.sharelatex.com/blog/2014/02/21/sharelatex-is-now-open-source.html#.UwcnsEJ_ugc)** + + +Installation +------------ ShareLaTeX uses a service orientied architecture (SOA) where we have lots of small APIs that talk to each other over HTTP and Redis pub-sub channels. This repository pulls together all of the different services and allows you to set up and run them quickly. -Installation ------------- - First, check out a local copy of this repository: $ git clone git@github.com:sharelatex/sharelatex.git From d7a1bc936cc7aebe69d6e3a2d67d0a979451b0a5 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 21 Feb 2014 10:20:33 +0000 Subject: [PATCH 025/525] Update dependencies in README to include latexmk --- server-ce/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/README.md b/server-ce/README.md index 1eeff8b103..cb8f6194e8 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -38,6 +38,7 @@ ShareLaTeX should run on OS X and Linux. You need: * [Node.js](http://nodejs.org/) 0.10 or greater * The [grunt](http://gruntjs.com/) command line tools (Run `npm install -g grunt-cli` to install them) * A local instance of [Redis](http://redis.io/) and [MongoDB](http://www.mongodb.org/) running on their standard ports. +* An update to date version of [TeXLive](https://www.tug.org/texlive/), with the `latexmk` program installed (should be included by default in TeXLive). Config ------ From 6b8f6b02638a141df656893bea1ade7f649d8b64 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 21 Feb 2014 10:44:48 +0000 Subject: [PATCH 026/525] Update README.md --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index cb8f6194e8..74dbcc1177 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -4,7 +4,7 @@ ShareLaTeX [ShareLaTeX](https://www.sharelatex.com) is now open source! ShareLaTeX is an online real-time collaborative LaTeX editor, and you can now run your own local version where you can host, edit, collaborate in real-time, and compile your LaTeX documents. We’re still 100% focused on running the hosted version at http://www.sharelatex.com, but we want to be more flexible in how you can use ShareLaTeX, and give something back to our wonderful community. **[Read more on our blog](https://www.sharelatex.com/blog/2014/02/21/sharelatex-is-now-open-source.html#.UwcnsEJ_ugc)** - +or **[join in the discussion on Hacker News](https://news.ycombinator.com/item?id=7276263)** Installation ------------ From 2f7abbbb833158814abd2bf126b277dade293f87 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 21 Feb 2014 13:32:37 +0000 Subject: [PATCH 027/525] Update README.md --- server-ce/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 74dbcc1177..34d1d3bd57 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -14,6 +14,10 @@ APIs that talk to each other over HTTP and Redis pub-sub channels. This reposito pulls together all of the different services and allows you to set up and run them quickly. +*Note: Please make sure you have your public key configured with github since +we use ssh to pull additional repositories from github when you run the install +script.* + First, check out a local copy of this repository: $ git clone git@github.com:sharelatex/sharelatex.git From 12eca48d450e35e394fd0571edf00f2cd3956a04 Mon Sep 17 00:00:00 2001 From: Fayimora Femi-Balogun Date: Fri, 21 Feb 2014 14:00:12 +0000 Subject: [PATCH 028/525] Fix minor typos in readme --- server-ce/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 34d1d3bd57..18e929ece7 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -42,7 +42,7 @@ ShareLaTeX should run on OS X and Linux. You need: * [Node.js](http://nodejs.org/) 0.10 or greater * The [grunt](http://gruntjs.com/) command line tools (Run `npm install -g grunt-cli` to install them) * A local instance of [Redis](http://redis.io/) and [MongoDB](http://www.mongodb.org/) running on their standard ports. -* An update to date version of [TeXLive](https://www.tug.org/texlive/), with the `latexmk` program installed (should be included by default in TeXLive). +* An up to date version of [TeXLive](https://www.tug.org/texlive/), with the `latexmk` program installed (should be included by default in TeXLive). Config ------ @@ -67,7 +67,7 @@ The different services are: ### [web](https://github.com/sharelatex/web-sharelatex) -The front facing web server that serves all the HTML pages, CSS and javascript +The front facing web server that serves all the HTML pages, CSS and JavaScript to the client. Also contains a lot of logic around creating and editing projects, and account management. @@ -85,7 +85,7 @@ documents. ### [filestore](https://github.com/sharelatex/filestore-sharelatex) -An API for perform CRUD (Create, Read, Update and Delete) operations on binary files +An API for performing CRUD (Create, Read, Update and Delete) operations on binary files (like images) stored in ShareLaTeX. Contributing From 9c8f79ca6fe4f47ac3730f220510d8f40c0c75cb Mon Sep 17 00:00:00 2001 From: goodbest Date: Fri, 21 Feb 2014 22:16:36 +0800 Subject: [PATCH 029/525] change git clone manner from ssh to https --- server-ce/Gruntfile.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 9ebfbfd218..0d12257428 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -5,16 +5,16 @@ Path = require "path" SERVICES = [{ name: "web" - repo: "git@github.com:sharelatex/web-sharelatex.git" + repo: "https://github.com/sharelatex/web-sharelatex.git" }, { name: "document-updater" - repo: "git@github.com:sharelatex/document-updater-sharelatex.git" + repo: "https://github.com/sharelatex/document-updater-sharelatex.git" }, { name: "clsi" - repo: "git@github.com:sharelatex/clsi-sharelatex.git" + repo: "https://github.com/sharelatex/clsi-sharelatex.git" }, { name: "filestore" - repo: "git@github.com:sharelatex/filestore-sharelatex.git" + repo: "https://github.com/sharelatex/filestore-sharelatex.git" }] From be003b4317469d6083e5a88743504b540712bdb5 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 21 Feb 2014 14:27:06 +0000 Subject: [PATCH 030/525] Update README.md with Redis version Doesn't really solve #25, but should make it clearer --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 18e929ece7..e138e90bfc 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -41,7 +41,7 @@ ShareLaTeX should run on OS X and Linux. You need: * [Node.js](http://nodejs.org/) 0.10 or greater * The [grunt](http://gruntjs.com/) command line tools (Run `npm install -g grunt-cli` to install them) -* A local instance of [Redis](http://redis.io/) and [MongoDB](http://www.mongodb.org/) running on their standard ports. +* A local instance of [Redis](http://redis.io/) (version 2.6 or later) and [MongoDB](http://www.mongodb.org/) running on their standard ports. * An up to date version of [TeXLive](https://www.tug.org/texlive/), with the `latexmk` program installed (should be included by default in TeXLive). Config From 187d5b211a105066aaded21c9ff2b571e3303169 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 21 Feb 2014 17:53:58 +0000 Subject: [PATCH 031/525] Update CONTRIBUTING.md --- server-ce/CONTRIBUTING.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index b1ae5a4936..b2fbb9a4c5 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -5,8 +5,7 @@ Thank you for reading this! If you'd like to report a bug or join in the develop of ShareLaTeX, then here are some notes on how to do that. *Note that ShareLaTeX is actually made up of many seperate repositories (a list is available -[here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories)).* -[CLICK HERE for an overview of all issues and pull requests in all the ShareLaTeX repositories](https://github.com/organizations/sharelatex/dashboard/issues) +[here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories)).* Reporting bugs and opening issues --------------------------------- From 6447e2140adae18ecb6a6c7656e6f38332e5f3d7 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 21 Feb 2014 19:16:01 +0000 Subject: [PATCH 032/525] Update latexmk install instructions --- server-ce/README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index e138e90bfc..849b6b1e3d 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -42,7 +42,14 @@ ShareLaTeX should run on OS X and Linux. You need: * [Node.js](http://nodejs.org/) 0.10 or greater * The [grunt](http://gruntjs.com/) command line tools (Run `npm install -g grunt-cli` to install them) * A local instance of [Redis](http://redis.io/) (version 2.6 or later) and [MongoDB](http://www.mongodb.org/) running on their standard ports. -* An up to date version of [TeXLive](https://www.tug.org/texlive/), with the `latexmk` program installed (should be included by default in TeXLive). +* An up to date version of [TeXLive](https://www.tug.org/texlive/), with the `latexmk` program installed. You need latexmk from TeXLive 2013 (or the later). If you're on an older version, or aren't sure, then the following commands will install the latest version locally: + + ```bash + $ mkdir ~/bin + $ curl http://mirror.physik-pool.tu-berlin.de/tex-archive/support/latexmk/latexmk.pl > ~/bin/latexmk + $ chmod a+x ~/bin/latexmk + $ export PATH=~/bin:$PATH + ``` Config ------ From 2176fc61421f7430a475046db6eeccfc48eb8b4f Mon Sep 17 00:00:00 2001 From: Swapnil Agarwal Date: Sat, 22 Feb 2014 00:59:52 +0530 Subject: [PATCH 033/525] Fix Minor Typo in README.md --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index e138e90bfc..eb896949f0 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -9,7 +9,7 @@ or **[join in the discussion on Hacker News](https://news.ycombinator.com/item?i Installation ------------ -ShareLaTeX uses a service orientied architecture (SOA) where we have lots of small +ShareLaTeX uses a service oriented architecture (SOA) where we have lots of small APIs that talk to each other over HTTP and Redis pub-sub channels. This repository pulls together all of the different services and allows you to set up and run them quickly. From 5db301bc31bcec1726d9b8d7dbcb6341ad73276f Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 21 Feb 2014 20:36:33 +0000 Subject: [PATCH 034/525] Update CONTRIBUTING.md --- server-ce/CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index b2fbb9a4c5..5b0a22d36b 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -23,6 +23,10 @@ If you can include a screenshot for front end issues that is very helpful. Pull Requests ------------- +See [our wiki](https://github.com/sharelatex/sharelatex/wiki/ShareLaTeX-Development-Environment) +for information on how to modify the ShareLaTeX code and set up a good development +environment. + We love pull requests, so be bold with them! Don't be afraid of going ahead and changing something, or adding a new feature. We're very happy to work with you to get your changes merged into ShareLaTeX. From 93266970175b6eb3b30ddf35fdf3ae46cd67e910 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 21 Feb 2014 20:37:26 +0000 Subject: [PATCH 035/525] Update README.md --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index cf9b3987b0..1d86e4790d 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -98,7 +98,7 @@ An API for performing CRUD (Create, Read, Update and Delete) operations on binar Contributing ------------ -Please see the [CONTRIBUTING](https://github.com/sharelatex/sharelatex/blob/master/CONTRIBUTING.md) file for information on contributing to the development of ShareLaTeX. +Please see the [CONTRIBUTING](https://github.com/sharelatex/sharelatex/blob/master/CONTRIBUTING.md) file for information on contributing to the development of ShareLaTeX. See [our wiki](https://github.com/sharelatex/sharelatex/wiki/ShareLaTeX-Development-Environment) for information on setting up a development environment and how to recompile and run ShareLaTeX after modifications. Authors --- From 0e956b3f321aefea87b17707475360aa233074cc Mon Sep 17 00:00:00 2001 From: Emery Coxe Date: Fri, 21 Feb 2014 20:13:26 -0600 Subject: [PATCH 036/525] update README instructions to use 'https' scheme for installation instructions rather than 'git' scheme --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 1d86e4790d..a3b1750657 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -20,7 +20,7 @@ script.* First, check out a local copy of this repository: - $ git clone git@github.com:sharelatex/sharelatex.git + $ git clone https://github.com/sharelatex/sharelatex.git $ cd sharelatex Next install all the node modules and ShareLaTeX services: From e6556fb3a1f9ca2f8671f2d7613aa34352ee4330 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 22 Feb 2014 10:50:38 +0000 Subject: [PATCH 037/525] Update default features in settings --- server-ce/config/settings.development.coffee | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/server-ce/config/settings.development.coffee b/server-ce/config/settings.development.coffee index 698b171ba4..ce930e07f1 100644 --- a/server-ce/config/settings.development.coffee +++ b/server-ce/config/settings.development.coffee @@ -130,14 +130,16 @@ module.exports = # # You can select the features that are enabled by default for new # new users. + defaultFeatures: defaultFeatures = + collaborators: -1 + dropbox: true + versioning: true + plans: plans = [{ planCode: "personal" name: "Personal" price: 0 - features: - collaborators: -1 - dropbox: true - versioning: true + features: defaultFeatures }] # Spelling languages From 20f9d9f94afc82ba0ec83953882e76cbf8a5489c Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 22 Feb 2014 12:08:03 +0000 Subject: [PATCH 038/525] Add in check task to check that redis and latexmk are installed correctly --- server-ce/Gruntfile.coffee | 132 +++++++++++++++++++++++++++---------- server-ce/README.md | 5 ++ server-ce/package.json | 3 +- 3 files changed, 105 insertions(+), 35 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 0d12257428..275c356db4 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -1,7 +1,9 @@ fs = require "fs" spawn = require("child_process").spawn +exec = require("child_process").exec rimraf = require "rimraf" Path = require "path" +semver = require "semver" SERVICES = [{ name: "web" @@ -61,6 +63,7 @@ module.exports = (grunt) -> "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install"]) "Update tasks": ("update:#{service.name}" for service in SERVICES).concat(["update:all", "update"]) "Config tasks": ["install:config"] + "Checks": ["check", "check:redis", "check:latexmk"] for service in SERVICES do (service) -> @@ -82,48 +85,109 @@ module.exports = (grunt) -> grunt.registerTask 'help', 'Display this help list', 'availabletasks' grunt.registerTask 'default', 'run' -Helpers = - installService: (repo_src, dir, callback = (error) ->) -> - Helpers.cloneGitRepo repo_src, dir, (error) -> - return callback(error) if error? - Helpers.installNpmModules dir, (error) -> - return callback(error) if error? - Helpers.runGruntInstall dir, (error) -> - return callback(error) if error? - callback() + grunt.registerTask "check:redis", "Check that redis is installed and running", () -> + Helpers.checkRedis @async() + grunt.registerTask "check:latexmk", "Check that latexmk is installed", () -> + Helpers.checkLatexmk @async() + grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk"] - updateService: (dir, callback = (error) ->) -> - Helpers.updateGitRepo dir, (error) -> - return callback(error) if error? - Helpers.installNpmModules dir, (error) -> + Helpers = + installService: (repo_src, dir, callback = (error) ->) -> + Helpers.cloneGitRepo repo_src, dir, (error) -> return callback(error) if error? - Helpers.runGruntInstall dir, (error) -> + Helpers.installNpmModules dir, (error) -> return callback(error) if error? - callback() + Helpers.runGruntInstall dir, (error) -> + return callback(error) if error? + callback() - cloneGitRepo: (repo_src, dir, callback = (error) ->) -> - if !fs.existsSync(dir) - proc = spawn "git", ["clone", repo_src, dir], stdio: "inherit" - proc.on "close", () -> + updateService: (dir, callback = (error) ->) -> + Helpers.updateGitRepo dir, (error) -> + return callback(error) if error? + Helpers.installNpmModules dir, (error) -> + return callback(error) if error? + Helpers.runGruntInstall dir, (error) -> + return callback(error) if error? + callback() + + cloneGitRepo: (repo_src, dir, callback = (error) ->) -> + if !fs.existsSync(dir) + proc = spawn "git", ["clone", repo_src, dir], stdio: "inherit" + proc.on "close", () -> + callback() + else + console.log "#{dir} already installed, skipping." callback() - else - console.log "#{dir} already installed, skipping." - callback() - updateGitRepo: (dir, callback = (error) ->) -> - proc = spawn "git", ["checkout", "master"], cwd: dir, stdio: "inherit" - proc.on "close", () -> - proc = spawn "git", ["pull"], cwd: dir, stdio: "inherit" + updateGitRepo: (dir, callback = (error) ->) -> + proc = spawn "git", ["checkout", "master"], cwd: dir, stdio: "inherit" + proc.on "close", () -> + proc = spawn "git", ["pull"], cwd: dir, stdio: "inherit" + proc.on "close", () -> + callback() + + installNpmModules: (dir, callback = (error) ->) -> + proc = spawn "npm", ["install"], stdio: "inherit", cwd: dir proc.on "close", () -> callback() - installNpmModules: (dir, callback = (error) ->) -> - proc = spawn "npm", ["install"], stdio: "inherit", cwd: dir - proc.on "close", () -> - callback() + runGruntInstall: (dir, callback = (error) ->) -> + proc = spawn "grunt", ["install"], stdio: "inherit", cwd: dir + proc.on "close", () -> + callback() + + checkRedis: (callback = (error) ->) -> + grunt.log.write "Checking Redis is running... " + exec "redis-cli info", (error, stdout, stderr) -> + if error? and error.message.match("Could not connect") + grunt.log.error "FAIL. Redis is not running" + return + else if error? + return callback(error) + else + m = stdout.match(/redis_version:(.*)/) + if !m? + grunt.log.error "FAIL." + grunt.log.error "Unknown redis version" + else + version = m[1] + if semver.gt(version, "2.6.0") + grunt.log.writeln "OK." + grunt.log.writeln "Running Redis version #{version}" + else + grunt.log.error "FAIL." + grunt.log.error "Redis version is too old (#{version}). Must be 2.6.0 or greater." + callback() + + checkLatexmk: (callback = (error) ->) -> + grunt.log.write "Checking latexmk is installed... " + exec "latexmk -version", (error, stdout, stderr) -> + if error? and error.message.match("command not found") + grunt.log.error "FAIL." + grunt.log.errorlns """ + Either latexmk is not installed or is not in your PATH. + + latexmk comes with TexLive 2013, and must be a version from 2013 or later. + This is a not a fatal error, but compiling will not work without latexmk + """ + else if error? + return callback(error) + else + m = stdout.match(/Version (.*)/) + if !m? + grunt.log.error "FAIL." + grunt.log.error "Unknown latexmk version" + else + version = m[1] + if semver.gt(version + ".0", "4.39.0") + grunt.log.writeln "OK." + grunt.log.writeln "Running latexmk version #{version}" + else + grunt.log.error "FAIL." + grunt.log.errorlns """ + latexmk version is too old (#{version}). Must be 4.39 or greater. + This is a not a fatal error, but compiling will not work without latexmk + """ + callback() - runGruntInstall: (dir, callback = (error) ->) -> - proc = spawn "grunt", ["install"], stdio: "inherit", cwd: dir - proc.on "close", () -> - callback() diff --git a/server-ce/README.md b/server-ce/README.md index a3b1750657..46259d0151 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -28,6 +28,11 @@ Next install all the node modules and ShareLaTeX services: $ npm install $ grunt install +Now check that your system is set up correctly to run ShareLaTeX (checks that you have +the required dependencies installed.) Watch out for any failures. + + $ grunt check + When that has finished, run ShareLaTeX with $ grunt run diff --git a/server-ce/package.json b/server-ce/package.json index ca6cb7b4f5..6b75122473 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -10,6 +10,7 @@ "grunt-bunyan": "~0.5.0", "grunt-execute": "~0.1.5", "grunt-available-tasks": "~0.4.1", - "grunt-concurrent": "~0.4.3" + "grunt-concurrent": "~0.4.3", + "semver": "~2.2.1" } } From a6b08939cd7c72e7826e8c4d0345860e978afe7d Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 22 Feb 2014 14:08:49 +0000 Subject: [PATCH 039/525] Fix latexmk version checking --- server-ce/Gruntfile.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 275c356db4..32993f3f39 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -161,7 +161,7 @@ module.exports = (grunt) -> checkLatexmk: (callback = (error) ->) -> grunt.log.write "Checking latexmk is installed... " - exec "latexmk -version", (error, stdout, stderr) -> + exec "latexmk --version", (error, stdout, stderr) -> if error? and error.message.match("command not found") grunt.log.error "FAIL." grunt.log.errorlns """ @@ -179,7 +179,7 @@ module.exports = (grunt) -> grunt.log.error "Unknown latexmk version" else version = m[1] - if semver.gt(version + ".0", "4.39.0") + if semver.gte(version + ".0", "4.39.0") grunt.log.writeln "OK." grunt.log.writeln "Running latexmk version #{version}" else From 1d5908f8bcb1fda691b24221e18d831656179101 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 22 Feb 2014 14:10:28 +0000 Subject: [PATCH 040/525] Remove HN post from REAMDE. Old news now :) --- server-ce/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 46259d0151..9a4e3782b3 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -4,7 +4,6 @@ ShareLaTeX [ShareLaTeX](https://www.sharelatex.com) is now open source! ShareLaTeX is an online real-time collaborative LaTeX editor, and you can now run your own local version where you can host, edit, collaborate in real-time, and compile your LaTeX documents. We’re still 100% focused on running the hosted version at http://www.sharelatex.com, but we want to be more flexible in how you can use ShareLaTeX, and give something back to our wonderful community. **[Read more on our blog](https://www.sharelatex.com/blog/2014/02/21/sharelatex-is-now-open-source.html#.UwcnsEJ_ugc)** -or **[join in the discussion on Hacker News](https://news.ycombinator.com/item?id=7276263)** Installation ------------ From 26d9b51df7085174fde22c3a9104bd467f8f0613 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 22 Feb 2014 14:11:12 +0000 Subject: [PATCH 041/525] Remove Github ssh keys message This is now redundant since everything uses https. --- server-ce/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 9a4e3782b3..251b9f6260 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -13,10 +13,6 @@ APIs that talk to each other over HTTP and Redis pub-sub channels. This reposito pulls together all of the different services and allows you to set up and run them quickly. -*Note: Please make sure you have your public key configured with github since -we use ssh to pull additional repositories from github when you run the install -script.* - First, check out a local copy of this repository: $ git clone https://github.com/sharelatex/sharelatex.git From dc779da2b51778c401fea2e0d098bc66ae567169 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 22 Feb 2014 15:02:21 +0000 Subject: [PATCH 042/525] Add in check for S3 credentials --- server-ce/Gruntfile.coffee | 47 +++++++++++++++++++++++++++++++++++--- server-ce/README.md | 2 +- server-ce/package.json | 6 +++-- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 32993f3f39..90208723f3 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -4,6 +4,8 @@ exec = require("child_process").exec rimraf = require "rimraf" Path = require "path" semver = require "semver" +settings = require "settings-sharelatex" +knox = require "knox" SERVICES = [{ name: "web" @@ -89,7 +91,9 @@ module.exports = (grunt) -> Helpers.checkRedis @async() grunt.registerTask "check:latexmk", "Check that latexmk is installed", () -> Helpers.checkLatexmk @async() - grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk"] + grunt.registerTask "check:s3", "Check that Amazon S3 credentials are configured", () -> + Helpers.checkS3 @async() + grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3"] Helpers = installService: (repo_src, dir, callback = (error) ->) -> @@ -141,7 +145,7 @@ module.exports = (grunt) -> exec "redis-cli info", (error, stdout, stderr) -> if error? and error.message.match("Could not connect") grunt.log.error "FAIL. Redis is not running" - return + return callback(error) else if error? return callback(error) else @@ -149,6 +153,7 @@ module.exports = (grunt) -> if !m? grunt.log.error "FAIL." grunt.log.error "Unknown redis version" + error = new Error("Unknown redis version") else version = m[1] if semver.gt(version, "2.6.0") @@ -157,7 +162,8 @@ module.exports = (grunt) -> else grunt.log.error "FAIL." grunt.log.error "Redis version is too old (#{version}). Must be 2.6.0 or greater." - callback() + error = new Error("Redis version is too old (#{version}). Must be 2.6.0 or greater.") + callback(error) checkLatexmk: (callback = (error) ->) -> grunt.log.write "Checking latexmk is installed... " @@ -170,6 +176,7 @@ module.exports = (grunt) -> latexmk comes with TexLive 2013, and must be a version from 2013 or later. This is a not a fatal error, but compiling will not work without latexmk """ + return callback(error) else if error? return callback(error) else @@ -177,6 +184,7 @@ module.exports = (grunt) -> if !m? grunt.log.error "FAIL." grunt.log.error "Unknown latexmk version" + error = new Error("Unknown latexmk version") else version = m[1] if semver.gte(version + ".0", "4.39.0") @@ -188,6 +196,39 @@ module.exports = (grunt) -> latexmk version is too old (#{version}). Must be 4.39 or greater. This is a not a fatal error, but compiling will not work without latexmk """ + error = new Error("latexmk is too old") + callback(error) + + checkS3: (callback = (error) ->) -> + grunt.log.write "Checking S3 credentials... " + try + client = knox.createClient({ + key: settings.s3.key + secret: settings.s3.secret + bucket: settings.s3.buckets.user_files + }) + catch e + grunt.log.error "FAIL." + grunt.log.errorlns """ + Please configure you Amazon S3 credentials in config/settings.development.coffee + + Amazon S3 (Simple Storage Service) is a cloud storage service provided by + Amazon. ShareLaTeX uses S3 for storing binary files like images. You can + sign up for an account and find out more at: + + http://aws.amazon.com/s3/ + + """ + return callback() + + client.getFile "does-not-exist", (error, response) -> + unless response? and response.statusCode == 404 + grunt.log.error "FAIL." + grunt.log.errorlns """ + Could not connect to Amazon S3. Please check your credentials. + """ + else + grunt.log.write "OK." callback() diff --git a/server-ce/README.md b/server-ce/README.md index 251b9f6260..0f47ece3bb 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -26,7 +26,7 @@ Next install all the node modules and ShareLaTeX services: Now check that your system is set up correctly to run ShareLaTeX (checks that you have the required dependencies installed.) Watch out for any failures. - $ grunt check + $ grunt check --force When that has finished, run ShareLaTeX with diff --git a/server-ce/package.json b/server-ce/package.json index 6b75122473..383fa5951f 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -2,7 +2,8 @@ "name": "sharelatex", "description": "An online collaborative LaTeX editor", "dependencies": { - "rimraf": "~2.2.6" + "rimraf": "~2.2.6", + "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git" }, "devDependencies": { "grunt": "~0.4.2", @@ -11,6 +12,7 @@ "grunt-execute": "~0.1.5", "grunt-available-tasks": "~0.4.1", "grunt-concurrent": "~0.4.3", - "semver": "~2.2.1" + "semver": "~2.2.1", + "knox": "~0.8.9" } } From 07debdf060a6ffb171b897d38d4433da99c26bf8 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sun, 23 Feb 2014 10:52:20 +0000 Subject: [PATCH 043/525] Update email address to team@sharelatex.com --- server-ce/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index 5b0a22d36b..e226cff3ff 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -50,5 +50,5 @@ Please do not publish security vulnerabilities publicly until we've had a chance to address them. All security related issues/patches should be sent directly to security@sharelatex.com where we will attempt to address them quickly. If you're unsure whether something is a security issue or not, then please be cautious and -contact us at security@sharelatex.com first. +contact us at team@sharelatex.com first. From e926c90ced78e4e9707ee22a5d37c094cf718f3d Mon Sep 17 00:00:00 2001 From: James Allen Date: Sun, 23 Feb 2014 10:52:43 +0000 Subject: [PATCH 044/525] Update email address to team@sharelatex.com --- server-ce/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index e226cff3ff..c2d28d6460 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -48,7 +48,7 @@ Security Please do not publish security vulnerabilities publicly until we've had a chance to address them. All security related issues/patches should be sent directly to -security@sharelatex.com where we will attempt to address them quickly. If you're +team@sharelatex.com where we will attempt to address them quickly. If you're unsure whether something is a security issue or not, then please be cautious and contact us at team@sharelatex.com first. From 9b4d7e65def4d5b74d3625b69135a55c9e6a4c69 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sun, 23 Feb 2014 11:45:08 +0000 Subject: [PATCH 045/525] Use example config file so that config changes do not interfere with git --- server-ce/Gruntfile.coffee | 17 +++++++++++++++-- ...ffee => settings.development.coffee.example} | 0 2 files changed, 15 insertions(+), 2 deletions(-) rename server-ce/config/{settings.development.coffee => settings.development.coffee.example} (100%) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 90208723f3..de115a234f 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -77,9 +77,13 @@ module.exports = (grunt) -> Helpers.updateService(service.name, done) grunt.registerTask "run:#{service.name}", "Run the ShareLaTeX #{service.name} service", ["bunyan", "execute:#{service.name}"] - grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", ("install:#{service.name}" for service in SERVICES) + grunt.registerTask 'install:config', "Copy the example config into the real config", () -> + Helpers.installConfig @async() + grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", + ("install:#{service.name}" for service in SERVICES).concat(["install:config"]) grunt.registerTask 'install', 'install:all' - grunt.registerTask 'update:all', "Checkout and update all ShareLaTeX services", ("update:#{service.name}" for service in SERVICES) + grunt.registerTask 'update:all', "Checkout and update all ShareLaTeX services", + ("update:#{service.name}" for service in SERVICES) grunt.registerTask 'update', 'update:all' grunt.registerTask 'run', "Run all of the sharelatex processes", ['concurrent:all'] grunt.registerTask 'run:all', 'run' @@ -135,6 +139,15 @@ module.exports = (grunt) -> proc.on "close", () -> callback() + installConfig: (callback = (error) ->) -> + if !fs.existsSync("config/settings.development.coffee") + grunt.log.writeln "Copying example config into config/settings.development.coffee" + exec "cp config/settings.development.coffee.example config/settings.development.coffee", (error, stdout, stderr) -> + callback(error) + else + grunt.log.writeln "Config file already exists. Skipping." + callback() + runGruntInstall: (dir, callback = (error) ->) -> proc = spawn "grunt", ["install"], stdio: "inherit", cwd: dir proc.on "close", () -> diff --git a/server-ce/config/settings.development.coffee b/server-ce/config/settings.development.coffee.example similarity index 100% rename from server-ce/config/settings.development.coffee rename to server-ce/config/settings.development.coffee.example From 74a9c99569315cb55b14d34e105ba7e9b12075e9 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sun, 23 Feb 2014 11:53:46 +0000 Subject: [PATCH 046/525] Check that make is installed before installing modules that need compiling --- server-ce/Gruntfile.coffee | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index de115a234f..ed81cea32e 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -62,10 +62,10 @@ module.exports = (grunt) -> "Misc": [ "help" ] - "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install"]) + "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install", "install:config"]) "Update tasks": ("update:#{service.name}" for service in SERVICES).concat(["update:all", "update"]) "Config tasks": ["install:config"] - "Checks": ["check", "check:redis", "check:latexmk"] + "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make"] for service in SERVICES do (service) -> @@ -80,10 +80,14 @@ module.exports = (grunt) -> grunt.registerTask 'install:config', "Copy the example config into the real config", () -> Helpers.installConfig @async() grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", - ("install:#{service.name}" for service in SERVICES).concat(["install:config"]) + ["check:make"].concat( + ("install:#{service.name}" for service in SERVICES) + ).concat(["install:config"]) grunt.registerTask 'install', 'install:all' grunt.registerTask 'update:all', "Checkout and update all ShareLaTeX services", - ("update:#{service.name}" for service in SERVICES) + ["check:make"].concat( + ("update:#{service.name}" for service in SERVICES) + ) grunt.registerTask 'update', 'update:all' grunt.registerTask 'run', "Run all of the sharelatex processes", ['concurrent:all'] grunt.registerTask 'run:all', 'run' @@ -97,6 +101,8 @@ module.exports = (grunt) -> Helpers.checkLatexmk @async() grunt.registerTask "check:s3", "Check that Amazon S3 credentials are configured", () -> Helpers.checkS3 @async() + grunt.registerTask "check:make", "Check that make is installed", () -> + Helpers.checkMake @async() grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3"] Helpers = @@ -244,4 +250,26 @@ module.exports = (grunt) -> grunt.log.write "OK." callback() + checkMake: (callback = (error) ->) -> + grunt.log.write "Checking make is installed... " + exec "make --version", (error, stdout, stderr) -> + if error? and error.message.match("command not found") + grunt.log.error "FAIL." + grunt.log.errorlns """ + Either make is not installed or is not in your path. + + On Ubuntu you can install make with: + + sudo apt-get install build-essential + + """ + return callback(error) + else if error? + return callback(error) + else + grunt.log.write "OK." + return callback() + + + From b8f7e9c8386333624a34f4d41b1377bf185bc8b5 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sun, 23 Feb 2014 11:55:06 +0000 Subject: [PATCH 047/525] Update README with config instructions --- server-ce/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 0f47ece3bb..4248d2c240 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -23,6 +23,9 @@ Next install all the node modules and ShareLaTeX services: $ npm install $ grunt install +This will create a config file in `config/settings.development.coffee`. You should open +this now and configure your AWS S3 credentials, and other custom settings. + Now check that your system is set up correctly to run ShareLaTeX (checks that you have the required dependencies installed.) Watch out for any failures. From bae181d1e759ce786856093e92e56c589d51e1d1 Mon Sep 17 00:00:00 2001 From: kbasten Date: Sun, 23 Feb 2014 21:22:53 +0100 Subject: [PATCH 048/525] Update settings.development.coffee.example --- server-ce/config/settings.development.coffee.example | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index ce930e07f1..c87055e0e9 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -26,6 +26,7 @@ module.exports = secret: "" buckets: # The S3 bucket name to store binary files in + # Must contain full url like: .s3.amazonaws.com user_files: "" # Databases From 31e845ecc4dc7d9dfc6c2696fa439ce5fab34039 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sun, 23 Feb 2014 21:37:07 +0000 Subject: [PATCH 049/525] Update wiki link --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 4248d2c240..c05334c9e8 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -101,7 +101,7 @@ An API for performing CRUD (Create, Read, Update and Delete) operations on binar Contributing ------------ -Please see the [CONTRIBUTING](https://github.com/sharelatex/sharelatex/blob/master/CONTRIBUTING.md) file for information on contributing to the development of ShareLaTeX. See [our wiki](https://github.com/sharelatex/sharelatex/wiki/ShareLaTeX-Development-Environment) for information on setting up a development environment and how to recompile and run ShareLaTeX after modifications. +Please see the [CONTRIBUTING](https://github.com/sharelatex/sharelatex/blob/master/CONTRIBUTING.md) file for information on contributing to the development of ShareLaTeX. See [our wiki](https://github.com/sharelatex/sharelatex/wiki/Developer-Guidelines) for information on setting up a development environment and how to recompile and run ShareLaTeX after modifications. Authors --- From 9a504e57dee199f430f57be441ec64577225035e Mon Sep 17 00:00:00 2001 From: James Allen Date: Sun, 23 Feb 2014 21:38:02 +0000 Subject: [PATCH 050/525] Update CONTRIBUTING.md --- server-ce/CONTRIBUTING.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index c2d28d6460..be4f6abc11 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -23,9 +23,8 @@ If you can include a screenshot for front end issues that is very helpful. Pull Requests ------------- -See [our wiki](https://github.com/sharelatex/sharelatex/wiki/ShareLaTeX-Development-Environment) -for information on how to modify the ShareLaTeX code and set up a good development -environment. +See [our wiki](https://github.com/sharelatex/sharelatex/wiki/Developer-Guidelines) +for how to manage the ShareLaTeX development environment and for our developer guidelines. We love pull requests, so be bold with them! Don't be afraid of going ahead and changing something, or adding a new feature. We're very happy to work with you From d7411089b142e439a1c546d911a07801878361b0 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 24 Feb 2014 12:55:27 +0000 Subject: [PATCH 051/525] Add in CLA info --- server-ce/CONTRIBUTING.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index be4f6abc11..8bcd728a12 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -51,3 +51,11 @@ team@sharelatex.com where we will attempt to address them quickly. If you're unsure whether something is a security issue or not, then please be cautious and contact us at team@sharelatex.com first. +Contributor License Agreement +----------------------------- + +Before we can accept and contributions of code, we need you to agree to our +[Contributor License Agreement](https://sharelatex.wufoo.com/forms/sharelatex-contributor-license-agreement/). +This is to ensure that you own the copyright of your contribution, and that you +agree to give us a license to use it in both the open source version, and the version +of ShareLaTeX running at www.sharelatex.com, which may have additional changes. From 35246b7716cf0bc1f90cfc4a0287a499538e0a53 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 24 Feb 2014 13:00:30 +0000 Subject: [PATCH 052/525] Revert "Update settings.development.coffee.example" This reverts commit 20866189abcb0f314e5d72a4322304630255c92f. --- server-ce/config/settings.development.coffee.example | 1 - 1 file changed, 1 deletion(-) diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index c87055e0e9..ce930e07f1 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -26,7 +26,6 @@ module.exports = secret: "" buckets: # The S3 bucket name to store binary files in - # Must contain full url like: .s3.amazonaws.com user_files: "" # Databases From ce430bf9af0eaa445f037bc5c48459aed76b9c59 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 24 Feb 2014 14:44:35 +0000 Subject: [PATCH 053/525] Add in Travis CI badges --- server-ce/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index c05334c9e8..c25f9075d9 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -75,25 +75,25 @@ and source code repository. These are all downloaded and set upwhen you run The different services are: -### [web](https://github.com/sharelatex/web-sharelatex) +### [web](https://github.com/sharelatex/web-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/web-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/web-sharelatex) The front facing web server that serves all the HTML pages, CSS and JavaScript to the client. Also contains a lot of logic around creating and editing projects, and account management. -### [document-updater](https://github.com/sharelatex/document-updater-sharelatex) +### [document-updater](https://github.com/sharelatex/document-updater-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/document-updater-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/document-updater-sharelatex) Processes updates that come in from the editor when users modify documents. Ensures that the updates are applied in the right order, and that only one operation is modifying the document at a time. Also caches the documents in redis for very fast but persistent modifications. -### [CLSI](https://github.com/sharelatex/clsi-sharelatex) +### [CLSI](https://github.com/sharelatex/clsi-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/clsi-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/clsi-sharelatex) The Common LaTeX Service Interface (CLSI) which provides an API for compiling LaTeX documents. -### [filestore](https://github.com/sharelatex/filestore-sharelatex) +### [filestore](https://github.com/sharelatex/filestore-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/filestore-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/filestore-sharelatex) An API for performing CRUD (Create, Read, Update and Delete) operations on binary files (like images) stored in ShareLaTeX. From 0ede6911dd11d47a636fbd5840bc6e4aef376881 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 24 Feb 2014 15:24:47 +0000 Subject: [PATCH 054/525] Update CONTRIBUTING.md --- server-ce/CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index 8bcd728a12..a40bc8814f 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -12,7 +12,7 @@ Reporting bugs and opening issues If you'd like a report a bug or open an issue then please: -1. **Find the correct repository.** ShareLaTeX is split across multiple different repositories, each containing a different service (you can find a list of [all repositories here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories), and [all issues here](https://github.com/organizations/sharelatex/dashboard/issues)). If you know the bug only applies to one service, then please open an issue in that repository. For general bugs and issues that span more than one service, please open an issue in the [sharelatex/sharelatex](https://github.com/sharelatex/sharelatex) repository. +1. **Find the correct repository.** ShareLaTeX is split across multiple different repositories, each containing a different service (you can find a list of [all repositories here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories)). If you know the bug only applies to one service, then please open an issue in that repository. For general bugs and issues that span more than one service, please open an issue in the [sharelatex/sharelatex](https://github.com/sharelatex/sharelatex) repository. 2. **Check if there is an existing issue.** If there is then please add any more information that you have, or give it a "+1" in the comments. @@ -34,6 +34,8 @@ If you've got an idea for a change then please discuss it in the open first, either by opening an issue, or by joining us in our [development chat room](http://www.hipchat.com/g1nJMcj7b). +If you're looking for something to work on, then take a look at our [development roadmap](https://github.com/sharelatex/sharelatex/wiki/Development-Roadmap), or have a look at the open issues in any of the repositories listed [here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories). + Developer Chat Room ------------------- From f1879a1694b8aaef1df5e49dcc0abd371dd0c22d Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 24 Feb 2014 19:08:08 +0000 Subject: [PATCH 055/525] Update Gruntfile.coffee --- server-ce/Gruntfile.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index ed81cea32e..55a75a293e 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -4,7 +4,6 @@ exec = require("child_process").exec rimraf = require "rimraf" Path = require "path" semver = require "semver" -settings = require "settings-sharelatex" knox = require "knox" SERVICES = [{ @@ -220,11 +219,12 @@ module.exports = (grunt) -> checkS3: (callback = (error) ->) -> grunt.log.write "Checking S3 credentials... " + Settings = require "settings-sharelatex" try client = knox.createClient({ - key: settings.s3.key - secret: settings.s3.secret - bucket: settings.s3.buckets.user_files + key: Settings.s3.key + secret: Settings.s3.secret + bucket: Settings.s3.buckets.user_files }) catch e grunt.log.error "FAIL." From 4afc12b3a6045c0420f0d7e0f4c11b6f251ffec1 Mon Sep 17 00:00:00 2001 From: Ciro Santillli Date: Tue, 25 Feb 2014 13:33:44 +0100 Subject: [PATCH 056/525] Add dummy version to package.json to fix install. --- server-ce/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/package.json b/server-ce/package.json index 383fa5951f..a36305c5e1 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -1,5 +1,6 @@ { "name": "sharelatex", + "version": "0.0.1", "description": "An online collaborative LaTeX editor", "dependencies": { "rimraf": "~2.2.6", From 4884254fc643481229e25640dabc85b6386a0b34 Mon Sep 17 00:00:00 2001 From: Ciro Santillli Date: Tue, 25 Feb 2014 14:30:31 +0100 Subject: [PATCH 057/525] Remove dollars from readme bash code. --- server-ce/README.md | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index c25f9075d9..2392117c8c 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -15,13 +15,17 @@ them quickly. First, check out a local copy of this repository: - $ git clone https://github.com/sharelatex/sharelatex.git - $ cd sharelatex +```bash +git clone https://github.com/sharelatex/sharelatex.git +cd sharelatex +``` Next install all the node modules and ShareLaTeX services: - $ npm install - $ grunt install +```bash +npm install +grunt install +``` This will create a config file in `config/settings.development.coffee`. You should open this now and configure your AWS S3 credentials, and other custom settings. @@ -29,11 +33,15 @@ this now and configure your AWS S3 credentials, and other custom settings. Now check that your system is set up correctly to run ShareLaTeX (checks that you have the required dependencies installed.) Watch out for any failures. - $ grunt check --force +```bash +grunt check --force +``` When that has finished, run ShareLaTeX with - $ grunt run +```bash +grunt run +``` ShareLaTeX should now be running at http://localhost:3000. @@ -47,12 +55,12 @@ ShareLaTeX should run on OS X and Linux. You need: * A local instance of [Redis](http://redis.io/) (version 2.6 or later) and [MongoDB](http://www.mongodb.org/) running on their standard ports. * An up to date version of [TeXLive](https://www.tug.org/texlive/), with the `latexmk` program installed. You need latexmk from TeXLive 2013 (or the later). If you're on an older version, or aren't sure, then the following commands will install the latest version locally: - ```bash - $ mkdir ~/bin - $ curl http://mirror.physik-pool.tu-berlin.de/tex-archive/support/latexmk/latexmk.pl > ~/bin/latexmk - $ chmod a+x ~/bin/latexmk - $ export PATH=~/bin:$PATH - ``` +```bash +mkdir ~/bin +curl http://mirror.physik-pool.tu-berlin.de/tex-archive/support/latexmk/latexmk.pl > ~/bin/latexmk +chmod a+x ~/bin/latexmk +export PATH=~/bin:$PATH +``` Config ------ @@ -64,7 +72,9 @@ which can be done by editing the file at `config/settings.development.coffee` A local settings file can be specified by setting the `SHARELATEX_CONFIG` environment variable to point to your own settings file. E.g. - $ export SHARELATEX_CONFIG=/home/james/config/settings.development.coffee +```bash +export SHARELATEX_CONFIG=/home/james/config/settings.development.coffee +``` Other repositories ------------------ From b02248bffbc46b43c3a7f039f764c995e4d27208 Mon Sep 17 00:00:00 2001 From: Ciro Santillli Date: Tue, 25 Feb 2014 12:27:27 +0100 Subject: [PATCH 058/525] Add .nvmrc --- server-ce/.nvmrc | 1 + server-ce/README.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 server-ce/.nvmrc diff --git a/server-ce/.nvmrc b/server-ce/.nvmrc new file mode 100644 index 0000000000..61012ac6c8 --- /dev/null +++ b/server-ce/.nvmrc @@ -0,0 +1 @@ +0.10.26 diff --git a/server-ce/README.md b/server-ce/README.md index c25f9075d9..7c9f8c5315 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -42,7 +42,7 @@ Dependencies ShareLaTeX should run on OS X and Linux. You need: -* [Node.js](http://nodejs.org/) 0.10 or greater +* [Node.js](http://nodejs.org/) 0.10 or greater. We recommend that you use [nvm](https://github.com/creationix/nvm) to install it. * The [grunt](http://gruntjs.com/) command line tools (Run `npm install -g grunt-cli` to install them) * A local instance of [Redis](http://redis.io/) (version 2.6 or later) and [MongoDB](http://www.mongodb.org/) running on their standard ports. * An up to date version of [TeXLive](https://www.tug.org/texlive/), with the `latexmk` program installed. You need latexmk from TeXLive 2013 (or the later). If you're on an older version, or aren't sure, then the following commands will install the latest version locally: From dbd214baaf2e731951a0486223c4e1b17b0a15a8 Mon Sep 17 00:00:00 2001 From: Ciro Santillli Date: Tue, 25 Feb 2014 16:38:41 +0100 Subject: [PATCH 059/525] Remove latexmk intall instructions from README. --- server-ce/README.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 2392117c8c..c1484ef412 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -53,14 +53,7 @@ ShareLaTeX should run on OS X and Linux. You need: * [Node.js](http://nodejs.org/) 0.10 or greater * The [grunt](http://gruntjs.com/) command line tools (Run `npm install -g grunt-cli` to install them) * A local instance of [Redis](http://redis.io/) (version 2.6 or later) and [MongoDB](http://www.mongodb.org/) running on their standard ports. -* An up to date version of [TeXLive](https://www.tug.org/texlive/), with the `latexmk` program installed. You need latexmk from TeXLive 2013 (or the later). If you're on an older version, or aren't sure, then the following commands will install the latest version locally: - -```bash -mkdir ~/bin -curl http://mirror.physik-pool.tu-berlin.de/tex-archive/support/latexmk/latexmk.pl > ~/bin/latexmk -chmod a+x ~/bin/latexmk -export PATH=~/bin:$PATH -``` +* [TeXLive](https://www.tug.org/texlive/) 2013 or later with the `latexmk` program installed. Config ------ From 2afc081549e1dad6190c99ac7fe0536724cb5b9c Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 26 Feb 2014 09:12:55 +0000 Subject: [PATCH 060/525] Adds filestoreBackend property to example settings --- server-ce/config/settings.development.coffee.example | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index ce930e07f1..9ec7b4d2a1 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -27,6 +27,9 @@ module.exports = buckets: # The S3 bucket name to store binary files in user_files: "" + + # Tell the filestore api to use s3 to persist files, in future more backends can be added + filestoreBackend: "s3" # Databases # --------- From eecaf0307e242cec1a9198153094b506d50d9798 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 26 Feb 2014 13:05:22 +0000 Subject: [PATCH 061/525] Updated readme links Changed links for mongo and redis to point at install instructions which can people can look at if they need to install these dependencies. --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 990fe4e8f5..60bbf47c79 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -52,7 +52,7 @@ ShareLaTeX should run on OS X and Linux. You need: * [Node.js](http://nodejs.org/) 0.10 or greater. We recommend that you use [nvm](https://github.com/creationix/nvm) to install it. * The [grunt](http://gruntjs.com/) command line tools (Run `npm install -g grunt-cli` to install them) -* A local instance of [Redis](http://redis.io/) (version 2.6 or later) and [MongoDB](http://www.mongodb.org/) running on their standard ports. +* A local instance of [Redis](http://redis.io/topics/quickstart) (version 2.6 or later) and [MongoDB](http://docs.mongodb.org/manual/installation/) running on their standard ports. * [TeXLive](https://www.tug.org/texlive/) 2013 or later with the `latexmk` program installed. Config From b495240d49a48339899fc1352d4345a430880785 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 26 Feb 2014 16:24:01 +0000 Subject: [PATCH 062/525] Add in track changes as a 'hidden' service --- server-ce/Gruntfile.coffee | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 55a75a293e..85d6a9b35a 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -20,6 +20,10 @@ SERVICES = [{ repo: "https://github.com/sharelatex/filestore-sharelatex.git" }] +TRACK_CHANGES = + name: "track-changes" + repo: "https://github.com/sharelatex/track-changes-sharelatex.git" + module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-bunyan' @@ -28,7 +32,7 @@ module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-concurrent' execute = {} - for service in SERVICES + for service in SERVICES.concat([TRACK_CHANGES]) execute[service.name] = src: "#{service.name}/app.js" @@ -66,7 +70,7 @@ module.exports = (grunt) -> "Config tasks": ["install:config"] "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make"] - for service in SERVICES + for service in SERVICES.concat([TRACK_CHANGES]) do (service) -> grunt.registerTask "install:#{service.name}", "Download and set up the #{service.name} service", () -> done = @async() From 26302597a798c2cb195a320bec8188709062a90c Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 28 Feb 2014 18:36:27 +0000 Subject: [PATCH 063/525] Add in Vagrant/Ansible backed installation method --- server-ce/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 60bbf47c79..10ac14dbd0 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -13,6 +13,8 @@ APIs that talk to each other over HTTP and Redis pub-sub channels. This reposito pulls together all of the different services and allows you to set up and run them quickly. +### Manually + First, check out a local copy of this repository: ```bash @@ -45,6 +47,10 @@ grunt run ShareLaTeX should now be running at http://localhost:3000. +### With Vagrant + +There is a Vagrant and Ansible backed VM installatoin script for ShareLaTeX, maintained by [@palkan](https://github/palkan), available here: https://github.com/palkan/sharelatex-vagrant-ansible + Dependencies ------------ From 88bd3592092777259a9730160600eb1668e642fe Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 28 Feb 2014 18:36:50 +0000 Subject: [PATCH 064/525] Update README.md --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 10ac14dbd0..a3ae88fdde 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -49,7 +49,7 @@ ShareLaTeX should now be running at http://localhost:3000. ### With Vagrant -There is a Vagrant and Ansible backed VM installatoin script for ShareLaTeX, maintained by [@palkan](https://github/palkan), available here: https://github.com/palkan/sharelatex-vagrant-ansible +There is a Vagrant and Ansible backed VM installation script for ShareLaTeX, maintained by [@palkan](https://github/palkan), available here: https://github.com/palkan/sharelatex-vagrant-ansible Dependencies ------------ From 4196e823aba84bce348174497be4f097d0be7b88 Mon Sep 17 00:00:00 2001 From: Oliver Matthews Date: Tue, 4 Mar 2014 14:35:49 +0000 Subject: [PATCH 065/525] refactor config settings. --- server-ce/Gruntfile.coffee | 81 ++++++++++++------- .../settings.development.coffee.example | 34 +++++--- 2 files changed, 78 insertions(+), 37 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 85d6a9b35a..affc7c5ce0 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -104,9 +104,11 @@ module.exports = (grunt) -> Helpers.checkLatexmk @async() grunt.registerTask "check:s3", "Check that Amazon S3 credentials are configured", () -> Helpers.checkS3 @async() + grunt.registerTask "check:fs", "Check that local filesystem options are configured", () -> + Helpers.checkFS @async() grunt.registerTask "check:make", "Check that make is installed", () -> Helpers.checkMake @async() - grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3"] + grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3", "check:fs"] Helpers = installService: (repo_src, dir, callback = (error) ->) -> @@ -222,38 +224,63 @@ module.exports = (grunt) -> callback(error) checkS3: (callback = (error) ->) -> - grunt.log.write "Checking S3 credentials... " Settings = require "settings-sharelatex" - try - client = knox.createClient({ - key: Settings.s3.key - secret: Settings.s3.secret - bucket: Settings.s3.buckets.user_files - }) - catch e - grunt.log.error "FAIL." - grunt.log.errorlns """ - Please configure you Amazon S3 credentials in config/settings.development.coffee - - Amazon S3 (Simple Storage Service) is a cloud storage service provided by - Amazon. ShareLaTeX uses S3 for storing binary files like images. You can - sign up for an account and find out more at: - - http://aws.amazon.com/s3/ - - """ - return callback() - - client.getFile "does-not-exist", (error, response) -> - unless response? and response.statusCode == 404 + if Settings.filestore.backend=="" + grunt.log.writeln "No backend specified. Assuming Amazon S3" + Settings.filestore.backend = "s3" + if Settings.filestore.backend=="s3" + grunt.log.write "Checking S3 credentials... " + try + client = knox.createClient({ + key: Settings.filestore.s3.key + secret: Settings.filestore.s3.secret + bucket: Settings.filestore.stores.user_files + }) + catch e grunt.log.error "FAIL." grunt.log.errorlns """ - Could not connect to Amazon S3. Please check your credentials. + Please configure you Amazon S3 credentials in config/settings.development.coffee + + Amazon S3 (Simple Storage Service) is a cloud storage service provided by + Amazon. ShareLaTeX uses S3 for storing binary files like images. You can + sign up for an account and find out more at: + + http://aws.amazon.com/s3/ + """ - else - grunt.log.write "OK." + return callback() + client.getFile "does-not-exist", (error, response) -> + unless response? and response.statusCode == 404 + grunt.log.error "FAIL." + grunt.log.errorlns """ + Could not connect to Amazon S3. Please check your credentials. + """ + else + grunt.log.write "OK." + callback() + else + grunt.log.writeln "Filestore other than S3 configured. Not checking S3." callback() + checkFS: (callback = (error) ->) -> + Settings = require "settings-sharelatex" + if Settings.filestore.backend=="fs" + grunt.log.write "Checking FS configuration..." + fs = require("fs") + fs.exists Settings.filestore.stores.user_files, (exists) -> + if exists + grunt.log.write "OK." + else + grunt.log.error "FAIL." + grunt.log.errorlns """ + Could not find directory "#{Settings.filestore.stores.user_files}". + Please check your configuration. + """ + else + grunt.log.writeln "Filestore other than FS configured. Not checking FS." + callback() + + checkMake: (callback = (error) ->) -> grunt.log.write "Checking make is installed... " exec "make --version", (error, stdout, stderr) -> diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index 9ec7b4d2a1..c623832ac8 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -19,17 +19,31 @@ module.exports = # File storage # ------------ # - # ShareLaTeX stores binary files like images in S3. - # Fill in your Amazon S3 credentials below. - s3: - key: "" - secret: "" - buckets: - # The S3 bucket name to store binary files in - user_files: "" + # ShareLaTeX needs somewhere to store binary files like images. + # There are currently two options: + # Amazon S3 (the default) + # local filesystem - # Tell the filestore api to use s3 to persist files, in future more backends can be added - filestoreBackend: "s3" + filestore: + # which backend persistor to use. + # choices are + # s3 - Amazon S3 + # fs - local filesystem + backend: "s3" + stores: + # where to store user and template binary files + # + # For Amazon S3 this is the bucket name to store binary files in + # Must contain full url like: .s3.amazonaws.com + # + # For local filesystem this is the directory to store the files in. + # Must contain full path, e.g. "/var/lib/sharelatex/data" + # This path must exist, not be tmpfs and be writable to by the user sharelatex is run as. + user_files: "" + s3: + # if you are using S3, then fill in your S3 details below + key: "" + secret: "" # Databases # --------- From d3efdea7ede4cf204be22dd9212cce3b11240c27 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 5 Mar 2014 12:49:51 +0000 Subject: [PATCH 066/525] Use file storage out of the box --- server-ce/.gitignore | 3 +++ .../settings.development.coffee.example | 24 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/server-ce/.gitignore b/server-ce/.gitignore index b9433f478a..2b808bda8b 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -6,8 +6,11 @@ web document-updater clsi filestore +track-changes compiles cache +user_files +template_files db.sqlite diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index c623832ac8..8f8466bf8c 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -21,29 +21,27 @@ module.exports = # # ShareLaTeX needs somewhere to store binary files like images. # There are currently two options: - # Amazon S3 (the default) - # local filesystem - + # Your local filesystem (the default) + # Amazon S3 filestore: # which backend persistor to use. # choices are # s3 - Amazon S3 # fs - local filesystem - backend: "s3" + backend: "fs" stores: - # where to store user and template binary files + # where to store user and template binary files # - # For Amazon S3 this is the bucket name to store binary files in - # Must contain full url like: .s3.amazonaws.com + # For Amazon S3 this is the bucket name to store binary files # # For local filesystem this is the directory to store the files in. - # Must contain full path, e.g. "/var/lib/sharelatex/data" # This path must exist, not be tmpfs and be writable to by the user sharelatex is run as. - user_files: "" - s3: - # if you are using S3, then fill in your S3 details below - key: "" - secret: "" + user_files: Path.resolve(__dirname + "/../user_files") + # Uncomment if you need to configure your S3 credentials + # s3: + # # if you are using S3, then fill in your S3 details below + # key: "" + # secret: "" # Databases # --------- From 718bfbf771106cea9144ed09969117f4f9f4d20d Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 5 Mar 2014 12:51:42 +0000 Subject: [PATCH 067/525] Update README.md --- server-ce/README.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index a3ae88fdde..e550a8eeb8 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -64,16 +64,8 @@ ShareLaTeX should run on OS X and Linux. You need: Config ------ -ShareLaTeX should mostly run out of the box, although it uses Amazon S3 for storing binary -files like images. You will need to configure ShareLaTeX to use your own S3 access key -which can be done by editing the file at `config/settings.development.coffee` - -A local settings file can be specified by setting the `SHARELATEX_CONFIG` environment variable -to point to your own settings file. E.g. - -```bash -export SHARELATEX_CONFIG=/home/james/config/settings.development.coffee -``` +ShareLaTeX should run out of the box, but if you want to adjust any settings you can do so by +editing the `config/settings.development.coffee` file. Available options are explained inline. Other repositories ------------------ From 26cd9c78be226e3d12e09045265fc3fb9af7c52e Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 5 Mar 2014 12:52:04 +0000 Subject: [PATCH 068/525] Fix typo --- server-ce/Gruntfile.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index affc7c5ce0..1138879520 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -239,7 +239,7 @@ module.exports = (grunt) -> catch e grunt.log.error "FAIL." grunt.log.errorlns """ - Please configure you Amazon S3 credentials in config/settings.development.coffee + Please configure your Amazon S3 credentials in config/settings.development.coffee Amazon S3 (Simple Storage Service) is a cloud storage service provided by Amazon. ShareLaTeX uses S3 for storing binary files like images. You can From 66ab033ebecd2861c74f78e1a4904366425b704b Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 5 Mar 2014 13:39:21 +0000 Subject: [PATCH 069/525] Make track changes api a first class citizen --- server-ce/Gruntfile.coffee | 10 ++++------ server-ce/README.md | 5 +++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 1138879520..3868f235fc 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -18,12 +18,10 @@ SERVICES = [{ }, { name: "filestore" repo: "https://github.com/sharelatex/filestore-sharelatex.git" -}] - -TRACK_CHANGES = +}, { name: "track-changes" repo: "https://github.com/sharelatex/track-changes-sharelatex.git" - +}] module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-bunyan' @@ -32,7 +30,7 @@ module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-concurrent' execute = {} - for service in SERVICES.concat([TRACK_CHANGES]) + for service in SERVICES execute[service.name] = src: "#{service.name}/app.js" @@ -70,7 +68,7 @@ module.exports = (grunt) -> "Config tasks": ["install:config"] "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make"] - for service in SERVICES.concat([TRACK_CHANGES]) + for service in SERVICES do (service) -> grunt.registerTask "install:#{service.name}", "Download and set up the #{service.name} service", () -> done = @async() diff --git a/server-ce/README.md b/server-ce/README.md index e550a8eeb8..470424714d 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -99,6 +99,11 @@ documents. An API for performing CRUD (Create, Read, Update and Delete) operations on binary files (like images) stored in ShareLaTeX. +### [track-changes](https://github.com/sharelatex/track-changes-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/track-changes-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/track-changes-sharelatex) + +An API for compressing and storing the updates applied to a document, and then rendering a diff of the changes +between any two time points. *Still in development and not hooked into the UI yet*. + Contributing ------------ From a0b6896246e60a16aac58fa4da335d519789cfa0 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 5 Mar 2014 13:41:00 +0000 Subject: [PATCH 070/525] add in track-changes settings --- server-ce/config/settings.development.coffee.example | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index 8f8466bf8c..35a93cc6ba 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -86,6 +86,9 @@ module.exports = filestore: port: filestorePort = 3009 host: "localhost" + trackchanges: + port: trackchangesPort = 3015 + host: "localhost" # Tell each service where to find the other services. If everything # is running locally then this is easy, but they exist as separate config @@ -101,6 +104,8 @@ module.exports = url: "http://localhost:#{clsiPort}" filestore: url: "http://localhost:#{filestorePort}" + trackchanges: + url: "http://localhost:#{trackchangesPort}" thirdPartyDataStore: url : "http://localhost:3002" emptyProjectFlushDelayMiliseconds: 5 * seconds From 98514dd49c8c00bc0869c861299a8c965ff2fb94 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 6 Mar 2014 10:12:53 +0000 Subject: [PATCH 071/525] Add in Docker based install instructions --- server-ce/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 470424714d..d9cb9d00d3 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -51,6 +51,10 @@ ShareLaTeX should now be running at http://localhost:3000. There is a Vagrant and Ansible backed VM installation script for ShareLaTeX, maintained by [@palkan](https://github/palkan), available here: https://github.com/palkan/sharelatex-vagrant-ansible +### With Docker + +An [automatic docker-based installer](https://github.com/tiagoboldt/sharelatex-docker) is available. It depends on docker and will build a production environment for running ShareLaTeX on any supported platform. + Dependencies ------------ From 34c7a35845172f2f33cd85d93f8892d96f8bfab0 Mon Sep 17 00:00:00 2001 From: Oliver Matthews Date: Fri, 7 Mar 2014 13:08:46 +0000 Subject: [PATCH 072/525] config changes for nodemailer --- .../settings.development.coffee.example | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index 35a93cc6ba..d2bd09d469 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -171,6 +171,24 @@ module.exports = {name: "English", code: "en"} ] + # Email support + # ------------- + # + # ShareLaTeX uses nodemailer (http://www.nodemailer.com/) to send transactional emails. + # To see the range of transport and options they support, see http://www.nodemailer.com/docs/transports + #email: + # Who should emails be from by default? + # fromAddress: "" + # The default replyTo field, if it should be set + # replyTo: "" + # lifecycle: false + ## Example transport and parameter settings for Amazon SES + # transport: "SES" + # parameters: + # AWSAccessKeyID: "" + # AWSSecretKey: "" + + # Third party services # -------------------- # @@ -193,11 +211,6 @@ module.exports = # ShareLaTeX's help desk is provided by tenderapp.com # tenderUrl: "" # - # ShareLaTeX uses Amazon's SES api to send transactional emails. - # Uncomment these lines and provide your credentials to be able to send emails. - # ses: - # "key":"" - # "secret":"" # Production Settings # ------------------- From 42447f6cbe3f846e028b7650f0afb1f8a25a5566 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 17 Mar 2014 12:49:15 +0000 Subject: [PATCH 073/525] Update templates api location --- server-ce/config/settings.development.coffee.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index d2bd09d469..ac1a544368 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -129,7 +129,7 @@ module.exports = blog: port: 3008 templates_api: - url: "http://localhost:3014" + url: "http://localhost:3007" # Where your instance of ShareLaTeX can be found publically. Used in emails # that are sent out, generated links, etc. From 28b5a59814dc8cf57ee7fcd4baceaeffb5072569 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 28 Mar 2014 12:54:19 +0000 Subject: [PATCH 074/525] Create user_files by default --- server-ce/user_files/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 server-ce/user_files/.gitignore diff --git a/server-ce/user_files/.gitignore b/server-ce/user_files/.gitignore new file mode 100644 index 0000000000..e69de29bb2 From c24cc69136b03f163ec0fa58a5c7732c9a4196ab Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 31 Mar 2014 19:48:13 +0100 Subject: [PATCH 075/525] Link to survey for about what people want --- server-ce/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index d9cb9d00d3..369ae8ae32 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -8,10 +8,9 @@ ShareLaTeX Installation ------------ -ShareLaTeX uses a service oriented architecture (SOA) where we have lots of small -APIs that talk to each other over HTTP and Redis pub-sub channels. This repository -pulls together all of the different services and allows you to set up and run -them quickly. +**[Please help us make ShareLaTeX as easy to install as possible by answering our quick survey about your system and needs](https://sharelatex.typeform.com/to/PLNits)** + +We're still figuring out the easiest way to let you install ShareLaTeX and get up and running quickly. If you fill in the above survey in we will be eternally grateful and it will help us make this install process as smooth as possible. For now, here is the best ways: ### Manually From 0e7b9d3ab1bd7217b19ae339f2785635e48b204a Mon Sep 17 00:00:00 2001 From: James Allen Date: Sun, 30 Mar 2014 16:51:48 +0100 Subject: [PATCH 076/525] Import apt version 2.3.8 --- server-ce/chef/cookbooks/apt/CHANGELOG.md | 173 +++++++++++ server-ce/chef/cookbooks/apt/README.md | 248 ++++++++++++++++ .../chef/cookbooks/apt/attributes/default.rb | 28 ++ .../apt/files/default/apt-proxy-v2.conf | 50 ++++ .../chef/cookbooks/apt/libraries/helpers.rb | 48 +++ .../chef/cookbooks/apt/libraries/matchers.rb | 17 ++ .../chef/cookbooks/apt/libraries/network.rb | 31 ++ server-ce/chef/cookbooks/apt/metadata.json | 54 ++++ server-ce/chef/cookbooks/apt/metadata.rb | 34 +++ .../cookbooks/apt/providers/preference.rb | 63 ++++ .../cookbooks/apt/providers/repository.rb | 150 ++++++++++ .../cookbooks/apt/recipes/cacher-client.rb | 81 ++++++ .../chef/cookbooks/apt/recipes/cacher-ng.rb | 43 +++ .../chef/cookbooks/apt/recipes/default.rb | 82 ++++++ .../cookbooks/apt/resources/preference.rb | 32 ++ .../cookbooks/apt/resources/repository.rb | 43 +++ .../apt/templates/debian-6.0/acng.conf.erb | 173 +++++++++++ .../apt/templates/default/01proxy.erb | 5 + .../apt/templates/default/acng.conf.erb | 275 ++++++++++++++++++ .../apt/templates/ubuntu-10.04/acng.conf.erb | 269 +++++++++++++++++ 20 files changed, 1899 insertions(+) create mode 100644 server-ce/chef/cookbooks/apt/CHANGELOG.md create mode 100644 server-ce/chef/cookbooks/apt/README.md create mode 100644 server-ce/chef/cookbooks/apt/attributes/default.rb create mode 100644 server-ce/chef/cookbooks/apt/files/default/apt-proxy-v2.conf create mode 100644 server-ce/chef/cookbooks/apt/libraries/helpers.rb create mode 100644 server-ce/chef/cookbooks/apt/libraries/matchers.rb create mode 100644 server-ce/chef/cookbooks/apt/libraries/network.rb create mode 100644 server-ce/chef/cookbooks/apt/metadata.json create mode 100644 server-ce/chef/cookbooks/apt/metadata.rb create mode 100644 server-ce/chef/cookbooks/apt/providers/preference.rb create mode 100644 server-ce/chef/cookbooks/apt/providers/repository.rb create mode 100644 server-ce/chef/cookbooks/apt/recipes/cacher-client.rb create mode 100644 server-ce/chef/cookbooks/apt/recipes/cacher-ng.rb create mode 100644 server-ce/chef/cookbooks/apt/recipes/default.rb create mode 100644 server-ce/chef/cookbooks/apt/resources/preference.rb create mode 100644 server-ce/chef/cookbooks/apt/resources/repository.rb create mode 100644 server-ce/chef/cookbooks/apt/templates/debian-6.0/acng.conf.erb create mode 100644 server-ce/chef/cookbooks/apt/templates/default/01proxy.erb create mode 100644 server-ce/chef/cookbooks/apt/templates/default/acng.conf.erb create mode 100644 server-ce/chef/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb diff --git a/server-ce/chef/cookbooks/apt/CHANGELOG.md b/server-ce/chef/cookbooks/apt/CHANGELOG.md new file mode 100644 index 0000000000..769fd7ef91 --- /dev/null +++ b/server-ce/chef/cookbooks/apt/CHANGELOG.md @@ -0,0 +1,173 @@ +apt Cookbook CHANGELOG +====================== +This file is used to list changes made in each version of the apt cookbook. + +v2.3.8 (2014-02-14) +------------------- +### Bug +- **[COOK-4287](https://tickets.opscode.com/browse/COOK-4287)** - Cleanup the Kitchen + + +v2.3.6 +------ +* [COOK-4154] - Add chefspec matchers.rb file to apt cookbook +* [COOK-4102] - Only index created repository + + +v2.3.6 +------ +* [COOK-4154] - Add chefspec matchers.rb file to apt cookbook +* [COOK-4102] - Only index created repository + + +v2.3.4 +------ +No change. Version bump for toolchain sanity + + +v2.3.2 +------ +- [COOK-3905] apt-get-update-periodic: configuration for the update period +- Updating style for rubocops +- Updating test-kitchen harness + + +v2.3.0 +------ +### Bug +- **[COOK-3812](https://tickets.opscode.com/browse/COOK-3812)** - Add a way to bypass the apt existence check + +### Improvement +- **[COOK-3567](https://tickets.opscode.com/browse/COOK-3567)** - Allow users to bypass apt-cache via attributes + + +v2.2.1 +------ +### Improvement +- **[COOK-664](https://tickets.opscode.com/browse/COOK-664)** - Check platform before running apt-specific commands + + +v2.2.0 +------ +### Bug +- **[COOK-3707](https://tickets.opscode.com/browse/COOK-3707)** - multiple nics confuse apt::cacher-client + +v2.1.2 +------ +### Improvement +- **[COOK-3551](https://tickets.opscode.com/browse/COOK-3551)** - Allow user to set up a trusted APT repository + +v2.1.1 +------ +### Bug +- **[COOK-1856](https://tickets.opscode.com/browse/COOK-1856)** - Match GPG keys without case sensitivity + +v2.1.0 +------ +- [COOK-3426]: cacher-ng fails with restrict_environment set to true +- [COOK-2859]: cacher-client executes out of order +- [COOK-3052]: Long GPG keys are downloaded on every run +- [COOK-1856]: apt cookbook should match keys without case sensitivity +- [COOK-3255]: Attribute name incorrect in README +- [COOK-3225]: Call use_inline_resources only if defined +- [COOK-3386]: Cache dir for apt-cacher-ng +- [COOK-3291]: apt_repository: enable usage of a keyserver on port 80 +- Greatly expanded test coverage with ChefSpec and Test-Kitchen + +v2.0.0 +------ +### Bug + +- [COOK-2258]: apt: LWRP results in error under why-run mode in apt 1.9.0 cookbook + +v1.10.0 +------- +### Improvement + +- [COOK-2885]: Improvements for apt cache server search + +### Bug + +- [COOK-2441]: Apt recipe broken in new chef version +- [COOK-2660]: Create Debian 6.0 "squeeze" specific template for + apt-cacher-ng + +v1.9.2 +------ +- [COOK-2631] - Create Ubuntu 10.04 specific template for apt-cacher-ng + +v1.9.0 +------ +- [COOK-2185] - Proxy for apt-key +- [COOK-2338] - Support pinning by glob() or regexp + +v1.8.4 +------ +- [COOK-2171] - Update README to clarify required Chef version: 10.18.0 + or higher. + +v1.8.2 +------ +- [COOK-2112] - need [] around "arch" in sources.list entries +- [COOK-2171] - fixes a regression in the notification + +v1.8.0 +------ +- [COOK-2143] - Allow for a custom cacher-ng port +- [COOK-2171] - On `apt_repository.run_action(:add)` the source file + is not created. +- [COOK-2184] - apt::cacher-ng, use `cacher_port` attribute in + acng.conf + +v1.7.0 +------ +- [COOK-2082] - add "arch" parameter to apt_repository LWRP + +v1.6.0 +------ +- [COOK-1893] - `apt_preference` use "`package_name`" resource instead of "name" +- [COOK-1894] - change filename for sources.list.d files +- [COOK-1914] - Wrong dir permissions for /etc/apt/preferences.d/ +- [COOK-1942] - README.md has wrong name for the keyserver attribute +- [COOK-2019] - create 01proxy before any other apt-get updates get executed + +v1.5.2 +------ +- [COOK-1682] - use template instead of file resource in apt::cacher-client +- [COOK-1875] - cacher-client should be Environment-aware + +V1.5.0 +------ +- [COOK-1500] - Avoid triggering apt-get update +- [COOK-1548] - Add execute commands for autoclean and autoremove +- [COOK-1591] - Setting up the apt proxy should leave https + connections direct +- [COOK-1596] - execute[apt-get-update-periodic] never runs +- [COOK-1762] - create /etc/apt/preferences.d directory +- [COOK-1776] - apt key check isn't idempotent + +v1.4.8 +------ +* Adds test-kitchen support +- [COOK-1435] - repository lwrp is not idempotent with http key + +v1.4.6 +------ +- [COOK-1530] - apt_repository isn't aware of update-success-stamp + file (also reverts COOK-1382 patch). + +v1.4.4 +------ +- [COOK-1229] - Allow cacher IP to be set manually in non-Chef Solo + environments +- [COOK-1530] - Immediately update apt-cache when sources.list file is dropped off + +v1.4.2 +------ +- [COOK-1155] - LWRP for apt pinning + +v1.4.0 +------ +- [COOK-889] - overwrite existing repo source files +- [COOK-921] - optionally use cookbook\_file or remote\_file for key +- [COOK-1032] - fixes problem with apt repository key installation diff --git a/server-ce/chef/cookbooks/apt/README.md b/server-ce/chef/cookbooks/apt/README.md new file mode 100644 index 0000000000..f23212a1df --- /dev/null +++ b/server-ce/chef/cookbooks/apt/README.md @@ -0,0 +1,248 @@ +apt Cookbook +============ +This cookbook includes recipes to execute apt-get update to ensure the local APT package cache is up to date. There are recipes for managing the apt-cacher-ng caching proxy and proxy clients. It also includes a LWRP for managing APT repositories in /etc/apt/sources.list.d as well as an LWRP for pinning packages via /etc/apt/preferences.d. + + +Requirements +------------ +**Version 2.0.0+ of this cookbook requires Chef 11.0.0 or later**. If your Chef version is earlier than 11.0.0, use version 1.10.0 of this cookbook. + +Version 1.8.2 to 1.10.0 of this cookbook requires **Chef 10.16.4** or later. + +If your Chef version is earlier than 10.16.4, use version 1.7.0 of this cookbook. + +### Platform +Please refer to the [TESTING file](TESTING.md) to see the currently (and passing) tested platforms. The release was tested on: + +* Ubuntu 10.04 +* Ubuntu 12.04 +* Ubuntu 13.04 +* Debian 7.1 +* Debian 6.0 (have with manual testing) + +May work with or without modification on other Debian derivatives. + + +------- +### default +This recipe installs the `update-notifier-common` package to provide the timestamp file used to only run `apt-get update` if the cache is more than one day old. + +This recipe should appear first in the run list of Debian or Ubuntu nodes to ensure that the package cache is up to date before managing any `package` resources with Chef. + +This recipe also sets up a local cache directory for preseeding packages. + +**Including the default recipe on a node that does not support apt (such as Windows) results in a noop.** + +### cacher-client +Configures the node to use the `apt-cacher-ng` server as a client. + +#### Bypassing the cache +Occasionally you may come across repositories that do not play nicely when the node is using an `apt-cacher-ng` server. You can configure `cacher-client` to bypass the server and connect directly to the repository with the `cache_bypass` attribute. + +To do this, you need to override the `cache_bypass` attribute with an array of repositories, with each array key as the repository URL and value as the protocol to use: + +```json +{ + ..., + 'apt': { + ..., + 'cache_bypass': { + URL: PROTOCOL + } + } +} +``` + +For example, to prevent caching and directly connect to the repository at `download.oracle.com` via http: + +```json +{ + 'apt': { + 'cache_bypass': { + 'download.oracle.com': 'http' + } + } +} +``` + +### cacher-ng +Installs the `apt-cacher-ng` package and service so the system can provide APT caching. You can check the usage report at http://{hostname}:3142/acng-report.html. + +If you wish to help the `cacher-ng` recipe seed itself, you must now explicitly include the `cacher-client` recipe in your run list **after** `cacher-ng` or you will block your ability to install any packages (ie. `apt-cacher-ng`). + + +Attributes +---------- +* `['apt']['cacher_ipaddress']` - use a cacher server (or standard proxy server) not available via search +* `['apt']['cacher_interface]` - interface to connect to the cacher-ng service, no default. +* `['apt']['cacher_port']` - port for the cacher-ng service (either client or server), default is '3142' +* `['apt']['cacher_dir']` - directory used by cacher-ng service, default is '/var/cache/apt-cacher-ng' +* `['apt']['cacher-client']['restrict_environment']` - restrict your node to using the `apt-cacher-ng` server in your Environment, default is 'false' +* `['apt']['compiletime']` - force the `cacher-client` recipe to run before other recipes. It forces apt to use the proxy before other recipes run. Useful if your nodes have limited access to public apt repositories. This is overridden if the `cacher-ng` recipe is in your run list. Default is 'false' +* `['apt']['cache_bypass']` - array of URLs to bypass the cache. Accepts the URL and protocol to fetch directly from the remote repository and not attempt to cache +* `['apt']['periodic_update_min_delay']` - minimum delay (in seconds) beetween two actual executions of `apt-get update` by the `execute[apt-get-update-periodic]` resource, default is '86400' (24 hours) + +Libraries +--------- +There is an `interface_ipaddress` method that returns the IP address for a particular host and interface, used by the `cacher-client` recipe. To enable it on the server use the `['apt']['cacher_interface']` attribute. + +Resources/Providers +------------------- +### `apt_repository` +This LWRP provides an easy way to manage additional APT repositories. Adding a new repository will notify running the `execute[apt-get-update]` resource immediately. + +#### Actions +- :add: creates a repository file and builds the repository listing +- :remove: removes the repository file + +#### Attribute Parameters +- repo_name: name attribute. The name of the channel to discover +- uri: the base of the Debian distribution +- distribution: this is usually your release's codename...ie something like `karmic`, `lucid` or `maverick` +- components: package groupings..when it doubt use `main` +- arch: constrain package to a particular arch like `i386`, `amd64` or even `armhf` or `powerpc`. Defaults to nil. +- trusted: treat all packages from this repository as authenticated regardless of signature +- deb_src: whether or not to add the repository as a source repo as well - value can be `true` or `false`, default `false`. +- keyserver: the GPG keyserver where the key for the repo should be retrieved +- key: if a `keyserver` is provided, this is assumed to be the fingerprint, otherwise it can be either the URI to the GPG key for the repo, or a cookbook_file. +- key_proxy: if set, pass the specified proxy via `http-proxy=` to GPG. +- cookbook: if key should be a cookbook_file, specify a cookbook where the key is located for files/default. Defaults to nil, so it will use the cookbook where the resource is used. + +#### Examples + +Add the Zenoss repo: + +```ruby +apt_repository 'zenoss' do + uri 'http://dev.zenoss.org/deb' + components ['main', 'stable'] +end +``` + +Add the Nginx PPA, grabbing the key from keyserver: + +```ruby +apt_repository 'nginx-php' do + uri 'http://ppa.launchpad.net/nginx/php5/ubuntu' + distribution node['lsb']['codename'] + components ['main'] + keyserver 'keyserver.ubuntu.com' + key 'C300EE8C' +end +``` + +Add the Nginx PPA, grab the key from the keyserver, and add source repo: + +```ruby +apt_repository 'nginx-php' do + uri 'http://ppa.launchpad.net/nginx/php5/ubuntu' + distribution node['lsb']['codename'] + components ['main'] + keyserver 'keyserver.ubuntu.com' + key 'C300EE8C' + deb_src true +end +``` + +Add the Cloudera Repo of CDH4 packages for Ubuntu 12.04 on AMD64: + +```ruby +apt_repository 'cloudera' do + uri 'http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh' + arch 'amd64' + distribution 'precise-cdh4' + components ['contrib'] + key 'http://archive.cloudera.com/debian/archive.key' +end +``` + +Remove Zenoss repo: + +```ruby +apt_repository 'zenoss' do + action :remove +end +``` + +### `apt_preference` +This LWRP provides an easy way to pin packages in /etc/apt/preferences.d. Although apt-pinning is quite helpful from time to time please note that Debian does not encourage its use without thorough consideration. + +Further information regarding apt-pinning is available via http://wiki.debian.org/AptPreferences. + +#### Actions +- :add: creates a preferences file under /etc/apt/preferences.d +- :remove: Removes the file, therefore unpin the package + +#### Attribute Parameters +- package_name: name attribute. The name of the package +- glob: Pin by glob() expression or regexp surrounded by /. +- pin: The package version/repository to pin +- pin_priority: The pinning priority aka "the highest package version wins" + +#### Examples +Pin libmysqlclient16 to version 5.1.49-3: + +```ruby +apt_preference 'libmysqlclient16' do + pin 'version 5.1.49-3' + pin_priority '700' +end +``` + +Unpin libmysqlclient16: + +```ruby +apt_preference 'libmysqlclient16' do + action :remove +end +``` + +Pin all packages from dotdeb.org: + +```ruby +apt_preference 'dotdeb' do + glob '*' + pin 'origin packages.dotdeb.org' + pin_priority '700' +end +``` + + +Usage +----- +Put `recipe[apt]` first in the run list. If you have other recipes that you want to use to configure how apt behaves, like new sources, notify the execute resource to run, e.g.: + +```ruby +template '/etc/apt/sources.list.d/my_apt_sources.list' do + notifies :run, 'execute[apt-get update]', :immediately +end +``` + +The above will run during execution phase since it is a normal template resource, and should appear before other package resources that need the sources in the template. + +Put `recipe[apt::cacher-ng]` in the run_list for a server to provide APT caching and add `recipe[apt::cacher-client]` on the rest of the Debian-based nodes to take advantage of the caching server. + +If you want to cleanup unused packages, there is also the `apt-get autoclean` and `apt-get autoremove` resources provided for automated cleanup. + + +License & Authors +----------------- +- Author:: Joshua Timberman (joshua@opscode.com) +- Author:: Matt Ray (matt@opscode.com) +- Author:: Seth Chisamore (schisamo@opscode.com) + +```text +Copyright 2009-2013, Opscode, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` diff --git a/server-ce/chef/cookbooks/apt/attributes/default.rb b/server-ce/chef/cookbooks/apt/attributes/default.rb new file mode 100644 index 0000000000..2f6b4e1444 --- /dev/null +++ b/server-ce/chef/cookbooks/apt/attributes/default.rb @@ -0,0 +1,28 @@ +# +# Cookbook Name:: apt +# Attributes:: default +# +# Copyright 2009-2013, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +default['apt']['cacher-client']['restrict_environment'] = false +default['apt']['cacher_dir'] = '/var/cache/apt-cacher-ng' +default['apt']['cacher_interface'] = nil +default['apt']['cacher_port'] = 3142 +default['apt']['caching_server'] = false +default['apt']['compiletime'] = false +default['apt']['key_proxy'] = '' +default['apt']['cache_bypass'] = {} +default['apt']['periodic_update_min_delay'] = 86_400 diff --git a/server-ce/chef/cookbooks/apt/files/default/apt-proxy-v2.conf b/server-ce/chef/cookbooks/apt/files/default/apt-proxy-v2.conf new file mode 100644 index 0000000000..69540047d1 --- /dev/null +++ b/server-ce/chef/cookbooks/apt/files/default/apt-proxy-v2.conf @@ -0,0 +1,50 @@ +[DEFAULT] +;; All times are in seconds, but you can add a suffix +;; for minutes(m), hours(h) or days(d) + +;; commented out address so apt-proxy will listen on all IPs +;; address = 127.0.0.1 +port = 9999 +cache_dir = /var/cache/apt-proxy + +;; Control files (Packages/Sources/Contents) refresh rate +min_refresh_delay = 1s +complete_clientless_downloads = 1 + +;; Debugging settings. +debug = all:4 db:0 + +time = 30 +passive_ftp = on + +;;-------------------------------------------------------------- +;; Cache housekeeping + +cleanup_freq = 1d +max_age = 120d +max_versions = 3 + +;;--------------------------------------------------------------- +;; Backend servers +;; +;; Place each server in its own [section] + +[ubuntu] +; Ubuntu archive +backends = + http://us.archive.ubuntu.com/ubuntu + +[ubuntu-security] +; Ubuntu security updates +backends = http://security.ubuntu.com/ubuntu + +[debian] +;; Backend servers, in order of preference +backends = + http://debian.osuosl.org/debian/ + +[security] +;; Debian security archive +backends = + http://security.debian.org/debian-security + http://ftp2.de.debian.org/debian-security diff --git a/server-ce/chef/cookbooks/apt/libraries/helpers.rb b/server-ce/chef/cookbooks/apt/libraries/helpers.rb new file mode 100644 index 0000000000..6fe95a97ad --- /dev/null +++ b/server-ce/chef/cookbooks/apt/libraries/helpers.rb @@ -0,0 +1,48 @@ +# +# Cookbook Name:: apt +# Library:: helpers +# +# Copyright 2013 Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module Apt + # Helpers for apt + module Helpers + # Determines if apt is installed on a system. + # + # @return [Boolean] + def apt_installed? + !which('apt-get').nil? + end + + # Finds a command in $PATH + # + # @return [String, nil] + def which(cmd) + paths = (ENV['PATH'].split(::File::PATH_SEPARATOR) + %w(/bin /usr/bin /sbin /usr/sbin)) + + paths.each do |path| + possible = File.join(path, cmd) + return possible if File.executable?(possible) + end + + nil + end + end +end + +Chef::Recipe.send(:include, ::Apt::Helpers) +Chef::Resource.send(:include, ::Apt::Helpers) +Chef::Provider.send(:include, ::Apt::Helpers) diff --git a/server-ce/chef/cookbooks/apt/libraries/matchers.rb b/server-ce/chef/cookbooks/apt/libraries/matchers.rb new file mode 100644 index 0000000000..aafce4da7a --- /dev/null +++ b/server-ce/chef/cookbooks/apt/libraries/matchers.rb @@ -0,0 +1,17 @@ +if defined?(ChefSpec) + def add_apt_preference(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:apt_preference, :add, resource_name) + end + + def remove_apt_preference(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:apt_preference, :remove, resource_name) + end + + def add_apt_repository(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:apt_repository, :add, resource_name) + end + + def remove_apt_repository(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:apt_repository, :remove, resource_name) + end +end diff --git a/server-ce/chef/cookbooks/apt/libraries/network.rb b/server-ce/chef/cookbooks/apt/libraries/network.rb new file mode 100644 index 0000000000..8535d6dce1 --- /dev/null +++ b/server-ce/chef/cookbooks/apt/libraries/network.rb @@ -0,0 +1,31 @@ +# +# Cookbook Name:: apt +# library:: network +# +# Copyright 2013, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module ::Apt + def interface_ipaddress(host, interface) + if interface + addresses = host['network']['interfaces'][interface]['addresses'] + addresses.select do |ip, data| + return ip if data['family'].eql?('inet') + end + else + return host.ipaddress + end + end +end diff --git a/server-ce/chef/cookbooks/apt/metadata.json b/server-ce/chef/cookbooks/apt/metadata.json new file mode 100644 index 0000000000..7a5316e229 --- /dev/null +++ b/server-ce/chef/cookbooks/apt/metadata.json @@ -0,0 +1,54 @@ +{ + "name": "apt", + "version": "2.3.8", + "description": "Configures apt and apt services and LWRPs for managing apt repositories and preferences", + "long_description": "apt Cookbook\n============\nThis cookbook includes recipes to execute apt-get update to ensure the local APT package cache is up to date. There are recipes for managing the apt-cacher-ng caching proxy and proxy clients. It also includes a LWRP for managing APT repositories in /etc/apt/sources.list.d as well as an LWRP for pinning packages via /etc/apt/preferences.d.\n\n\nRequirements\n------------\n**Version 2.0.0+ of this cookbook requires Chef 11.0.0 or later**. If your Chef version is earlier than 11.0.0, use version 1.10.0 of this cookbook.\n\nVersion 1.8.2 to 1.10.0 of this cookbook requires **Chef 10.16.4** or later.\n\nIf your Chef version is earlier than 10.16.4, use version 1.7.0 of this cookbook.\n\n### Platform\nPlease refer to the [TESTING file](TESTING.md) to see the currently (and passing) tested platforms. The release was tested on:\n\n* Ubuntu 10.04\n* Ubuntu 12.04\n* Ubuntu 13.04\n* Debian 7.1\n* Debian 6.0 (have with manual testing)\n\nMay work with or without modification on other Debian derivatives.\n\n\n-------\n### default\nThis recipe installs the `update-notifier-common` package to provide the timestamp file used to only run `apt-get update` if the cache is more than one day old.\n\nThis recipe should appear first in the run list of Debian or Ubuntu nodes to ensure that the package cache is up to date before managing any `package` resources with Chef.\n\nThis recipe also sets up a local cache directory for preseeding packages.\n\n**Including the default recipe on a node that does not support apt (such as Windows) results in a noop.**\n\n### cacher-client\nConfigures the node to use the `apt-cacher-ng` server as a client.\n\n#### Bypassing the cache\nOccasionally you may come across repositories that do not play nicely when the node is using an `apt-cacher-ng` server. You can configure `cacher-client` to bypass the server and connect directly to the repository with the `cache_bypass` attribute.\n\nTo do this, you need to override the `cache_bypass` attribute with an array of repositories, with each array key as the repository URL and value as the protocol to use:\n\n```json\n{\n ...,\n 'apt': {\n ...,\n 'cache_bypass': {\n URL: PROTOCOL\n }\n }\n}\n```\n\nFor example, to prevent caching and directly connect to the repository at `download.oracle.com` via http:\n\n```json\n{\n 'apt': {\n 'cache_bypass': {\n 'download.oracle.com': 'http'\n }\n }\n}\n```\n\n### cacher-ng\nInstalls the `apt-cacher-ng` package and service so the system can provide APT caching. You can check the usage report at http://{hostname}:3142/acng-report.html.\n\nIf you wish to help the `cacher-ng` recipe seed itself, you must now explicitly include the `cacher-client` recipe in your run list **after** `cacher-ng` or you will block your ability to install any packages (ie. `apt-cacher-ng`).\n\n\nAttributes\n----------\n* `['apt']['cacher_ipaddress']` - use a cacher server (or standard proxy server) not available via search\n* `['apt']['cacher_interface]` - interface to connect to the cacher-ng service, no default.\n* `['apt']['cacher_port']` - port for the cacher-ng service (either client or server), default is '3142'\n* `['apt']['cacher_dir']` - directory used by cacher-ng service, default is '/var/cache/apt-cacher-ng'\n* `['apt']['cacher-client']['restrict_environment']` - restrict your node to using the `apt-cacher-ng` server in your Environment, default is 'false'\n* `['apt']['compiletime']` - force the `cacher-client` recipe to run before other recipes. It forces apt to use the proxy before other recipes run. Useful if your nodes have limited access to public apt repositories. This is overridden if the `cacher-ng` recipe is in your run list. Default is 'false'\n* `['apt']['cache_bypass']` - array of URLs to bypass the cache. Accepts the URL and protocol to fetch directly from the remote repository and not attempt to cache\n* `['apt']['periodic_update_min_delay']` - minimum delay (in seconds) beetween two actual executions of `apt-get update` by the `execute[apt-get-update-periodic]` resource, default is '86400' (24 hours)\n\nLibraries\n---------\nThere is an `interface_ipaddress` method that returns the IP address for a particular host and interface, used by the `cacher-client` recipe. To enable it on the server use the `['apt']['cacher_interface']` attribute.\n\nResources/Providers\n-------------------\n### `apt_repository`\nThis LWRP provides an easy way to manage additional APT repositories. Adding a new repository will notify running the `execute[apt-get-update]` resource immediately.\n\n#### Actions\n- :add: creates a repository file and builds the repository listing\n- :remove: removes the repository file\n\n#### Attribute Parameters\n- repo_name: name attribute. The name of the channel to discover\n- uri: the base of the Debian distribution\n- distribution: this is usually your release's codename...ie something like `karmic`, `lucid` or `maverick`\n- components: package groupings..when it doubt use `main`\n- arch: constrain package to a particular arch like `i386`, `amd64` or even `armhf` or `powerpc`. Defaults to nil.\n- trusted: treat all packages from this repository as authenticated regardless of signature\n- deb_src: whether or not to add the repository as a source repo as well - value can be `true` or `false`, default `false`.\n- keyserver: the GPG keyserver where the key for the repo should be retrieved\n- key: if a `keyserver` is provided, this is assumed to be the fingerprint, otherwise it can be either the URI to the GPG key for the repo, or a cookbook_file.\n- key_proxy: if set, pass the specified proxy via `http-proxy=` to GPG.\n- cookbook: if key should be a cookbook_file, specify a cookbook where the key is located for files/default. Defaults to nil, so it will use the cookbook where the resource is used.\n\n#### Examples\n\nAdd the Zenoss repo:\n\n```ruby\napt_repository 'zenoss' do\n uri 'http://dev.zenoss.org/deb'\n components ['main', 'stable']\nend\n```\n\nAdd the Nginx PPA, grabbing the key from keyserver:\n\n```ruby\napt_repository 'nginx-php' do\n uri 'http://ppa.launchpad.net/nginx/php5/ubuntu'\n distribution node['lsb']['codename']\n components ['main']\n keyserver 'keyserver.ubuntu.com'\n key 'C300EE8C'\nend\n```\n\nAdd the Nginx PPA, grab the key from the keyserver, and add source repo:\n\n```ruby\napt_repository 'nginx-php' do\n uri 'http://ppa.launchpad.net/nginx/php5/ubuntu'\n distribution node['lsb']['codename']\n components ['main']\n keyserver 'keyserver.ubuntu.com'\n key 'C300EE8C'\n deb_src true\nend\n```\n\nAdd the Cloudera Repo of CDH4 packages for Ubuntu 12.04 on AMD64:\n\n```ruby\napt_repository 'cloudera' do\n uri 'http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh'\n arch 'amd64'\n distribution 'precise-cdh4'\n components ['contrib']\n key 'http://archive.cloudera.com/debian/archive.key'\nend\n```\n\nRemove Zenoss repo:\n\n```ruby\napt_repository 'zenoss' do\n action :remove\nend\n```\n\n### `apt_preference`\nThis LWRP provides an easy way to pin packages in /etc/apt/preferences.d. Although apt-pinning is quite helpful from time to time please note that Debian does not encourage its use without thorough consideration.\n\nFurther information regarding apt-pinning is available via http://wiki.debian.org/AptPreferences.\n\n#### Actions\n- :add: creates a preferences file under /etc/apt/preferences.d\n- :remove: Removes the file, therefore unpin the package\n\n#### Attribute Parameters\n- package_name: name attribute. The name of the package\n- glob: Pin by glob() expression or regexp surrounded by /.\n- pin: The package version/repository to pin\n- pin_priority: The pinning priority aka \"the highest package version wins\"\n\n#### Examples\nPin libmysqlclient16 to version 5.1.49-3:\n\n```ruby\napt_preference 'libmysqlclient16' do\n pin 'version 5.1.49-3'\n pin_priority '700'\nend\n```\n\nUnpin libmysqlclient16:\n\n```ruby\napt_preference 'libmysqlclient16' do\n action :remove\nend\n```\n\nPin all packages from dotdeb.org:\n\n```ruby\napt_preference 'dotdeb' do\n glob '*'\n pin 'origin packages.dotdeb.org'\n pin_priority '700'\nend\n```\n\n\nUsage\n-----\nPut `recipe[apt]` first in the run list. If you have other recipes that you want to use to configure how apt behaves, like new sources, notify the execute resource to run, e.g.:\n\n```ruby\ntemplate '/etc/apt/sources.list.d/my_apt_sources.list' do\n notifies :run, 'execute[apt-get update]', :immediately\nend\n```\n\nThe above will run during execution phase since it is a normal template resource, and should appear before other package resources that need the sources in the template.\n\nPut `recipe[apt::cacher-ng]` in the run_list for a server to provide APT caching and add `recipe[apt::cacher-client]` on the rest of the Debian-based nodes to take advantage of the caching server.\n\nIf you want to cleanup unused packages, there is also the `apt-get autoclean` and `apt-get autoremove` resources provided for automated cleanup.\n\n\nLicense & Authors\n-----------------\n- Author:: Joshua Timberman (joshua@opscode.com)\n- Author:: Matt Ray (matt@opscode.com)\n- Author:: Seth Chisamore (schisamo@opscode.com)\n\n```text\nCopyright 2009-2013, Opscode, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n", + "maintainer": "Opscode, Inc.", + "maintainer_email": "cookbooks@opscode.com", + "license": "Apache 2.0", + "platforms": { + "ubuntu": ">= 0.0.0", + "debian": ">= 0.0.0" + }, + "dependencies": { + }, + "recommendations": { + }, + "suggestions": { + }, + "conflicting": { + }, + "providing": { + }, + "replacing": { + }, + "attributes": { + "apt/cacher-client/restrict_environment": { + "description": "Whether to restrict the search for the caching server to the same environment as this node", + "default": "false" + }, + "apt/cacher_port": { + "description": "Default listen port for the caching server", + "default": "3142" + }, + "apt/cacher_interface": { + "description": "Default listen interface for the caching server", + "default": null + }, + "apt/key_proxy": { + "description": "Passed as the proxy passed to GPG for the apt_repository resource", + "default": "" + }, + "apt/caching_server": { + "description": "Set this to true if the node is a caching server", + "default": "false" + } + }, + "groupings": { + }, + "recipes": { + "apt": "Runs apt-get update during compile phase and sets up preseed directories", + "apt::cacher-ng": "Set up an apt-cacher-ng caching proxy", + "apt::cacher-client": "Client for the apt::cacher-ng caching proxy" + } +} \ No newline at end of file diff --git a/server-ce/chef/cookbooks/apt/metadata.rb b/server-ce/chef/cookbooks/apt/metadata.rb new file mode 100644 index 0000000000..4ca3ffce63 --- /dev/null +++ b/server-ce/chef/cookbooks/apt/metadata.rb @@ -0,0 +1,34 @@ +name 'apt' +maintainer 'Opscode, Inc.' +maintainer_email 'cookbooks@opscode.com' +license 'Apache 2.0' +description 'Configures apt and apt services and LWRPs for managing apt repositories and preferences' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '2.3.8' +recipe 'apt', 'Runs apt-get update during compile phase and sets up preseed directories' +recipe 'apt::cacher-ng', 'Set up an apt-cacher-ng caching proxy' +recipe 'apt::cacher-client', 'Client for the apt::cacher-ng caching proxy' + +%w{ ubuntu debian }.each do |os| + supports os +end + +attribute 'apt/cacher-client/restrict_environment', + :description => 'Whether to restrict the search for the caching server to the same environment as this node', + :default => 'false' + +attribute 'apt/cacher_port', + :description => 'Default listen port for the caching server', + :default => '3142' + +attribute 'apt/cacher_interface', + :description => 'Default listen interface for the caching server', + :default => nil + +attribute 'apt/key_proxy', + :description => 'Passed as the proxy passed to GPG for the apt_repository resource', + :default => '' + +attribute 'apt/caching_server', + :description => 'Set this to true if the node is a caching server', + :default => 'false' diff --git a/server-ce/chef/cookbooks/apt/providers/preference.rb b/server-ce/chef/cookbooks/apt/providers/preference.rb new file mode 100644 index 0000000000..fd9f62413e --- /dev/null +++ b/server-ce/chef/cookbooks/apt/providers/preference.rb @@ -0,0 +1,63 @@ +# +# Cookbook Name:: apt +# Provider:: preference +# +# Copyright 2010-2011, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Build preferences.d file contents +def build_pref(package_name, pin, pin_priority) + "Package: #{package_name}\nPin: #{pin}\nPin-Priority: #{pin_priority}\n" +end + +action :add do + new_resource.updated_by_last_action(false) + + preference = build_pref( + new_resource.glob || new_resource.package_name, + new_resource.pin, + new_resource.pin_priority + ) + + preference_dir = directory '/etc/apt/preferences.d' do + owner 'root' + group 'root' + mode 00755 + recursive true + action :nothing + end + + preference_file = file "/etc/apt/preferences.d/#{new_resource.name}" do + owner 'root' + group 'root' + mode 00644 + content preference + action :nothing + end + + preference_dir.run_action(:create) + # write out the preference file, replace it if it already exists + preference_file.run_action(:create) +end + +action :remove do + if ::File.exists?("/etc/apt/preferences.d/#{new_resource.name}") + Chef::Log.info "Un-pinning #{new_resource.name} from /etc/apt/preferences.d/" + file "/etc/apt/preferences.d/#{new_resource.name}" do + action :delete + end + new_resource.updated_by_last_action(true) + end +end diff --git a/server-ce/chef/cookbooks/apt/providers/repository.rb b/server-ce/chef/cookbooks/apt/providers/repository.rb new file mode 100644 index 0000000000..a48105071e --- /dev/null +++ b/server-ce/chef/cookbooks/apt/providers/repository.rb @@ -0,0 +1,150 @@ +# +# Cookbook Name:: apt +# Provider:: repository +# +# Copyright 2010-2011, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +use_inline_resources if defined?(use_inline_resources) + +def whyrun_supported? + true +end + +# install apt key from keyserver +def install_key_from_keyserver(key, keyserver) + execute "install-key #{key}" do + if !node['apt']['key_proxy'].empty? + command "apt-key adv --keyserver-options http-proxy=#{node['apt']['key_proxy']} --keyserver hkp://#{keyserver}:80 --recv #{key}" + else + command "apt-key adv --keyserver #{keyserver} --recv #{key}" + end + action :run + not_if do + extract_fingerprints_from_cmd('apt-key finger').any? do |fingerprint| + fingerprint.end_with?(key.upcase) + end + end + end +end + +# run command and extract gpg ids +def extract_fingerprints_from_cmd(cmd) + so = Mixlib::ShellOut.new(cmd) + so.run_command + so.stdout.split(/\n/).map do |t| + if z = t.match(/^ +Key fingerprint = ([0-9A-F ]+)/) + z[1].split.join + end + end.compact +end + +# install apt key from URI +def install_key_from_uri(uri) + key_name = uri.split(/\//).last + cached_keyfile = "#{Chef::Config[:file_cache_path]}/#{key_name}" + if new_resource.key =~ /http/ + remote_file cached_keyfile do + source new_resource.key + mode 00644 + action :create + end + else + cookbook_file cached_keyfile do + source new_resource.key + cookbook new_resource.cookbook + mode 00644 + action :create + end + end + + execute "install-key #{key_name}" do + command "apt-key add #{cached_keyfile}" + action :run + not_if do + installed_keys = extract_fingerprints_from_cmd('apt-key finger') + proposed_keys = extract_fingerprints_from_cmd("gpg --with-fingerprint #{cached_keyfile}") + (installed_keys & proposed_keys).sort == proposed_keys.sort + end + end +end + +# build repo file contents +def build_repo(uri, distribution, components, trusted, arch, add_deb_src) + components = components.join(' ') if components.respond_to?(:join) + repo_options = [] + repo_options << "arch=#{arch}" if arch + repo_options << 'trusted=yes' if trusted + repo_options = '[' + repo_options.join(' ') + ']' unless repo_options.empty? + repo_info = "#{uri} #{distribution} #{components}\n" + repo_info = "#{repo_options} #{repo_info}" unless repo_options.empty? + repo = "deb #{repo_info}" + repo << "deb-src #{repo_info}" if add_deb_src + repo +end + +action :add do + # add key + if new_resource.keyserver && new_resource.key + install_key_from_keyserver(new_resource.key, new_resource.keyserver) + elsif new_resource.key + install_key_from_uri(new_resource.key) + end + + file '/var/lib/apt/periodic/update-success-stamp' do + action :nothing + end + + execute 'apt-cache gencaches' do + ignore_failure true + action :nothing + end + + execute 'apt-get update' do + command "apt-get update -o Dir::Etc::sourcelist='sources.list.d/#{new_resource.name}.list' -o Dir::Etc::sourceparts='-' -o APT::Get::List-Cleanup='0'" + ignore_failure true + action :nothing + notifies :run, 'execute[apt-cache gencaches]', :immediately + end + + # build repo file + repository = build_repo( + new_resource.uri, + new_resource.distribution, + new_resource.components, + new_resource.trusted, + new_resource.arch, + new_resource.deb_src + ) + + file "/etc/apt/sources.list.d/#{new_resource.name}.list" do + owner 'root' + group 'root' + mode 00644 + content repository + action :create + notifies :delete, 'file[/var/lib/apt/periodic/update-success-stamp]', :immediately + notifies :run, 'execute[apt-get update]', :immediately if new_resource.cache_rebuild + end +end + +action :remove do + if ::File.exists?("/etc/apt/sources.list.d/#{new_resource.name}.list") + Chef::Log.info "Removing #{new_resource.name} repository from /etc/apt/sources.list.d/" + file "/etc/apt/sources.list.d/#{new_resource.name}.list" do + action :delete + end + end +end diff --git a/server-ce/chef/cookbooks/apt/recipes/cacher-client.rb b/server-ce/chef/cookbooks/apt/recipes/cacher-client.rb new file mode 100644 index 0000000000..bee010f115 --- /dev/null +++ b/server-ce/chef/cookbooks/apt/recipes/cacher-client.rb @@ -0,0 +1,81 @@ +# +# Cookbook Name:: apt +# Recipe:: cacher-client +# +# Copyright 2011-2013 Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +class ::Chef::Recipe + include ::Apt +end + +# remove Acquire::http::Proxy lines from /etc/apt/apt.conf since we use 01proxy +# these are leftover from preseed installs +execute 'Remove proxy from /etc/apt/apt.conf' do + command "sed --in-place '/^Acquire::http::Proxy/d' /etc/apt/apt.conf" + only_if 'grep Acquire::http::Proxy /etc/apt/apt.conf' +end + +servers = [] +if node['apt'] + if node['apt']['cacher_ipaddress'] + cacher = Chef::Node.new + cacher.default.name = node['apt']['cacher_ipaddress'] + cacher.default.ipaddress = node['apt']['cacher_ipaddress'] + cacher.default.apt.cacher_port = node['apt']['cacher_port'] + cacher.default.apt_cacher_interface = node['apt']['cacher_interface'] + servers << cacher + elsif node['apt']['caching_server'] + node.override['apt']['compiletime'] = false + servers << node + end +end + +unless Chef::Config[:solo] || servers.length > 0 + query = 'apt_caching_server:true' + query += " AND chef_environment:#{node.chef_environment}" if node['apt']['cacher-client']['restrict_environment'] + Chef::Log.debug("apt::cacher-client searching for '#{query}'") + servers += search(:node, query) +end + +if servers.length > 0 + Chef::Log.info("apt-cacher-ng server found on #{servers[0]}.") + if servers[0]['apt']['cacher_interface'] + cacher_ipaddress = interface_ipaddress(servers[0], servers[0]['apt']['cacher_interface']) + else + cacher_ipaddress = servers[0].ipaddress + end + t = template '/etc/apt/apt.conf.d/01proxy' do + source '01proxy.erb' + owner 'root' + group 'root' + mode 00644 + variables( + :proxy => cacher_ipaddress, + :port => servers[0]['apt']['cacher_port'], + :bypass => node['apt']['cache_bypass'] + ) + action(node['apt']['compiletime'] ? :nothing : :create) + notifies :run, 'execute[apt-get update]', :immediately + end + t.run_action(:create) if node['apt']['compiletime'] +else + Chef::Log.info('No apt-cacher-ng server found.') + file '/etc/apt/apt.conf.d/01proxy' do + action :delete + end +end + +include_recipe 'apt::default' diff --git a/server-ce/chef/cookbooks/apt/recipes/cacher-ng.rb b/server-ce/chef/cookbooks/apt/recipes/cacher-ng.rb new file mode 100644 index 0000000000..8629dcfabf --- /dev/null +++ b/server-ce/chef/cookbooks/apt/recipes/cacher-ng.rb @@ -0,0 +1,43 @@ +# +# Cookbook Name:: apt +# Recipe:: cacher-ng +# +# Copyright 2008-2013, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +node.set['apt']['caching_server'] = true + +package 'apt-cacher-ng' do + action :install +end + +directory node['apt']['cacher_dir'] do + owner 'apt-cacher-ng' + group 'apt-cacher-ng' + mode 0755 +end + +template '/etc/apt-cacher-ng/acng.conf' do + source 'acng.conf.erb' + owner 'root' + group 'root' + mode 00644 + notifies :restart, 'service[apt-cacher-ng]', :immediately +end + +service 'apt-cacher-ng' do + supports :restart => true, :status => false + action [:enable, :start] +end diff --git a/server-ce/chef/cookbooks/apt/recipes/default.rb b/server-ce/chef/cookbooks/apt/recipes/default.rb new file mode 100644 index 0000000000..9ce8cbe8ce --- /dev/null +++ b/server-ce/chef/cookbooks/apt/recipes/default.rb @@ -0,0 +1,82 @@ +# +# Cookbook Name:: apt +# Recipe:: default +# +# Copyright 2008-2013, Opscode, Inc. +# Copyright 2009, Bryan McLellan +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# On systems where apt is not installed, the resources in this recipe are not +# executed. However, they _must_ still be present in the resource collection +# or other cookbooks which notify these resources will fail on non-apt-enabled +# systems. + +Chef::Log.debug 'apt is not installed. Apt-specific resources will not be executed.' unless apt_installed? + +# Run apt-get update to create the stamp file +execute 'apt-get-update' do + command 'apt-get update' + ignore_failure true + only_if { apt_installed? } + not_if { ::File.exists?('/var/lib/apt/periodic/update-success-stamp') } +end + +# For other recipes to call to force an update +execute 'apt-get update' do + command 'apt-get update' + ignore_failure true + only_if { apt_installed? } + action :nothing +end + +# Automatically remove packages that are no longer needed for dependencies +execute 'apt-get autoremove' do + command 'apt-get -y autoremove' + only_if { apt_installed? } + action :nothing +end + +# Automatically remove .deb files for packages no longer on your system +execute 'apt-get autoclean' do + command 'apt-get -y autoclean' + only_if { apt_installed? } + action :nothing +end + +# provides /var/lib/apt/periodic/update-success-stamp on apt-get update +package 'update-notifier-common' do + notifies :run, 'execute[apt-get-update]', :immediately + only_if { apt_installed? } +end + +execute 'apt-get-update-periodic' do + command 'apt-get update' + ignore_failure true + only_if do + apt_installed? && + ::File.exists?('/var/lib/apt/periodic/update-success-stamp') && + ::File.mtime('/var/lib/apt/periodic/update-success-stamp') < Time.now - node['apt']['periodic_update_min_delay'] + end +end + +%w{/var/cache/local /var/cache/local/preseeding}.each do |dirname| + directory dirname do + owner 'root' + group 'root' + mode 00755 + action :create + only_if { apt_installed? } + end +end diff --git a/server-ce/chef/cookbooks/apt/resources/preference.rb b/server-ce/chef/cookbooks/apt/resources/preference.rb new file mode 100644 index 0000000000..21589eec4b --- /dev/null +++ b/server-ce/chef/cookbooks/apt/resources/preference.rb @@ -0,0 +1,32 @@ +# +# Cookbook Name:: apt +# Resource:: preference +# +# Copyright 2010-2013, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +actions :add, :remove +default_action :add if defined?(default_action) # Chef > 10.8 + +# Needed for Chef versions < 0.10.10 +def initialize(*args) + super + @action = :add +end + +attribute :package_name, :kind_of => String, :name_attribute => true +attribute :glob, :kind_of => String +attribute :pin, :kind_of => String +attribute :pin_priority, :kind_of => String diff --git a/server-ce/chef/cookbooks/apt/resources/repository.rb b/server-ce/chef/cookbooks/apt/resources/repository.rb new file mode 100644 index 0000000000..be737fee7b --- /dev/null +++ b/server-ce/chef/cookbooks/apt/resources/repository.rb @@ -0,0 +1,43 @@ +# +# Cookbook Name:: apt +# Resource:: repository +# +# Copyright 2010-2013, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +actions :add, :remove +default_action :add if defined?(default_action) # Chef > 10.8 + +# Needed for Chef versions < 0.10.10 +def initialize(*args) + super + @action = :add +end + +# name of the repo, used for source.list filename +attribute :repo_name, :kind_of => String, :name_attribute => true +attribute :uri, :kind_of => String +attribute :distribution, :kind_of => String +attribute :components, :kind_of => Array, :default => [] +attribute :arch, :kind_of => String, :default => nil +attribute :trusted, :kind_of => [TrueClass, FalseClass], :default => false +# whether or not to add the repository as a source repo as well +attribute :deb_src, :default => false +attribute :keyserver, :kind_of => String, :default => nil +attribute :key, :kind_of => String, :default => nil +attribute :cookbook, :kind_of => String, :default => nil +# trigger cache rebuild +# If not you can trigger in the recipe itself after checking the status of resource.updated{_by_last_action}? +attribute :cache_rebuild, :kind_of => [TrueClass, FalseClass], :default => true diff --git a/server-ce/chef/cookbooks/apt/templates/debian-6.0/acng.conf.erb b/server-ce/chef/cookbooks/apt/templates/debian-6.0/acng.conf.erb new file mode 100644 index 0000000000..98a681c2c3 --- /dev/null +++ b/server-ce/chef/cookbooks/apt/templates/debian-6.0/acng.conf.erb @@ -0,0 +1,173 @@ +# Letter case in directive names does not matter. Must be separated with colons. +# Valid boolean values are a zero number for false, non-zero numbers for true. + +CacheDir: <%= node['apt']['cacher_dir'] %> + +# set empty to disable logging +LogDir: /var/log/apt-cacher-ng + +# TCP (http) port +# Set to 9999 to emulate apt-proxy +Port:<%= node['apt']['cacher_port'] %> + +# Addresses or hostnames to listen on. Multiple addresses must be separated by +# spaces. Each entry must be associated with a local interface. DNS resolution +# is performed using getaddrinfo(3) for all available protocols (i.e. IPv4 and +# IPv6 if available). +# +# Default: not set, will listen on all interfaces. +# +# BindAddress: localhost 192.168.7.254 publicNameOnMainInterface + +#Proxy: http://www-proxy.example.net:80 +#proxy: http://username:proxypassword@proxy.example.net:3128 + +# Repository remapping. See manual for details. +# In this example, backends file is generated during package installation. +Remap-debrep: file:deb_mirror*.gz /debian ; file:backends_debian +Remap-uburep: file:ubuntu_mirrors /ubuntu ; file:backends_ubuntu +Remap-debvol: file:debvol_mirror*.gz /debian-volatile ; file:backends_debvol +Remap-cygwin: file:cygwin_mirrors /cygwin # ; file:backends_cygwin # incomplete, please create this file + +# Virtual page accessible in a web browser to see statistics and status +# information, i.e. under http://localhost:3142/acng-report.html +ReportPage: acng-report.html + +# Socket file for accessing through local UNIX socket instead of TCP/IP. Can be +# used with inetd bridge or cron client. +# SocketPath:/var/run/apt-cacher-ng/socket + +# Forces log file to be written to disk after every line when set to 1. Default +# is 0, buffer flush happens after client disconnects. +# +# (technically, this is an alias to the Debug option provided for convenience) +# +# UnbufferLogs: 0 + +# Set to 0 to store only type, time and transfer sizes. +# 1 -> client IP and relative local path are logged too +# VerboseLog: 1 + +# Don't detach from the console +# ForeGround: 0 + +# Store the pid of the daemon process therein +# PidFile: /var/run/apt-cacher-ng/pid + +# Forbid outgoing connections, work around them or respond with 503 error +# offlinemode:0 + +# Forbid all downloads that don't run through preconfigured backends (.where) +#ForceManaged: 0 + +# Days before considering an unreferenced file expired (to be deleted). +# Warning: if the value is set too low and particular index files are not +# available for some days (mirror downtime) there is a risk of deletion of +# still usefull package files. +ExTreshold: 4 + +# Stop expiration when a critical problem appeared. Currently only failed +# refresh of an index file is considered as critical. +# +# WARNING: don't touch this option or set to a non-zero number. +# Anything else is DANGEROUS and may cause data loss. +# +# ExAbortOnProblems: 1 + +# Replace some Windows/DOS-FS incompatible chars when storing +# StupidFs: 0 + +# Experimental feature for apt-listbugs: pass-through SOAP requests and +# responses to/from bugs.debian.org. If not set, default is true if +# ForceManaged is enabled and false otherwise. +# ForwardBtsSoap: 1 + +# The daemon has a small cache for DNS data, to speed up resolution. The +# expiration time of the DNS entries can be configured in seconds. +# DnsCacheSeconds: 3600 + +# Don't touch the following values without good consideration! +# +# Max. count of connection threads kept ready (for faster response in the +# future). Should be a sane value between 0 and average number of connections, +# and depend on the amount of spare RAM. +# MaxStandbyConThreads: 8 +# +# Hard limit of active thread count for incomming connections, i.e. operation +# is refused when this value is reached (below zero = unlimited). +# MaxConThreads: -1 +# +#VfilePattern = (^|.*?/)(Index|Packages\.bz2|Packages\.gz|Packages|Release|Release\.gpg|Sources\.bz2|Sources\.gz|Sources|release|index\.db-.*\.gz|Contents-[^/]*\.gz|pkglist[^/]*\.bz2|rclist[^/]*\.bz2|/meta-release[^/]*|Translation[^/]*\.bz2)$ +#PfilePattern = .*(\.deb|\.rpm|\.dsc|\.tar\.gz\.gpg|\.tar\.gz|\.diff\.gz|\.diff\.bz2|\.jigdo|\.template|changelog|copyright|\.udeb|\.diff/.*\.gz|vmlinuz|initrd\.gz|(Devel)?ReleaseAnnouncement(\\?.*)?)$ +# Whitelist for expiration, file types not to be removed even when being +# unreferenced. Default: same as VfilePattern which is a safe bed. When and +# only when the only used mirrors are official repositories (with working +# Release files) then it might be set to something more restrictive, like +# (^|.*?/)(Release|Release\.gpg|release|meta-release|Translation[^/]*\.bz2)$ +#WfilePattern = (^|.*?/)(Index|Packages\.bz2|Packages\.gz|Packages|Release|Release\.gpg|Sources\.bz2|Sources\.gz|Sources|release|index\.db-.*\.gz|Contents-[^/]*\.gz|pkglist[^/]*\.bz2|rclist[^/]*\.bz2|/meta-release[^/]*|Translation[^/]*\.bz2)$ + +# Higher modes only working with the debug version +# Warning, writes a lot into apt-cacher.err logfile +# Value overwrites UnbufferLogs setting (aliased) +# Debug:3 + +# Usually, general purpose proxies like Squid expose the IP adress of the +# client user to the remote server using the X-Forwarded-For HTTP header. This +# behaviour can be optionally turned on with the Expose-Origin option. +# ExposeOrigin: 0 + +# When logging the originating IP address, trust the information supplied by +# the client in the X-Forwarded-For header. +# LogSubmittedOrigin: 0 + +# The version string reported to the peer, to be displayed as HTTP client (and +# version) in the logs of the mirror. +# WARNING: some archives use this header to detect/guess capabilities of the +# client (i.e. redirection support) and change the behaviour accordingly, while +# ACNG might not support the expected features. Expect side effects. +# +# UserAgent: Yet Another HTTP Client/1.2.3p4 + +# In some cases the Import and Expiration tasks might create fresh volatile +# data for internal use by reconstructing them using patch files. This +# by-product might be recompressed with bzip2 and with some luck the resulting +# file becomes identical to the *.bz2 file on the server, usable for APT +# clients trying to fetch the full .bz2 compressed version. Injection of the +# generated files into the cache has however a disadvantage on underpowered +# servers: bzip2 compession can create high load on the server system and the +# visible download of the busy .bz2 files also becomes slower. +# +# RecompBz2: 0 + +# Network timeout for outgoing connections. +# NetworkTimeout: 60 + +# Sometimes it makes sense to not store the data in cache and just return the +# package data to client as it comes in. DontCache parameters can enable this +# behaviour for certain URL types. The tokens are extended regular expressions +# that URLs are matched against. +# +# DontCacheRequested is applied to the URL as it comes in from the client. +# Example: exclude packages built with kernel-package for x86 +# DontCacheRequested: linux-.*_10\...\.Custo._i386 +# Example usecase: exclude popular private IP ranges from caching +# DontCacheRequested: 192.168.0 ^10\..* 172.30 +# +# DontCacheResolved is applied to URLs after mapping to the target server. If +# multiple backend servers are specified then it's only matched against the +# download link for the FIRST possible source (due to implementation limits). +# Example usecase: all Ubuntu stuff comes from a local mirror (specified as +# backend), don't cache it again: +# DontCacheResolved: ubuntumirror.local.net +# +# DontCache directive sets (overrides) both, DontCacheResolved and +# DontCacheRequested. Provided for convenience, see those directives for +# details. +# +# Default permission set of freshly created files and directories, as octal +# numbers (see chmod(1) for details). +# Can by limited by the umask value (see umask(2) for details) if it's set in +# the environment of the starting shell, e.g. in apt-cacher-ng init script or +# in its configuration file. +# DirPerms: 00755 +# FilePerms: 00664 diff --git a/server-ce/chef/cookbooks/apt/templates/default/01proxy.erb b/server-ce/chef/cookbooks/apt/templates/default/01proxy.erb new file mode 100644 index 0000000000..37bce8770d --- /dev/null +++ b/server-ce/chef/cookbooks/apt/templates/default/01proxy.erb @@ -0,0 +1,5 @@ +Acquire::http::Proxy "http://<%= @proxy %>:<%= @port %>"; +Acquire::https::Proxy "DIRECT"; +<% @bypass.each do |bypass, type| %> +Acquire::<%= type %>::Proxy::<%= bypass %> "DIRECT"; +<% end %> diff --git a/server-ce/chef/cookbooks/apt/templates/default/acng.conf.erb b/server-ce/chef/cookbooks/apt/templates/default/acng.conf.erb new file mode 100644 index 0000000000..3aa0c92a4b --- /dev/null +++ b/server-ce/chef/cookbooks/apt/templates/default/acng.conf.erb @@ -0,0 +1,275 @@ +# Letter case in directive names does not matter. Must be separated with colons. +# Valid boolean values are a zero number for false, non-zero numbers for true. + +CacheDir: <%= node['apt']['cacher_dir'] %> + +# set empty to disable logging +LogDir: /var/log/apt-cacher-ng + +# place to look for additional configuration and resource files if they are not +# found in the configuration directory +# SupportDir: /usr/lib/apt-cacher-ng + +# TCP (http) port +# Set to 9999 to emulate apt-proxy +Port:<%= node['apt']['cacher_port'] %> + +# Addresses or hostnames to listen on. Multiple addresses must be separated by +# spaces. Each entry must be an exact local address which is associated with a +# local interface. DNS resolution is performed using getaddrinfo(3) for all +# available protocols (IPv4, IPv6, ...). Using a protocol specific format will +# create binding(s) only on protocol specific socket(s) (e.g. 0.0.0.0 will listen +# only to IPv4). +# +# Default: not set, will listen on all interfaces and protocols +# +# BindAddress: localhost 192.168.7.254 publicNameOnMainInterface + +# The specification of another proxy which shall be used for downloads. +# Username and password are, and see manual for limitations. +# +#Proxy: http://www-proxy.example.net:80 +#proxy: username:proxypassword@proxy.example.net:3128 + +# Repository remapping. See manual for details. +# In this example, some backends files might be generated during package +# installation using information collected on the system. +Remap-debrep: file:deb_mirror*.gz /debian ; file:backends_debian # Debian Archives +Remap-uburep: file:ubuntu_mirrors /ubuntu ; file:backends_ubuntu # Ubuntu Archives +Remap-debvol: file:debvol_mirror*.gz /debian-volatile ; file:backends_debvol # Debian Volatile Archives +Remap-cygwin: file:cygwin_mirrors /cygwin # ; file:backends_cygwin # incomplete, please create this file or specify preferred mirrors here +Remap-sfnet: file:sfnet_mirrors # ; file:backends_sfnet # incomplete, please create this file or specify preferred mirrors here +Remap-alxrep: file:archlx_mirrors /archlinux # ; file:backend_archlx # Arch Linux +Remap-fedora: file:fedora_mirrors # Fedora Linux +Remap-epel: file:epel_mirrors # Fedora EPEL +Remap-slrep: file:sl_mirrors # Scientific Linux + +# This is usually not needed for security.debian.org because it's always the +# same DNS hostname. However, it might be enabled in order to use hooks, +# ForceManaged mode or special flags in this context. +# Remap-secdeb: security.debian.org + +# Virtual page accessible in a web browser to see statistics and status +# information, i.e. under http://localhost:3142/acng-report.html +ReportPage: acng-report.html + +# Socket file for accessing through local UNIX socket instead of TCP/IP. Can be +# used with inetd bridge or cron client. +# SocketPath:/var/run/apt-cacher-ng/socket + +# Forces log file to be written to disk after every line when set to 1. Default +# is 0, buffers are flushed when the client disconnects. +# +# (technically, alias to the Debug option, see its documentation for details) +# +# UnbufferLogs: 0 + +# Set to 0 to store only type, time and transfer sizes. +# 1 -> client IP and relative local path are logged too +# VerboseLog: 1 + +# Don't detach from the console +# ForeGround: 0 + +# Store the pid of the daemon process therein +# PidFile: /var/run/apt-cacher-ng/pid + +# Forbid outgoing connections, work around them or respond with 503 error +# offlinemode:0 + +# Forbid all downloads that don't run through preconfigured backends (.where) +#ForceManaged: 0 + +# Days before considering an unreferenced file expired (to be deleted). +# Warning: if the value is set too low and particular index files are not +# available for some days (mirror downtime) there is a risk of deletion of +# still useful package files. +ExTreshold: 4 + +# Stop expiration when a critical problem appeared. Currently only failed +# refresh of an index file is considered as critical. +# +# WARNING: don't touch this option or set to zero. +# Anything else is DANGEROUS and may cause data loss. +# +# ExAbortOnProblems: 1 + +# Replace some Windows/DOS-FS incompatible chars when storing +# StupidFs: 0 + +# Experimental feature for apt-listbugs: pass-through SOAP requests and +# responses to/from bugs.debian.org. If not set, default is true if +# ForceManaged is enabled and false otherwise. +# ForwardBtsSoap: 1 + +# The daemon has a small cache for DNS data, to speed up resolution. The +# expiration time of the DNS entries can be configured in seconds. +# DnsCacheSeconds: 3600 + +# Don't touch the following values without good consideration! +# +# Max. count of connection threads kept ready (for faster response in the +# future). Should be a sane value between 0 and average number of connections, +# and depend on the amount of spare RAM. +# MaxStandbyConThreads: 8 +# +# Hard limit of active thread count for incoming connections, i.e. operation +# is refused when this value is reached (below zero = unlimited). +# MaxConThreads: -1 +# +# Pigeonholing files with regular expressions (static/volatile). Can be +# overriden here but not should not be done permanently because future update +# of default settings would not be applied later. +# VfilePattern = (^|.*?/)(Index|Packages(\.gz|\.bz2|\.lzma|\.xz)?|InRelease|Release|Release\.gpg|Sources(\.gz|\.bz2|\.lzma|\.xz)?|release|index\.db-.*\.gz|Contents-[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|pkglist[^/]*\.bz2|rclist[^/]*\.bz2|/meta-release[^/]*|Translation[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|MD5SUMS|SHA1SUMS|((setup|setup-legacy)(\.ini|\.bz2|\.hint)(\.sig)?)|mirrors\.lst|repo(index|md)\.xml(\.asc|\.key)?|directory\.yast|products|content(\.asc|\.key)?|media|filelists\.xml\.gz|filelists\.sqlite\.bz2|repomd\.xml|packages\.[a-zA-Z][a-zA-Z]\.gz|info\.txt|license\.tar\.gz|license\.zip|.*\.db(\.tar\.gz)?|.*\.files\.tar\.gz|.*\.abs\.tar\.gz|metalink\?repo|.*prestodelta\.xml\.gz)$|/dists/.*/installer-[^/]+/[^0-9][^/]+/images/.* +# PfilePattern = .*(\.d?deb|\.rpm|\.dsc|\.tar(\.gz|\.bz2|\.lzma|\.xz)(\.gpg)?|\.diff(\.gz|\.bz2|\.lzma|\.xz)|\.jigdo|\.template|changelog|copyright|\.udeb|\.debdelta|\.diff/.*\.gz|(Devel)?ReleaseAnnouncement(\?.*)?|[a-f0-9]+-(susedata|updateinfo|primary|deltainfo).xml.gz|fonts/(final/)?[a-z]+32.exe(\?download.*)?|/dists/.*/installer-[^/]+/[0-9][^/]+/images/.*)$ +# Whitelist for expiration, file types not to be removed even when being +# unreferenced. Default: many parts from VfilePattern where no parent index +# exists or might be unknown. +# WfilePattern = (^|.*?/)(Release|InRelease|Release\.gpg|(Packages|Sources)(\.gz|\.bz2|\.lzma|\.xz)?|Translation[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|MD5SUMS|SHA1SUMS|.*\.xml|.*\.db\.tar\.gz|.*\.files\.tar\.gz|.*\.abs\.tar\.gz|[a-z]+32.exe)$|/dists/.*/installer-.*/images/.* + +# Higher modes only working with the debug version +# Warning, writes a lot into apt-cacher.err logfile +# Value overwrites UnbufferLogs setting (aliased) +# Debug:3 + +# Usually, general purpose proxies like Squid expose the IP address of the +# client user to the remote server using the X-Forwarded-For HTTP header. This +# behaviour can be optionally turned on with the Expose-Origin option. +# ExposeOrigin: 0 + +# When logging the originating IP address, trust the information supplied by +# the client in the X-Forwarded-For header. +# LogSubmittedOrigin: 0 + +# The version string reported to the peer, to be displayed as HTTP client (and +# version) in the logs of the mirror. +# WARNING: some archives use this header to detect/guess capabilities of the +# client (i.e. redirection support) and change the behaviour accordingly, while +# ACNG might not support the expected features. Expect side effects. +# +# UserAgent: Yet Another HTTP Client/1.2.3p4 + +# In some cases the Import and Expiration tasks might create fresh volatile +# data for internal use by reconstructing them using patch files. This +# by-product might be recompressed with bzip2 and with some luck the resulting +# file becomes identical to the *.bz2 file on the server, usable for APT +# clients trying to fetch the full .bz2 compressed version. Injection of the +# generated files into the cache has however a disadvantage on underpowered +# servers: bzip2 compression can create high load on the server system and the +# visible download of the busy .bz2 files also becomes slower. +# +# RecompBz2: 0 + +# Network timeout for outgoing connections. +# NetworkTimeout: 60 + +# Sometimes it makes sense to not store the data in cache and just return the +# package data to client as it comes in. DontCache parameters can enable this +# behaviour for certain URL types. The tokens are extended regular expressions +# that URLs are matched against. +# +# DontCacheRequested is applied to the URL as it comes in from the client. +# Example: exclude packages built with kernel-package for x86 +# DontCacheRequested: linux-.*_10\...\.Custo._i386 +# Example usecase: exclude popular private IP ranges from caching +# DontCacheRequested: 192.168.0 ^10\..* 172.30 +# +# DontCacheResolved is applied to URLs after mapping to the target server. If +# multiple backend servers are specified then it's only matched against the +# download link for the FIRST possible source (due to implementation limits). +# Example usecase: all Ubuntu stuff comes from a local mirror (specified as +# backend), don't cache it again: +# DontCacheResolved: ubuntumirror.local.net +# +# DontCache directive sets (overrides) both, DontCacheResolved and +# DontCacheRequested. Provided for convenience, see those directives for +# details. +# +# Default permission set of freshly created files and directories, as octal +# numbers (see chmod(1) for details). +# Can by limited by the umask value (see umask(2) for details) if it's set in +# the environment of the starting shell, e.g. in apt-cacher-ng init script or +# in its configuration file. +# DirPerms: 00755 +# FilePerms: 00664 +# +# +# It's possible to use use apt-cacher-ng as a regular web server with limited +# feature set, i.e. +# including directory browsing and download of any file; +# excluding sorting, mime types/encodings, CGI execution, index page +# redirection and other funny things. +# To get this behavior, mappings between virtual directories and real +# directories on the server must be defined with the LocalDirs directive. +# Virtual and real dirs are separated by spaces, multiple pairs are separated +# by semi-colons. Real directories must be absolute paths. +# NOTE: Since the names of that key directories share the same namespace as +# repository names (see Remap-...) it's administrators job to avoid such +# collisions on them (unless created deliberately). +# +# LocalDirs: woo /data/debarchive/woody ; hamm /data/debarchive/hamm + +# Precache a set of files referenced by specified index files. This can be used +# to create a partial mirror usable for offline work. There are certain limits +# and restrictions on the path specification, see manual for details. A list of +# (maybe) relevant index files could be retrieved via +# "apt-get --print-uris update" on a client machine. +# +# PrecacheFor: debrep/dists/unstable/*/source/Sources* debrep/dists/unstable/*/binary-amd64/Packages* + +# Arbitrary set of data to append to request headers sent over the wire. Should +# be a well formated HTTP headers part including newlines (DOS style) which +# can be entered as escape sequences (\r\n). +# RequestAppendix: X-Tracking-Choice: do-not-track\r\n + +# Specifies the IP protocol families to use for remote connections. Order does +# matter, first specified are considered first. Possible combinations: +# v6 v4 +# v4 v6 +# v6 +# v4 +# (empty or not set: use system default) +# +# ConnectProto: v6 v4 + +# Regular expiration algorithm finds package files which are no longer listed +# in any index file and removes them of them after a safety period. +# This option allows to keep more versions of a package in the cache after +# safety period is over. +# KeepExtraVersions: 1 + +# Optionally uses TCP access control provided by libwrap, see hosts_access(5) +# for details. Daemon name is apt-cacher-ng. Default if not set: decided on +# startup by looking for explicit mentioning of apt-cacher-ng in +# /etc/hosts.allow or /etc/hosts.deny files. +# UseWrap: 0 + +# If many machines from the same local network attempt to update index files +# (apt-get update) at nearly the same time, the known state of these index file +# is temporarily frozen and multiple requests receive the cached response +# without contacting the server. This parameter (in seconds) specifies the +# length of this period before the files are considered outdated. +# Setting it too low transfers more data and increases remote server load, +# setting it too high (more than a couple of minutes) increases the risk of +# delivering inconsistent responses to the clients. +# FreshIndexMaxAge: 27 + +# Usually the users are not allowed to specify custom TCP ports of remote +# mirrors in the requests, only the default HTTP port can be used (instead, +# proxy administrator can create Remap- rules with custom ports). This +# restriction can be disabled by specifying a list of allowed ports or 0 for +# any port. +# +# AllowUserPorts: 80 + +# Normally the HTTP redirection responses are forwarded to the original caller +# (i.e. APT) which starts a new download attempt from the new URL. This +# solution is ok for client configurations with proxy mode but doesn't work +# well with configurations using URL prefixes. To work around this the server +# can restart its own download with another URL. However, this might be used to +# circumvent download source policies by malicious users. +# The RedirMax option specifies how many such redirects the server should +# follow per request, 0 disables the internal redirection. If not set, +# default value is 0 if ForceManaged is used and 5 otherwise. +# +# RedirMax: 5 diff --git a/server-ce/chef/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb b/server-ce/chef/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb new file mode 100644 index 0000000000..0e7c779b3a --- /dev/null +++ b/server-ce/chef/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb @@ -0,0 +1,269 @@ +# Letter case in directive names does not matter. Must be separated with colons. +# Valid boolean values are a zero number for false, non-zero numbers for true. + +CacheDir: <%= node['apt']['cacher_dir'] %> + +# set empty to disable logging +LogDir: /var/log/apt-cacher-ng + +# place to look for additional configuration and resource files if they are not +# found in the configuration directory +# SupportDir: /usr/lib/apt-cacher-ng + +# TCP (http) port +# Set to 9999 to emulate apt-proxy +Port:<%= node['apt']['cacher_port'] %> + +# Addresses or hostnames to listen on. Multiple addresses must be separated by +# spaces. Each entry must be an exact local address which is associated with a +# local interface. DNS resolution is performed using getaddrinfo(3) for all +# available protocols (IPv4, IPv6, ...). Using a protocol specific format will +# create binding(s) only on protocol specific socket(s) (e.g. 0.0.0.0 will listen +# only to IPv4). +# +# Default: not set, will listen on all interfaces and protocols +# +# BindAddress: localhost 192.168.7.254 publicNameOnMainInterface + +# The specification of another proxy which shall be used for downloads. +# Username and password are, and see manual for limitations. +# +#Proxy: http://www-proxy.example.net:80 +#proxy: username:proxypassword@proxy.example.net:3128 + +# Repository remapping. See manual for details. +# In this example, some backends files might be generated during package +# installation using information collected on the system. +Remap-debrep: file:deb_mirror*.gz /debian ; file:backends_debian # Debian Archives +Remap-uburep: file:ubuntu_mirrors /ubuntu ; file:backends_ubuntu # Ubuntu Archives +Remap-debvol: file:debvol_mirror*.gz /debian-volatile ; file:backends_debvol # Debian Volatile Archives + +# This is usually not needed for security.debian.org because it's always the +# same DNS hostname. However, it might be enabled in order to use hooks, +# ForceManaged mode or special flags in this context. +# Remap-secdeb: security.debian.org + +# Virtual page accessible in a web browser to see statistics and status +# information, i.e. under http://localhost:3142/acng-report.html +ReportPage: acng-report.html + +# Socket file for accessing through local UNIX socket instead of TCP/IP. Can be +# used with inetd bridge or cron client. +# SocketPath:/var/run/apt-cacher-ng/socket + +# Forces log file to be written to disk after every line when set to 1. Default +# is 0, buffers are flushed when the client disconnects. +# +# (technically, alias to the Debug option, see its documentation for details) +# +# UnbufferLogs: 0 + +# Set to 0 to store only type, time and transfer sizes. +# 1 -> client IP and relative local path are logged too +# VerboseLog: 1 + +# Don't detach from the console +# ForeGround: 0 + +# Store the pid of the daemon process therein +# PidFile: /var/run/apt-cacher-ng/pid + +# Forbid outgoing connections, work around them or respond with 503 error +# offlinemode:0 + +# Forbid all downloads that don't run through preconfigured backends (.where) +#ForceManaged: 0 + +# Days before considering an unreferenced file expired (to be deleted). +# Warning: if the value is set too low and particular index files are not +# available for some days (mirror downtime) there is a risk of deletion of +# still useful package files. +ExTreshold: 4 + +# Stop expiration when a critical problem appeared. Currently only failed +# refresh of an index file is considered as critical. +# +# WARNING: don't touch this option or set to zero. +# Anything else is DANGEROUS and may cause data loss. +# +# ExAbortOnProblems: 1 + +# Replace some Windows/DOS-FS incompatible chars when storing +# StupidFs: 0 + +# Experimental feature for apt-listbugs: pass-through SOAP requests and +# responses to/from bugs.debian.org. If not set, default is true if +# ForceManaged is enabled and false otherwise. +# ForwardBtsSoap: 1 + +# The daemon has a small cache for DNS data, to speed up resolution. The +# expiration time of the DNS entries can be configured in seconds. +# DnsCacheSeconds: 3600 + +# Don't touch the following values without good consideration! +# +# Max. count of connection threads kept ready (for faster response in the +# future). Should be a sane value between 0 and average number of connections, +# and depend on the amount of spare RAM. +# MaxStandbyConThreads: 8 +# +# Hard limit of active thread count for incoming connections, i.e. operation +# is refused when this value is reached (below zero = unlimited). +# MaxConThreads: -1 +# +# Pigeonholing files with regular expressions (static/volatile). Can be +# overriden here but not should not be done permanently because future update +# of default settings would not be applied later. +# VfilePattern = (^|.*?/)(Index|Packages(\.gz|\.bz2|\.lzma|\.xz)?|InRelease|Release|Release\.gpg|Sources(\.gz|\.bz2|\.lzma|\.xz)?|release|index\.db-.*\.gz|Contents-[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|pkglist[^/]*\.bz2|rclist[^/]*\.bz2|/meta-release[^/]*|Translation[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|MD5SUMS|SHA1SUMS|((setup|setup-legacy)(\.ini|\.bz2|\.hint)(\.sig)?)|mirrors\.lst|repo(index|md)\.xml(\.asc|\.key)?|directory\.yast|products|content(\.asc|\.key)?|media|filelists\.xml\.gz|filelists\.sqlite\.bz2|repomd\.xml|packages\.[a-zA-Z][a-zA-Z]\.gz|info\.txt|license\.tar\.gz|license\.zip|.*\.db(\.tar\.gz)?|.*\.files\.tar\.gz|.*\.abs\.tar\.gz|metalink\?repo|.*prestodelta\.xml\.gz)$|/dists/.*/installer-[^/]+/[^0-9][^/]+/images/.* +# PfilePattern = .*(\.d?deb|\.rpm|\.dsc|\.tar(\.gz|\.bz2|\.lzma|\.xz)(\.gpg)?|\.diff(\.gz|\.bz2|\.lzma|\.xz)|\.jigdo|\.template|changelog|copyright|\.udeb|\.debdelta|\.diff/.*\.gz|(Devel)?ReleaseAnnouncement(\?.*)?|[a-f0-9]+-(susedata|updateinfo|primary|deltainfo).xml.gz|fonts/(final/)?[a-z]+32.exe(\?download.*)?|/dists/.*/installer-[^/]+/[0-9][^/]+/images/.*)$ +# Whitelist for expiration, file types not to be removed even when being +# unreferenced. Default: many parts from VfilePattern where no parent index +# exists or might be unknown. +# WfilePattern = (^|.*?/)(Release|InRelease|Release\.gpg|(Packages|Sources)(\.gz|\.bz2|\.lzma|\.xz)?|Translation[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|MD5SUMS|SHA1SUMS|.*\.xml|.*\.db\.tar\.gz|.*\.files\.tar\.gz|.*\.abs\.tar\.gz|[a-z]+32.exe)$|/dists/.*/installer-.*/images/.* + +# Higher modes only working with the debug version +# Warning, writes a lot into apt-cacher.err logfile +# Value overwrites UnbufferLogs setting (aliased) +# Debug:3 + +# Usually, general purpose proxies like Squid expose the IP address of the +# client user to the remote server using the X-Forwarded-For HTTP header. This +# behaviour can be optionally turned on with the Expose-Origin option. +# ExposeOrigin: 0 + +# When logging the originating IP address, trust the information supplied by +# the client in the X-Forwarded-For header. +# LogSubmittedOrigin: 0 + +# The version string reported to the peer, to be displayed as HTTP client (and +# version) in the logs of the mirror. +# WARNING: some archives use this header to detect/guess capabilities of the +# client (i.e. redirection support) and change the behaviour accordingly, while +# ACNG might not support the expected features. Expect side effects. +# +# UserAgent: Yet Another HTTP Client/1.2.3p4 + +# In some cases the Import and Expiration tasks might create fresh volatile +# data for internal use by reconstructing them using patch files. This +# by-product might be recompressed with bzip2 and with some luck the resulting +# file becomes identical to the *.bz2 file on the server, usable for APT +# clients trying to fetch the full .bz2 compressed version. Injection of the +# generated files into the cache has however a disadvantage on underpowered +# servers: bzip2 compression can create high load on the server system and the +# visible download of the busy .bz2 files also becomes slower. +# +# RecompBz2: 0 + +# Network timeout for outgoing connections. +# NetworkTimeout: 60 + +# Sometimes it makes sense to not store the data in cache and just return the +# package data to client as it comes in. DontCache parameters can enable this +# behaviour for certain URL types. The tokens are extended regular expressions +# that URLs are matched against. +# +# DontCacheRequested is applied to the URL as it comes in from the client. +# Example: exclude packages built with kernel-package for x86 +# DontCacheRequested: linux-.*_10\...\.Custo._i386 +# Example usecase: exclude popular private IP ranges from caching +# DontCacheRequested: 192.168.0 ^10\..* 172.30 +# +# DontCacheResolved is applied to URLs after mapping to the target server. If +# multiple backend servers are specified then it's only matched against the +# download link for the FIRST possible source (due to implementation limits). +# Example usecase: all Ubuntu stuff comes from a local mirror (specified as +# backend), don't cache it again: +# DontCacheResolved: ubuntumirror.local.net +# +# DontCache directive sets (overrides) both, DontCacheResolved and +# DontCacheRequested. Provided for convenience, see those directives for +# details. +# +# Default permission set of freshly created files and directories, as octal +# numbers (see chmod(1) for details). +# Can by limited by the umask value (see umask(2) for details) if it's set in +# the environment of the starting shell, e.g. in apt-cacher-ng init script or +# in its configuration file. +# DirPerms: 00755 +# FilePerms: 00664 +# +# +# It's possible to use use apt-cacher-ng as a regular web server with limited +# feature set, i.e. +# including directory browsing and download of any file; +# excluding sorting, mime types/encodings, CGI execution, index page +# redirection and other funny things. +# To get this behavior, mappings between virtual directories and real +# directories on the server must be defined with the LocalDirs directive. +# Virtual and real dirs are separated by spaces, multiple pairs are separated +# by semi-colons. Real directories must be absolute paths. +# NOTE: Since the names of that key directories share the same namespace as +# repository names (see Remap-...) it's administrators job to avoid such +# collisions on them (unless created deliberately). +# +# LocalDirs: woo /data/debarchive/woody ; hamm /data/debarchive/hamm + +# Precache a set of files referenced by specified index files. This can be used +# to create a partial mirror usable for offline work. There are certain limits +# and restrictions on the path specification, see manual for details. A list of +# (maybe) relevant index files could be retrieved via +# "apt-get --print-uris update" on a client machine. +# +# PrecacheFor: debrep/dists/unstable/*/source/Sources* debrep/dists/unstable/*/binary-amd64/Packages* + +# Arbitrary set of data to append to request headers sent over the wire. Should +# be a well formated HTTP headers part including newlines (DOS style) which +# can be entered as escape sequences (\r\n). +# RequestAppendix: X-Tracking-Choice: do-not-track\r\n + +# Specifies the IP protocol families to use for remote connections. Order does +# matter, first specified are considered first. Possible combinations: +# v6 v4 +# v4 v6 +# v6 +# v4 +# (empty or not set: use system default) +# +# ConnectProto: v6 v4 + +# Regular expiration algorithm finds package files which are no longer listed +# in any index file and removes them of them after a safety period. +# This option allows to keep more versions of a package in the cache after +# safety period is over. +# KeepExtraVersions: 1 + +# Optionally uses TCP access control provided by libwrap, see hosts_access(5) +# for details. Daemon name is apt-cacher-ng. Default if not set: decided on +# startup by looking for explicit mentioning of apt-cacher-ng in +# /etc/hosts.allow or /etc/hosts.deny files. +# UseWrap: 0 + +# If many machines from the same local network attempt to update index files +# (apt-get update) at nearly the same time, the known state of these index file +# is temporarily frozen and multiple requests receive the cached response +# without contacting the server. This parameter (in seconds) specifies the +# length of this period before the files are considered outdated. +# Setting it too low transfers more data and increases remote server load, +# setting it too high (more than a couple of minutes) increases the risk of +# delivering inconsistent responses to the clients. +# FreshIndexMaxAge: 27 + +# Usually the users are not allowed to specify custom TCP ports of remote +# mirrors in the requests, only the default HTTP port can be used (instead, +# proxy administrator can create Remap- rules with custom ports). This +# restriction can be disabled by specifying a list of allowed ports or 0 for +# any port. +# +# AllowUserPorts: 80 + +# Normally the HTTP redirection responses are forwarded to the original caller +# (i.e. APT) which starts a new download attempt from the new URL. This +# solution is ok for client configurations with proxy mode but doesn't work +# well with configurations using URL prefixes. To work around this the server +# can restart its own download with another URL. However, this might be used to +# circumvent download source policies by malicious users. +# The RedirMax option specifies how many such redirects the server should +# follow per request, 0 disables the internal redirection. If not set, +# default value is 0 if ForceManaged is used and 5 otherwise. +# +# RedirMax: 5 From 38380b1a5f0dc2fa6587e874c861f142a50ca7b8 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sun, 30 Mar 2014 18:50:53 +0100 Subject: [PATCH 077/525] Create Vagrant + Chef config for setting up ShareLaTeX --- server-ce/.gitignore | 2 + server-ce/Vagrantfile | 52 ++++ server-ce/chef/.chef/knife.rb | 3 + server-ce/chef/cookbooks/mongodb/CHANGELOG.md | 12 + server-ce/chef/cookbooks/mongodb/README.md | 68 +++++ server-ce/chef/cookbooks/mongodb/metadata.rb | 8 + .../chef/cookbooks/mongodb/recipes/default.rb | 19 ++ server-ce/chef/cookbooks/nodejs/CHANGELOG.md | 12 + server-ce/chef/cookbooks/nodejs/README.md | 68 +++++ server-ce/chef/cookbooks/nodejs/metadata.rb | 8 + .../chef/cookbooks/nodejs/recipes/default.rb | 24 ++ .../chef/cookbooks/redis-server/CHANGELOG.md | 12 + .../chef/cookbooks/redis-server/README.md | 68 +++++ .../chef/cookbooks/redis-server/metadata.rb | 8 + .../cookbooks/redis-server/recipes/default.rb | 20 ++ .../chef/cookbooks/sharelatex/CHANGELOG.md | 12 + server-ce/chef/cookbooks/sharelatex/README.md | 68 +++++ .../chef/cookbooks/sharelatex/metadata.rb | 7 + .../cookbooks/sharelatex/providers/app.rb | 107 +++++++ .../cookbooks/sharelatex/recipes/default.rb | 38 +++ .../cookbooks/sharelatex/resources/app.rb | 11 + .../templates/default/settings.coffee.erb | 268 ++++++++++++++++++ 22 files changed, 895 insertions(+) create mode 100644 server-ce/Vagrantfile create mode 100644 server-ce/chef/.chef/knife.rb create mode 100644 server-ce/chef/cookbooks/mongodb/CHANGELOG.md create mode 100644 server-ce/chef/cookbooks/mongodb/README.md create mode 100644 server-ce/chef/cookbooks/mongodb/metadata.rb create mode 100644 server-ce/chef/cookbooks/mongodb/recipes/default.rb create mode 100644 server-ce/chef/cookbooks/nodejs/CHANGELOG.md create mode 100644 server-ce/chef/cookbooks/nodejs/README.md create mode 100644 server-ce/chef/cookbooks/nodejs/metadata.rb create mode 100644 server-ce/chef/cookbooks/nodejs/recipes/default.rb create mode 100644 server-ce/chef/cookbooks/redis-server/CHANGELOG.md create mode 100644 server-ce/chef/cookbooks/redis-server/README.md create mode 100644 server-ce/chef/cookbooks/redis-server/metadata.rb create mode 100644 server-ce/chef/cookbooks/redis-server/recipes/default.rb create mode 100644 server-ce/chef/cookbooks/sharelatex/CHANGELOG.md create mode 100644 server-ce/chef/cookbooks/sharelatex/README.md create mode 100644 server-ce/chef/cookbooks/sharelatex/metadata.rb create mode 100644 server-ce/chef/cookbooks/sharelatex/providers/app.rb create mode 100644 server-ce/chef/cookbooks/sharelatex/recipes/default.rb create mode 100644 server-ce/chef/cookbooks/sharelatex/resources/app.rb create mode 100644 server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb diff --git a/server-ce/.gitignore b/server-ce/.gitignore index 2b808bda8b..f874ec7375 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -14,3 +14,5 @@ user_files template_files db.sqlite + +.vagrant diff --git a/server-ce/Vagrantfile b/server-ce/Vagrantfile new file mode 100644 index 0000000000..40fa80750f --- /dev/null +++ b/server-ce/Vagrantfile @@ -0,0 +1,52 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + config.vm.box = "ubuntu-12.04" + config.vm.box_url = "http://files.vagrantup.com/precise64.box" + + config.vm.network :forwarded_port, guest: 3000, host: 3000 + + config.ssh.forward_agent = true + + config.vm.provider "virtualbox" do |v| + v.memory = 1024 + end + + config.vm.provision :chef_solo do |chef| + chef.cookbooks_path = "chef/cookbooks" + chef.add_recipe 'redis-server' + chef.add_recipe 'mongodb' + chef.add_recipe 'nodejs' + chef.add_recipe 'sharelatex' + + # You may also specify custom JSON attributes: + chef.json = {} + end + + # Enable provisioning with chef server, specifying the chef server URL, + # and the path to the validation key (relative to this Vagrantfile). + # + # The Opscode Platform uses HTTPS. Substitute your organization for + # ORGNAME in the URL and validation key. + # + # If you have your own Chef Server, use the appropriate URL, which may be + # HTTP instead of HTTPS depending on your configuration. Also change the + # validation key to validation.pem. + # + # config.vm.provision :chef_client do |chef| + # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME" + # chef.validation_key_path = "ORGNAME-validator.pem" + # end + # + # If you're using the Opscode platform, your validator client is + # ORGNAME-validator, replacing ORGNAME with your organization name. + # + # If you have your own Chef Server, the default validation client name is + # chef-validator, unless you changed the configuration. + # + # chef.validation_client_name = "ORGNAME-validator" +end diff --git a/server-ce/chef/.chef/knife.rb b/server-ce/chef/.chef/knife.rb new file mode 100644 index 0000000000..6a49a42b89 --- /dev/null +++ b/server-ce/chef/.chef/knife.rb @@ -0,0 +1,3 @@ +current_dir = File.dirname(__FILE__) +cookbook_path ["#{current_dir}/../cookbooks"] + diff --git a/server-ce/chef/cookbooks/mongodb/CHANGELOG.md b/server-ce/chef/cookbooks/mongodb/CHANGELOG.md new file mode 100644 index 0000000000..5be9eb31c9 --- /dev/null +++ b/server-ce/chef/cookbooks/mongodb/CHANGELOG.md @@ -0,0 +1,12 @@ +# CHANGELOG for mongodb + +This file is used to list changes made in each version of mongodb. + +## 0.1.0: + +* Initial release of mongodb + +- - - +Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. + +The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/server-ce/chef/cookbooks/mongodb/README.md b/server-ce/chef/cookbooks/mongodb/README.md new file mode 100644 index 0000000000..8ea30c6ce4 --- /dev/null +++ b/server-ce/chef/cookbooks/mongodb/README.md @@ -0,0 +1,68 @@ +mongodb Cookbook +================ +TODO: Enter the cookbook description here. + +e.g. +This cookbook makes your favorite breakfast sandwhich. + +Requirements +------------ +TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. + +e.g. +#### packages +- `toaster` - mongodb needs toaster to brown your bagel. + +Attributes +---------- +TODO: List you cookbook attributes here. + +e.g. +#### mongodb::default + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['mongodb']['bacon']Booleanwhether to include bacontrue
+ +Usage +----- +#### mongodb::default +TODO: Write usage instructions for each cookbook. + +e.g. +Just include `mongodb` in your node's `run_list`: + +```json +{ + "name":"my_node", + "run_list": [ + "recipe[mongodb]" + ] +} +``` + +Contributing +------------ +TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. + +e.g. +1. Fork the repository on Github +2. Create a named feature branch (like `add_component_x`) +3. Write you change +4. Write tests for your change (if applicable) +5. Run the tests, ensuring they all pass +6. Submit a Pull Request using Github + +License and Authors +------------------- +Authors: TODO: List authors diff --git a/server-ce/chef/cookbooks/mongodb/metadata.rb b/server-ce/chef/cookbooks/mongodb/metadata.rb new file mode 100644 index 0000000000..2a39cb29c8 --- /dev/null +++ b/server-ce/chef/cookbooks/mongodb/metadata.rb @@ -0,0 +1,8 @@ +name 'mongodb' +maintainer 'ShareLaTeX' +maintainer_email 'team@sharelatex.com' +license 'AGPLv3' +description 'Installs/Configures mongodb' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' +depends 'apt' diff --git a/server-ce/chef/cookbooks/mongodb/recipes/default.rb b/server-ce/chef/cookbooks/mongodb/recipes/default.rb new file mode 100644 index 0000000000..56b251c261 --- /dev/null +++ b/server-ce/chef/cookbooks/mongodb/recipes/default.rb @@ -0,0 +1,19 @@ +# +# Cookbook Name:: mongodb +# Recipe:: default +# +# Copyright 2014, ShareLaTeX +# + +# See http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/ +apt_repository 'mongodb-10gen' do + uri 'http://downloads-distro.mongodb.org/repo/ubuntu-upstart' + distribution 'dist' + components ['10gen'] + keyserver 'keyserver.ubuntu.com' + key '7F0CEB10' +end + +package 'mongodb-10gen' do + action :install +end \ No newline at end of file diff --git a/server-ce/chef/cookbooks/nodejs/CHANGELOG.md b/server-ce/chef/cookbooks/nodejs/CHANGELOG.md new file mode 100644 index 0000000000..8267e4fa26 --- /dev/null +++ b/server-ce/chef/cookbooks/nodejs/CHANGELOG.md @@ -0,0 +1,12 @@ +# CHANGELOG for nodejs + +This file is used to list changes made in each version of nodejs. + +## 0.1.0: + +* Initial release of nodejs + +- - - +Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. + +The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/server-ce/chef/cookbooks/nodejs/README.md b/server-ce/chef/cookbooks/nodejs/README.md new file mode 100644 index 0000000000..daec67045d --- /dev/null +++ b/server-ce/chef/cookbooks/nodejs/README.md @@ -0,0 +1,68 @@ +nodejs Cookbook +=============== +TODO: Enter the cookbook description here. + +e.g. +This cookbook makes your favorite breakfast sandwhich. + +Requirements +------------ +TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. + +e.g. +#### packages +- `toaster` - nodejs needs toaster to brown your bagel. + +Attributes +---------- +TODO: List you cookbook attributes here. + +e.g. +#### nodejs::default + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['nodejs']['bacon']Booleanwhether to include bacontrue
+ +Usage +----- +#### nodejs::default +TODO: Write usage instructions for each cookbook. + +e.g. +Just include `nodejs` in your node's `run_list`: + +```json +{ + "name":"my_node", + "run_list": [ + "recipe[nodejs]" + ] +} +``` + +Contributing +------------ +TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. + +e.g. +1. Fork the repository on Github +2. Create a named feature branch (like `add_component_x`) +3. Write you change +4. Write tests for your change (if applicable) +5. Run the tests, ensuring they all pass +6. Submit a Pull Request using Github + +License and Authors +------------------- +Authors: TODO: List authors diff --git a/server-ce/chef/cookbooks/nodejs/metadata.rb b/server-ce/chef/cookbooks/nodejs/metadata.rb new file mode 100644 index 0000000000..9a3d03ffdf --- /dev/null +++ b/server-ce/chef/cookbooks/nodejs/metadata.rb @@ -0,0 +1,8 @@ +name 'nodejs' +maintainer 'YOUR_COMPANY_NAME' +maintainer_email 'YOUR_EMAIL' +license 'AGPLv3' +description 'Installs/Configures nodejs' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' +depends 'apt' diff --git a/server-ce/chef/cookbooks/nodejs/recipes/default.rb b/server-ce/chef/cookbooks/nodejs/recipes/default.rb new file mode 100644 index 0000000000..3da73c4764 --- /dev/null +++ b/server-ce/chef/cookbooks/nodejs/recipes/default.rb @@ -0,0 +1,24 @@ +# +# Cookbook Name:: nodejs +# Recipe:: default +# +# Copyright 2014, ShareLaTeX +# + +# See https://launchpad.net/~chris-lea/+archive/nodejs +apt_repository 'node.js' do + uri 'http://ppa.launchpad.net/chris-lea/node.js/ubuntu' + distribution node['lsb']['codename'] + components ['main'] + keyserver 'keyserver.ubuntu.com' + key 'C7917B12' +end + +package 'nodejs' do + action :install +end + +execute 'install grunt' do + command "npm install -g grunt-cli" + not_if "npm --no-color -g ls 'grunt-cli' 2> /dev/null | grep 'grunt-cli'" +end \ No newline at end of file diff --git a/server-ce/chef/cookbooks/redis-server/CHANGELOG.md b/server-ce/chef/cookbooks/redis-server/CHANGELOG.md new file mode 100644 index 0000000000..7e2b5bbee2 --- /dev/null +++ b/server-ce/chef/cookbooks/redis-server/CHANGELOG.md @@ -0,0 +1,12 @@ +# CHANGELOG for redis + +This file is used to list changes made in each version of redis. + +## 0.1.0: + +* Initial release of redis + +- - - +Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. + +The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/server-ce/chef/cookbooks/redis-server/README.md b/server-ce/chef/cookbooks/redis-server/README.md new file mode 100644 index 0000000000..d344c7a185 --- /dev/null +++ b/server-ce/chef/cookbooks/redis-server/README.md @@ -0,0 +1,68 @@ +redis Cookbook +============== +TODO: Enter the cookbook description here. + +e.g. +This cookbook makes your favorite breakfast sandwhich. + +Requirements +------------ +TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. + +e.g. +#### packages +- `toaster` - redis needs toaster to brown your bagel. + +Attributes +---------- +TODO: List you cookbook attributes here. + +e.g. +#### redis::default + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['redis']['bacon']Booleanwhether to include bacontrue
+ +Usage +----- +#### redis::default +TODO: Write usage instructions for each cookbook. + +e.g. +Just include `redis` in your node's `run_list`: + +```json +{ + "name":"my_node", + "run_list": [ + "recipe[redis]" + ] +} +``` + +Contributing +------------ +TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. + +e.g. +1. Fork the repository on Github +2. Create a named feature branch (like `add_component_x`) +3. Write you change +4. Write tests for your change (if applicable) +5. Run the tests, ensuring they all pass +6. Submit a Pull Request using Github + +License and Authors +------------------- +Authors: TODO: List authors diff --git a/server-ce/chef/cookbooks/redis-server/metadata.rb b/server-ce/chef/cookbooks/redis-server/metadata.rb new file mode 100644 index 0000000000..41d0512ede --- /dev/null +++ b/server-ce/chef/cookbooks/redis-server/metadata.rb @@ -0,0 +1,8 @@ +name 'redis-server' +maintainer 'ShareLaTeX' +maintainer_email 'team@sharelatex.com' +license 'AGPLv3' +description 'Installs/Configures redis-server' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' +depends 'apt' diff --git a/server-ce/chef/cookbooks/redis-server/recipes/default.rb b/server-ce/chef/cookbooks/redis-server/recipes/default.rb new file mode 100644 index 0000000000..886c6475c4 --- /dev/null +++ b/server-ce/chef/cookbooks/redis-server/recipes/default.rb @@ -0,0 +1,20 @@ +# +# Cookbook Name:: redis +# Recipe:: default +# +# Copyright 2014, ShareLaTeX +# + +# See https://launchpad.net/~chris-lea/+archive/redis-server +apt_repository 'redis-server' do + uri 'http://ppa.launchpad.net/chris-lea/redis-server/ubuntu' + distribution node['lsb']['codename'] + components ['main'] + keyserver 'keyserver.ubuntu.com' + key 'C7917B12' +end + +package 'redis-server' do + action :upgrade + options "--force-yes" +end \ No newline at end of file diff --git a/server-ce/chef/cookbooks/sharelatex/CHANGELOG.md b/server-ce/chef/cookbooks/sharelatex/CHANGELOG.md new file mode 100644 index 0000000000..f6af89fc28 --- /dev/null +++ b/server-ce/chef/cookbooks/sharelatex/CHANGELOG.md @@ -0,0 +1,12 @@ +# CHANGELOG for sharelatex + +This file is used to list changes made in each version of sharelatex. + +## 0.1.0: + +* Initial release of sharelatex + +- - - +Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. + +The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/server-ce/chef/cookbooks/sharelatex/README.md b/server-ce/chef/cookbooks/sharelatex/README.md new file mode 100644 index 0000000000..f47306d8b1 --- /dev/null +++ b/server-ce/chef/cookbooks/sharelatex/README.md @@ -0,0 +1,68 @@ +sharelatex Cookbook +=================== +TODO: Enter the cookbook description here. + +e.g. +This cookbook makes your favorite breakfast sandwhich. + +Requirements +------------ +TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. + +e.g. +#### packages +- `toaster` - sharelatex needs toaster to brown your bagel. + +Attributes +---------- +TODO: List you cookbook attributes here. + +e.g. +#### sharelatex::default + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['sharelatex']['bacon']Booleanwhether to include bacontrue
+ +Usage +----- +#### sharelatex::default +TODO: Write usage instructions for each cookbook. + +e.g. +Just include `sharelatex` in your node's `run_list`: + +```json +{ + "name":"my_node", + "run_list": [ + "recipe[sharelatex]" + ] +} +``` + +Contributing +------------ +TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. + +e.g. +1. Fork the repository on Github +2. Create a named feature branch (like `add_component_x`) +3. Write you change +4. Write tests for your change (if applicable) +5. Run the tests, ensuring they all pass +6. Submit a Pull Request using Github + +License and Authors +------------------- +Authors: TODO: List authors diff --git a/server-ce/chef/cookbooks/sharelatex/metadata.rb b/server-ce/chef/cookbooks/sharelatex/metadata.rb new file mode 100644 index 0000000000..a6562c6cff --- /dev/null +++ b/server-ce/chef/cookbooks/sharelatex/metadata.rb @@ -0,0 +1,7 @@ +name 'sharelatex' +maintainer 'YOUR_COMPANY_NAME' +maintainer_email 'YOUR_EMAIL' +license 'All rights reserved' +description 'Installs/Configures sharelatex' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' diff --git a/server-ce/chef/cookbooks/sharelatex/providers/app.rb b/server-ce/chef/cookbooks/sharelatex/providers/app.rb new file mode 100644 index 0000000000..335dfa1627 --- /dev/null +++ b/server-ce/chef/cookbooks/sharelatex/providers/app.rb @@ -0,0 +1,107 @@ +action :start do + package "git" + package "build-essential" + + r = new_resource + + deploy_to = "/var/www/" + r.name + + node_environment = "production" + + directory deploy_to do + user r.user if r.user + recursive true + end + + env = { + "HOME" => deploy_to + } + + directory "#{deploy_to}/releases" do + user r.user if r.user + recursive true + end + + shared_dir = "#{deploy_to}/shared" + directory shared_dir do + user r.user if r.user + recursive true + end + directory "#{shared_dir}/config" do + user r.user if r.user + recursive true + end + directory "#{shared_dir}/log" do + user r.user if r.user + recursive true + end + + deploy_revision deploy_to do + repository r.repository + revision r.revision + user r.user if r.user + + purge_before_symlink [ + "log", "config", "node_modules" + ] + create_dirs_before_symlink [] + symlinks({ + "log" => "log", + "config" => "config" + }) + symlink_before_migrate({ + "node_modules" => "node_modules" + }) + + environment env + + migrate true + migration_command "npm install; grunt install" + + before_migrate do + directory "#{deploy_to}/shared/node_modules" do + user r.user if r.user + recursive true + end + end + + #notifies :restart, "service[#{r.name}]" + end + + file "/etc/init/#{r.name}.conf" do + content <<-EOS + description "#{r.name}" + author "ShareLaTeX " + + start on started mountall + stop on shutdown + + respawn + + limit nofile 8192 8192 + + script + echo $$ > /var/run/#{r.name}.pid + chdir #{deploy_to}/current + exec sudo -u #{r.user} env NODE_ENV=#{node_environment} SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee node app.js >> log/production.log + end script + EOS + end + + service "#{r.name}" do + provider Chef::Provider::Service::Upstart + action :start + end + + file "/etc/logrotate.d/#{r.name}" do + content <<-EOS + #{deploy_to}/shared/log/*.log { + rotate 7 + size 5M + missingok + compress + copytruncate + } + EOS + end +end \ No newline at end of file diff --git a/server-ce/chef/cookbooks/sharelatex/recipes/default.rb b/server-ce/chef/cookbooks/sharelatex/recipes/default.rb new file mode 100644 index 0000000000..72f4c76b07 --- /dev/null +++ b/server-ce/chef/cookbooks/sharelatex/recipes/default.rb @@ -0,0 +1,38 @@ +# +# Cookbook Name:: sharelatex +# Recipe:: default +# +# Copyright 2014, ShareLaTeX +# + +directory "/etc/sharelatex" + +template "/etc/sharelatex/settings.coffee" do + mode 0400 + user "www-data" +end + +sharelatex_app "web-sharelatex" do + repository "https://github.com/sharelatex/web-sharelatex.git" + revision "master" +end + +sharelatex_app "document-updater-sharelatex" do + repository "https://github.com/sharelatex/document-updater-sharelatex.git" + revision "master" +end + +sharelatex_app "filestore-sharelatex" do + repository "https://github.com/sharelatex/filestore-sharelatex.git" + revision "master" +end + +sharelatex_app "track-changes-sharelatex" do + repository "https://github.com/sharelatex/track-changes-sharelatex.git" + revision "master" +end + +sharelatex_app "clsi-sharelatex" do + repository "https://github.com/sharelatex/clsi-sharelatex.git" + revision "master" +end \ No newline at end of file diff --git a/server-ce/chef/cookbooks/sharelatex/resources/app.rb b/server-ce/chef/cookbooks/sharelatex/resources/app.rb new file mode 100644 index 0000000000..22b4cacf60 --- /dev/null +++ b/server-ce/chef/cookbooks/sharelatex/resources/app.rb @@ -0,0 +1,11 @@ +actions :start + +attribute :revision, :kind_of => String, :default => "master" +attribute :repository, :kind_of => String +attribute :user, :kind_of => String, :default => "www-data" + +def initialize(*args) + super + @action = :start +end + diff --git a/server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb b/server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb new file mode 100644 index 0000000000..ac1a544368 --- /dev/null +++ b/server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb @@ -0,0 +1,268 @@ +Path = require('path') +http = require('http') +http.globalAgent.maxSockets = 300 + +# Make time interval config easier. +seconds = 1000 +minutes = 60 * seconds + +# These credentials are used for authenticating api requests +# between services that may need to go over public channels +httpAuthUser = "sharelatex" +httpAuthPass = "password" +httpAuthUsers = {} +httpAuthUsers[httpAuthUser] = httpAuthPass + +sessionSecret = "secret-please-change" + +module.exports = + # File storage + # ------------ + # + # ShareLaTeX needs somewhere to store binary files like images. + # There are currently two options: + # Your local filesystem (the default) + # Amazon S3 + filestore: + # which backend persistor to use. + # choices are + # s3 - Amazon S3 + # fs - local filesystem + backend: "fs" + stores: + # where to store user and template binary files + # + # For Amazon S3 this is the bucket name to store binary files + # + # For local filesystem this is the directory to store the files in. + # This path must exist, not be tmpfs and be writable to by the user sharelatex is run as. + user_files: Path.resolve(__dirname + "/../user_files") + # Uncomment if you need to configure your S3 credentials + # s3: + # # if you are using S3, then fill in your S3 details below + # key: "" + # secret: "" + + # Databases + # --------- + mongo: + url : 'mongodb://127.0.0.1/sharelatex' + + redis: + web: + host: "localhost" + port: "6379" + password: "" + + api: + host: "localhost" + port: "6379" + password: "" + + mysql: + clsi: + database: "clsi" + username: "clsi" + password: "" + dialect: "sqlite" + storage: Path.resolve(__dirname + "/../db.sqlite") + + # Service locations + # ----------------- + + # Configure which ports to run each service on. Generally you + # can leave these as they are unless you have some other services + # running which conflict, or want to run the web process on port 80. + internal: + web: + port: webPort = 3000 + host: "localhost" + documentupdater: + port: docUpdaterPort = 3003 + host: "localhost" + clsi: + port: clsiPort = 3013 + host: "localhost" + filestore: + port: filestorePort = 3009 + host: "localhost" + trackchanges: + port: trackchangesPort = 3015 + host: "localhost" + + # Tell each service where to find the other services. If everything + # is running locally then this is easy, but they exist as separate config + # options incase you want to run some services on remote hosts. + apis: + web: + url: "http://localhost:#{webPort}" + user: httpAuthUser + pass: httpAuthPass + documentupdater: + url : "http://localhost:#{docUpdaterPort}" + clsi: + url: "http://localhost:#{clsiPort}" + filestore: + url: "http://localhost:#{filestorePort}" + trackchanges: + url: "http://localhost:#{trackchangesPort}" + thirdPartyDataStore: + url : "http://localhost:3002" + emptyProjectFlushDelayMiliseconds: 5 * seconds + tags: + url :"http://localhost:3012" + spelling: + url : "http://localhost:3005" + versioning: + snapshotwaitms:3000 + url: "http://localhost:4000" + username: httpAuthUser + password: httpAuthPass + recurly: + privateKey: "" + apiKey: "" + subdomain: "" + chat: + url: "http://localhost:3010" + templates: + port: 3007 + blog: + port: 3008 + templates_api: + url: "http://localhost:3007" + + # Where your instance of ShareLaTeX can be found publically. Used in emails + # that are sent out, generated links, etc. + siteUrl : 'http://localhost:3000' + + # Same, but with http auth credentials. + httpAuthSiteUrl: 'http://#{httpAuthUser}:#{httpAuthPass}@localhost:3000' + + # Security + # -------- + security: + sessionSecret: sessionSecret + + httpAuthUsers: httpAuthUsers + + # Default features + # ---------------- + # + # You can select the features that are enabled by default for new + # new users. + defaultFeatures: defaultFeatures = + collaborators: -1 + dropbox: true + versioning: true + + plans: plans = [{ + planCode: "personal" + name: "Personal" + price: 0 + features: defaultFeatures + }] + + # Spelling languages + # ------------------ + # + # You must have the corresponding aspell package installed to + # be able to use a language. + languages: [ + {name: "English", code: "en"} + ] + + # Email support + # ------------- + # + # ShareLaTeX uses nodemailer (http://www.nodemailer.com/) to send transactional emails. + # To see the range of transport and options they support, see http://www.nodemailer.com/docs/transports + #email: + # Who should emails be from by default? + # fromAddress: "" + # The default replyTo field, if it should be set + # replyTo: "" + # lifecycle: false + ## Example transport and parameter settings for Amazon SES + # transport: "SES" + # parameters: + # AWSAccessKeyID: "" + # AWSSecretKey: "" + + + # Third party services + # -------------------- + # + # ShareLaTeX's regular newsletter is managed by Markdown mail. Add your + # credentials here to integrate with this. + # markdownmail: + # secret: "" + # list_id: "" + # + # Fill in your unique token from various analytics services to enable + # them. + # analytics: + # mixpanel: + # token: "" + # ga: + # token: "" + # heap: + # token: "" + # + # ShareLaTeX's help desk is provided by tenderapp.com + # tenderUrl: "" + # + + # Production Settings + # ------------------- + + # Should javascript assets be served minified or not. Note that you will + # need to run `grunt compile:minify` within the web-sharelatex directory + # to generate these. + useMinifiedJs: false + + # Should static assets be sent with a header to tell the browser to cache + # them. + cacheStaticAssets: false + + # If you are running ShareLaTeX over https, set this to true to send the + # cookie with a secure flag (recommended). + secureCookie: false + + # Internal configs + # ---------------- + path: + # If we ever need to write something to disk (e.g. incoming requests + # that need processing but may be too big for memory, then write + # them to disk here). + dumpFolder: Path.resolve "data/dumpFolder" + # Where to write the project to disk before running LaTeX on it + compilesDir: Path.resolve(__dirname + "/../compiles") + # Where to cache downloaded URLs for the CLSI + clsiCacheDir: Path.resolve(__dirname + "/../cache") + + # Automatic Snapshots + # ------------------- + automaticSnapshots: + # How long should we wait after the user last edited to + # take a snapshot? + waitTimeAfterLastEdit: 5 * minutes + # Even if edits are still taking place, this is maximum + # time to wait before taking another snapshot. + maxTimeBetweenSnapshots: 30 * minutes + + # Smoke test + # ---------- + # Provide log in credentials and a project to be able to run + # some basic smoke tests to check the core functionality. + # + # smokeTest: + # user: "" + # password: "" + # projectId: "" + + # Filestore health check + # ---------------------- + # Project and file details to check in filestore when calling /health_check + # health_check: + # project_id: "" + # file_id: "" From 5b6eaf546b4f82186454b1cef04bbebbfe5326a3 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 31 Mar 2014 09:40:07 +0100 Subject: [PATCH 078/525] Fix settings to use global directories --- .../chef/cookbooks/sharelatex/providers/app.rb | 9 ++++++++- .../chef/cookbooks/sharelatex/recipes/default.rb | 13 +++++++------ .../templates/default/settings.coffee.erb | 10 +++++----- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/server-ce/chef/cookbooks/sharelatex/providers/app.rb b/server-ce/chef/cookbooks/sharelatex/providers/app.rb index 335dfa1627..499a58cfb1 100644 --- a/server-ce/chef/cookbooks/sharelatex/providers/app.rb +++ b/server-ce/chef/cookbooks/sharelatex/providers/app.rb @@ -65,7 +65,7 @@ action :start do end end - #notifies :restart, "service[#{r.name}]" + notifies :restart, "service[#{r.name}]" end file "/etc/init/#{r.name}.conf" do @@ -88,6 +88,13 @@ action :start do EOS end + directory "/etc/sharelatex" + template "/etc/sharelatex/settings.coffee" do + mode 0400 + user "www-data" + notifies :restart, "service[#{r.name}]" + end + service "#{r.name}" do provider Chef::Provider::Service::Upstart action :start diff --git a/server-ce/chef/cookbooks/sharelatex/recipes/default.rb b/server-ce/chef/cookbooks/sharelatex/recipes/default.rb index 72f4c76b07..e7bb3221b4 100644 --- a/server-ce/chef/cookbooks/sharelatex/recipes/default.rb +++ b/server-ce/chef/cookbooks/sharelatex/recipes/default.rb @@ -5,11 +5,11 @@ # Copyright 2014, ShareLaTeX # -directory "/etc/sharelatex" - -template "/etc/sharelatex/settings.coffee" do - mode 0400 - user "www-data" +for dir in ["compiles", "clsi-cache", "user_files"] do + directory "/var/lib/sharelatex/#{dir}" do + user "www-data" + recursive true + end end sharelatex_app "web-sharelatex" do @@ -35,4 +35,5 @@ end sharelatex_app "clsi-sharelatex" do repository "https://github.com/sharelatex/clsi-sharelatex.git" revision "master" -end \ No newline at end of file +end + diff --git a/server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb b/server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb index ac1a544368..96215179e0 100644 --- a/server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb +++ b/server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb @@ -36,7 +36,7 @@ module.exports = # # For local filesystem this is the directory to store the files in. # This path must exist, not be tmpfs and be writable to by the user sharelatex is run as. - user_files: Path.resolve(__dirname + "/../user_files") + user_files: "/var/lib/sharelatex/user_files" # Uncomment if you need to configure your S3 credentials # s3: # # if you are using S3, then fill in your S3 details below @@ -65,7 +65,7 @@ module.exports = username: "clsi" password: "" dialect: "sqlite" - storage: Path.resolve(__dirname + "/../db.sqlite") + storage: "/var/lib/sharelatex/clsi.sqlite" # Service locations # ----------------- @@ -230,15 +230,15 @@ module.exports = # Internal configs # ---------------- - path: + path: # If we ever need to write something to disk (e.g. incoming requests # that need processing but may be too big for memory, then write # them to disk here). dumpFolder: Path.resolve "data/dumpFolder" # Where to write the project to disk before running LaTeX on it - compilesDir: Path.resolve(__dirname + "/../compiles") + compilesDir: "/var/lib/sharelatex/compiles" # Where to cache downloaded URLs for the CLSI - clsiCacheDir: Path.resolve(__dirname + "/../cache") + clsiCacheDir: "/var/lib/sharelatex/clsi-cache" # Automatic Snapshots # ------------------- From e4be5b4feb9558b01e6cb48225dd6ddbb9c3f28d Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 31 Mar 2014 16:41:13 +0100 Subject: [PATCH 079/525] Add in TeXLive and imagemagick --- server-ce/Vagrantfile | 1 + .../chef/cookbooks/sharelatex/metadata.rb | 1 + .../cookbooks/sharelatex/providers/app.rb | 9 ++- .../cookbooks/sharelatex/recipes/default.rb | 12 +++- .../cookbooks/sharelatex/resources/app.rb | 2 + server-ce/chef/cookbooks/texlive/CHANGELOG.md | 12 ++++ server-ce/chef/cookbooks/texlive/README.md | 68 +++++++++++++++++++ .../cookbooks/texlive/attributes/default.rb | 2 + server-ce/chef/cookbooks/texlive/metadata.rb | 7 ++ .../chef/cookbooks/texlive/recipes/default.rb | 42 ++++++++++++ 10 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 server-ce/chef/cookbooks/texlive/CHANGELOG.md create mode 100644 server-ce/chef/cookbooks/texlive/README.md create mode 100644 server-ce/chef/cookbooks/texlive/attributes/default.rb create mode 100644 server-ce/chef/cookbooks/texlive/metadata.rb create mode 100644 server-ce/chef/cookbooks/texlive/recipes/default.rb diff --git a/server-ce/Vagrantfile b/server-ce/Vagrantfile index 40fa80750f..0f9f595fce 100644 --- a/server-ce/Vagrantfile +++ b/server-ce/Vagrantfile @@ -21,6 +21,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| chef.add_recipe 'redis-server' chef.add_recipe 'mongodb' chef.add_recipe 'nodejs' + chef.add_recipe 'texlive' chef.add_recipe 'sharelatex' # You may also specify custom JSON attributes: diff --git a/server-ce/chef/cookbooks/sharelatex/metadata.rb b/server-ce/chef/cookbooks/sharelatex/metadata.rb index a6562c6cff..319ee0441b 100644 --- a/server-ce/chef/cookbooks/sharelatex/metadata.rb +++ b/server-ce/chef/cookbooks/sharelatex/metadata.rb @@ -5,3 +5,4 @@ license 'All rights reserved' description 'Installs/Configures sharelatex' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '0.1.0' +depends 'texlive' diff --git a/server-ce/chef/cookbooks/sharelatex/providers/app.rb b/server-ce/chef/cookbooks/sharelatex/providers/app.rb index 499a58cfb1..42581bb121 100644 --- a/server-ce/chef/cookbooks/sharelatex/providers/app.rb +++ b/server-ce/chef/cookbooks/sharelatex/providers/app.rb @@ -68,6 +68,11 @@ action :start do notifies :restart, "service[#{r.name}]" end + env = "" + r.environment.each do |key, value| + env += "#{key}=#{value} " + end + file "/etc/init/#{r.name}.conf" do content <<-EOS description "#{r.name}" @@ -83,9 +88,11 @@ action :start do script echo $$ > /var/run/#{r.name}.pid chdir #{deploy_to}/current - exec sudo -u #{r.user} env NODE_ENV=#{node_environment} SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee node app.js >> log/production.log + exec sudo -u #{r.user} env NODE_ENV=#{node_environment} SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee #{env} node app.js >> log/production.log 2>&1 end script EOS + + notifies :restart, "service[#{r.name}]" end directory "/etc/sharelatex" diff --git a/server-ce/chef/cookbooks/sharelatex/recipes/default.rb b/server-ce/chef/cookbooks/sharelatex/recipes/default.rb index e7bb3221b4..0448ef8037 100644 --- a/server-ce/chef/cookbooks/sharelatex/recipes/default.rb +++ b/server-ce/chef/cookbooks/sharelatex/recipes/default.rb @@ -5,9 +5,14 @@ # Copyright 2014, ShareLaTeX # -for dir in ["compiles", "clsi-cache", "user_files"] do +# For filestore conversions +package "imagemagick" +package "optipng" + +for dir in ["", "compiles", "clsi-cache", "user_files"] do directory "/var/lib/sharelatex/#{dir}" do - user "www-data" + user "www-data" + group "www-data" recursive true end end @@ -35,5 +40,8 @@ end sharelatex_app "clsi-sharelatex" do repository "https://github.com/sharelatex/clsi-sharelatex.git" revision "master" + environment({ + "PATH" => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:#{node[:texlive][:bin_dir]}" + }) end diff --git a/server-ce/chef/cookbooks/sharelatex/resources/app.rb b/server-ce/chef/cookbooks/sharelatex/resources/app.rb index 22b4cacf60..3e76eb16f6 100644 --- a/server-ce/chef/cookbooks/sharelatex/resources/app.rb +++ b/server-ce/chef/cookbooks/sharelatex/resources/app.rb @@ -3,6 +3,8 @@ actions :start attribute :revision, :kind_of => String, :default => "master" attribute :repository, :kind_of => String attribute :user, :kind_of => String, :default => "www-data" +attribute :group, :kind_of => String, :default => "www-data" +attribute :environment, :kind_of => Hash, :default => {} def initialize(*args) super diff --git a/server-ce/chef/cookbooks/texlive/CHANGELOG.md b/server-ce/chef/cookbooks/texlive/CHANGELOG.md new file mode 100644 index 0000000000..e1b59f6e0c --- /dev/null +++ b/server-ce/chef/cookbooks/texlive/CHANGELOG.md @@ -0,0 +1,12 @@ +# CHANGELOG for latex + +This file is used to list changes made in each version of latex. + +## 0.1.0: + +* Initial release of latex + +- - - +Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. + +The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/server-ce/chef/cookbooks/texlive/README.md b/server-ce/chef/cookbooks/texlive/README.md new file mode 100644 index 0000000000..06f25ec5e4 --- /dev/null +++ b/server-ce/chef/cookbooks/texlive/README.md @@ -0,0 +1,68 @@ +latex Cookbook +============== +TODO: Enter the cookbook description here. + +e.g. +This cookbook makes your favorite breakfast sandwhich. + +Requirements +------------ +TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. + +e.g. +#### packages +- `toaster` - latex needs toaster to brown your bagel. + +Attributes +---------- +TODO: List you cookbook attributes here. + +e.g. +#### latex::default + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['latex']['bacon']Booleanwhether to include bacontrue
+ +Usage +----- +#### latex::default +TODO: Write usage instructions for each cookbook. + +e.g. +Just include `latex` in your node's `run_list`: + +```json +{ + "name":"my_node", + "run_list": [ + "recipe[latex]" + ] +} +``` + +Contributing +------------ +TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. + +e.g. +1. Fork the repository on Github +2. Create a named feature branch (like `add_component_x`) +3. Write you change +4. Write tests for your change (if applicable) +5. Run the tests, ensuring they all pass +6. Submit a Pull Request using Github + +License and Authors +------------------- +Authors: TODO: List authors diff --git a/server-ce/chef/cookbooks/texlive/attributes/default.rb b/server-ce/chef/cookbooks/texlive/attributes/default.rb new file mode 100644 index 0000000000..a3d2166187 --- /dev/null +++ b/server-ce/chef/cookbooks/texlive/attributes/default.rb @@ -0,0 +1,2 @@ +default[:texlive][:schema] = "small" +default[:texlive][:bin_dir] = "/usr/local/texlive/2013/bin/x86_64-linux" diff --git a/server-ce/chef/cookbooks/texlive/metadata.rb b/server-ce/chef/cookbooks/texlive/metadata.rb new file mode 100644 index 0000000000..ceaaaf2e9c --- /dev/null +++ b/server-ce/chef/cookbooks/texlive/metadata.rb @@ -0,0 +1,7 @@ +name 'texlive' +maintainer 'ShareLaTeX' +maintainer_email 'team@sharelatex.com' +license 'All rights reserved' +description 'Installs/Configures texlive' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' diff --git a/server-ce/chef/cookbooks/texlive/recipes/default.rb b/server-ce/chef/cookbooks/texlive/recipes/default.rb new file mode 100644 index 0000000000..7aab8ef32b --- /dev/null +++ b/server-ce/chef/cookbooks/texlive/recipes/default.rb @@ -0,0 +1,42 @@ +# +# Cookbook Name:: texlive +# Recipe:: default +# +# Copyright 2014, YOUR_COMPANY_NAME +# +# All rights reserved - Do Not Redistribute +# + +remote_file "#{Chef::Config[:file_cache_path]}/install-tl-unx.tar.gz" do + source "http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz" + action :create_if_missing +end + +directory "/install-tl-unx" +bash "extract install-tl" do + cwd Chef::Config[:file_cache_path] + code <<-EOH + tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 + EOH + creates "/install-tl-unx/install-tl" +end + +file "/install-tl-unx/texlive.profile" do + content "selected_scheme scheme-#{node[:texlive][:schema]}" +end + +bash "install texlive" do + cwd "/install-tl-unx" + code <<-EOH + /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile + EOH + creates "#{node[:texlive][:bin_dir]}/pdflatex" +end + +bash "install latexmk" do + environment({ + "PATH" => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:#{node[:texlive][:bin_dir]}" + }) + code "tlmgr install latexmk" + creates "#{node[:texlive][:bin_dir]}/latexmk" +end \ No newline at end of file From 2c2df0bf9ac7f2549efdb1cf3e36022e4e52a7f0 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 31 Mar 2014 17:36:21 +0100 Subject: [PATCH 080/525] Run at the apt cookbook to keep apt up to date --- server-ce/Vagrantfile | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/Vagrantfile b/server-ce/Vagrantfile index 0f9f595fce..f0313e9ccd 100644 --- a/server-ce/Vagrantfile +++ b/server-ce/Vagrantfile @@ -18,6 +18,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.provision :chef_solo do |chef| chef.cookbooks_path = "chef/cookbooks" + chef.add_recipe 'apt' chef.add_recipe 'redis-server' chef.add_recipe 'mongodb' chef.add_recipe 'nodejs' From b97f3bd9343c7992d7eaf553f24dd9805c8d2386 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 9 Apr 2014 10:56:00 +0100 Subject: [PATCH 081/525] Require redis 2.6.12 or greater --- server-ce/Gruntfile.coffee | 6 +++--- server-ce/README.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 3868f235fc..b897077a52 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -178,13 +178,13 @@ module.exports = (grunt) -> error = new Error("Unknown redis version") else version = m[1] - if semver.gt(version, "2.6.0") + if semver.gte(version, "2.6.12") grunt.log.writeln "OK." grunt.log.writeln "Running Redis version #{version}" else grunt.log.error "FAIL." - grunt.log.error "Redis version is too old (#{version}). Must be 2.6.0 or greater." - error = new Error("Redis version is too old (#{version}). Must be 2.6.0 or greater.") + grunt.log.error "Redis version is too old (#{version}). Must be 2.6.12 or greater." + error = new Error("Redis version is too old (#{version}). Must be 2.6.12 or greater.") callback(error) checkLatexmk: (callback = (error) ->) -> diff --git a/server-ce/README.md b/server-ce/README.md index 369ae8ae32..8018001c3b 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -61,7 +61,7 @@ ShareLaTeX should run on OS X and Linux. You need: * [Node.js](http://nodejs.org/) 0.10 or greater. We recommend that you use [nvm](https://github.com/creationix/nvm) to install it. * The [grunt](http://gruntjs.com/) command line tools (Run `npm install -g grunt-cli` to install them) -* A local instance of [Redis](http://redis.io/topics/quickstart) (version 2.6 or later) and [MongoDB](http://docs.mongodb.org/manual/installation/) running on their standard ports. +* A local instance of [Redis](http://redis.io/topics/quickstart) (version 2.6.12 or later) and [MongoDB](http://docs.mongodb.org/manual/installation/) running on their standard ports. * [TeXLive](https://www.tug.org/texlive/) 2013 or later with the `latexmk` program installed. Config From 5b67fc9981f50977d4f2a7e1813b19faab67314d Mon Sep 17 00:00:00 2001 From: David Ediger Date: Fri, 25 Apr 2014 16:17:17 -0400 Subject: [PATCH 082/525] Adding fairy configuration --- server-ce/config/settings.development.coffee.example | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index ac1a544368..a54ae0a9cc 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -59,6 +59,11 @@ module.exports = port: "6379" password: "" + fairy: + host: "localhost" + port: "6379" + password: "" + mysql: clsi: database: "clsi" From 94e683a9a1c0d0076ebffafd8fa8031c54ee5d72 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 29 Apr 2014 12:05:18 +0100 Subject: [PATCH 083/525] Add in docstore --- server-ce/Gruntfile.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index b897077a52..b732143aa4 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -21,6 +21,9 @@ SERVICES = [{ }, { name: "track-changes" repo: "https://github.com/sharelatex/track-changes-sharelatex.git" +}, { + name: "docstore" + repo: "https://github.com/sharelatex/docstore-sharelatex.git" }] module.exports = (grunt) -> From 6bd85467db0a45553807aec3f2a7cae93d1110bf Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 30 Apr 2014 11:16:49 +0100 Subject: [PATCH 084/525] add in docstore to settings --- server-ce/config/settings.development.coffee.example | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index a54ae0a9cc..10c893dd30 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -94,6 +94,9 @@ module.exports = trackchanges: port: trackchangesPort = 3015 host: "localhost" + docstore: + port: docstorePort = 3016 + host: "localhost" # Tell each service where to find the other services. If everything # is running locally then this is easy, but they exist as separate config @@ -111,6 +114,8 @@ module.exports = url: "http://localhost:#{filestorePort}" trackchanges: url: "http://localhost:#{trackchangesPort}" + docstore: + url: "http://localhost:#{docstorePort}" thirdPartyDataStore: url : "http://localhost:3002" emptyProjectFlushDelayMiliseconds: 5 * seconds From 93c151132a2384801bfc85c8ed8dae31ad1c616a Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 30 Apr 2014 11:34:32 +0100 Subject: [PATCH 085/525] Neaten settings --- server-ce/config/settings.development.coffee.example | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index 10c893dd30..4e7e16a3cc 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -184,15 +184,12 @@ module.exports = # Email support # ------------- # - # ShareLaTeX uses nodemailer (http://www.nodemailer.com/) to send transactional emails. - # To see the range of transport and options they support, see http://www.nodemailer.com/docs/transports - #email: - # Who should emails be from by default? + # ShareLaTeX uses nodemailer (http://www.nodemailer.com/) to send transactional emails. + # To see the range of transport and options they support, see http://www.nodemailer.com/docs/transports + # email: # fromAddress: "" - # The default replyTo field, if it should be set # replyTo: "" # lifecycle: false - ## Example transport and parameter settings for Amazon SES # transport: "SES" # parameters: # AWSAccessKeyID: "" From e6d5800f1b7544dfae007634f6ebcbe08628e61e Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 15 May 2014 17:45:24 +0100 Subject: [PATCH 086/525] Start putting together .deb package builder --- server-ce/.gitignore | 1 + server-ce/Gruntfile.coffee | 66 +++++++++++++++++++ server-ce/package/scripts/after_install.sh | 21 ++++++ server-ce/package/upstart/sharelatex-clsi | 19 ++++++ server-ce/package/upstart/sharelatex-docstore | 19 ++++++ .../upstart/sharelatex-document-updater | 19 ++++++ .../package/upstart/sharelatex-filestore | 19 ++++++ server-ce/package/upstart/sharelatex-template | 19 ++++++ .../package/upstart/sharelatex-track-changes | 19 ++++++ server-ce/package/upstart/sharelatex-web | 19 ++++++ 10 files changed, 221 insertions(+) create mode 100644 server-ce/package/scripts/after_install.sh create mode 100644 server-ce/package/upstart/sharelatex-clsi create mode 100644 server-ce/package/upstart/sharelatex-docstore create mode 100644 server-ce/package/upstart/sharelatex-document-updater create mode 100644 server-ce/package/upstart/sharelatex-filestore create mode 100644 server-ce/package/upstart/sharelatex-template create mode 100644 server-ce/package/upstart/sharelatex-track-changes create mode 100644 server-ce/package/upstart/sharelatex-web diff --git a/server-ce/.gitignore b/server-ce/.gitignore index f874ec7375..1e4d53f6b3 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -7,6 +7,7 @@ document-updater clsi filestore track-changes +docstore compiles cache diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index b732143aa4..add7904afb 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -111,6 +111,9 @@ module.exports = (grunt) -> Helpers.checkMake @async() grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3", "check:fs"] + grunt.registerTask "build_deb", "Build an installable .deb file from the current directory", () -> + Helpers.buildDeb @async() + Helpers = installService: (repo_src, dir, callback = (error) ->) -> Helpers.cloneGitRepo repo_src, dir, (error) -> @@ -302,6 +305,69 @@ module.exports = (grunt) -> grunt.log.write "OK." return callback() + buildDeb: (callback = (error) ->) -> + # TODO: filestore uses local 'uploads' directory, not configurable in settings + command = ["fpm", "-s", "dir", "-t", "deb", "-n", "sharelatex", "-v", "0.0.1", "--verbose"] + command.push( + "--maintainer", "'ShareLaTeX '" + "--config-files", "/etc/sharelatex/settings.coffee", + "--directories", "/var/data/sharelatex" + "--directories", "/var/log/sharelatex" + ) + + command.push( + "--depends", "'redis-server > 2.6.12'" + "--depends", "'mongodb-10gen > 2.4.0'" + "--depends", "'nodejs > 0.10.0'" + ) + + template = fs.readFileSync("package/upstart/sharelatex-template").toString() + for service in SERVICES + fs.writeFileSync "package/upstart/sharelatex-#{service.name}", template.replace(/SERVICE/g, service.name) + command.push( + "--deb-upstart", "package/upstart/sharelatex-#{service.name}" + ) + + after_install_script = """ + #!/bin/sh + sudo adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex + + mkdir -p /var/log/sharelatex + chown sharelatex:sharelatex /var/log/sharelatex + + """ + + for dir in ["user_files", "uploads", "compiles", "cache", "dump"] + after_install_script += """ + mkdir -p /var/data/sharelatex/#{dir} + chown sharelatex:sharelatex /var/data/sharelatex/#{dir} + + """ + + for service in SERVICES + after_install_script += "service sharelatex-#{service.name} restart\n" + fs.writeFileSync "package/scripts/after_install.sh", after_install_script + command.push("--after-install", "package/scripts/after_install.sh") + + command.push("--exclude", "'**/.git'") + for path in ["filestore/user_files", "filestore/uploads", "clsi/cache", "clsi/compiles"] + command.push "--exclude", path + + for service in SERVICES + command.push "#{service.name}=/var/www/sharelatex/" + + command.push( + "package/config/settings.coffee=/etc/sharelatex/settings.coffee" + ) + console.log command.join(" ") + exec command.join(" "), (error, stdout, stderr) -> + return callback(error) if error? + console.log stdout + console.error stderr if stderr? + callback() + + + diff --git a/server-ce/package/scripts/after_install.sh b/server-ce/package/scripts/after_install.sh new file mode 100644 index 0000000000..e1dc6ff6fa --- /dev/null +++ b/server-ce/package/scripts/after_install.sh @@ -0,0 +1,21 @@ +#!/bin/sh +sudo adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex + +mkdir -p /var/log/sharelatex +chown sharelatex:sharelatex /var/log/sharelatex +mkdir -p /var/data/sharelatex/user_files +chown sharelatex:sharelatex /var/data/sharelatex/user_files +mkdir -p /var/data/sharelatex/uploads +chown sharelatex:sharelatex /var/data/sharelatex/uploads +mkdir -p /var/data/sharelatex/compiles +chown sharelatex:sharelatex /var/data/sharelatex/compiles +mkdir -p /var/data/sharelatex/cache +chown sharelatex:sharelatex /var/data/sharelatex/cache +mkdir -p /var/data/sharelatex/dump +chown sharelatex:sharelatex /var/data/sharelatex/dump +service sharelatex-web restart +service sharelatex-document-updater restart +service sharelatex-clsi restart +service sharelatex-filestore restart +service sharelatex-track-changes restart +service sharelatex-docstore restart diff --git a/server-ce/package/upstart/sharelatex-clsi b/server-ce/package/upstart/sharelatex-clsi new file mode 100644 index 0000000000..3dfe85b14a --- /dev/null +++ b/server-ce/package/upstart/sharelatex-clsi @@ -0,0 +1,19 @@ +description "sharelatex-clsi" +author "ShareLaTeX " + +start on started mountall +stop on shutdown + +respawn + +limit nofile 8192 8192 + +pre-start script + mkdir -p /var/log/sharelatex +end script + +script + echo $$ > /var/run/sharelatex-clsi.pid + chdir /var/www/sharelatex/clsi + exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/clsi.log 2>&1 +end script diff --git a/server-ce/package/upstart/sharelatex-docstore b/server-ce/package/upstart/sharelatex-docstore new file mode 100644 index 0000000000..542fe550ad --- /dev/null +++ b/server-ce/package/upstart/sharelatex-docstore @@ -0,0 +1,19 @@ +description "sharelatex-docstore" +author "ShareLaTeX " + +start on started mountall +stop on shutdown + +respawn + +limit nofile 8192 8192 + +pre-start script + mkdir -p /var/log/sharelatex +end script + +script + echo $$ > /var/run/sharelatex-docstore.pid + chdir /var/www/sharelatex/docstore + exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/docstore.log 2>&1 +end script diff --git a/server-ce/package/upstart/sharelatex-document-updater b/server-ce/package/upstart/sharelatex-document-updater new file mode 100644 index 0000000000..ef31136031 --- /dev/null +++ b/server-ce/package/upstart/sharelatex-document-updater @@ -0,0 +1,19 @@ +description "sharelatex-document-updater" +author "ShareLaTeX " + +start on started mountall +stop on shutdown + +respawn + +limit nofile 8192 8192 + +pre-start script + mkdir -p /var/log/sharelatex +end script + +script + echo $$ > /var/run/sharelatex-document-updater.pid + chdir /var/www/sharelatex/document-updater + exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/document-updater.log 2>&1 +end script diff --git a/server-ce/package/upstart/sharelatex-filestore b/server-ce/package/upstart/sharelatex-filestore new file mode 100644 index 0000000000..6f5c73bc4f --- /dev/null +++ b/server-ce/package/upstart/sharelatex-filestore @@ -0,0 +1,19 @@ +description "sharelatex-filestore" +author "ShareLaTeX " + +start on started mountall +stop on shutdown + +respawn + +limit nofile 8192 8192 + +pre-start script + mkdir -p /var/log/sharelatex +end script + +script + echo $$ > /var/run/sharelatex-filestore.pid + chdir /var/www/sharelatex/filestore + exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/filestore.log 2>&1 +end script diff --git a/server-ce/package/upstart/sharelatex-template b/server-ce/package/upstart/sharelatex-template new file mode 100644 index 0000000000..f9ed4c6a93 --- /dev/null +++ b/server-ce/package/upstart/sharelatex-template @@ -0,0 +1,19 @@ +description "sharelatex-SERVICE" +author "ShareLaTeX " + +start on started mountall +stop on shutdown + +respawn + +limit nofile 8192 8192 + +pre-start script + mkdir -p /var/log/sharelatex +end script + +script + echo $$ > /var/run/sharelatex-SERVICE.pid + chdir /var/www/sharelatex/SERVICE + exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/SERVICE.log 2>&1 +end script diff --git a/server-ce/package/upstart/sharelatex-track-changes b/server-ce/package/upstart/sharelatex-track-changes new file mode 100644 index 0000000000..2b3b61dfd1 --- /dev/null +++ b/server-ce/package/upstart/sharelatex-track-changes @@ -0,0 +1,19 @@ +description "sharelatex-track-changes" +author "ShareLaTeX " + +start on started mountall +stop on shutdown + +respawn + +limit nofile 8192 8192 + +pre-start script + mkdir -p /var/log/sharelatex +end script + +script + echo $$ > /var/run/sharelatex-track-changes.pid + chdir /var/www/sharelatex/track-changes + exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/track-changes.log 2>&1 +end script diff --git a/server-ce/package/upstart/sharelatex-web b/server-ce/package/upstart/sharelatex-web new file mode 100644 index 0000000000..86d83bba78 --- /dev/null +++ b/server-ce/package/upstart/sharelatex-web @@ -0,0 +1,19 @@ +description "sharelatex-web" +author "ShareLaTeX " + +start on started mountall +stop on shutdown + +respawn + +limit nofile 8192 8192 + +pre-start script + mkdir -p /var/log/sharelatex +end script + +script + echo $$ > /var/run/sharelatex-web.pid + chdir /var/www/sharelatex/web + exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/web.log 2>&1 +end script From 7141afc41362740fd39e60c25af8101ff9f1301c Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 28 May 2014 12:28:43 +0100 Subject: [PATCH 087/525] Use spawn to run fpm --- server-ce/Gruntfile.coffee | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index add7904afb..d5c96773fd 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -307,18 +307,18 @@ module.exports = (grunt) -> buildDeb: (callback = (error) ->) -> # TODO: filestore uses local 'uploads' directory, not configurable in settings - command = ["fpm", "-s", "dir", "-t", "deb", "-n", "sharelatex", "-v", "0.0.1", "--verbose"] + command = ["-s", "dir", "-t", "deb", "-n", "sharelatex", "-v", "0.0.1", "--verbose"] command.push( - "--maintainer", "'ShareLaTeX '" + "--maintainer", "ShareLaTeX " "--config-files", "/etc/sharelatex/settings.coffee", "--directories", "/var/data/sharelatex" "--directories", "/var/log/sharelatex" ) command.push( - "--depends", "'redis-server > 2.6.12'" - "--depends", "'mongodb-10gen > 2.4.0'" - "--depends", "'nodejs > 0.10.0'" + "--depends", "redis-server > 2.6.12" + "--depends", "mongodb-10gen > 2.4.0" + "--depends", "nodejs > 0.10.0" ) template = fs.readFileSync("package/upstart/sharelatex-template").toString() @@ -359,12 +359,9 @@ module.exports = (grunt) -> command.push( "package/config/settings.coffee=/etc/sharelatex/settings.coffee" ) - console.log command.join(" ") - exec command.join(" "), (error, stdout, stderr) -> - return callback(error) if error? - console.log stdout - console.error stderr if stderr? - callback() + console.log "fpm " + command.join(" ") + proc = spawn "fpm", command, stdio: "inherit" + proc.on "close", callback From 70ca95844aa1ea08994d4ad1bfba1a4c21d388ce Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 28 May 2014 12:42:49 +0100 Subject: [PATCH 088/525] Report failed fpm command --- server-ce/Gruntfile.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index d5c96773fd..e983c3ee69 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -361,7 +361,11 @@ module.exports = (grunt) -> ) console.log "fpm " + command.join(" ") proc = spawn "fpm", command, stdio: "inherit" - proc.on "close", callback + proc.on "close", (code) -> + if code != 0 + callback(new Error("exit code: #{code}")) + else + callback() From a6c3b92632c41ea389008d23beeff18da1839868 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 28 May 2014 12:44:53 +0100 Subject: [PATCH 089/525] Don't ignore package/config/settings.coffee --- server-ce/.gitignore | 2 +- server-ce/package/config/settings.coffee | 277 +++++++++++++++++++++++ 2 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 server-ce/package/config/settings.coffee diff --git a/server-ce/.gitignore b/server-ce/.gitignore index 1e4d53f6b3..c370cef045 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -1,4 +1,4 @@ -config +/config config-local node_modules diff --git a/server-ce/package/config/settings.coffee b/server-ce/package/config/settings.coffee new file mode 100644 index 0000000000..e2eb707b2c --- /dev/null +++ b/server-ce/package/config/settings.coffee @@ -0,0 +1,277 @@ +Path = require('path') +http = require('http') +http.globalAgent.maxSockets = 300 + +# Make time interval config easier. +seconds = 1000 +minutes = 60 * seconds + +# These credentials are used for authenticating api requests +# between services that may need to go over public channels +httpAuthUser = "sharelatex" +httpAuthPass = "password" +httpAuthUsers = {} +httpAuthUsers[httpAuthUser] = httpAuthPass + +sessionSecret = "secret-please-change" + +module.exports = + # File storage + # ------------ + # + # ShareLaTeX needs somewhere to store binary files like images. + # There are currently two options: + # Your local filesystem (the default) + # Amazon S3 + filestore: + # which backend persistor to use. + # choices are + # s3 - Amazon S3 + # fs - local filesystem + backend: "fs" + stores: + # where to store user and template binary files + # + # For Amazon S3 this is the bucket name to store binary files + # + # For local filesystem this is the directory to store the files in. + # This path must exist, not be tmpfs and be writable to by the user sharelatex is run as. + user_files: "/var/data/sharelatex/user_files" + # Uncomment if you need to configure your S3 credentials + # s3: + # # if you are using S3, then fill in your S3 details below + # key: "" + # secret: "" + + # Databases + # --------- + mongo: + url : 'mongodb://127.0.0.1/sharelatex' + + redis: + web: + host: "localhost" + port: "6379" + password: "" + + api: + host: "localhost" + port: "6379" + password: "" + + fairy: + host: "localhost" + port: "6379" + password: "" + + mysql: + clsi: + database: "clsi" + username: "clsi" + password: "" + dialect: "sqlite" + storage: "/var/data/sharelatex/clsi_db.sqlite" + + # Service locations + # ----------------- + + # Configure which ports to run each service on. Generally you + # can leave these as they are unless you have some other services + # running which conflict, or want to run the web process on port 80. + internal: + web: + port: webPort = 3000 + host: "localhost" + documentupdater: + port: docUpdaterPort = 3003 + host: "localhost" + clsi: + port: clsiPort = 3013 + host: "localhost" + filestore: + port: filestorePort = 3009 + host: "localhost" + trackchanges: + port: trackchangesPort = 3015 + host: "localhost" + docstore: + port: docstorePort = 3016 + host: "localhost" + + # Tell each service where to find the other services. If everything + # is running locally then this is easy, but they exist as separate config + # options incase you want to run some services on remote hosts. + apis: + web: + url: "http://localhost:#{webPort}" + user: httpAuthUser + pass: httpAuthPass + documentupdater: + url : "http://localhost:#{docUpdaterPort}" + clsi: + url: "http://localhost:#{clsiPort}" + filestore: + url: "http://localhost:#{filestorePort}" + trackchanges: + url: "http://localhost:#{trackchangesPort}" + docstore: + url: "http://localhost:#{docstorePort}" + thirdPartyDataStore: + url : "http://localhost:3002" + emptyProjectFlushDelayMiliseconds: 5 * seconds + tags: + url :"http://localhost:3012" + spelling: + url : "http://localhost:3005" + versioning: + snapshotwaitms:3000 + url: "http://localhost:4000" + username: httpAuthUser + password: httpAuthPass + recurly: + privateKey: "" + apiKey: "" + subdomain: "" + chat: + url: "http://localhost:3010" + templates: + port: 3007 + blog: + port: 3008 + templates_api: + url: "http://localhost:3007" + + # Where your instance of ShareLaTeX can be found publically. Used in emails + # that are sent out, generated links, etc. + siteUrl : 'http://localhost:3000' + + # Same, but with http auth credentials. + httpAuthSiteUrl: 'http://#{httpAuthUser}:#{httpAuthPass}@localhost:3000' + + # Security + # -------- + security: + sessionSecret: sessionSecret + + httpAuthUsers: httpAuthUsers + + # Default features + # ---------------- + # + # You can select the features that are enabled by default for new + # new users. + defaultFeatures: defaultFeatures = + collaborators: -1 + dropbox: true + versioning: true + + plans: plans = [{ + planCode: "personal" + name: "Personal" + price: 0 + features: defaultFeatures + }] + + # Spelling languages + # ------------------ + # + # You must have the corresponding aspell package installed to + # be able to use a language. + languages: [ + {name: "English", code: "en"} + ] + + # Email support + # ------------- + # + # ShareLaTeX uses nodemailer (http://www.nodemailer.com/) to send transactional emails. + # To see the range of transport and options they support, see http://www.nodemailer.com/docs/transports + # email: + # fromAddress: "" + # replyTo: "" + # lifecycle: false + # transport: "SES" + # parameters: + # AWSAccessKeyID: "" + # AWSSecretKey: "" + + + # Third party services + # -------------------- + # + # ShareLaTeX's regular newsletter is managed by Markdown mail. Add your + # credentials here to integrate with this. + # markdownmail: + # secret: "" + # list_id: "" + # + # Fill in your unique token from various analytics services to enable + # them. + # analytics: + # mixpanel: + # token: "" + # ga: + # token: "" + # heap: + # token: "" + # + # ShareLaTeX's help desk is provided by tenderapp.com + # tenderUrl: "" + # + + # Production Settings + # ------------------- + + # Should javascript assets be served minified or not. Note that you will + # need to run `grunt compile:minify` within the web-sharelatex directory + # to generate these. + useMinifiedJs: false + + # Should static assets be sent with a header to tell the browser to cache + # them. + cacheStaticAssets: false + + # If you are running ShareLaTeX over https, set this to true to send the + # cookie with a secure flag (recommended). + secureCookie: false + + # Internal configs + # ---------------- + path: + # If we ever need to write something to disk (e.g. incoming requests + # that need processing but may be too big for memory, then write + # them to disk here). + dumpFolder: "/var/data/sharelatex/dump" + # Where to write the project to disk before running LaTeX on it + compilesDir: "/var/data/sharelatex/compiles" + # Where to cache downloaded URLs for the CLSI + clsiCacheDir: "/var/data/sharelatex/cache" + # Where to write uploads before they are processed + uploadFolder: "/var/data/sharelatex/uploads" + + # Automatic Snapshots + # ------------------- + automaticSnapshots: + # How long should we wait after the user last edited to + # take a snapshot? + waitTimeAfterLastEdit: 5 * minutes + # Even if edits are still taking place, this is maximum + # time to wait before taking another snapshot. + maxTimeBetweenSnapshots: 30 * minutes + + # Smoke test + # ---------- + # Provide log in credentials and a project to be able to run + # some basic smoke tests to check the core functionality. + # + # smokeTest: + # user: "" + # password: "" + # projectId: "" + + # Filestore health check + # ---------------------- + # Project and file details to check in filestore when calling /health_check + # health_check: + # project_id: "" + # file_id: "" From d43fbf89f311dced35074749c24e9a717298d6d5 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 22 Jul 2014 13:40:35 +0100 Subject: [PATCH 090/525] ignore .DS_Store --- server-ce/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/.gitignore b/server-ce/.gitignore index c370cef045..e3c4f14025 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -16,4 +16,5 @@ template_files db.sqlite +.DS_Store .vagrant From 9420522a4858806942935175fe53e759226d69a7 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 11:15:05 +0100 Subject: [PATCH 091/525] Add in mention of chat service --- server-ce/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 8018001c3b..7181fa514d 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -105,7 +105,11 @@ An API for performing CRUD (Create, Read, Update and Delete) operations on binar ### [track-changes](https://github.com/sharelatex/track-changes-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/track-changes-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/track-changes-sharelatex) An API for compressing and storing the updates applied to a document, and then rendering a diff of the changes -between any two time points. *Still in development and not hooked into the UI yet*. +between any two time points. + +### [chat](https://github.com/sharelatex/chat-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/chat-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/chat-sharelatex) + +The backend API for storing and fetching chat messages. Contributing ------------ From 88fcbd62a7d4a1d62b822890ba8b36ba7f4563d2 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 11:16:38 +0100 Subject: [PATCH 092/525] Include mention of docstore service --- server-ce/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 7181fa514d..1adc10a03d 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -97,6 +97,11 @@ modifications. The Common LaTeX Service Interface (CLSI) which provides an API for compiling LaTeX documents. +### [docstore](https://github.com/sharelatex/docstore-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/docstore-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/docstore-sharelatex) + +An API for performing CRUD (Create, Read, Update and Delete) operations on text files +stored in ShareLaTeX. + ### [filestore](https://github.com/sharelatex/filestore-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/filestore-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/filestore-sharelatex) An API for performing CRUD (Create, Read, Update and Delete) operations on binary files From 216ca23162c9ba41e6a456331c060a57192cfd19 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 12:00:39 +0100 Subject: [PATCH 093/525] Add in tags and chat services --- server-ce/.gitignore | 3 +++ server-ce/Gruntfile.coffee | 6 ++++++ .../config/settings.development.coffee.example | 16 +++++++++++----- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/server-ce/.gitignore b/server-ce/.gitignore index e3c4f14025..6fba4033d1 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -8,6 +8,9 @@ clsi filestore track-changes docstore +tags +chat +spelling compiles cache diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index e983c3ee69..e6fcc4fb42 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -24,6 +24,12 @@ SERVICES = [{ }, { name: "docstore" repo: "https://github.com/sharelatex/docstore-sharelatex.git" +}, { + name: "chat" + repo: "https://github.com/sharelatex/chat-sharelatex.git" +}, { + name: "tags" + repo: "https://github.com/sharelatex/tags-sharelatex.git" }] module.exports = (grunt) -> diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index 4e7e16a3cc..91d698ae9a 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -85,12 +85,18 @@ module.exports = documentupdater: port: docUpdaterPort = 3003 host: "localhost" - clsi: - port: clsiPort = 3013 - host: "localhost" filestore: port: filestorePort = 3009 host: "localhost" + chat: + port: chatPort = 3010 + host: "localhost" + tags: + port: tagsPort = 3012 + host: "localhost" + clsi: + port: clsiPort = 3013 + host: "localhost" trackchanges: port: trackchangesPort = 3015 host: "localhost" @@ -120,7 +126,7 @@ module.exports = url : "http://localhost:3002" emptyProjectFlushDelayMiliseconds: 5 * seconds tags: - url :"http://localhost:3012" + url :"http://localhost:#{tagsPort}" spelling: url : "http://localhost:3005" versioning: @@ -133,7 +139,7 @@ module.exports = apiKey: "" subdomain: "" chat: - url: "http://localhost:3010" + url: "http://localhost:#{chatPort}" templates: port: 3007 blog: From d7c50048bb117fac968460df7dfcb5aeb6bec9c4 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 12:02:22 +0100 Subject: [PATCH 094/525] Include tags service --- server-ce/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 1adc10a03d..db5efca1c4 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -116,6 +116,11 @@ between any two time points. The backend API for storing and fetching chat messages. +### [tags](https://github.com/sharelatex/tags-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/tags-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/tags-sharelatex) + +The backend API for managing project tags (folders). + + Contributing ------------ From 810435ef02f764b16a28aa39068d3b7cb7a49021 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 12:39:55 +0100 Subject: [PATCH 095/525] Include spelling --- server-ce/Gruntfile.coffee | 3 +++ server-ce/README.md | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index e6fcc4fb42..ff6c31d390 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -30,6 +30,9 @@ SERVICES = [{ }, { name: "tags" repo: "https://github.com/sharelatex/tags-sharelatex.git" +}, { + name: "spelling" + repo: "https://github.com/sharelatex/spelling-sharelatex.git" }] module.exports = (grunt) -> diff --git a/server-ce/README.md b/server-ce/README.md index db5efca1c4..fb115b1567 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -120,6 +120,10 @@ The backend API for storing and fetching chat messages. The backend API for managing project tags (folders). +### [spelling](https://github.com/sharelatex/spelling-sharelatex) + +An API for running server-side spelling checking on ShareLaTeX documents. + Contributing ------------ From 2876c13402833919a98e4184a70da20749e4a371 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 12:40:27 +0100 Subject: [PATCH 096/525] Ignore /data dir --- server-ce/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/.gitignore b/server-ce/.gitignore index 6fba4033d1..de71076dff 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -16,6 +16,7 @@ compiles cache user_files template_files +data db.sqlite From b8699100ec089802345cfb0e9480d61f79e8dbe4 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 12:57:06 +0100 Subject: [PATCH 097/525] Add in aspell check --- server-ce/Gruntfile.coffee | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index ff6c31d390..b1c5f9e9cf 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -116,9 +116,11 @@ module.exports = (grunt) -> Helpers.checkS3 @async() grunt.registerTask "check:fs", "Check that local filesystem options are configured", () -> Helpers.checkFS @async() + grunt.registerTask "check:aspell", "Check that aspell is installed", () -> + Helpers.checkAspell @async() grunt.registerTask "check:make", "Check that make is installed", () -> Helpers.checkMake @async() - grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3", "check:fs"] + grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3", "check:fs", "check:aspell"] grunt.registerTask "build_deb", "Build an installable .deb file from the current directory", () -> Helpers.buildDeb @async() @@ -235,6 +237,33 @@ module.exports = (grunt) -> """ error = new Error("latexmk is too old") callback(error) + + checkAspell: (callback = (error) ->) -> + grunt.log.write "Checking aspell is installed... " + exec "aspell dump dicts", (error, stdout, stderr) -> + if error? and error.message.match("command not found") + grunt.log.error "FAIL." + grunt.log.errorlns """ + Either aspell is not installed or is not in your PATH. + + On Ubuntu you can install aspell with: + sudo apt-get install aspell + + Or on a mac: + brew install aspell + + This is not a fatal error, but the spell-checker will not work + without aspell + """ + return callback(error) + else if error? + return callback(error) + else + grunt.log.writeln "OK." + grunt.log.writeln "The following spell check dictionaries are available:" + grunt.log.write stdout + callback() + callback(error) checkS3: (callback = (error) ->) -> Settings = require "settings-sharelatex" @@ -269,7 +298,7 @@ module.exports = (grunt) -> Could not connect to Amazon S3. Please check your credentials. """ else - grunt.log.write "OK." + grunt.log.writeln "OK." callback() else grunt.log.writeln "Filestore other than S3 configured. Not checking S3." From bdf4fbb59ac9a0860828fbbad2a0dc7a7316b4d2 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 13:34:57 +0100 Subject: [PATCH 098/525] Set up dev environment with Vagrant --- server-ce/Gruntfile.coffee | 6 +- server-ce/Vagrantfile | 2 +- .../{sharelatex => packages}/README.md | 16 +- server-ce/chef/cookbooks/packages/metadata.rb | 7 + .../cookbooks/packages/recipes/default.rb | 9 + .../chef/cookbooks/sharelatex/CHANGELOG.md | 12 - .../chef/cookbooks/sharelatex/metadata.rb | 8 - .../cookbooks/sharelatex/providers/app.rb | 121 -------- .../cookbooks/sharelatex/recipes/default.rb | 47 --- .../cookbooks/sharelatex/resources/app.rb | 13 - .../templates/default/settings.coffee.erb | 268 ------------------ .../cookbooks/texlive/attributes/default.rb | 2 +- 12 files changed, 29 insertions(+), 482 deletions(-) rename server-ce/chef/cookbooks/{sharelatex => packages}/README.md (81%) create mode 100644 server-ce/chef/cookbooks/packages/metadata.rb create mode 100644 server-ce/chef/cookbooks/packages/recipes/default.rb delete mode 100644 server-ce/chef/cookbooks/sharelatex/CHANGELOG.md delete mode 100644 server-ce/chef/cookbooks/sharelatex/metadata.rb delete mode 100644 server-ce/chef/cookbooks/sharelatex/providers/app.rb delete mode 100644 server-ce/chef/cookbooks/sharelatex/recipes/default.rb delete mode 100644 server-ce/chef/cookbooks/sharelatex/resources/app.rb delete mode 100644 server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index b1c5f9e9cf..e4c04601f3 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -207,7 +207,7 @@ module.exports = (grunt) -> checkLatexmk: (callback = (error) ->) -> grunt.log.write "Checking latexmk is installed... " exec "latexmk --version", (error, stdout, stderr) -> - if error? and error.message.match("command not found") + if error? and error.message.match("not found") grunt.log.error "FAIL." grunt.log.errorlns """ Either latexmk is not installed or is not in your PATH. @@ -241,7 +241,7 @@ module.exports = (grunt) -> checkAspell: (callback = (error) ->) -> grunt.log.write "Checking aspell is installed... " exec "aspell dump dicts", (error, stdout, stderr) -> - if error? and error.message.match("command not found") + if error? and error.message.match("not found") grunt.log.error "FAIL." grunt.log.errorlns """ Either aspell is not installed or is not in your PATH. @@ -326,7 +326,7 @@ module.exports = (grunt) -> checkMake: (callback = (error) ->) -> grunt.log.write "Checking make is installed... " exec "make --version", (error, stdout, stderr) -> - if error? and error.message.match("command not found") + if error? and error.message.match("not found") grunt.log.error "FAIL." grunt.log.errorlns """ Either make is not installed or is not in your path. diff --git a/server-ce/Vagrantfile b/server-ce/Vagrantfile index f0313e9ccd..d46e3a9d6e 100644 --- a/server-ce/Vagrantfile +++ b/server-ce/Vagrantfile @@ -23,7 +23,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| chef.add_recipe 'mongodb' chef.add_recipe 'nodejs' chef.add_recipe 'texlive' - chef.add_recipe 'sharelatex' + chef.add_recipe 'packages' # You may also specify custom JSON attributes: chef.json = {} diff --git a/server-ce/chef/cookbooks/sharelatex/README.md b/server-ce/chef/cookbooks/packages/README.md similarity index 81% rename from server-ce/chef/cookbooks/sharelatex/README.md rename to server-ce/chef/cookbooks/packages/README.md index f47306d8b1..d344c7a185 100644 --- a/server-ce/chef/cookbooks/sharelatex/README.md +++ b/server-ce/chef/cookbooks/packages/README.md @@ -1,5 +1,5 @@ -sharelatex Cookbook -=================== +redis Cookbook +============== TODO: Enter the cookbook description here. e.g. @@ -11,14 +11,14 @@ TODO: List your cookbook requirements. Be sure to include any requirements this e.g. #### packages -- `toaster` - sharelatex needs toaster to brown your bagel. +- `toaster` - redis needs toaster to brown your bagel. Attributes ---------- TODO: List you cookbook attributes here. e.g. -#### sharelatex::default +#### redis::default @@ -27,7 +27,7 @@ e.g. - + @@ -36,17 +36,17 @@ e.g. Usage ----- -#### sharelatex::default +#### redis::default TODO: Write usage instructions for each cookbook. e.g. -Just include `sharelatex` in your node's `run_list`: +Just include `redis` in your node's `run_list`: ```json { "name":"my_node", "run_list": [ - "recipe[sharelatex]" + "recipe[redis]" ] } ``` diff --git a/server-ce/chef/cookbooks/packages/metadata.rb b/server-ce/chef/cookbooks/packages/metadata.rb new file mode 100644 index 0000000000..d3a750d846 --- /dev/null +++ b/server-ce/chef/cookbooks/packages/metadata.rb @@ -0,0 +1,7 @@ +name 'packages' +maintainer 'ShareLaTeX' +maintainer_email 'team@sharelatex.com' +license 'AGPLv3' +description 'Installs/Configures packages' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' diff --git a/server-ce/chef/cookbooks/packages/recipes/default.rb b/server-ce/chef/cookbooks/packages/recipes/default.rb new file mode 100644 index 0000000000..1933cf3951 --- /dev/null +++ b/server-ce/chef/cookbooks/packages/recipes/default.rb @@ -0,0 +1,9 @@ +# +# Cookbook Name:: packages +# Recipe:: default +# +# Copyright 2014, ShareLaTeX +# + +package 'git' +package 'vim' \ No newline at end of file diff --git a/server-ce/chef/cookbooks/sharelatex/CHANGELOG.md b/server-ce/chef/cookbooks/sharelatex/CHANGELOG.md deleted file mode 100644 index f6af89fc28..0000000000 --- a/server-ce/chef/cookbooks/sharelatex/CHANGELOG.md +++ /dev/null @@ -1,12 +0,0 @@ -# CHANGELOG for sharelatex - -This file is used to list changes made in each version of sharelatex. - -## 0.1.0: - -* Initial release of sharelatex - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/server-ce/chef/cookbooks/sharelatex/metadata.rb b/server-ce/chef/cookbooks/sharelatex/metadata.rb deleted file mode 100644 index 319ee0441b..0000000000 --- a/server-ce/chef/cookbooks/sharelatex/metadata.rb +++ /dev/null @@ -1,8 +0,0 @@ -name 'sharelatex' -maintainer 'YOUR_COMPANY_NAME' -maintainer_email 'YOUR_EMAIL' -license 'All rights reserved' -description 'Installs/Configures sharelatex' -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '0.1.0' -depends 'texlive' diff --git a/server-ce/chef/cookbooks/sharelatex/providers/app.rb b/server-ce/chef/cookbooks/sharelatex/providers/app.rb deleted file mode 100644 index 42581bb121..0000000000 --- a/server-ce/chef/cookbooks/sharelatex/providers/app.rb +++ /dev/null @@ -1,121 +0,0 @@ -action :start do - package "git" - package "build-essential" - - r = new_resource - - deploy_to = "/var/www/" + r.name - - node_environment = "production" - - directory deploy_to do - user r.user if r.user - recursive true - end - - env = { - "HOME" => deploy_to - } - - directory "#{deploy_to}/releases" do - user r.user if r.user - recursive true - end - - shared_dir = "#{deploy_to}/shared" - directory shared_dir do - user r.user if r.user - recursive true - end - directory "#{shared_dir}/config" do - user r.user if r.user - recursive true - end - directory "#{shared_dir}/log" do - user r.user if r.user - recursive true - end - - deploy_revision deploy_to do - repository r.repository - revision r.revision - user r.user if r.user - - purge_before_symlink [ - "log", "config", "node_modules" - ] - create_dirs_before_symlink [] - symlinks({ - "log" => "log", - "config" => "config" - }) - symlink_before_migrate({ - "node_modules" => "node_modules" - }) - - environment env - - migrate true - migration_command "npm install; grunt install" - - before_migrate do - directory "#{deploy_to}/shared/node_modules" do - user r.user if r.user - recursive true - end - end - - notifies :restart, "service[#{r.name}]" - end - - env = "" - r.environment.each do |key, value| - env += "#{key}=#{value} " - end - - file "/etc/init/#{r.name}.conf" do - content <<-EOS - description "#{r.name}" - author "ShareLaTeX " - - start on started mountall - stop on shutdown - - respawn - - limit nofile 8192 8192 - - script - echo $$ > /var/run/#{r.name}.pid - chdir #{deploy_to}/current - exec sudo -u #{r.user} env NODE_ENV=#{node_environment} SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee #{env} node app.js >> log/production.log 2>&1 - end script - EOS - - notifies :restart, "service[#{r.name}]" - end - - directory "/etc/sharelatex" - template "/etc/sharelatex/settings.coffee" do - mode 0400 - user "www-data" - notifies :restart, "service[#{r.name}]" - end - - service "#{r.name}" do - provider Chef::Provider::Service::Upstart - action :start - end - - file "/etc/logrotate.d/#{r.name}" do - content <<-EOS - #{deploy_to}/shared/log/*.log { - rotate 7 - size 5M - missingok - compress - copytruncate - } - EOS - end -end \ No newline at end of file diff --git a/server-ce/chef/cookbooks/sharelatex/recipes/default.rb b/server-ce/chef/cookbooks/sharelatex/recipes/default.rb deleted file mode 100644 index 0448ef8037..0000000000 --- a/server-ce/chef/cookbooks/sharelatex/recipes/default.rb +++ /dev/null @@ -1,47 +0,0 @@ -# -# Cookbook Name:: sharelatex -# Recipe:: default -# -# Copyright 2014, ShareLaTeX -# - -# For filestore conversions -package "imagemagick" -package "optipng" - -for dir in ["", "compiles", "clsi-cache", "user_files"] do - directory "/var/lib/sharelatex/#{dir}" do - user "www-data" - group "www-data" - recursive true - end -end - -sharelatex_app "web-sharelatex" do - repository "https://github.com/sharelatex/web-sharelatex.git" - revision "master" -end - -sharelatex_app "document-updater-sharelatex" do - repository "https://github.com/sharelatex/document-updater-sharelatex.git" - revision "master" -end - -sharelatex_app "filestore-sharelatex" do - repository "https://github.com/sharelatex/filestore-sharelatex.git" - revision "master" -end - -sharelatex_app "track-changes-sharelatex" do - repository "https://github.com/sharelatex/track-changes-sharelatex.git" - revision "master" -end - -sharelatex_app "clsi-sharelatex" do - repository "https://github.com/sharelatex/clsi-sharelatex.git" - revision "master" - environment({ - "PATH" => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:#{node[:texlive][:bin_dir]}" - }) -end - diff --git a/server-ce/chef/cookbooks/sharelatex/resources/app.rb b/server-ce/chef/cookbooks/sharelatex/resources/app.rb deleted file mode 100644 index 3e76eb16f6..0000000000 --- a/server-ce/chef/cookbooks/sharelatex/resources/app.rb +++ /dev/null @@ -1,13 +0,0 @@ -actions :start - -attribute :revision, :kind_of => String, :default => "master" -attribute :repository, :kind_of => String -attribute :user, :kind_of => String, :default => "www-data" -attribute :group, :kind_of => String, :default => "www-data" -attribute :environment, :kind_of => Hash, :default => {} - -def initialize(*args) - super - @action = :start -end - diff --git a/server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb b/server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb deleted file mode 100644 index 96215179e0..0000000000 --- a/server-ce/chef/cookbooks/sharelatex/templates/default/settings.coffee.erb +++ /dev/null @@ -1,268 +0,0 @@ -Path = require('path') -http = require('http') -http.globalAgent.maxSockets = 300 - -# Make time interval config easier. -seconds = 1000 -minutes = 60 * seconds - -# These credentials are used for authenticating api requests -# between services that may need to go over public channels -httpAuthUser = "sharelatex" -httpAuthPass = "password" -httpAuthUsers = {} -httpAuthUsers[httpAuthUser] = httpAuthPass - -sessionSecret = "secret-please-change" - -module.exports = - # File storage - # ------------ - # - # ShareLaTeX needs somewhere to store binary files like images. - # There are currently two options: - # Your local filesystem (the default) - # Amazon S3 - filestore: - # which backend persistor to use. - # choices are - # s3 - Amazon S3 - # fs - local filesystem - backend: "fs" - stores: - # where to store user and template binary files - # - # For Amazon S3 this is the bucket name to store binary files - # - # For local filesystem this is the directory to store the files in. - # This path must exist, not be tmpfs and be writable to by the user sharelatex is run as. - user_files: "/var/lib/sharelatex/user_files" - # Uncomment if you need to configure your S3 credentials - # s3: - # # if you are using S3, then fill in your S3 details below - # key: "" - # secret: "" - - # Databases - # --------- - mongo: - url : 'mongodb://127.0.0.1/sharelatex' - - redis: - web: - host: "localhost" - port: "6379" - password: "" - - api: - host: "localhost" - port: "6379" - password: "" - - mysql: - clsi: - database: "clsi" - username: "clsi" - password: "" - dialect: "sqlite" - storage: "/var/lib/sharelatex/clsi.sqlite" - - # Service locations - # ----------------- - - # Configure which ports to run each service on. Generally you - # can leave these as they are unless you have some other services - # running which conflict, or want to run the web process on port 80. - internal: - web: - port: webPort = 3000 - host: "localhost" - documentupdater: - port: docUpdaterPort = 3003 - host: "localhost" - clsi: - port: clsiPort = 3013 - host: "localhost" - filestore: - port: filestorePort = 3009 - host: "localhost" - trackchanges: - port: trackchangesPort = 3015 - host: "localhost" - - # Tell each service where to find the other services. If everything - # is running locally then this is easy, but they exist as separate config - # options incase you want to run some services on remote hosts. - apis: - web: - url: "http://localhost:#{webPort}" - user: httpAuthUser - pass: httpAuthPass - documentupdater: - url : "http://localhost:#{docUpdaterPort}" - clsi: - url: "http://localhost:#{clsiPort}" - filestore: - url: "http://localhost:#{filestorePort}" - trackchanges: - url: "http://localhost:#{trackchangesPort}" - thirdPartyDataStore: - url : "http://localhost:3002" - emptyProjectFlushDelayMiliseconds: 5 * seconds - tags: - url :"http://localhost:3012" - spelling: - url : "http://localhost:3005" - versioning: - snapshotwaitms:3000 - url: "http://localhost:4000" - username: httpAuthUser - password: httpAuthPass - recurly: - privateKey: "" - apiKey: "" - subdomain: "" - chat: - url: "http://localhost:3010" - templates: - port: 3007 - blog: - port: 3008 - templates_api: - url: "http://localhost:3007" - - # Where your instance of ShareLaTeX can be found publically. Used in emails - # that are sent out, generated links, etc. - siteUrl : 'http://localhost:3000' - - # Same, but with http auth credentials. - httpAuthSiteUrl: 'http://#{httpAuthUser}:#{httpAuthPass}@localhost:3000' - - # Security - # -------- - security: - sessionSecret: sessionSecret - - httpAuthUsers: httpAuthUsers - - # Default features - # ---------------- - # - # You can select the features that are enabled by default for new - # new users. - defaultFeatures: defaultFeatures = - collaborators: -1 - dropbox: true - versioning: true - - plans: plans = [{ - planCode: "personal" - name: "Personal" - price: 0 - features: defaultFeatures - }] - - # Spelling languages - # ------------------ - # - # You must have the corresponding aspell package installed to - # be able to use a language. - languages: [ - {name: "English", code: "en"} - ] - - # Email support - # ------------- - # - # ShareLaTeX uses nodemailer (http://www.nodemailer.com/) to send transactional emails. - # To see the range of transport and options they support, see http://www.nodemailer.com/docs/transports - #email: - # Who should emails be from by default? - # fromAddress: "" - # The default replyTo field, if it should be set - # replyTo: "" - # lifecycle: false - ## Example transport and parameter settings for Amazon SES - # transport: "SES" - # parameters: - # AWSAccessKeyID: "" - # AWSSecretKey: "" - - - # Third party services - # -------------------- - # - # ShareLaTeX's regular newsletter is managed by Markdown mail. Add your - # credentials here to integrate with this. - # markdownmail: - # secret: "" - # list_id: "" - # - # Fill in your unique token from various analytics services to enable - # them. - # analytics: - # mixpanel: - # token: "" - # ga: - # token: "" - # heap: - # token: "" - # - # ShareLaTeX's help desk is provided by tenderapp.com - # tenderUrl: "" - # - - # Production Settings - # ------------------- - - # Should javascript assets be served minified or not. Note that you will - # need to run `grunt compile:minify` within the web-sharelatex directory - # to generate these. - useMinifiedJs: false - - # Should static assets be sent with a header to tell the browser to cache - # them. - cacheStaticAssets: false - - # If you are running ShareLaTeX over https, set this to true to send the - # cookie with a secure flag (recommended). - secureCookie: false - - # Internal configs - # ---------------- - path: - # If we ever need to write something to disk (e.g. incoming requests - # that need processing but may be too big for memory, then write - # them to disk here). - dumpFolder: Path.resolve "data/dumpFolder" - # Where to write the project to disk before running LaTeX on it - compilesDir: "/var/lib/sharelatex/compiles" - # Where to cache downloaded URLs for the CLSI - clsiCacheDir: "/var/lib/sharelatex/clsi-cache" - - # Automatic Snapshots - # ------------------- - automaticSnapshots: - # How long should we wait after the user last edited to - # take a snapshot? - waitTimeAfterLastEdit: 5 * minutes - # Even if edits are still taking place, this is maximum - # time to wait before taking another snapshot. - maxTimeBetweenSnapshots: 30 * minutes - - # Smoke test - # ---------- - # Provide log in credentials and a project to be able to run - # some basic smoke tests to check the core functionality. - # - # smokeTest: - # user: "" - # password: "" - # projectId: "" - - # Filestore health check - # ---------------------- - # Project and file details to check in filestore when calling /health_check - # health_check: - # project_id: "" - # file_id: "" diff --git a/server-ce/chef/cookbooks/texlive/attributes/default.rb b/server-ce/chef/cookbooks/texlive/attributes/default.rb index a3d2166187..b9941626e4 100644 --- a/server-ce/chef/cookbooks/texlive/attributes/default.rb +++ b/server-ce/chef/cookbooks/texlive/attributes/default.rb @@ -1,2 +1,2 @@ default[:texlive][:schema] = "small" -default[:texlive][:bin_dir] = "/usr/local/texlive/2013/bin/x86_64-linux" +default[:texlive][:bin_dir] = "/usr/local/texlive/2014/bin/x86_64-linux" From bbd3f92fcc8a83662928ab9f13f88bcac7c68e47 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 13:36:32 +0100 Subject: [PATCH 099/525] Include build-essentials --- server-ce/Gruntfile.coffee | 8 +++++--- server-ce/chef/cookbooks/packages/recipes/default.rb | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index e4c04601f3..f97ee5c0c2 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -247,9 +247,11 @@ module.exports = (grunt) -> Either aspell is not installed or is not in your PATH. On Ubuntu you can install aspell with: + sudo apt-get install aspell Or on a mac: + brew install aspell This is not a fatal error, but the spell-checker will not work @@ -330,11 +332,11 @@ module.exports = (grunt) -> grunt.log.error "FAIL." grunt.log.errorlns """ Either make is not installed or is not in your path. - + On Ubuntu you can install make with: - + sudo apt-get install build-essential - + """ return callback(error) else if error? diff --git a/server-ce/chef/cookbooks/packages/recipes/default.rb b/server-ce/chef/cookbooks/packages/recipes/default.rb index 1933cf3951..f1c9024aad 100644 --- a/server-ce/chef/cookbooks/packages/recipes/default.rb +++ b/server-ce/chef/cookbooks/packages/recipes/default.rb @@ -6,4 +6,5 @@ # package 'git' -package 'vim' \ No newline at end of file +package 'vim' +package 'build-essential' \ No newline at end of file From 2287335dcf1b118eb553fca2165668d34fb85507 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 13:44:21 +0100 Subject: [PATCH 100/525] Update message format --- server-ce/Gruntfile.coffee | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index f97ee5c0c2..c0274039c0 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -213,7 +213,12 @@ module.exports = (grunt) -> Either latexmk is not installed or is not in your PATH. latexmk comes with TexLive 2013, and must be a version from 2013 or later. - This is a not a fatal error, but compiling will not work without latexmk + If you have already have TeXLive installed, then make sure it is + included in your PATH (example for 64-bit linux): + + export PATH=$PATH:/usr/local/texlive/2014/bin/x86_64-linux/ + + This is a not a fatal error, but compiling will not work without latexmk. """ return callback(error) else if error? @@ -254,8 +259,7 @@ module.exports = (grunt) -> brew install aspell - This is not a fatal error, but the spell-checker will not work - without aspell + This is not a fatal error, but the spell-checker will not work without aspell """ return callback(error) else if error? From fee8260a9c49ea1eb1c0d2185d915c18eacce9fe Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 13:45:26 +0100 Subject: [PATCH 101/525] Update formatting of fs check message --- server-ce/Gruntfile.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index c0274039c0..05611ab60d 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -313,11 +313,11 @@ module.exports = (grunt) -> checkFS: (callback = (error) ->) -> Settings = require "settings-sharelatex" if Settings.filestore.backend=="fs" - grunt.log.write "Checking FS configuration..." + grunt.log.write "Checking FS configuration... " fs = require("fs") fs.exists Settings.filestore.stores.user_files, (exists) -> if exists - grunt.log.write "OK." + grunt.log.writeln "OK." else grunt.log.error "FAIL." grunt.log.errorlns """ From 28e86453644e71663a559432b6dfb12bfbee4351 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 13:46:06 +0100 Subject: [PATCH 102/525] Update formatting of fs check message --- server-ce/Gruntfile.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 05611ab60d..1975c3f22a 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -324,10 +324,10 @@ module.exports = (grunt) -> Could not find directory "#{Settings.filestore.stores.user_files}". Please check your configuration. """ + callback() else grunt.log.writeln "Filestore other than FS configured. Not checking FS." - callback() - + callback() checkMake: (callback = (error) ->) -> grunt.log.write "Checking make is installed... " From 9e99bd835fbe6b0b08a2645e1a615d8f2777d922 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 15 Aug 2014 15:05:07 +0100 Subject: [PATCH 103/525] Update default config to be more sane --- server-ce/.gitignore | 5 +- server-ce/Gruntfile.coffee | 36 +- .../settings.development.coffee.example | 398 ++++++++---------- server-ce/package.json | 1 + server-ce/user_files/.gitignore | 0 5 files changed, 201 insertions(+), 239 deletions(-) delete mode 100644 server-ce/user_files/.gitignore diff --git a/server-ce/.gitignore b/server-ce/.gitignore index de71076dff..8dd120550d 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -12,11 +12,8 @@ tags chat spelling -compiles -cache -user_files -template_files data +tmp db.sqlite diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 1975c3f22a..f676cfbad1 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -5,6 +5,8 @@ rimraf = require "rimraf" Path = require "path" semver = require "semver" knox = require "knox" +crypto = require "crypto" +async = require "async" SERVICES = [{ name: "web" @@ -75,7 +77,7 @@ module.exports = (grunt) -> "Misc": [ "help" ] - "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install", "install:config"]) + "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install", "install:dirs", "install:config"]) "Update tasks": ("update:#{service.name}" for service in SERVICES).concat(["update:all", "update"]) "Config tasks": ["install:config"] "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make"] @@ -92,6 +94,8 @@ module.exports = (grunt) -> grunt.registerTask 'install:config', "Copy the example config into the real config", () -> Helpers.installConfig @async() + grunt.registerTask 'install:dirs', "Copy the example config into the real config", () -> + Helpers.createDataDirs @async() grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", ["check:make"].concat( ("install:#{service.name}" for service in SERVICES) @@ -164,12 +168,34 @@ module.exports = (grunt) -> proc = spawn "npm", ["install"], stdio: "inherit", cwd: dir proc.on "close", () -> callback() + + createDataDirs: (callback = (error) ->) -> + DIRS = [ + "tmp/dumpFolder" + "tmp/uploads" + "data/user_files" + "data/compiles" + "data/cache" + ] + jobs = [] + for dir in DIRS + do (dir) -> + jobs.push (callback) -> + path = Path.join(__dirname, dir) + grunt.log.writeln "Ensuring '#{path}' exists" + exec "mkdir -p #{path}", callback + async.series jobs, callback installConfig: (callback = (error) ->) -> - if !fs.existsSync("config/settings.development.coffee") - grunt.log.writeln "Copying example config into config/settings.development.coffee" - exec "cp config/settings.development.coffee.example config/settings.development.coffee", (error, stdout, stderr) -> - callback(error) + src = "config/settings.development.coffee.example" + dest = "config/settings.development.coffee" + if !fs.existsSync(dest) + grunt.log.writeln "Creating config at #{dest}" + config = fs.readFileSync(src).toString() + config = config.replace /CRYPTO_RANDOM/g, () -> + crypto.randomBytes(64).toString("hex") + fs.writeFileSync dest, config + callback() else grunt.log.writeln "Config file already exists. Skipping." callback() diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index 91d698ae9a..c51e2be595 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -1,281 +1,219 @@ Path = require('path') -http = require('http') -http.globalAgent.maxSockets = 300 - -# Make time interval config easier. -seconds = 1000 -minutes = 60 * seconds # These credentials are used for authenticating api requests # between services that may need to go over public channels httpAuthUser = "sharelatex" -httpAuthPass = "password" +httpAuthPass = "CRYPTO_RANDOM" # Randomly generated for you httpAuthUsers = {} httpAuthUsers[httpAuthUser] = httpAuthPass -sessionSecret = "secret-please-change" +DATA_DIR = Path.resolve(Path.join(__dirname, "..", "data")) +TMP_DIR = Path.resolve(Path.join(__dirname, "..", "tmp")) module.exports = - # File storage - # ------------ - # - # ShareLaTeX needs somewhere to store binary files like images. - # There are currently two options: - # Your local filesystem (the default) - # Amazon S3 - filestore: - # which backend persistor to use. - # choices are - # s3 - Amazon S3 - # fs - local filesystem - backend: "fs" - stores: - # where to store user and template binary files - # - # For Amazon S3 this is the bucket name to store binary files - # - # For local filesystem this is the directory to store the files in. - # This path must exist, not be tmpfs and be writable to by the user sharelatex is run as. - user_files: Path.resolve(__dirname + "/../user_files") - # Uncomment if you need to configure your S3 credentials - # s3: - # # if you are using S3, then fill in your S3 details below - # key: "" - # secret: "" - # Databases # --------- + + # ShareLaTeX's main persistant data store is MongoDB (http://www.mongodb.org/) + # Documentation about the URL connection string format can be found at: + # + # http://docs.mongodb.org/manual/reference/connection-string/ + # + # The following works out of the box with Mongo's default settings: mongo: url : 'mongodb://127.0.0.1/sharelatex' + # Redis is used in ShareLaTeX for high volume queries, like real-time + # editing, and session management. + # + # The following config will work with Redis's default settings: redis: web: host: "localhost" port: "6379" password: "" - api: - host: "localhost" - port: "6379" - password: "" - - fairy: - host: "localhost" - port: "6379" - password: "" - + # The compile server (the clsi) uses a SQL database to cache files and + # meta-data. sqllite is the default, and the load is low enough that this will + # be fine in production (we use sqllite at sharelatex.com). + # + # If you want to configure a different database, see the Sequelize documentation + # for available options: + # + # https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage + # mysql: clsi: database: "clsi" username: "clsi" password: "" dialect: "sqlite" - storage: Path.resolve(__dirname + "/../db.sqlite") + storage: Path.join(DATA_DIR, "db.sqlite") - # Service locations - # ----------------- + # File storage + # ------------ - # Configure which ports to run each service on. Generally you - # can leave these as they are unless you have some other services - # running which conflict, or want to run the web process on port 80. - internal: - web: - port: webPort = 3000 - host: "localhost" - documentupdater: - port: docUpdaterPort = 3003 - host: "localhost" - filestore: - port: filestorePort = 3009 - host: "localhost" - chat: - port: chatPort = 3010 - host: "localhost" - tags: - port: tagsPort = 3012 - host: "localhost" - clsi: - port: clsiPort = 3013 - host: "localhost" - trackchanges: - port: trackchangesPort = 3015 - host: "localhost" - docstore: - port: docstorePort = 3016 - host: "localhost" - - # Tell each service where to find the other services. If everything - # is running locally then this is easy, but they exist as separate config - # options incase you want to run some services on remote hosts. - apis: - web: - url: "http://localhost:#{webPort}" - user: httpAuthUser - pass: httpAuthPass - documentupdater: - url : "http://localhost:#{docUpdaterPort}" - clsi: - url: "http://localhost:#{clsiPort}" - filestore: - url: "http://localhost:#{filestorePort}" - trackchanges: - url: "http://localhost:#{trackchangesPort}" - docstore: - url: "http://localhost:#{docstorePort}" - thirdPartyDataStore: - url : "http://localhost:3002" - emptyProjectFlushDelayMiliseconds: 5 * seconds - tags: - url :"http://localhost:#{tagsPort}" - spelling: - url : "http://localhost:3005" - versioning: - snapshotwaitms:3000 - url: "http://localhost:4000" - username: httpAuthUser - password: httpAuthPass - recurly: - privateKey: "" - apiKey: "" - subdomain: "" - chat: - url: "http://localhost:#{chatPort}" - templates: - port: 3007 - blog: - port: 3008 - templates_api: - url: "http://localhost:3007" - - # Where your instance of ShareLaTeX can be found publically. Used in emails - # that are sent out, generated links, etc. - siteUrl : 'http://localhost:3000' - - # Same, but with http auth credentials. - httpAuthSiteUrl: 'http://#{httpAuthUser}:#{httpAuthPass}@localhost:3000' - - # Security - # -------- - security: - sessionSecret: sessionSecret - - httpAuthUsers: httpAuthUsers - - # Default features - # ---------------- + # ShareLaTeX can store binary files like images either locally or in Amazon + # S3. The default is locally: + filestore: + backend: "fs" + stores: + user_files: Path.join(DATA_DIR, "user_files") + + # To use Amazon S3 as a storage backend, comment out the above config, and + # uncomment the following, filling in your key, secret, and bucket name: # - # You can select the features that are enabled by default for new - # new users. - defaultFeatures: defaultFeatures = - collaborators: -1 - dropbox: true - versioning: true + # filestore: + # backend: "s3" + # stores: + # user_files: "BUCKET_NAME" + # s3: + # key: "AWS_KEY" + # secret: "AWS_SECRET" + # - plans: plans = [{ - planCode: "personal" - name: "Personal" - price: 0 - features: defaultFeatures - }] - - # Spelling languages + # Local disk caching # ------------------ - # - # You must have the corresponding aspell package installed to - # be able to use a language. - languages: [ - {name: "English", code: "en"} - ] + path: + # If we ever need to write something to disk (e.g. incoming requests + # that need processing but may be too big for memory), then write + # them to disk here: + dumpFolder: Path.join(TMP_DIR, "dumpFolder") + # Where to write uploads before they are processed + uploadFolder: Path.join(TMP_DIR, "uploads") + # Where to write the project to disk before running LaTeX on it + compilesDir: Path.join(DATA_DIR, "compiles") + # Where to cache downloaded URLs for the CLSI + clsiCacheDir: Path.join(DATA_DIR, "cache") - # Email support + # Server Config # ------------- - # - # ShareLaTeX uses nodemailer (http://www.nodemailer.com/) to send transactional emails. - # To see the range of transport and options they support, see http://www.nodemailer.com/docs/transports - # email: - # fromAddress: "" - # replyTo: "" - # lifecycle: false - # transport: "SES" - # parameters: - # AWSAccessKeyID: "" - # AWSSecretKey: "" + # Where your instance of ShareLaTeX can be found publicly. This is used + # when emails are sent out and in generated links: + siteUrl : 'http://localhost:3000' + + # If provided, a sessionSecret is used to sign cookies so that they cannot be + # spoofed. This is recommended. + security: + sessionSecret: "CRYPTO_RANDOM" # This was randomly generated for you - # Third party services - # -------------------- - # - # ShareLaTeX's regular newsletter is managed by Markdown mail. Add your - # credentials here to integrate with this. - # markdownmail: - # secret: "" - # list_id: "" - # - # Fill in your unique token from various analytics services to enable - # them. - # analytics: - # mixpanel: - # token: "" - # ga: - # token: "" - # heap: - # token: "" - # - # ShareLaTeX's help desk is provided by tenderapp.com - # tenderUrl: "" - # - - # Production Settings - # ------------------- - + # These credentials are used for authenticating api requests + # between services that may need to go over public channels + httpAuthUsers: httpAuthUsers + # Should javascript assets be served minified or not. Note that you will # need to run `grunt compile:minify` within the web-sharelatex directory # to generate these. useMinifiedJs: false # Should static assets be sent with a header to tell the browser to cache - # them. + # them. This should be false in development where changes are being made, + # but should be set to true in production. cacheStaticAssets: false # If you are running ShareLaTeX over https, set this to true to send the # cookie with a secure flag (recommended). secureCookie: false - - # Internal configs - # ---------------- - path: - # If we ever need to write something to disk (e.g. incoming requests - # that need processing but may be too big for memory, then write - # them to disk here). - dumpFolder: Path.resolve "data/dumpFolder" - # Where to write the project to disk before running LaTeX on it - compilesDir: Path.resolve(__dirname + "/../compiles") - # Where to cache downloaded URLs for the CLSI - clsiCacheDir: Path.resolve(__dirname + "/../cache") - # Automatic Snapshots - # ------------------- - automaticSnapshots: - # How long should we wait after the user last edited to - # take a snapshot? - waitTimeAfterLastEdit: 5 * minutes - # Even if edits are still taking place, this is maximum - # time to wait before taking another snapshot. - maxTimeBetweenSnapshots: 30 * minutes + # If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) + # then set this to true to allow it to correctly detect the forwarded IP + # address and http/https protocol information. + behindProxy: false - # Smoke test - # ---------- - # Provide log in credentials and a project to be able to run - # some basic smoke tests to check the core functionality. + # Sending Email + # ------------- # - # smokeTest: - # user: "" - # password: "" - # projectId: "" + # You must configure a mail server to be able to send invite emails from + # ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer + # documentation for available options: + # + # http://www.nodemailer.com/docs/transports + # + # email: + # fromAddress: "" + # replyTo: "" + # transport: "SES" + # parameters: + # AWSAccessKeyID: "" + # AWSSecretKey: "" - # Filestore health check - # ---------------------- - # Project and file details to check in filestore when calling /health_check - # health_check: - # project_id: "" - # file_id: "" + # Spell Check Languages + # --------------------- + # + # You must have the corresponding aspell dictionary installed to + # be able to use a language. Run `grunt check:aspell` to check which + # dictionaries you have installed. These should be set for the `code` for + # each language. + languages: [ + {name: "English", code: "en"} + ] + + # Service locations + # ----------------- + + # ShareLaTeX is comprised of many small services, which each expose + # an HTTP API running on a different port. Generally you + # can leave these as they are unless you have some other services + # running which conflict, or want to run the web process on port 80. + # internal: + # web: + # port: webPort = 3000 + # host: "localhost" + # documentupdater: + # port: docUpdaterPort = 3003 + # host: "localhost" + # filestore: + # port: filestorePort = 3009 + # host: "localhost" + # chat: + # port: chatPort = 3010 + # host: "localhost" + # tags: + # port: tagsPort = 3012 + # host: "localhost" + # clsi: + # port: clsiPort = 3013 + # host: "localhost" + # trackchanges: + # port: trackchangesPort = 3015 + # host: "localhost" + # docstore: + # port: docstorePort = 3016 + # host: "localhost" + # spelling: + # port: spellingPort = 3005 + # host: "localhost" + + # If you change the above config, or run some services on remote servers, + # you need to tell the other services where to find them: + apis: + web: + url: "http://localhost:3000" + user: httpAuthUser + pass: httpAuthPass + # documentupdater: + # url : "http://localhost:#{docUpdaterPort}" + # clsi: + # url: "http://localhost:#{clsiPort}" + # filestore: + # url: "http://localhost:#{filestorePort}" + # trackchanges: + # url: "http://localhost:#{trackchangesPort}" + # docstore: + # url: "http://localhost:#{docstorePort}" + # tags: + # url: "http://localhost:#{tagsPort}" + # spelling: + # url: "http://localhost:#{spellingPort}" + # chat: + # url: "http://localhost:#{chatPort}" + + +# With lots of incoming and outgoing HTTP connections to different services, +# sometimes long running, it is a good idea to increase the default number +# of sockets that Node will hold open. +http = require('http') +http.globalAgent.maxSockets = 300 +https = require('https') +https.globalAgent.maxSockets = 300 diff --git a/server-ce/package.json b/server-ce/package.json index a36305c5e1..2e922d5b14 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -3,6 +3,7 @@ "version": "0.0.1", "description": "An online collaborative LaTeX editor", "dependencies": { + "async": "^0.9.0", "rimraf": "~2.2.6", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git" }, diff --git a/server-ce/user_files/.gitignore b/server-ce/user_files/.gitignore deleted file mode 100644 index e69de29bb2..0000000000 From bbe54179666e4150416ee1a9e81e1895b443e4e4 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 18 Aug 2014 10:46:42 +0100 Subject: [PATCH 104/525] Update upstart scripts --- server-ce/Gruntfile.coffee | 18 ++++++++----- server-ce/package/upstart/sharelatex-chat | 27 +++++++++++++++++++ server-ce/package/upstart/sharelatex-clsi | 20 +++++++++----- server-ce/package/upstart/sharelatex-docstore | 20 +++++++++----- .../upstart/sharelatex-document-updater | 20 +++++++++----- .../package/upstart/sharelatex-filestore | 20 +++++++++----- server-ce/package/upstart/sharelatex-spelling | 27 +++++++++++++++++++ server-ce/package/upstart/sharelatex-tags | 27 +++++++++++++++++++ server-ce/package/upstart/sharelatex-template | 20 +++++++++----- .../package/upstart/sharelatex-track-changes | 20 +++++++++----- server-ce/package/upstart/sharelatex-web | 18 +++++++++---- 11 files changed, 190 insertions(+), 47 deletions(-) create mode 100644 server-ce/package/upstart/sharelatex-chat create mode 100644 server-ce/package/upstart/sharelatex-spelling create mode 100644 server-ce/package/upstart/sharelatex-tags diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index f676cfbad1..35c8053a14 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -126,8 +126,10 @@ module.exports = (grunt) -> Helpers.checkMake @async() grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3", "check:fs", "check:aspell"] - grunt.registerTask "build_deb", "Build an installable .deb file from the current directory", () -> + grunt.registerTask "build:deb", "Build an installable .deb file from the current directory", () -> Helpers.buildDeb @async() + grunt.registerTask "build:upstart_scripts", "Create upstart scripts for each service", () -> + Helpers.buildUpstartScripts() Helpers = installService: (repo_src, dir, callback = (error) ->) -> @@ -375,13 +377,18 @@ module.exports = (grunt) -> grunt.log.write "OK." return callback() + buildUpstartScripts: () -> + template = fs.readFileSync("package/upstart/sharelatex-template").toString() + for service in SERVICES + fs.writeFileSync "package/upstart/sharelatex-#{service.name}", template.replace(/__SERVICE__/g, service.name) + buildDeb: (callback = (error) ->) -> # TODO: filestore uses local 'uploads' directory, not configurable in settings command = ["-s", "dir", "-t", "deb", "-n", "sharelatex", "-v", "0.0.1", "--verbose"] command.push( "--maintainer", "ShareLaTeX " "--config-files", "/etc/sharelatex/settings.coffee", - "--directories", "/var/data/sharelatex" + "--directories", "/var/lib/sharelatex" "--directories", "/var/log/sharelatex" ) @@ -391,9 +398,8 @@ module.exports = (grunt) -> "--depends", "nodejs > 0.10.0" ) - template = fs.readFileSync("package/upstart/sharelatex-template").toString() + @buildUpstartScripts() for service in SERVICES - fs.writeFileSync "package/upstart/sharelatex-#{service.name}", template.replace(/SERVICE/g, service.name) command.push( "--deb-upstart", "package/upstart/sharelatex-#{service.name}" ) @@ -409,8 +415,8 @@ module.exports = (grunt) -> for dir in ["user_files", "uploads", "compiles", "cache", "dump"] after_install_script += """ - mkdir -p /var/data/sharelatex/#{dir} - chown sharelatex:sharelatex /var/data/sharelatex/#{dir} + mkdir -p /var/lib/sharelatex/#{dir} + chown sharelatex:sharelatex /var/lib/sharelatex/#{dir} """ diff --git a/server-ce/package/upstart/sharelatex-chat b/server-ce/package/upstart/sharelatex-chat new file mode 100644 index 0000000000..869b5d82d5 --- /dev/null +++ b/server-ce/package/upstart/sharelatex-chat @@ -0,0 +1,27 @@ +description "sharelatex-web" +author "ShareLaTeX " + +start on started mountall +stop on shutdown + +respawn + +limit nofile 8192 8192 + +pre-start script + mkdir -p /var/log/sharelatex +end script + +script + SERVICE=chat + USER=sharelatex + GROUP=sharelatex + # You may need to replace this with an absolute + # path to Node.js if it's not in your system PATH. + NODE=node + SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + + echo $$ > /var/run/sharelatex-$SERVICE.pid + chdir /var/www/sharelatex/$SERVICE + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 +end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-clsi b/server-ce/package/upstart/sharelatex-clsi index 3dfe85b14a..733ff72c44 100644 --- a/server-ce/package/upstart/sharelatex-clsi +++ b/server-ce/package/upstart/sharelatex-clsi @@ -1,4 +1,4 @@ -description "sharelatex-clsi" +description "sharelatex-web" author "ShareLaTeX " start on started mountall @@ -9,11 +9,19 @@ respawn limit nofile 8192 8192 pre-start script - mkdir -p /var/log/sharelatex + mkdir -p /var/log/sharelatex end script script - echo $$ > /var/run/sharelatex-clsi.pid - chdir /var/www/sharelatex/clsi - exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/clsi.log 2>&1 -end script + SERVICE=clsi + USER=sharelatex + GROUP=sharelatex + # You may need to replace this with an absolute + # path to Node.js if it's not in your system PATH. + NODE=node + SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + + echo $$ > /var/run/sharelatex-$SERVICE.pid + chdir /var/www/sharelatex/$SERVICE + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 +end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-docstore b/server-ce/package/upstart/sharelatex-docstore index 542fe550ad..0bf1ad3c1e 100644 --- a/server-ce/package/upstart/sharelatex-docstore +++ b/server-ce/package/upstart/sharelatex-docstore @@ -1,4 +1,4 @@ -description "sharelatex-docstore" +description "sharelatex-web" author "ShareLaTeX " start on started mountall @@ -9,11 +9,19 @@ respawn limit nofile 8192 8192 pre-start script - mkdir -p /var/log/sharelatex + mkdir -p /var/log/sharelatex end script script - echo $$ > /var/run/sharelatex-docstore.pid - chdir /var/www/sharelatex/docstore - exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/docstore.log 2>&1 -end script + SERVICE=docstore + USER=sharelatex + GROUP=sharelatex + # You may need to replace this with an absolute + # path to Node.js if it's not in your system PATH. + NODE=node + SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + + echo $$ > /var/run/sharelatex-$SERVICE.pid + chdir /var/www/sharelatex/$SERVICE + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 +end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-document-updater b/server-ce/package/upstart/sharelatex-document-updater index ef31136031..71e7ef2d83 100644 --- a/server-ce/package/upstart/sharelatex-document-updater +++ b/server-ce/package/upstart/sharelatex-document-updater @@ -1,4 +1,4 @@ -description "sharelatex-document-updater" +description "sharelatex-web" author "ShareLaTeX " start on started mountall @@ -9,11 +9,19 @@ respawn limit nofile 8192 8192 pre-start script - mkdir -p /var/log/sharelatex + mkdir -p /var/log/sharelatex end script script - echo $$ > /var/run/sharelatex-document-updater.pid - chdir /var/www/sharelatex/document-updater - exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/document-updater.log 2>&1 -end script + SERVICE=document-updater + USER=sharelatex + GROUP=sharelatex + # You may need to replace this with an absolute + # path to Node.js if it's not in your system PATH. + NODE=node + SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + + echo $$ > /var/run/sharelatex-$SERVICE.pid + chdir /var/www/sharelatex/$SERVICE + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 +end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-filestore b/server-ce/package/upstart/sharelatex-filestore index 6f5c73bc4f..31a637ba45 100644 --- a/server-ce/package/upstart/sharelatex-filestore +++ b/server-ce/package/upstart/sharelatex-filestore @@ -1,4 +1,4 @@ -description "sharelatex-filestore" +description "sharelatex-web" author "ShareLaTeX " start on started mountall @@ -9,11 +9,19 @@ respawn limit nofile 8192 8192 pre-start script - mkdir -p /var/log/sharelatex + mkdir -p /var/log/sharelatex end script script - echo $$ > /var/run/sharelatex-filestore.pid - chdir /var/www/sharelatex/filestore - exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/filestore.log 2>&1 -end script + SERVICE=filestore + USER=sharelatex + GROUP=sharelatex + # You may need to replace this with an absolute + # path to Node.js if it's not in your system PATH. + NODE=node + SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + + echo $$ > /var/run/sharelatex-$SERVICE.pid + chdir /var/www/sharelatex/$SERVICE + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 +end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-spelling b/server-ce/package/upstart/sharelatex-spelling new file mode 100644 index 0000000000..4e2c3ed80e --- /dev/null +++ b/server-ce/package/upstart/sharelatex-spelling @@ -0,0 +1,27 @@ +description "sharelatex-web" +author "ShareLaTeX " + +start on started mountall +stop on shutdown + +respawn + +limit nofile 8192 8192 + +pre-start script + mkdir -p /var/log/sharelatex +end script + +script + SERVICE=spelling + USER=sharelatex + GROUP=sharelatex + # You may need to replace this with an absolute + # path to Node.js if it's not in your system PATH. + NODE=node + SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + + echo $$ > /var/run/sharelatex-$SERVICE.pid + chdir /var/www/sharelatex/$SERVICE + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 +end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-tags b/server-ce/package/upstart/sharelatex-tags new file mode 100644 index 0000000000..0a4a47af5b --- /dev/null +++ b/server-ce/package/upstart/sharelatex-tags @@ -0,0 +1,27 @@ +description "sharelatex-web" +author "ShareLaTeX " + +start on started mountall +stop on shutdown + +respawn + +limit nofile 8192 8192 + +pre-start script + mkdir -p /var/log/sharelatex +end script + +script + SERVICE=tags + USER=sharelatex + GROUP=sharelatex + # You may need to replace this with an absolute + # path to Node.js if it's not in your system PATH. + NODE=node + SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + + echo $$ > /var/run/sharelatex-$SERVICE.pid + chdir /var/www/sharelatex/$SERVICE + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 +end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-template b/server-ce/package/upstart/sharelatex-template index f9ed4c6a93..15a0e37683 100644 --- a/server-ce/package/upstart/sharelatex-template +++ b/server-ce/package/upstart/sharelatex-template @@ -1,4 +1,4 @@ -description "sharelatex-SERVICE" +description "sharelatex-web" author "ShareLaTeX " start on started mountall @@ -9,11 +9,19 @@ respawn limit nofile 8192 8192 pre-start script - mkdir -p /var/log/sharelatex + mkdir -p /var/log/sharelatex end script script - echo $$ > /var/run/sharelatex-SERVICE.pid - chdir /var/www/sharelatex/SERVICE - exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/SERVICE.log 2>&1 -end script + SERVICE=__SERVICE__ + USER=sharelatex + GROUP=sharelatex + # You may need to replace this with an absolute + # path to Node.js if it's not in your system PATH. + NODE=node + SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + + echo $$ > /var/run/sharelatex-$SERVICE.pid + chdir /var/www/sharelatex/$SERVICE + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 +end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-track-changes b/server-ce/package/upstart/sharelatex-track-changes index 2b3b61dfd1..1454819aaa 100644 --- a/server-ce/package/upstart/sharelatex-track-changes +++ b/server-ce/package/upstart/sharelatex-track-changes @@ -1,4 +1,4 @@ -description "sharelatex-track-changes" +description "sharelatex-web" author "ShareLaTeX " start on started mountall @@ -9,11 +9,19 @@ respawn limit nofile 8192 8192 pre-start script - mkdir -p /var/log/sharelatex + mkdir -p /var/log/sharelatex end script script - echo $$ > /var/run/sharelatex-track-changes.pid - chdir /var/www/sharelatex/track-changes - exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/track-changes.log 2>&1 -end script + SERVICE=track-changes + USER=sharelatex + GROUP=sharelatex + # You may need to replace this with an absolute + # path to Node.js if it's not in your system PATH. + NODE=node + SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + + echo $$ > /var/run/sharelatex-$SERVICE.pid + chdir /var/www/sharelatex/$SERVICE + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 +end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-web b/server-ce/package/upstart/sharelatex-web index 86d83bba78..f18e751b70 100644 --- a/server-ce/package/upstart/sharelatex-web +++ b/server-ce/package/upstart/sharelatex-web @@ -9,11 +9,19 @@ respawn limit nofile 8192 8192 pre-start script - mkdir -p /var/log/sharelatex + mkdir -p /var/log/sharelatex end script script - echo $$ > /var/run/sharelatex-web.pid - chdir /var/www/sharelatex/web - exec sudo -u sharelatex -g sharelatex env SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_ENV=production node app.js >> /var/log/sharelatex/web.log 2>&1 -end script + SERVICE=web + USER=sharelatex + GROUP=sharelatex + # You may need to replace this with an absolute + # path to Node.js if it's not in your system PATH. + NODE=node + SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + + echo $$ > /var/run/sharelatex-$SERVICE.pid + chdir /var/www/sharelatex/$SERVICE + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 +end script \ No newline at end of file From d8804834ac24631454d493d3357dcf42b7a5cdc8 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 18 Aug 2014 11:10:01 +0100 Subject: [PATCH 105/525] Update README.md --- server-ce/README.md | 63 +++++---------------------------------------- 1 file changed, 7 insertions(+), 56 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index fb115b1567..b2bc3698a7 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,59 +1,18 @@ ShareLaTeX ========== -[ShareLaTeX](https://www.sharelatex.com) is now open source! ShareLaTeX is an online real-time collaborative LaTeX editor, and you can now run your own local version where you can host, edit, collaborate in real-time, and compile your LaTeX documents. We’re still 100% focused on running the hosted version at http://www.sharelatex.com, but we want to be more flexible in how you can use ShareLaTeX, and give something back to our wonderful community. - -**[Read more on our blog](https://www.sharelatex.com/blog/2014/02/21/sharelatex-is-now-open-source.html#.UwcnsEJ_ugc)** +[ShareLaTeX](https://www.sharelatex.com) is an open-source online real-time collaborative LaTeX editor. We run a hosted version at http://www.sharelatex.com, but you can also run your own local version, and contribute to the development of ShareLaTeX. Installation ------------ +We have detailed installation instructions in our wiki: + +* [Installing ShareLaTeX in Production](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) +* [Setting up a ShareLaTeX Development Environment](https://github.com/sharelatex/sharelatex/wiki/Setting-up-a-Development-Environment) + **[Please help us make ShareLaTeX as easy to install as possible by answering our quick survey about your system and needs](https://sharelatex.typeform.com/to/PLNits)** -We're still figuring out the easiest way to let you install ShareLaTeX and get up and running quickly. If you fill in the above survey in we will be eternally grateful and it will help us make this install process as smooth as possible. For now, here is the best ways: - -### Manually - -First, check out a local copy of this repository: - -```bash -git clone https://github.com/sharelatex/sharelatex.git -cd sharelatex -``` - -Next install all the node modules and ShareLaTeX services: - -```bash -npm install -grunt install -``` - -This will create a config file in `config/settings.development.coffee`. You should open -this now and configure your AWS S3 credentials, and other custom settings. - -Now check that your system is set up correctly to run ShareLaTeX (checks that you have -the required dependencies installed.) Watch out for any failures. - -```bash -grunt check --force -``` - -When that has finished, run ShareLaTeX with - -```bash -grunt run -``` - -ShareLaTeX should now be running at http://localhost:3000. - -### With Vagrant - -There is a Vagrant and Ansible backed VM installation script for ShareLaTeX, maintained by [@palkan](https://github/palkan), available here: https://github.com/palkan/sharelatex-vagrant-ansible - -### With Docker - -An [automatic docker-based installer](https://github.com/tiagoboldt/sharelatex-docker) is available. It depends on docker and will build a production environment for running ShareLaTeX on any supported platform. - Dependencies ------------ @@ -64,18 +23,10 @@ ShareLaTeX should run on OS X and Linux. You need: * A local instance of [Redis](http://redis.io/topics/quickstart) (version 2.6.12 or later) and [MongoDB](http://docs.mongodb.org/manual/installation/) running on their standard ports. * [TeXLive](https://www.tug.org/texlive/) 2013 or later with the `latexmk` program installed. -Config ------- - -ShareLaTeX should run out of the box, but if you want to adjust any settings you can do so by -editing the `config/settings.development.coffee` file. Available options are explained inline. - Other repositories ------------------ -ShareLaTeX consists of many separate services, each with their own Node.js process -and source code repository. These are all downloaded and set upwhen you run -`grunt install` +This repository does not contain any code. It acts a wrapper and toolkit for managing the many different ShareLaTeX services. These each run as their own Node.js process and have their own Github repository. These are all downloaded and set up when you run `grunt install` The different services are: From b031e98ff870d1a9211944c1ac2b7a626f31c16e Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 18 Aug 2014 15:13:48 +0100 Subject: [PATCH 106/525] Update .deb package builder --- server-ce/Gruntfile.coffee | 21 ++++++++++++--- server-ce/package/scripts/after_install.sh | 30 ++++++++++++++-------- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 35c8053a14..2d762e599f 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -130,6 +130,7 @@ module.exports = (grunt) -> Helpers.buildDeb @async() grunt.registerTask "build:upstart_scripts", "Create upstart scripts for each service", () -> Helpers.buildUpstartScripts() + Helpers = installService: (repo_src, dir, callback = (error) ->) -> @@ -382,8 +383,13 @@ module.exports = (grunt) -> for service in SERVICES fs.writeFileSync "package/upstart/sharelatex-#{service.name}", template.replace(/__SERVICE__/g, service.name) + buildPackageSettingsFile: () -> + config = fs.readFileSync("config/settings.development.coffee.example").toString() + config = config.replace /DATA_DIR.*/, "DATA_DIR = '/var/lib/sharelatex/data'" + config = config.replace /TMP_DIR.*/, "TMP_DIR = '/var/lib/sharelatex/tmp'" + fs.writeFileSync "package/config/settings.coffee", config + buildDeb: (callback = (error) ->) -> - # TODO: filestore uses local 'uploads' directory, not configurable in settings command = ["-s", "dir", "-t", "deb", "-n", "sharelatex", "-v", "0.0.1", "--verbose"] command.push( "--maintainer", "ShareLaTeX " @@ -394,9 +400,11 @@ module.exports = (grunt) -> command.push( "--depends", "redis-server > 2.6.12" - "--depends", "mongodb-10gen > 2.4.0" + "--depends", "mongodb-org > 2.4.0" "--depends", "nodejs > 0.10.0" ) + + @buildPackageSettingsFile() @buildUpstartScripts() for service in SERVICES @@ -406,14 +414,21 @@ module.exports = (grunt) -> after_install_script = """ #!/bin/sh + # Create random secret keys + sed -i "s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee + sed -i "s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee + sudo adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex mkdir -p /var/log/sharelatex chown sharelatex:sharelatex /var/log/sharelatex + + mkdir -p /var/lib/sharelatex + chown sharelatex:sharelatex /var/lib/sharelatex """ - for dir in ["user_files", "uploads", "compiles", "cache", "dump"] + for dir in ["data/user_files", "tmp/uploads", "data/compiles", "data/cache", "tmp/dumpFolder"] after_install_script += """ mkdir -p /var/lib/sharelatex/#{dir} chown sharelatex:sharelatex /var/lib/sharelatex/#{dir} diff --git a/server-ce/package/scripts/after_install.sh b/server-ce/package/scripts/after_install.sh index e1dc6ff6fa..5b39d4d9ef 100644 --- a/server-ce/package/scripts/after_install.sh +++ b/server-ce/package/scripts/after_install.sh @@ -1,21 +1,31 @@ #!/bin/sh +# Create random secret keys +sed -i "s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee +sed -i "s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee + sudo adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex mkdir -p /var/log/sharelatex chown sharelatex:sharelatex /var/log/sharelatex -mkdir -p /var/data/sharelatex/user_files -chown sharelatex:sharelatex /var/data/sharelatex/user_files -mkdir -p /var/data/sharelatex/uploads -chown sharelatex:sharelatex /var/data/sharelatex/uploads -mkdir -p /var/data/sharelatex/compiles -chown sharelatex:sharelatex /var/data/sharelatex/compiles -mkdir -p /var/data/sharelatex/cache -chown sharelatex:sharelatex /var/data/sharelatex/cache -mkdir -p /var/data/sharelatex/dump -chown sharelatex:sharelatex /var/data/sharelatex/dump + +mkdir -p /var/lib/sharelatex +chown sharelatex:sharelatex /var/lib/sharelatex +mkdir -p /var/lib/sharelatex/data/user_files +chown sharelatex:sharelatex /var/lib/sharelatex/data/user_files +mkdir -p /var/lib/sharelatex/tmp/uploads +chown sharelatex:sharelatex /var/lib/sharelatex/tmp/uploads +mkdir -p /var/lib/sharelatex/data/compiles +chown sharelatex:sharelatex /var/lib/sharelatex/data/compiles +mkdir -p /var/lib/sharelatex/data/cache +chown sharelatex:sharelatex /var/lib/sharelatex/data/cache +mkdir -p /var/lib/sharelatex/tmp/dumpFolder +chown sharelatex:sharelatex /var/lib/sharelatex/tmp/dumpFolder service sharelatex-web restart service sharelatex-document-updater restart service sharelatex-clsi restart service sharelatex-filestore restart service sharelatex-track-changes restart service sharelatex-docstore restart +service sharelatex-chat restart +service sharelatex-tags restart +service sharelatex-spelling restart From 5a9c8e0127c6f2ac903f3e8a181d298fec651720 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 10:41:04 +0100 Subject: [PATCH 107/525] Add nginx config file to .deb build --- server-ce/Gruntfile.coffee | 4 ++- .../chef/cookbooks/mongodb/recipes/default.rb | 4 +-- server-ce/package/nginx/sharelatex | 32 +++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 server-ce/package/nginx/sharelatex diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 2d762e599f..f12ab9bb3a 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -393,7 +393,8 @@ module.exports = (grunt) -> command = ["-s", "dir", "-t", "deb", "-n", "sharelatex", "-v", "0.0.1", "--verbose"] command.push( "--maintainer", "ShareLaTeX " - "--config-files", "/etc/sharelatex/settings.coffee", + "--config-files", "/etc/sharelatex/settings.coffee" + "--config-files", "/etc/nginx/sites-enabled/sharelatex" "--directories", "/var/lib/sharelatex" "--directories", "/var/log/sharelatex" ) @@ -449,6 +450,7 @@ module.exports = (grunt) -> command.push( "package/config/settings.coffee=/etc/sharelatex/settings.coffee" + "package/nginx/sharelatex=/etc/nginx/sites-enabled/sharelatex" ) console.log "fpm " + command.join(" ") proc = spawn "fpm", command, stdio: "inherit" diff --git a/server-ce/chef/cookbooks/mongodb/recipes/default.rb b/server-ce/chef/cookbooks/mongodb/recipes/default.rb index 56b251c261..f1a8a4f6be 100644 --- a/server-ce/chef/cookbooks/mongodb/recipes/default.rb +++ b/server-ce/chef/cookbooks/mongodb/recipes/default.rb @@ -6,7 +6,7 @@ # # See http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/ -apt_repository 'mongodb-10gen' do +apt_repository 'mongodb-org' do uri 'http://downloads-distro.mongodb.org/repo/ubuntu-upstart' distribution 'dist' components ['10gen'] @@ -14,6 +14,6 @@ apt_repository 'mongodb-10gen' do key '7F0CEB10' end -package 'mongodb-10gen' do +package 'mongodb-org' do action :install end \ No newline at end of file diff --git a/server-ce/package/nginx/sharelatex b/server-ce/package/nginx/sharelatex new file mode 100644 index 0000000000..f484240893 --- /dev/null +++ b/server-ce/package/nginx/sharelatex @@ -0,0 +1,32 @@ +server { + listen 80; + server_name _; # Catch all, see http://nginx.org/en/docs/http/server_names.html + + set $static_path /var/www/sharelatex/web/public; + + location / { + proxy_pass http://localhost:3000; + proxy_set_header Host $http_x_forwarded_host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_read_timeout 3m; + proxy_send_timeout 3m; + } + + location /stylesheets { + expires 1y; + root $static_path/; + } + + location /minjs { + expires 1y; + root $static_path/; + } + + location /img { + expires 1y; + root $static_path/; + } +} From ff3c813c7c310c4786b36a5d16e8cc1af775c968 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 11:24:55 +0100 Subject: [PATCH 108/525] Generate Secret keys properly and start services on boot --- server-ce/Gruntfile.coffee | 6 +++--- server-ce/Vagrantfile | 1 + server-ce/package/upstart/sharelatex-template | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index f12ab9bb3a..fbb9d489af 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -415,9 +415,9 @@ module.exports = (grunt) -> after_install_script = """ #!/bin/sh - # Create random secret keys - sed -i "s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee - sed -i "s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee + # Create random secret keys (twice, once for http auth pass, once for cookie secret). + sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee + sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee sudo adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex diff --git a/server-ce/Vagrantfile b/server-ce/Vagrantfile index d46e3a9d6e..63ddd3b205 100644 --- a/server-ce/Vagrantfile +++ b/server-ce/Vagrantfile @@ -9,6 +9,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box_url = "http://files.vagrantup.com/precise64.box" config.vm.network :forwarded_port, guest: 3000, host: 3000 + config.vm.network :forwarded_port, guest: 80, host: 8080 config.ssh.forward_agent = true diff --git a/server-ce/package/upstart/sharelatex-template b/server-ce/package/upstart/sharelatex-template index 15a0e37683..14af9ccd5a 100644 --- a/server-ce/package/upstart/sharelatex-template +++ b/server-ce/package/upstart/sharelatex-template @@ -1,7 +1,7 @@ description "sharelatex-web" author "ShareLaTeX " -start on started mountall +start on (local-filesystems and net-device-up IFACE!=lo) stop on shutdown respawn From c6cd54b3a4bced67e242ebf261e821324784e79b Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 11:56:38 +0100 Subject: [PATCH 109/525] Don't include .git and grunt- directories in build --- server-ce/Gruntfile.coffee | 3 +- server-ce/package/config/settings.coffee | 396 ++++++++---------- server-ce/package/scripts/after_install.sh | 6 +- server-ce/package/upstart/sharelatex-chat | 2 +- server-ce/package/upstart/sharelatex-clsi | 2 +- server-ce/package/upstart/sharelatex-docstore | 2 +- .../upstart/sharelatex-document-updater | 2 +- .../package/upstart/sharelatex-filestore | 2 +- server-ce/package/upstart/sharelatex-spelling | 2 +- server-ce/package/upstart/sharelatex-tags | 2 +- .../package/upstart/sharelatex-track-changes | 2 +- server-ce/package/upstart/sharelatex-web | 2 +- 12 files changed, 183 insertions(+), 240 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index fbb9d489af..db7f54fa4c 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -441,7 +441,8 @@ module.exports = (grunt) -> fs.writeFileSync "package/scripts/after_install.sh", after_install_script command.push("--after-install", "package/scripts/after_install.sh") - command.push("--exclude", "'**/.git'") + command.push("--exclude", "**/.git") + command.push("--exclude", "**/node_modules/grunt-*") for path in ["filestore/user_files", "filestore/uploads", "clsi/cache", "clsi/compiles"] command.push "--exclude", path diff --git a/server-ce/package/config/settings.coffee b/server-ce/package/config/settings.coffee index e2eb707b2c..bfefca8715 100644 --- a/server-ce/package/config/settings.coffee +++ b/server-ce/package/config/settings.coffee @@ -1,277 +1,219 @@ Path = require('path') -http = require('http') -http.globalAgent.maxSockets = 300 - -# Make time interval config easier. -seconds = 1000 -minutes = 60 * seconds # These credentials are used for authenticating api requests # between services that may need to go over public channels httpAuthUser = "sharelatex" -httpAuthPass = "password" +httpAuthPass = "CRYPTO_RANDOM" # Randomly generated for you httpAuthUsers = {} httpAuthUsers[httpAuthUser] = httpAuthPass -sessionSecret = "secret-please-change" +DATA_DIR = '/var/lib/sharelatex/data' +TMP_DIR = '/var/lib/sharelatex/tmp' module.exports = - # File storage - # ------------ - # - # ShareLaTeX needs somewhere to store binary files like images. - # There are currently two options: - # Your local filesystem (the default) - # Amazon S3 - filestore: - # which backend persistor to use. - # choices are - # s3 - Amazon S3 - # fs - local filesystem - backend: "fs" - stores: - # where to store user and template binary files - # - # For Amazon S3 this is the bucket name to store binary files - # - # For local filesystem this is the directory to store the files in. - # This path must exist, not be tmpfs and be writable to by the user sharelatex is run as. - user_files: "/var/data/sharelatex/user_files" - # Uncomment if you need to configure your S3 credentials - # s3: - # # if you are using S3, then fill in your S3 details below - # key: "" - # secret: "" - # Databases # --------- + + # ShareLaTeX's main persistant data store is MongoDB (http://www.mongodb.org/) + # Documentation about the URL connection string format can be found at: + # + # http://docs.mongodb.org/manual/reference/connection-string/ + # + # The following works out of the box with Mongo's default settings: mongo: url : 'mongodb://127.0.0.1/sharelatex' + # Redis is used in ShareLaTeX for high volume queries, like real-time + # editing, and session management. + # + # The following config will work with Redis's default settings: redis: web: host: "localhost" port: "6379" password: "" - api: - host: "localhost" - port: "6379" - password: "" - - fairy: - host: "localhost" - port: "6379" - password: "" - + # The compile server (the clsi) uses a SQL database to cache files and + # meta-data. sqllite is the default, and the load is low enough that this will + # be fine in production (we use sqllite at sharelatex.com). + # + # If you want to configure a different database, see the Sequelize documentation + # for available options: + # + # https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage + # mysql: clsi: database: "clsi" username: "clsi" password: "" dialect: "sqlite" - storage: "/var/data/sharelatex/clsi_db.sqlite" + storage: Path.join(DATA_DIR, "db.sqlite") - # Service locations - # ----------------- + # File storage + # ------------ - # Configure which ports to run each service on. Generally you - # can leave these as they are unless you have some other services - # running which conflict, or want to run the web process on port 80. - internal: - web: - port: webPort = 3000 - host: "localhost" - documentupdater: - port: docUpdaterPort = 3003 - host: "localhost" - clsi: - port: clsiPort = 3013 - host: "localhost" - filestore: - port: filestorePort = 3009 - host: "localhost" - trackchanges: - port: trackchangesPort = 3015 - host: "localhost" - docstore: - port: docstorePort = 3016 - host: "localhost" - - # Tell each service where to find the other services. If everything - # is running locally then this is easy, but they exist as separate config - # options incase you want to run some services on remote hosts. - apis: - web: - url: "http://localhost:#{webPort}" - user: httpAuthUser - pass: httpAuthPass - documentupdater: - url : "http://localhost:#{docUpdaterPort}" - clsi: - url: "http://localhost:#{clsiPort}" - filestore: - url: "http://localhost:#{filestorePort}" - trackchanges: - url: "http://localhost:#{trackchangesPort}" - docstore: - url: "http://localhost:#{docstorePort}" - thirdPartyDataStore: - url : "http://localhost:3002" - emptyProjectFlushDelayMiliseconds: 5 * seconds - tags: - url :"http://localhost:3012" - spelling: - url : "http://localhost:3005" - versioning: - snapshotwaitms:3000 - url: "http://localhost:4000" - username: httpAuthUser - password: httpAuthPass - recurly: - privateKey: "" - apiKey: "" - subdomain: "" - chat: - url: "http://localhost:3010" - templates: - port: 3007 - blog: - port: 3008 - templates_api: - url: "http://localhost:3007" - - # Where your instance of ShareLaTeX can be found publically. Used in emails - # that are sent out, generated links, etc. - siteUrl : 'http://localhost:3000' - - # Same, but with http auth credentials. - httpAuthSiteUrl: 'http://#{httpAuthUser}:#{httpAuthPass}@localhost:3000' - - # Security - # -------- - security: - sessionSecret: sessionSecret - - httpAuthUsers: httpAuthUsers - - # Default features - # ---------------- + # ShareLaTeX can store binary files like images either locally or in Amazon + # S3. The default is locally: + filestore: + backend: "fs" + stores: + user_files: Path.join(DATA_DIR, "user_files") + + # To use Amazon S3 as a storage backend, comment out the above config, and + # uncomment the following, filling in your key, secret, and bucket name: # - # You can select the features that are enabled by default for new - # new users. - defaultFeatures: defaultFeatures = - collaborators: -1 - dropbox: true - versioning: true + # filestore: + # backend: "s3" + # stores: + # user_files: "BUCKET_NAME" + # s3: + # key: "AWS_KEY" + # secret: "AWS_SECRET" + # - plans: plans = [{ - planCode: "personal" - name: "Personal" - price: 0 - features: defaultFeatures - }] - - # Spelling languages + # Local disk caching # ------------------ - # - # You must have the corresponding aspell package installed to - # be able to use a language. - languages: [ - {name: "English", code: "en"} - ] + path: + # If we ever need to write something to disk (e.g. incoming requests + # that need processing but may be too big for memory), then write + # them to disk here: + dumpFolder: Path.join(TMP_DIR, "dumpFolder") + # Where to write uploads before they are processed + uploadFolder: Path.join(TMP_DIR, "uploads") + # Where to write the project to disk before running LaTeX on it + compilesDir: Path.join(DATA_DIR, "compiles") + # Where to cache downloaded URLs for the CLSI + clsiCacheDir: Path.join(DATA_DIR, "cache") - # Email support + # Server Config # ------------- - # - # ShareLaTeX uses nodemailer (http://www.nodemailer.com/) to send transactional emails. - # To see the range of transport and options they support, see http://www.nodemailer.com/docs/transports - # email: - # fromAddress: "" - # replyTo: "" - # lifecycle: false - # transport: "SES" - # parameters: - # AWSAccessKeyID: "" - # AWSSecretKey: "" + # Where your instance of ShareLaTeX can be found publicly. This is used + # when emails are sent out and in generated links: + siteUrl : 'http://localhost:3000' + + # If provided, a sessionSecret is used to sign cookies so that they cannot be + # spoofed. This is recommended. + security: + sessionSecret: "CRYPTO_RANDOM" # This was randomly generated for you - # Third party services - # -------------------- - # - # ShareLaTeX's regular newsletter is managed by Markdown mail. Add your - # credentials here to integrate with this. - # markdownmail: - # secret: "" - # list_id: "" - # - # Fill in your unique token from various analytics services to enable - # them. - # analytics: - # mixpanel: - # token: "" - # ga: - # token: "" - # heap: - # token: "" - # - # ShareLaTeX's help desk is provided by tenderapp.com - # tenderUrl: "" - # - - # Production Settings - # ------------------- - + # These credentials are used for authenticating api requests + # between services that may need to go over public channels + httpAuthUsers: httpAuthUsers + # Should javascript assets be served minified or not. Note that you will # need to run `grunt compile:minify` within the web-sharelatex directory # to generate these. useMinifiedJs: false # Should static assets be sent with a header to tell the browser to cache - # them. + # them. This should be false in development where changes are being made, + # but should be set to true in production. cacheStaticAssets: false # If you are running ShareLaTeX over https, set this to true to send the # cookie with a secure flag (recommended). secureCookie: false + + # If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) + # then set this to true to allow it to correctly detect the forwarded IP + # address and http/https protocol information. + behindProxy: false - # Internal configs - # ---------------- - path: - # If we ever need to write something to disk (e.g. incoming requests - # that need processing but may be too big for memory, then write - # them to disk here). - dumpFolder: "/var/data/sharelatex/dump" - # Where to write the project to disk before running LaTeX on it - compilesDir: "/var/data/sharelatex/compiles" - # Where to cache downloaded URLs for the CLSI - clsiCacheDir: "/var/data/sharelatex/cache" - # Where to write uploads before they are processed - uploadFolder: "/var/data/sharelatex/uploads" - - # Automatic Snapshots - # ------------------- - automaticSnapshots: - # How long should we wait after the user last edited to - # take a snapshot? - waitTimeAfterLastEdit: 5 * minutes - # Even if edits are still taking place, this is maximum - # time to wait before taking another snapshot. - maxTimeBetweenSnapshots: 30 * minutes - - # Smoke test - # ---------- - # Provide log in credentials and a project to be able to run - # some basic smoke tests to check the core functionality. + # Sending Email + # ------------- # - # smokeTest: - # user: "" - # password: "" - # projectId: "" + # You must configure a mail server to be able to send invite emails from + # ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer + # documentation for available options: + # + # http://www.nodemailer.com/docs/transports + # + # email: + # fromAddress: "" + # replyTo: "" + # transport: "SES" + # parameters: + # AWSAccessKeyID: "" + # AWSSecretKey: "" - # Filestore health check - # ---------------------- - # Project and file details to check in filestore when calling /health_check - # health_check: - # project_id: "" - # file_id: "" + # Spell Check Languages + # --------------------- + # + # You must have the corresponding aspell dictionary installed to + # be able to use a language. Run `grunt check:aspell` to check which + # dictionaries you have installed. These should be set for the `code` for + # each language. + languages: [ + {name: "English", code: "en"} + ] + + # Service locations + # ----------------- + + # ShareLaTeX is comprised of many small services, which each expose + # an HTTP API running on a different port. Generally you + # can leave these as they are unless you have some other services + # running which conflict, or want to run the web process on port 80. + # internal: + # web: + # port: webPort = 3000 + # host: "localhost" + # documentupdater: + # port: docUpdaterPort = 3003 + # host: "localhost" + # filestore: + # port: filestorePort = 3009 + # host: "localhost" + # chat: + # port: chatPort = 3010 + # host: "localhost" + # tags: + # port: tagsPort = 3012 + # host: "localhost" + # clsi: + # port: clsiPort = 3013 + # host: "localhost" + # trackchanges: + # port: trackchangesPort = 3015 + # host: "localhost" + # docstore: + # port: docstorePort = 3016 + # host: "localhost" + # spelling: + # port: spellingPort = 3005 + # host: "localhost" + + # If you change the above config, or run some services on remote servers, + # you need to tell the other services where to find them: + apis: + web: + url: "http://localhost:3000" + user: httpAuthUser + pass: httpAuthPass + # documentupdater: + # url : "http://localhost:#{docUpdaterPort}" + # clsi: + # url: "http://localhost:#{clsiPort}" + # filestore: + # url: "http://localhost:#{filestorePort}" + # trackchanges: + # url: "http://localhost:#{trackchangesPort}" + # docstore: + # url: "http://localhost:#{docstorePort}" + # tags: + # url: "http://localhost:#{tagsPort}" + # spelling: + # url: "http://localhost:#{spellingPort}" + # chat: + # url: "http://localhost:#{chatPort}" + + +# With lots of incoming and outgoing HTTP connections to different services, +# sometimes long running, it is a good idea to increase the default number +# of sockets that Node will hold open. +http = require('http') +http.globalAgent.maxSockets = 300 +https = require('https') +https.globalAgent.maxSockets = 300 diff --git a/server-ce/package/scripts/after_install.sh b/server-ce/package/scripts/after_install.sh index 5b39d4d9ef..d33a4db6be 100644 --- a/server-ce/package/scripts/after_install.sh +++ b/server-ce/package/scripts/after_install.sh @@ -1,7 +1,7 @@ #!/bin/sh -# Create random secret keys -sed -i "s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee -sed -i "s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee +# Create random secret keys (twice, once for http auth pass, once for cookie secret). +sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee +sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee sudo adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex diff --git a/server-ce/package/upstart/sharelatex-chat b/server-ce/package/upstart/sharelatex-chat index 869b5d82d5..9ef1f1f87e 100644 --- a/server-ce/package/upstart/sharelatex-chat +++ b/server-ce/package/upstart/sharelatex-chat @@ -1,7 +1,7 @@ description "sharelatex-web" author "ShareLaTeX " -start on started mountall +start on (local-filesystems and net-device-up IFACE!=lo) stop on shutdown respawn diff --git a/server-ce/package/upstart/sharelatex-clsi b/server-ce/package/upstart/sharelatex-clsi index 733ff72c44..30368a074f 100644 --- a/server-ce/package/upstart/sharelatex-clsi +++ b/server-ce/package/upstart/sharelatex-clsi @@ -1,7 +1,7 @@ description "sharelatex-web" author "ShareLaTeX " -start on started mountall +start on (local-filesystems and net-device-up IFACE!=lo) stop on shutdown respawn diff --git a/server-ce/package/upstart/sharelatex-docstore b/server-ce/package/upstart/sharelatex-docstore index 0bf1ad3c1e..d6a90b80d3 100644 --- a/server-ce/package/upstart/sharelatex-docstore +++ b/server-ce/package/upstart/sharelatex-docstore @@ -1,7 +1,7 @@ description "sharelatex-web" author "ShareLaTeX " -start on started mountall +start on (local-filesystems and net-device-up IFACE!=lo) stop on shutdown respawn diff --git a/server-ce/package/upstart/sharelatex-document-updater b/server-ce/package/upstart/sharelatex-document-updater index 71e7ef2d83..2e3e6ad3a0 100644 --- a/server-ce/package/upstart/sharelatex-document-updater +++ b/server-ce/package/upstart/sharelatex-document-updater @@ -1,7 +1,7 @@ description "sharelatex-web" author "ShareLaTeX " -start on started mountall +start on (local-filesystems and net-device-up IFACE!=lo) stop on shutdown respawn diff --git a/server-ce/package/upstart/sharelatex-filestore b/server-ce/package/upstart/sharelatex-filestore index 31a637ba45..de1e8ba330 100644 --- a/server-ce/package/upstart/sharelatex-filestore +++ b/server-ce/package/upstart/sharelatex-filestore @@ -1,7 +1,7 @@ description "sharelatex-web" author "ShareLaTeX " -start on started mountall +start on (local-filesystems and net-device-up IFACE!=lo) stop on shutdown respawn diff --git a/server-ce/package/upstart/sharelatex-spelling b/server-ce/package/upstart/sharelatex-spelling index 4e2c3ed80e..4c2dcc86a1 100644 --- a/server-ce/package/upstart/sharelatex-spelling +++ b/server-ce/package/upstart/sharelatex-spelling @@ -1,7 +1,7 @@ description "sharelatex-web" author "ShareLaTeX " -start on started mountall +start on (local-filesystems and net-device-up IFACE!=lo) stop on shutdown respawn diff --git a/server-ce/package/upstart/sharelatex-tags b/server-ce/package/upstart/sharelatex-tags index 0a4a47af5b..34257b4863 100644 --- a/server-ce/package/upstart/sharelatex-tags +++ b/server-ce/package/upstart/sharelatex-tags @@ -1,7 +1,7 @@ description "sharelatex-web" author "ShareLaTeX " -start on started mountall +start on (local-filesystems and net-device-up IFACE!=lo) stop on shutdown respawn diff --git a/server-ce/package/upstart/sharelatex-track-changes b/server-ce/package/upstart/sharelatex-track-changes index 1454819aaa..c43207fd77 100644 --- a/server-ce/package/upstart/sharelatex-track-changes +++ b/server-ce/package/upstart/sharelatex-track-changes @@ -1,7 +1,7 @@ description "sharelatex-web" author "ShareLaTeX " -start on started mountall +start on (local-filesystems and net-device-up IFACE!=lo) stop on shutdown respawn diff --git a/server-ce/package/upstart/sharelatex-web b/server-ce/package/upstart/sharelatex-web index f18e751b70..1db599a1bd 100644 --- a/server-ce/package/upstart/sharelatex-web +++ b/server-ce/package/upstart/sharelatex-web @@ -1,7 +1,7 @@ description "sharelatex-web" author "ShareLaTeX " -start on started mountall +start on (local-filesystems and net-device-up IFACE!=lo) stop on shutdown respawn From 27f746ddc443f755180f0a7259f725f69de7d75e Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 12:05:22 +0100 Subject: [PATCH 110/525] Include LaTeX path in upstart --- server-ce/Gruntfile.coffee | 7 ++++--- server-ce/package/scripts/after_install.sh | 13 +------------ server-ce/package/upstart/sharelatex-chat | 3 ++- server-ce/package/upstart/sharelatex-clsi | 3 ++- server-ce/package/upstart/sharelatex-docstore | 3 ++- .../package/upstart/sharelatex-document-updater | 3 ++- server-ce/package/upstart/sharelatex-filestore | 3 ++- server-ce/package/upstart/sharelatex-spelling | 3 ++- server-ce/package/upstart/sharelatex-tags | 3 ++- server-ce/package/upstart/sharelatex-template | 3 ++- server-ce/package/upstart/sharelatex-track-changes | 3 ++- server-ce/package/upstart/sharelatex-web | 3 ++- 12 files changed, 25 insertions(+), 25 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index db7f54fa4c..357e3c660a 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -425,16 +425,17 @@ module.exports = (grunt) -> chown sharelatex:sharelatex /var/log/sharelatex mkdir -p /var/lib/sharelatex - chown sharelatex:sharelatex /var/lib/sharelatex """ for dir in ["data/user_files", "tmp/uploads", "data/compiles", "data/cache", "tmp/dumpFolder"] after_install_script += """ mkdir -p /var/lib/sharelatex/#{dir} - chown sharelatex:sharelatex /var/lib/sharelatex/#{dir} - """ + + after_install_script += """ + chown -R sharelatex:sharelatex /var/lib/sharelatex + """ for service in SERVICES after_install_script += "service sharelatex-#{service.name} restart\n" diff --git a/server-ce/package/scripts/after_install.sh b/server-ce/package/scripts/after_install.sh index d33a4db6be..fa47d7d94b 100644 --- a/server-ce/package/scripts/after_install.sh +++ b/server-ce/package/scripts/after_install.sh @@ -9,18 +9,7 @@ mkdir -p /var/log/sharelatex chown sharelatex:sharelatex /var/log/sharelatex mkdir -p /var/lib/sharelatex -chown sharelatex:sharelatex /var/lib/sharelatex -mkdir -p /var/lib/sharelatex/data/user_files -chown sharelatex:sharelatex /var/lib/sharelatex/data/user_files -mkdir -p /var/lib/sharelatex/tmp/uploads -chown sharelatex:sharelatex /var/lib/sharelatex/tmp/uploads -mkdir -p /var/lib/sharelatex/data/compiles -chown sharelatex:sharelatex /var/lib/sharelatex/data/compiles -mkdir -p /var/lib/sharelatex/data/cache -chown sharelatex:sharelatex /var/lib/sharelatex/data/cache -mkdir -p /var/lib/sharelatex/tmp/dumpFolder -chown sharelatex:sharelatex /var/lib/sharelatex/tmp/dumpFolder -service sharelatex-web restart +mkdir -p /var/lib/sharelatex/data/user_filesmkdir -p /var/lib/sharelatex/tmp/uploadsmkdir -p /var/lib/sharelatex/data/compilesmkdir -p /var/lib/sharelatex/data/cachemkdir -p /var/lib/sharelatex/tmp/dumpFolderchown -R sharelatex:sharelatex /var/lib/sharelatexservice sharelatex-web restart service sharelatex-document-updater restart service sharelatex-clsi restart service sharelatex-filestore restart diff --git a/server-ce/package/upstart/sharelatex-chat b/server-ce/package/upstart/sharelatex-chat index 9ef1f1f87e..6f33cdf277 100644 --- a/server-ce/package/upstart/sharelatex-chat +++ b/server-ce/package/upstart/sharelatex-chat @@ -20,8 +20,9 @@ script # path to Node.js if it's not in your system PATH. NODE=node SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid chdir /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-clsi b/server-ce/package/upstart/sharelatex-clsi index 30368a074f..9fa4e3cba9 100644 --- a/server-ce/package/upstart/sharelatex-clsi +++ b/server-ce/package/upstart/sharelatex-clsi @@ -20,8 +20,9 @@ script # path to Node.js if it's not in your system PATH. NODE=node SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid chdir /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-docstore b/server-ce/package/upstart/sharelatex-docstore index d6a90b80d3..6cf35a1ed6 100644 --- a/server-ce/package/upstart/sharelatex-docstore +++ b/server-ce/package/upstart/sharelatex-docstore @@ -20,8 +20,9 @@ script # path to Node.js if it's not in your system PATH. NODE=node SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid chdir /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-document-updater b/server-ce/package/upstart/sharelatex-document-updater index 2e3e6ad3a0..f0a6cb356c 100644 --- a/server-ce/package/upstart/sharelatex-document-updater +++ b/server-ce/package/upstart/sharelatex-document-updater @@ -20,8 +20,9 @@ script # path to Node.js if it's not in your system PATH. NODE=node SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid chdir /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-filestore b/server-ce/package/upstart/sharelatex-filestore index de1e8ba330..9aacb585b0 100644 --- a/server-ce/package/upstart/sharelatex-filestore +++ b/server-ce/package/upstart/sharelatex-filestore @@ -20,8 +20,9 @@ script # path to Node.js if it's not in your system PATH. NODE=node SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid chdir /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-spelling b/server-ce/package/upstart/sharelatex-spelling index 4c2dcc86a1..4e9f36f394 100644 --- a/server-ce/package/upstart/sharelatex-spelling +++ b/server-ce/package/upstart/sharelatex-spelling @@ -20,8 +20,9 @@ script # path to Node.js if it's not in your system PATH. NODE=node SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid chdir /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-tags b/server-ce/package/upstart/sharelatex-tags index 34257b4863..d075865f1b 100644 --- a/server-ce/package/upstart/sharelatex-tags +++ b/server-ce/package/upstart/sharelatex-tags @@ -20,8 +20,9 @@ script # path to Node.js if it's not in your system PATH. NODE=node SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid chdir /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-template b/server-ce/package/upstart/sharelatex-template index 14af9ccd5a..9270388370 100644 --- a/server-ce/package/upstart/sharelatex-template +++ b/server-ce/package/upstart/sharelatex-template @@ -20,8 +20,9 @@ script # path to Node.js if it's not in your system PATH. NODE=node SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid chdir /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-track-changes b/server-ce/package/upstart/sharelatex-track-changes index c43207fd77..1e7df4980b 100644 --- a/server-ce/package/upstart/sharelatex-track-changes +++ b/server-ce/package/upstart/sharelatex-track-changes @@ -20,8 +20,9 @@ script # path to Node.js if it's not in your system PATH. NODE=node SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid chdir /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-web b/server-ce/package/upstart/sharelatex-web index 1db599a1bd..122115a5fb 100644 --- a/server-ce/package/upstart/sharelatex-web +++ b/server-ce/package/upstart/sharelatex-web @@ -20,8 +20,9 @@ script # path to Node.js if it's not in your system PATH. NODE=node SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid chdir /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file From 39b8022ae8a09a40b3f1f7c66f1bf14b3b4eedce Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 12:28:19 +0100 Subject: [PATCH 111/525] Move nginx config file location --- server-ce/Gruntfile.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 357e3c660a..954bf645cb 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -394,7 +394,7 @@ module.exports = (grunt) -> command.push( "--maintainer", "ShareLaTeX " "--config-files", "/etc/sharelatex/settings.coffee" - "--config-files", "/etc/nginx/sites-enabled/sharelatex" + "--config-files", "/etc/nginx/conf.d/sharelatex.conf" "--directories", "/var/lib/sharelatex" "--directories", "/var/log/sharelatex" ) @@ -452,7 +452,7 @@ module.exports = (grunt) -> command.push( "package/config/settings.coffee=/etc/sharelatex/settings.coffee" - "package/nginx/sharelatex=/etc/nginx/sites-enabled/sharelatex" + "package/nginx/sharelatex=/etc/nginx/conf.d/sharelatex.conf" ) console.log "fpm " + command.join(" ") proc = spawn "fpm", command, stdio: "inherit" From ea9d056e0e8091f100d0bf9b3893303661a88e91 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 12:50:29 +0100 Subject: [PATCH 112/525] Leave new lines in after_install script --- server-ce/Gruntfile.coffee | 2 ++ server-ce/package/scripts/after_install.sh | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 954bf645cb..a2d5e1ef1c 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -431,10 +431,12 @@ module.exports = (grunt) -> for dir in ["data/user_files", "tmp/uploads", "data/compiles", "data/cache", "tmp/dumpFolder"] after_install_script += """ mkdir -p /var/lib/sharelatex/#{dir} + """ after_install_script += """ chown -R sharelatex:sharelatex /var/lib/sharelatex + """ for service in SERVICES diff --git a/server-ce/package/scripts/after_install.sh b/server-ce/package/scripts/after_install.sh index fa47d7d94b..034a5bf655 100644 --- a/server-ce/package/scripts/after_install.sh +++ b/server-ce/package/scripts/after_install.sh @@ -9,7 +9,13 @@ mkdir -p /var/log/sharelatex chown sharelatex:sharelatex /var/log/sharelatex mkdir -p /var/lib/sharelatex -mkdir -p /var/lib/sharelatex/data/user_filesmkdir -p /var/lib/sharelatex/tmp/uploadsmkdir -p /var/lib/sharelatex/data/compilesmkdir -p /var/lib/sharelatex/data/cachemkdir -p /var/lib/sharelatex/tmp/dumpFolderchown -R sharelatex:sharelatex /var/lib/sharelatexservice sharelatex-web restart +mkdir -p /var/lib/sharelatex/data/user_files +mkdir -p /var/lib/sharelatex/tmp/uploads +mkdir -p /var/lib/sharelatex/data/compiles +mkdir -p /var/lib/sharelatex/data/cache +mkdir -p /var/lib/sharelatex/tmp/dumpFolder +chown -R sharelatex:sharelatex /var/lib/sharelatex +service sharelatex-web restart service sharelatex-document-updater restart service sharelatex-clsi restart service sharelatex-filestore restart From 790fc06b3170a100da44836881a5c85ae14d52e9 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 13:14:47 +0100 Subject: [PATCH 113/525] Support different versions of sharelatex repos --- server-ce/Gruntfile.coffee | 48 ++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index a2d5e1ef1c..a83e835dc3 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -11,30 +11,39 @@ async = require "async" SERVICES = [{ name: "web" repo: "https://github.com/sharelatex/web-sharelatex.git" + version: "master" }, { name: "document-updater" repo: "https://github.com/sharelatex/document-updater-sharelatex.git" + version: "master" }, { name: "clsi" repo: "https://github.com/sharelatex/clsi-sharelatex.git" + version: "master" }, { name: "filestore" repo: "https://github.com/sharelatex/filestore-sharelatex.git" + version: "master" }, { name: "track-changes" repo: "https://github.com/sharelatex/track-changes-sharelatex.git" + version: "master" }, { name: "docstore" repo: "https://github.com/sharelatex/docstore-sharelatex.git" + version: "master" }, { name: "chat" repo: "https://github.com/sharelatex/chat-sharelatex.git" + version: "master" }, { name: "tags" repo: "https://github.com/sharelatex/tags-sharelatex.git" + version: "master" }, { name: "spelling" repo: "https://github.com/sharelatex/spelling-sharelatex.git" + version: "master" }] module.exports = (grunt) -> @@ -86,10 +95,10 @@ module.exports = (grunt) -> do (service) -> grunt.registerTask "install:#{service.name}", "Download and set up the #{service.name} service", () -> done = @async() - Helpers.installService(service.repo, service.name, done) + Helpers.installService(service, done) grunt.registerTask "update:#{service.name}", "Checkout and update the #{service.name} service", () -> done = @async() - Helpers.updateService(service.name, done) + Helpers.updateService(service, done) grunt.registerTask "run:#{service.name}", "Run the ShareLaTeX #{service.name} service", ["bunyan", "execute:#{service.name}"] grunt.registerTask 'install:config', "Copy the example config into the real config", () -> @@ -133,41 +142,50 @@ module.exports = (grunt) -> Helpers = - installService: (repo_src, dir, callback = (error) ->) -> - Helpers.cloneGitRepo repo_src, dir, (error) -> + installService: (service, callback = (error) ->) -> + Helpers.cloneGitRepo service, (error) -> return callback(error) if error? - Helpers.installNpmModules dir, (error) -> + Helpers.installNpmModules service, (error) -> return callback(error) if error? - Helpers.runGruntInstall dir, (error) -> + Helpers.runGruntInstall service, (error) -> return callback(error) if error? callback() - updateService: (dir, callback = (error) ->) -> - Helpers.updateGitRepo dir, (error) -> + updateService: (service, callback = (error) ->) -> + Helpers.updateGitRepo service, (error) -> return callback(error) if error? - Helpers.installNpmModules dir, (error) -> + Helpers.installNpmModules service, (error) -> return callback(error) if error? - Helpers.runGruntInstall dir, (error) -> + Helpers.runGruntInstall service, (error) -> return callback(error) if error? callback() - cloneGitRepo: (repo_src, dir, callback = (error) ->) -> + cloneGitRepo: (service, callback = (error) ->) -> + repo_src = service.repo + dir = service.name if !fs.existsSync(dir) - proc = spawn "git", ["clone", repo_src, dir], stdio: "inherit" + proc = spawn "git", [ + "clone", + "-b", service.version, + repo_src, + dir + ], stdio: "inherit" proc.on "close", () -> callback() else console.log "#{dir} already installed, skipping." callback() - updateGitRepo: (dir, callback = (error) ->) -> - proc = spawn "git", ["checkout", "master"], cwd: dir, stdio: "inherit" + updateGitRepo: (service, callback = (error) ->) -> + dir = service.name + proc = spawn "git", ["checkout", service.version], cwd: dir, stdio: "inherit" proc.on "close", () -> proc = spawn "git", ["pull"], cwd: dir, stdio: "inherit" proc.on "close", () -> callback() - installNpmModules: (dir, callback = (error) ->) -> + installNpmModules: (service, callback = (error) ->) -> + dir = service.name proc = spawn "npm", ["install"], stdio: "inherit", cwd: dir proc.on "close", () -> callback() From 72fc79e48bcaede8c63771ddd76b613db2baaf80 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 14:46:45 +0100 Subject: [PATCH 114/525] Create release tasks --- server-ce/Gruntfile.coffee | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index a83e835dc3..d17eeaac35 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -100,6 +100,9 @@ module.exports = (grunt) -> done = @async() Helpers.updateService(service, done) grunt.registerTask "run:#{service.name}", "Run the ShareLaTeX #{service.name} service", ["bunyan", "execute:#{service.name}"] + grunt.registerTask "release:#{service.name}", "Create a new release version of #{service.name} (specify with --release option)", () -> + done = @async() + Helpers.createNewRelease(service, grunt.option("release"), done) grunt.registerTask 'install:config', "Copy the example config into the real config", () -> Helpers.installConfig @async() @@ -139,7 +142,6 @@ module.exports = (grunt) -> Helpers.buildDeb @async() grunt.registerTask "build:upstart_scripts", "Create upstart scripts for each service", () -> Helpers.buildUpstartScripts() - Helpers = installService: (service, callback = (error) ->) -> @@ -183,7 +185,25 @@ module.exports = (grunt) -> proc = spawn "git", ["pull"], cwd: dir, stdio: "inherit" proc.on "close", () -> callback() - + + createNewRelease: (service, version, callback = (error) ->) -> + dir = service.name + proc = spawn "sed", [ + "-i", "", + "s/\"version\".*$/\"version\": \"#{version}\",/g", + "package.json" + ], cwd: dir, stdio: "inherit" + proc.on "close", () -> + proc = spawn "git", ["commit", "-a", "-m", "Release version #{version}"], cwd: dir, stdio: "inherit" + proc.on "close", () -> + proc = spawn "git", ["tag", "v#{version}"], cwd: dir, stdio: "inherit" + proc.on "close", () -> + proc = spawn "git", ["push"], cwd: dir, stdio: "inherit" + proc.on "close", () -> + proc = spawn "git", ["push", "--tags"], cwd: dir, stdio: "inherit" + proc.on "close", () -> + callback() + installNpmModules: (service, callback = (error) ->) -> dir = service.name proc = spawn "npm", ["install"], stdio: "inherit", cwd: dir From 7a765fa02586824851623653879c4a3d55157a9f Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 15:10:50 +0100 Subject: [PATCH 115/525] Run grunt install inside service directory --- server-ce/Gruntfile.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index d17eeaac35..38885c6cc3 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -241,7 +241,8 @@ module.exports = (grunt) -> grunt.log.writeln "Config file already exists. Skipping." callback() - runGruntInstall: (dir, callback = (error) ->) -> + runGruntInstall: (service, callback = (error) ->) -> + dir = service.name proc = spawn "grunt", ["install"], stdio: "inherit", cwd: dir proc.on "close", () -> callback() From 376e894acada62c3eb4e82c9ce386b50ef65bc6d Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 15:24:58 +0100 Subject: [PATCH 116/525] Install directories on initial installation --- server-ce/Gruntfile.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 38885c6cc3..6f618a8850 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -111,7 +111,7 @@ module.exports = (grunt) -> grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", ["check:make"].concat( ("install:#{service.name}" for service in SERVICES) - ).concat(["install:config"]) + ).concat(["install:config", "install:dirs"]) grunt.registerTask 'install', 'install:all' grunt.registerTask 'update:all', "Checkout and update all ShareLaTeX services", ["check:make"].concat( From 844a1690d92d36e94e9aed2c0c45dfdc40c700ac Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 17:07:18 +0100 Subject: [PATCH 117/525] Update README.md --- server-ce/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index b2bc3698a7..650db15057 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -11,7 +11,9 @@ We have detailed installation instructions in our wiki: * [Installing ShareLaTeX in Production](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) * [Setting up a ShareLaTeX Development Environment](https://github.com/sharelatex/sharelatex/wiki/Setting-up-a-Development-Environment) -**[Please help us make ShareLaTeX as easy to install as possible by answering our quick survey about your system and needs](https://sharelatex.typeform.com/to/PLNits)** +**If you have any problems, have a look at our page of [Frequent Problems and Questions](https://github.com/sharelatex/sharelatex/wiki/FAQ).** + +*[Please help us make ShareLaTeX as easy to install as possible by answering our quick survey about your system and needs](https://sharelatex.typeform.com/to/PLNits)* Dependencies ------------ From d64577fb9dc128b460f7c81e68f23eee694df93b Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 21 Oct 2014 14:20:53 +0100 Subject: [PATCH 118/525] Update README.md --- server-ce/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 650db15057..84dff1826b 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -3,6 +3,8 @@ ShareLaTeX [ShareLaTeX](https://www.sharelatex.com) is an open-source online real-time collaborative LaTeX editor. We run a hosted version at http://www.sharelatex.com, but you can also run your own local version, and contribute to the development of ShareLaTeX. +*[If you want help installing and maintaining ShareLaTeX at your university or workplace, we offer an officially supported version called ShareLaTeX Server Pro. It also comes with extra security and admin features. Click here to find out more!](https://www.sharelatex.com/university/onsite.html)* + Installation ------------ @@ -13,7 +15,6 @@ We have detailed installation instructions in our wiki: **If you have any problems, have a look at our page of [Frequent Problems and Questions](https://github.com/sharelatex/sharelatex/wiki/FAQ).** -*[Please help us make ShareLaTeX as easy to install as possible by answering our quick survey about your system and needs](https://sharelatex.typeform.com/to/PLNits)* Dependencies ------------ From bb03a0f500aaaf023992ec996457ace80721e6c8 Mon Sep 17 00:00:00 2001 From: Ingolf Becker Date: Fri, 14 Nov 2014 16:02:36 +0000 Subject: [PATCH 119/525] Changed chdir to cd for changing directories --- server-ce/package/upstart/sharelatex-chat | 2 +- server-ce/package/upstart/sharelatex-clsi | 2 +- server-ce/package/upstart/sharelatex-docstore | 2 +- server-ce/package/upstart/sharelatex-document-updater | 2 +- server-ce/package/upstart/sharelatex-filestore | 2 +- server-ce/package/upstart/sharelatex-spelling | 2 +- server-ce/package/upstart/sharelatex-tags | 2 +- server-ce/package/upstart/sharelatex-template | 2 +- server-ce/package/upstart/sharelatex-track-changes | 2 +- server-ce/package/upstart/sharelatex-web | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/server-ce/package/upstart/sharelatex-chat b/server-ce/package/upstart/sharelatex-chat index 6f33cdf277..c9abcf64d0 100644 --- a/server-ce/package/upstart/sharelatex-chat +++ b/server-ce/package/upstart/sharelatex-chat @@ -23,6 +23,6 @@ script LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid - chdir /var/www/sharelatex/$SERVICE + cd /var/www/sharelatex/$SERVICE exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-clsi b/server-ce/package/upstart/sharelatex-clsi index 9fa4e3cba9..577392a124 100644 --- a/server-ce/package/upstart/sharelatex-clsi +++ b/server-ce/package/upstart/sharelatex-clsi @@ -23,6 +23,6 @@ script LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid - chdir /var/www/sharelatex/$SERVICE + cd /var/www/sharelatex/$SERVICE exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-docstore b/server-ce/package/upstart/sharelatex-docstore index 6cf35a1ed6..4a93d74afb 100644 --- a/server-ce/package/upstart/sharelatex-docstore +++ b/server-ce/package/upstart/sharelatex-docstore @@ -23,6 +23,6 @@ script LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid - chdir /var/www/sharelatex/$SERVICE + cd /var/www/sharelatex/$SERVICE exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-document-updater b/server-ce/package/upstart/sharelatex-document-updater index f0a6cb356c..3cd58e3661 100644 --- a/server-ce/package/upstart/sharelatex-document-updater +++ b/server-ce/package/upstart/sharelatex-document-updater @@ -23,6 +23,6 @@ script LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid - chdir /var/www/sharelatex/$SERVICE + cd /var/www/sharelatex/$SERVICE exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-filestore b/server-ce/package/upstart/sharelatex-filestore index 9aacb585b0..2cefd29ce5 100644 --- a/server-ce/package/upstart/sharelatex-filestore +++ b/server-ce/package/upstart/sharelatex-filestore @@ -23,6 +23,6 @@ script LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid - chdir /var/www/sharelatex/$SERVICE + cd /var/www/sharelatex/$SERVICE exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-spelling b/server-ce/package/upstart/sharelatex-spelling index 4e9f36f394..cdad8b20ea 100644 --- a/server-ce/package/upstart/sharelatex-spelling +++ b/server-ce/package/upstart/sharelatex-spelling @@ -23,6 +23,6 @@ script LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid - chdir /var/www/sharelatex/$SERVICE + cd /var/www/sharelatex/$SERVICE exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-tags b/server-ce/package/upstart/sharelatex-tags index d075865f1b..340bad2748 100644 --- a/server-ce/package/upstart/sharelatex-tags +++ b/server-ce/package/upstart/sharelatex-tags @@ -23,6 +23,6 @@ script LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid - chdir /var/www/sharelatex/$SERVICE + cd /var/www/sharelatex/$SERVICE exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-template b/server-ce/package/upstart/sharelatex-template index 9270388370..e9b58d9838 100644 --- a/server-ce/package/upstart/sharelatex-template +++ b/server-ce/package/upstart/sharelatex-template @@ -23,6 +23,6 @@ script LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid - chdir /var/www/sharelatex/$SERVICE + cd /var/www/sharelatex/$SERVICE exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-track-changes b/server-ce/package/upstart/sharelatex-track-changes index 1e7df4980b..95c9f57b4c 100644 --- a/server-ce/package/upstart/sharelatex-track-changes +++ b/server-ce/package/upstart/sharelatex-track-changes @@ -23,6 +23,6 @@ script LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid - chdir /var/www/sharelatex/$SERVICE + cd /var/www/sharelatex/$SERVICE exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-web b/server-ce/package/upstart/sharelatex-web index 122115a5fb..92cbf0cb0b 100644 --- a/server-ce/package/upstart/sharelatex-web +++ b/server-ce/package/upstart/sharelatex-web @@ -23,6 +23,6 @@ script LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux echo $$ > /var/run/sharelatex-$SERVICE.pid - chdir /var/www/sharelatex/$SERVICE + cd /var/www/sharelatex/$SERVICE exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 end script \ No newline at end of file From 6fd2e5e6d7961a7fe1886d2e433e071fe8a62e40 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 21 Nov 2014 12:44:53 +0000 Subject: [PATCH 120/525] Add in real-time service --- server-ce/.gitignore | 1 + server-ce/Gruntfile.coffee | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/server-ce/.gitignore b/server-ce/.gitignore index 8dd120550d..b2cbe4ce63 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -11,6 +11,7 @@ docstore tags chat spelling +real-time data tmp diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 6f618a8850..d9c5114557 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -12,6 +12,10 @@ SERVICES = [{ name: "web" repo: "https://github.com/sharelatex/web-sharelatex.git" version: "master" +}, { + name: "real-time" + repo: "https://github.com/sharelatex/real-time-sharelatex.git" + version: "master" }, { name: "document-updater" repo: "https://github.com/sharelatex/document-updater-sharelatex.git" From a0e43f555994ae3265681ad1c784c3487bc1acea Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Mon, 24 Nov 2014 16:13:17 +0000 Subject: [PATCH 121/525] force an npm rebuild to work around issue #129, missing bcrypt bindings file see https://github.com/npm/npm/issues/5400 --- server-ce/Gruntfile.coffee | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index d9c5114557..cb75fed1c2 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -153,18 +153,22 @@ module.exports = (grunt) -> return callback(error) if error? Helpers.installNpmModules service, (error) -> return callback(error) if error? - Helpers.runGruntInstall service, (error) -> + Helpers.rebuildNpmModules service, (error) -> return callback(error) if error? - callback() + Helpers.runGruntInstall service, (error) -> + return callback(error) if error? + callback() updateService: (service, callback = (error) ->) -> Helpers.updateGitRepo service, (error) -> return callback(error) if error? Helpers.installNpmModules service, (error) -> return callback(error) if error? - Helpers.runGruntInstall service, (error) -> + Helpers.rebuildNpmModules service, (error) -> return callback(error) if error? - callback() + Helpers.runGruntInstall service, (error) -> + return callback(error) if error? + callback() cloneGitRepo: (service, callback = (error) ->) -> repo_src = service.repo @@ -207,13 +211,21 @@ module.exports = (grunt) -> proc = spawn "git", ["push", "--tags"], cwd: dir, stdio: "inherit" proc.on "close", () -> callback() - + installNpmModules: (service, callback = (error) ->) -> dir = service.name proc = spawn "npm", ["install"], stdio: "inherit", cwd: dir proc.on "close", () -> callback() - + + # work around for https://github.com/npm/npm/issues/5400 + # where binary modules are not built due to bug in npm + rebuildNpmModules: (service, callback = (error) ->) -> + dir = service.name + proc = spawn "npm", ["rebuild"], stdio: "inherit", cwd: dir + proc.on "close", () -> + callback() + createDataDirs: (callback = (error) ->) -> DIRS = [ "tmp/dumpFolder" From 9df88828358dba2d1802b567060f31ffb0aca3eb Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 4 Dec 2014 10:11:29 +0000 Subject: [PATCH 122/525] Update README.md --- server-ce/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 84dff1826b..7239983343 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -78,6 +78,10 @@ The backend API for managing project tags (folders). An API for running server-side spelling checking on ShareLaTeX documents. +Dropbox +------- + +Please note that certain features like Dropbox integration are not functional in the open source code base yet, despite appearing in the user interface. We're working on this, sorry! Contributing ------------ From f33d9956f9ebeac913ccef98f80249414c782800 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 15 Jan 2015 12:30:42 +0000 Subject: [PATCH 123/525] added minimum memory requirements --- server-ce/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 7239983343..5592c47b73 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -26,6 +26,8 @@ ShareLaTeX should run on OS X and Linux. You need: * A local instance of [Redis](http://redis.io/topics/quickstart) (version 2.6.12 or later) and [MongoDB](http://docs.mongodb.org/manual/installation/) running on their standard ports. * [TeXLive](https://www.tug.org/texlive/) 2013 or later with the `latexmk` program installed. +ShareLaTeX needs a minimum of 2gb of memory, it is likely to be more than that though depending on usage. + Other repositories ------------------ From 219e9a3305490d1e5a6ea915503cab9765677248 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 28 Jan 2015 17:50:39 +0000 Subject: [PATCH 124/525] mvp migration script --- server-ce/Gruntfile.coffee | 18 +++ .../migrations/1422460849371-doc-lines.coffee | 113 ++++++++++++++++++ server-ce/package.json | 6 +- 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 server-ce/migrations/1422460849371-doc-lines.coffee diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index d9c5114557..61be652c2d 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -55,6 +55,8 @@ module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-execute' grunt.loadNpmTasks 'grunt-available-tasks' grunt.loadNpmTasks 'grunt-concurrent' + grunt.loadNpmTasks "grunt-contrib-coffee" + execute = {} for service in SERVICES @@ -70,6 +72,18 @@ module.exports = (grunt) -> options: limit: SERVICES.length logConcurrentOutput: true + coffee: + migrate: + expand: true, + flatten: false, + cwd: './', + src: ['./migrations/*.coffee'], + dest: './', + ext: '.js' + options: + bare:true + + availabletasks: tasks: @@ -147,6 +161,10 @@ module.exports = (grunt) -> grunt.registerTask "build:upstart_scripts", "Create upstart scripts for each service", () -> Helpers.buildUpstartScripts() + + grunt.registerTask 'migrate', 'run migrations', ['coffee:migrate'] + + Helpers = installService: (service, callback = (error) ->) -> Helpers.cloneGitRepo service, (error) -> diff --git a/server-ce/migrations/1422460849371-doc-lines.coffee b/server-ce/migrations/1422460849371-doc-lines.coffee new file mode 100644 index 0000000000..1d370e986f --- /dev/null +++ b/server-ce/migrations/1422460849371-doc-lines.coffee @@ -0,0 +1,113 @@ + +fs = require("fs") +mongojs = require("mongojs") +ObjectId = mongojs.ObjectId +db = mongojs('sharelatex', ['projects', 'docs']) +_ = require("underscore") +async = require("async") + +local_db_path = "/tmp/process-db" + +Datastore = require('nedb') +processDb = new Datastore({ filename: local_db_path}) + + +printProgress = -> + processDb.count {processed:false}, (err, todo)-> + processDb.count {}, (err, total)-> + console.log "#{todo}/#{total} processed" + setTimeout printProgress, 1000 + + +writeProjectIdsToDisk = (callback)-> + db.projects.find {}, {_id:1}, (err,ids)-> + console.log "total found projects in mongo #{ids.length}" + ids = _.map ids, (id)-> return id._id.toString() + jobs = _.map ids, (id)-> + return (cb)-> + processDb.findOne {project_id:id}, (err, doc)-> + if doc? + return cb() + processDb.insert {project_id:id, processed:false}, cb + async.series jobs, (err)-> + processDb.count {processed:false}, (err, count)-> + console.log "projects to process: #{count}" + callback() + +getNextProjectToProccess = (callback)-> + processDb.findOne {processed:false}, (err, doc)-> + callback err, doc.project_id + +markProjectAsProcessed = (project_id, callback)-> + processDb.update project_id:project_id, {$set:{processed:true}}, {}, callback + + +getAllDocs = (project_id, callback = (error, docs) ->) -> + db.projects.findOne _id:ObjectId(project_id), (error, project) -> + return callback(error) if error? + return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? + findAllDocsInProject project, (error, docs) -> + return callback(error) if error? + return callback null, docs + +findAllDocsInProject = (project, callback = (error, docs) ->) -> + callback null, _findAllDocsInFolder project.rootFolder[0] + +_findDocInFolder = (folder = {}, doc_id, currentPath) -> + for doc, i in folder.docs or [] + if doc?._id? and doc._id.toString() == doc_id.toString() + return { + doc: doc + mongoPath: "#{currentPath}.docs.#{i}" + } + + for childFolder, i in folder.folders or [] + result = _findDocInFolder childFolder, doc_id, "#{currentPath}.folders.#{i}" + return result if result? + + return null + +_findAllDocsInFolder = (folder = {}) -> + docs = folder.docs or [] + for childFolder in folder.folders or [] + docs = docs.concat _findAllDocsInFolder childFolder + return docs + +insertDocIntoDocCollection = (project_id, doc_id, lines, oldRev, callback)-> + update = {} + update["_id"] = ObjectId(doc_id) + update["lines"] = lines + update["project_id"] = ObjectId(project_id) + update["rev"] = oldRev + db.docs.insert _id: ObjectId(doc_id), callback + +saveDocsIntoMongo = (project_id, docs, callback)-> + jobs = _.map docs, (doc)-> + (cb)-> + insertDocIntoDocCollection project_id, doc._id, project_id.lines, doc.rev, cb + async.series jobs, callback + + +processNext = -> + processDb.count {processed:false}, (err, total)-> + if total == 0 + console.log "DONE" + process.exit() + else + getNextProjectToProccess (err, project_id)-> + getAllDocs project_id, (err, docs)-> + saveDocsIntoMongo project_id, docs, -> + markProjectAsProcessed project_id, -> + processNext() + +processDb.loadDatabase -> + writeProjectIdsToDisk -> + processNext() + +exports.up = (next)-> + + next() + + +exports.down = (next)-> + next() diff --git a/server-ce/package.json b/server-ce/package.json index 2e922d5b14..fdb5894911 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -4,8 +4,11 @@ "description": "An online collaborative LaTeX editor", "dependencies": { "async": "^0.9.0", + "mongojs": "^0.18.1", + "nedb": "^1.1.1", "rimraf": "~2.2.6", - "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git" + "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git", + "underscore": "^1.7.0" }, "devDependencies": { "grunt": "~0.4.2", @@ -14,6 +17,7 @@ "grunt-execute": "~0.1.5", "grunt-available-tasks": "~0.4.1", "grunt-concurrent": "~0.4.3", + "grunt-contrib-coffee": "~0.10.1", "semver": "~2.2.1", "knox": "~0.8.9" } From b95f94d90eec168cad3e71de9e9f9b7b0b52ad59 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 29 Jan 2015 11:37:52 +0000 Subject: [PATCH 125/525] moved to a file appending with grep data store --- .../migrations/1422460849371-doc-lines.coffee | 83 ++++++++++--------- server-ce/package.json | 2 +- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/server-ce/migrations/1422460849371-doc-lines.coffee b/server-ce/migrations/1422460849371-doc-lines.coffee index 1d370e986f..07ed0f8d6b 100644 --- a/server-ce/migrations/1422460849371-doc-lines.coffee +++ b/server-ce/migrations/1422460849371-doc-lines.coffee @@ -3,44 +3,33 @@ fs = require("fs") mongojs = require("mongojs") ObjectId = mongojs.ObjectId db = mongojs('sharelatex', ['projects', 'docs']) -_ = require("underscore") +_ = require("lodash") async = require("async") +exec = require("child_process").exec -local_db_path = "/tmp/process-db" - -Datastore = require('nedb') -processDb = new Datastore({ filename: local_db_path}) +finished_projects_path = "/tmp/finished-projects" printProgress = -> - processDb.count {processed:false}, (err, todo)-> - processDb.count {}, (err, total)-> - console.log "#{todo}/#{total} processed" - setTimeout printProgress, 1000 + exec "wc #{finished_projects_path}", (error, results) -> + #console.log results + setTimeout printProgress, 1000 * 30 +checkIfFileHasBeenProccessed = (project_id, callback)-> + exec "grep #{project_id} #{finished_projects_path}", (error, results) -> + hasBeenProcessed = _.include(results, project_id) + console.log hasBeenProcessed, project_id + callback(null, hasBeenProcessed) -writeProjectIdsToDisk = (callback)-> +getProjectIds = (callback)-> + console.log "finding all project id's - #{new Date().toString()}" db.projects.find {}, {_id:1}, (err,ids)-> - console.log "total found projects in mongo #{ids.length}" + console.log "total found projects in mongo #{ids.length} - #{new Date().toString()}" ids = _.map ids, (id)-> return id._id.toString() - jobs = _.map ids, (id)-> - return (cb)-> - processDb.findOne {project_id:id}, (err, doc)-> - if doc? - return cb() - processDb.insert {project_id:id, processed:false}, cb - async.series jobs, (err)-> - processDb.count {processed:false}, (err, count)-> - console.log "projects to process: #{count}" - callback() - -getNextProjectToProccess = (callback)-> - processDb.findOne {processed:false}, (err, doc)-> - callback err, doc.project_id + callback(err, ids) markProjectAsProcessed = (project_id, callback)-> - processDb.update project_id:project_id, {$set:{processed:true}}, {}, callback - + fs.appendFile finished_projects_path, "#{project_id}\n", callback getAllDocs = (project_id, callback = (error, docs) ->) -> db.projects.findOne _id:ObjectId(project_id), (error, project) -> @@ -88,21 +77,33 @@ saveDocsIntoMongo = (project_id, docs, callback)-> async.series jobs, callback -processNext = -> - processDb.count {processed:false}, (err, total)-> - if total == 0 - console.log "DONE" - process.exit() - else - getNextProjectToProccess (err, project_id)-> - getAllDocs project_id, (err, docs)-> - saveDocsIntoMongo project_id, docs, -> - markProjectAsProcessed project_id, -> - processNext() +processNext = (project_id, callback)-> + #console.log("starting to process #{project_id} - #{new Date().toString()}") + checkIfFileHasBeenProccessed project_id, (err, hasBeenProcessed)-> + if hasBeenProcessed + return callback() + getAllDocs project_id, (err, docs)-> + if err? + console.error err, project_id, "could not get all docs" + return callback() + saveDocsIntoMongo project_id, docs, -> + if err? + console.error err, project_id, "could not save docs into mongo" + return callback() + markProjectAsProcessed project_id, -> + callback() -processDb.loadDatabase -> - writeProjectIdsToDisk -> - processNext() +getProjectIds (err, ids)-> + printProgress() + jobs = _.map ids, (id)-> + return (cb)-> + processNext(id, cb) + async.series jobs, (err)-> + if err? + console.error err, "at end of jobs" + else + console.log "finished" + process.exit() exports.up = (next)-> diff --git a/server-ce/package.json b/server-ce/package.json index fdb5894911..a50146f3ef 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -4,8 +4,8 @@ "description": "An online collaborative LaTeX editor", "dependencies": { "async": "^0.9.0", + "lodash": "^3.0.0", "mongojs": "^0.18.1", - "nedb": "^1.1.1", "rimraf": "~2.2.6", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git", "underscore": "^1.7.0" From 6f4545810f9299370fbc6ab0902513ac61aff81f Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 29 Jan 2015 12:20:49 +0000 Subject: [PATCH 126/525] added some null checks and more persistance --- .../migrations/1422460849371-doc-lines.coffee | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/server-ce/migrations/1422460849371-doc-lines.coffee b/server-ce/migrations/1422460849371-doc-lines.coffee index 07ed0f8d6b..a97d2907ac 100644 --- a/server-ce/migrations/1422460849371-doc-lines.coffee +++ b/server-ce/migrations/1422460849371-doc-lines.coffee @@ -8,7 +8,7 @@ async = require("async") exec = require("child_process").exec finished_projects_path = "/tmp/finished-projects" - +all_projects_path = "/tmp/all-projects" printProgress = -> exec "wc #{finished_projects_path}", (error, results) -> @@ -18,15 +18,32 @@ printProgress = -> checkIfFileHasBeenProccessed = (project_id, callback)-> exec "grep #{project_id} #{finished_projects_path}", (error, results) -> hasBeenProcessed = _.include(results, project_id) - console.log hasBeenProcessed, project_id + #console.log hasBeenProcessed, project_id callback(null, hasBeenProcessed) -getProjectIds = (callback)-> +loadProjectIds = (callback)-> + fs.readFile all_projects_path, "utf-8", (err, data)-> + console.log data.length + ids = data.split("\n") + console.log ids.length + callback err, ids + +getAndWriteProjectids = (callback)-> console.log "finding all project id's - #{new Date().toString()}" - db.projects.find {}, {_id:1}, (err,ids)-> + db.projects.find {}, {_id:1}, (err, ids)-> console.log "total found projects in mongo #{ids.length} - #{new Date().toString()}" - ids = _.map ids, (id)-> return id._id.toString() - callback(err, ids) + ids = _.pluck ids, '_id' + ids = _.filter ids, (id)-> id? + fileData = ids.join("\n") + fs.writeFile all_projects_path, fileData, -> + callback(err, ids) + +getProjectIds = (callback)-> + exists = fs.existsSync all_projects_path + if exists + loadProjectIds callback + else + getAndWriteProjectids callback markProjectAsProcessed = (project_id, callback)-> fs.appendFile finished_projects_path, "#{project_id}\n", callback @@ -34,7 +51,9 @@ markProjectAsProcessed = (project_id, callback)-> getAllDocs = (project_id, callback = (error, docs) ->) -> db.projects.findOne _id:ObjectId(project_id), (error, project) -> return callback(error) if error? - return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? + if !project? + console.error("No such project: #{project_id}") + return callback("no such project #{project_id}") findAllDocsInProject project, (error, docs) -> return callback(error) if error? return callback null, docs @@ -78,9 +97,9 @@ saveDocsIntoMongo = (project_id, docs, callback)-> processNext = (project_id, callback)-> - #console.log("starting to process #{project_id} - #{new Date().toString()}") checkIfFileHasBeenProccessed project_id, (err, hasBeenProcessed)-> if hasBeenProcessed + console.log "#{project_id} already procssed, skipping" return callback() getAllDocs project_id, (err, docs)-> if err? From 97ea2b6aa1e7c3bd015092fd240ae6a67a2f23b6 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 6 Feb 2015 17:01:50 +0000 Subject: [PATCH 127/525] Initial Dockerfile image build --- server-ce/00_make_sharelatex_data_dirs.sh | 21 + server-ce/00_regen_sharelatex_secrets.sh | 7 + server-ce/Dockerfile | 81 ++++ server-ce/README.md | 70 +++ server-ce/nginx/nginx.conf | 74 +++ server-ce/nginx/sharelatex.conf | 45 ++ server-ce/runit/chat-sharelatex.sh | 3 + server-ce/runit/clsi-sharelatex.sh | 3 + server-ce/runit/docstore-sharelatex.sh | 3 + .../runit/document-updater-sharelatex.sh | 3 + server-ce/runit/filestore-sharelatex.sh | 3 + server-ce/runit/nginx.sh | 2 + server-ce/runit/real-time-sharelatex.sh | 3 + server-ce/runit/spelling-sharelatex.sh | 3 + server-ce/runit/tags-sharelatex.sh | 3 + server-ce/runit/track-changes-sharelatex.sh | 3 + server-ce/runit/web-sharelatex.sh | 3 + server-ce/settings.coffee | 422 ++++++++++++++++++ 18 files changed, 752 insertions(+) create mode 100755 server-ce/00_make_sharelatex_data_dirs.sh create mode 100755 server-ce/00_regen_sharelatex_secrets.sh create mode 100644 server-ce/Dockerfile create mode 100644 server-ce/README.md create mode 100644 server-ce/nginx/nginx.conf create mode 100644 server-ce/nginx/sharelatex.conf create mode 100755 server-ce/runit/chat-sharelatex.sh create mode 100755 server-ce/runit/clsi-sharelatex.sh create mode 100755 server-ce/runit/docstore-sharelatex.sh create mode 100755 server-ce/runit/document-updater-sharelatex.sh create mode 100755 server-ce/runit/filestore-sharelatex.sh create mode 100755 server-ce/runit/nginx.sh create mode 100755 server-ce/runit/real-time-sharelatex.sh create mode 100755 server-ce/runit/spelling-sharelatex.sh create mode 100755 server-ce/runit/tags-sharelatex.sh create mode 100755 server-ce/runit/track-changes-sharelatex.sh create mode 100755 server-ce/runit/web-sharelatex.sh create mode 100644 server-ce/settings.coffee diff --git a/server-ce/00_make_sharelatex_data_dirs.sh b/server-ce/00_make_sharelatex_data_dirs.sh new file mode 100755 index 0000000000..f8d424f201 --- /dev/null +++ b/server-ce/00_make_sharelatex_data_dirs.sh @@ -0,0 +1,21 @@ +#!/bin/sh +mkdir -p /var/lib/sharelatex/data +chown sharelatex:sharelatex /var/lib/sharelatex/data + +mkdir -p /var/lib/sharelatex/data/user_files +chown sharelatex:sharelatex /var/lib/sharelatex/data/user_files + +mkdir -p /var/lib/sharelatex/data/compiles +chown sharelatex:sharelatex /var/lib/sharelatex/data/compiles + +mkdir -p /var/lib/sharelatex/data/cache +chown sharelatex:sharelatex /var/lib/sharelatex/data/cache + +mkdir -p /var/lib/sharelatex/tmp +chown sharelatex:sharelatex /var/lib/sharelatex/tmp + +mkdir -p /var/lib/sharelatex/tmp/uploads +chown sharelatex:sharelatex /var/lib/sharelatex/tmp/uploads + +mkdir -p /var/lib/sharelatex/tmp/dumpFolder +chown sharelatex:sharelatex /var/lib/sharelatex/tmp/dumpFolder \ No newline at end of file diff --git a/server-ce/00_regen_sharelatex_secrets.sh b/server-ce/00_regen_sharelatex_secrets.sh new file mode 100755 index 0000000000..80fd293260 --- /dev/null +++ b/server-ce/00_regen_sharelatex_secrets.sh @@ -0,0 +1,7 @@ +#!/bin/sh +# Create random secret keys (twice, once for http auth pass, once for cookie secret). +CRYPTO_RANDOM=$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 -w 0 | rev | cut -b 2- | rev | tr -d '\n+/') +sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$CRYPTO_RANDOM/" /etc/sharelatex/settings.coffee + +CRYPTO_RANDOM=$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 -w 0 | rev | cut -b 2- | rev | tr -d '\n+/') +sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$CRYPTO_RANDOM/" /etc/sharelatex/settings.coffee diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile new file mode 100644 index 0000000000..77e6ea1aba --- /dev/null +++ b/server-ce/Dockerfile @@ -0,0 +1,81 @@ +FROM phusion/baseimage:0.9.16 + +RUN curl -sL https://deb.nodesource.com/setup | sudo bash - +RUN apt-get install -y build-essential nodejs + +RUN npm install -g grunt-cli + +# Set up sharelatex user and home directory +RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex; \ + mkdir -p /var/lib/sharelatex; \ + chown sharelatex:sharelatex /var/lib/sharelatex; \ + mkdir -p /var/log/sharelatex; \ + chown sharelatex:sharelatex /var/log/sharelatex; + +RUN apt-get install -y git python +RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex + +# zlib1g-dev is needed to compile the synctex binaries in the CLSI during `grunt install`. +RUN apt-get install -y zlib1g-dev + +RUN cd /var/www/sharelatex; \ + npm install; \ + grunt install; + +# Minify js assets +RUN cd /var/www/sharelatex/web; \ + grunt compile:minify; + +RUN apt-get install -y nginx; +RUN rm /etc/nginx/sites-enabled/default +ADD nginx/nginx.conf /etc/nginx/nginx.conf +ADD nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf + +RUN mkdir /etc/service/nginx +ADD runit/nginx.sh /etc/service/nginx/run + +RUN mkdir /etc/service/chat-sharelatex; \ + mkdir /etc/service/clsi-sharelatex; \ + mkdir /etc/service/docstore-sharelatex; \ + mkdir /etc/service/document-updater-sharelatex; \ + mkdir /etc/service/filestore-sharelatex; \ + mkdir /etc/service/real-time-sharelatex; \ + mkdir /etc/service/spelling-sharelatex; \ + mkdir /etc/service/tags-sharelatex; \ + mkdir /etc/service/track-changes-sharelatex; \ + mkdir /etc/service/web-sharelatex; + +ADD runit/chat-sharelatex.sh /etc/service/chat-sharelatex/run +ADD runit/clsi-sharelatex.sh /etc/service/clsi-sharelatex/run +ADD runit/docstore-sharelatex.sh /etc/service/docstore-sharelatex/run +ADD runit/document-updater-sharelatex.sh /etc/service/document-updater-sharelatex/run +ADD runit/filestore-sharelatex.sh /etc/service/filestore-sharelatex/run +ADD runit/real-time-sharelatex.sh /etc/service/real-time-sharelatex/run +ADD runit/spelling-sharelatex.sh /etc/service/spelling-sharelatex/run +ADD runit/tags-sharelatex.sh /etc/service/tags-sharelatex/run +ADD runit/track-changes-sharelatex.sh /etc/service/track-changes-sharelatex/run +ADD runit/web-sharelatex.sh /etc/service/web-sharelatex/run + +RUN mkdir /etc/sharelatex +ADD settings.coffee /etc/sharelatex/settings.coffee + +# phusion/baseimage init script +ADD 00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh +ADD 00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh + +# TexLive +RUN apt-get install -y wget +RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ + mkdir /install-tl-unx; \ + tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 + +RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ + /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile + +ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2014/bin/x86_64-linux/ +RUN tlmgr install latexmk + +# Aspell +RUN apt-get install -y aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu + +ENTRYPOINT ["/sbin/my_init"] \ No newline at end of file diff --git a/server-ce/README.md b/server-ce/README.md new file mode 100644 index 0000000000..ba4eae9155 --- /dev/null +++ b/server-ce/README.md @@ -0,0 +1,70 @@ +ShareLaTeX Docker Image +======================= + +*THIS IS A WORK IN PROGRESS AND THESE INSTRUCTIONS DO NOT WORK YET!* + +The recommended way to install and run ShareLaTeX Community Edition is via Docker: + +``` +$ docker run -d -v /sharelatex-data:/var/lib/sharelatex --net=host --name=sharelatex sharelatex/sharelatex +``` + +This will download the ShareLaTeX image and start it running in the background. + +**Which port does it listen on?**. + +### Mongo and Redis + +The `--net=host` option to docker will allow the ShareLaTeX container to access +ports on the local system. By default it looks for an instance of +[MongoDB](http://www.mongodb.org/) (must be version 2.4 or later) running on port 27017, and +[Redis](http://redis.io/) (must be version 2.6.12 or later) running on port 6379. These are the default ports for +a standard installation of MongoDB and Redis. + +### Persisting and backing up data + +The `-v /sharelatex-data:/var/lib/sharelatex` option in the `run` command tells Docker to mount the local +directory `/sharelatex-data` in the container at `/var/lib/sharelatex`. This is +where ShareLaTeX will store user uploaded files, and allows you to make external backups +of these files, as well as persist them between updates to the ShareLaTeX image. + +### LaTeX environment + +To save bandwidth, the ShareLaTeX image only comes with a minimal install of +TeXLive. To upgrade to a complete TeXLive installation, run the following command: + +``` +$ docker exec sharelatex tlmgr install scheme-full +``` + +Or you can install packages manually as you need by replacing `scheme-full` by +the package name + +### Configuration Options + +You can pass configuration options to ShareLaTeX as environment variables: + +``` +$ docker run -d \ + -v /sharelatex-data:/var/lib/sharelatex \ + --net=host \ + --name=sharelatex \ + --env SHARELATEX_MONGO_URL=mongodb://my.mongo.host/sharelatex \ + sharelatex/sharelatex +``` + +The available configuration parameters are: + +* `SHARELATEX_SITE_URL`: Where your instance of ShareLaTeX is publically available. +This is used in public links, and when connecting over websockets, so much be +configured correctly! +* `SHARELATEX_MONGO_URL`: The URL of the Mongo database to use +* `SHARELATEX_REDIS_HOST`: The host name of the Redis instance to use +* `SHARELATEX_REDIS_PORT`: The port of the Redis instance to use +* `SHARELATEX_REDIS_PASS`: The password to use when connecting to Redis (if applicable) +* `SHARELATEX_SECURE_COOKIE`: Set this to something non-zero to use a secure cookie. + This requires that your ShareLaTeX instance is running behind SSL. + +### Upgrading from older versions + +*TODO: Just stop container, remove 'sharelatex' tag, and run with the new version.* \ No newline at end of file diff --git a/server-ce/nginx/nginx.conf b/server-ce/nginx/nginx.conf new file mode 100644 index 0000000000..03d228c622 --- /dev/null +++ b/server-ce/nginx/nginx.conf @@ -0,0 +1,74 @@ +daemon off; +user www-data; +worker_processes 4; +pid /run/nginx.pid; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + # server_tokens off; + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # Logging Settings + ## + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + ## + # Gzip Settings + ## + + gzip on; + gzip_disable "msie6"; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + # gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # nginx-naxsi config + ## + # Uncomment it if you installed nginx-naxsi + ## + + #include /etc/nginx/naxsi_core.rules; + + ## + # nginx-passenger config + ## + # Uncomment it if you installed nginx-passenger + ## + + #passenger_root /usr; + #passenger_ruby /usr/bin/ruby; + + ## + # Virtual Host Configs + ## + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} diff --git a/server-ce/nginx/sharelatex.conf b/server-ce/nginx/sharelatex.conf new file mode 100644 index 0000000000..e9d6566ffd --- /dev/null +++ b/server-ce/nginx/sharelatex.conf @@ -0,0 +1,45 @@ +server { + listen 80; + server_name _; # Catch all, see http://nginx.org/en/docs/http/server_names.html + + set $static_path /var/www/sharelatex/web/public; + + location / { + proxy_pass http://localhost:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_read_timeout 3m; + proxy_send_timeout 3m; + } + + location /socket.io { + proxy_pass http://localhost:3026; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_read_timeout 3m; + proxy_send_timeout 3m; + } + + location /stylesheets { + expires 1y; + root $static_path/; + } + + location /minjs { + expires 1y; + root $static_path/; + } + + location /img { + expires 1y; + root $static_path/; + } +} diff --git a/server-ce/runit/chat-sharelatex.sh b/server-ce/runit/chat-sharelatex.sh new file mode 100755 index 0000000000..509ff8588e --- /dev/null +++ b/server-ce/runit/chat-sharelatex.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/chat/app.js >> /var/log/sharelatex/chat.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/clsi-sharelatex.sh b/server-ce/runit/clsi-sharelatex.sh new file mode 100755 index 0000000000..59298743c8 --- /dev/null +++ b/server-ce/runit/clsi-sharelatex.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/clsi/app.js >> /var/log/sharelatex/clsi.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/docstore-sharelatex.sh b/server-ce/runit/docstore-sharelatex.sh new file mode 100755 index 0000000000..ba7a96c8d7 --- /dev/null +++ b/server-ce/runit/docstore-sharelatex.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/docstore/app.js >> /var/log/sharelatex/docstore.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/document-updater-sharelatex.sh b/server-ce/runit/document-updater-sharelatex.sh new file mode 100755 index 0000000000..8f692ecdbe --- /dev/null +++ b/server-ce/runit/document-updater-sharelatex.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/document-updater/app.js >> /var/log/sharelatex/document-updater.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/filestore-sharelatex.sh b/server-ce/runit/filestore-sharelatex.sh new file mode 100755 index 0000000000..b02695f747 --- /dev/null +++ b/server-ce/runit/filestore-sharelatex.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/filestore/app.js >> /var/log/sharelatex/filestore.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/nginx.sh b/server-ce/runit/nginx.sh new file mode 100755 index 0000000000..9eacfb4ff2 --- /dev/null +++ b/server-ce/runit/nginx.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec nginx \ No newline at end of file diff --git a/server-ce/runit/real-time-sharelatex.sh b/server-ce/runit/real-time-sharelatex.sh new file mode 100755 index 0000000000..19aaed457b --- /dev/null +++ b/server-ce/runit/real-time-sharelatex.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/real-time/app.js >> /var/log/sharelatex/real-time.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/spelling-sharelatex.sh b/server-ce/runit/spelling-sharelatex.sh new file mode 100755 index 0000000000..848c6ac7d1 --- /dev/null +++ b/server-ce/runit/spelling-sharelatex.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/spelling/app.js >> /var/log/sharelatex/spelling.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/tags-sharelatex.sh b/server-ce/runit/tags-sharelatex.sh new file mode 100755 index 0000000000..8616c1356c --- /dev/null +++ b/server-ce/runit/tags-sharelatex.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/tags/app.js >> /var/log/sharelatex/tags.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/track-changes-sharelatex.sh b/server-ce/runit/track-changes-sharelatex.sh new file mode 100755 index 0000000000..347d8f021a --- /dev/null +++ b/server-ce/runit/track-changes-sharelatex.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/track-changes/app.js >> /var/log/sharelatex/track-changes.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/web-sharelatex.sh b/server-ce/runit/web-sharelatex.sh new file mode 100755 index 0000000000..b0bda54c81 --- /dev/null +++ b/server-ce/runit/web-sharelatex.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/web/app.js >> /var/log/sharelatex/web.log 2>&1 \ No newline at end of file diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee new file mode 100644 index 0000000000..d4b6987f85 --- /dev/null +++ b/server-ce/settings.coffee @@ -0,0 +1,422 @@ +Path = require('path') + +# These credentials are used for authenticating api requests +# between services that may need to go over public channels +httpAuthUser = "sharelatex" +httpAuthPass = "CRYPTO_RANDOM" # Randomly generated for you +httpAuthUsers = {} +httpAuthUsers[httpAuthUser] = httpAuthPass + +DATA_DIR = '/var/lib/sharelatex/data' +TMP_DIR = '/var/lib/sharelatex/tmp' + +module.exports = + # Databases + # --------- + + # ShareLaTeX's main persistant data store is MongoDB (http://www.mongodb.org/) + # Documentation about the URL connection string format can be found at: + # + # http://docs.mongodb.org/manual/reference/connection-string/ + # + # The following works out of the box with Mongo's default settings: + mongo: + url : process.env["SHARELATEX_MONGO_URL"] or 'mongodb://127.0.0.1/sharelatex' + + # Redis is used in ShareLaTeX for high volume queries, like real-time + # editing, and session management. + # + # The following config will work with Redis's default settings: + redis: + web: redisConfig = + host: process.env["SHARELATEX_REDIS_HOST"] or "localhost" + port: process.env["SHARELATEX_REDIS_PORT"] or "6379" + password: process.env["SHARELATEX_REDIS_PASS"] or "" + fairy: redisConfig + + # The compile server (the clsi) uses a SQL database to cache files and + # meta-data. sqllite is the default, and the load is low enough that this will + # be fine in production (we use sqllite at sharelatex.com). + # + # If you want to configure a different database, see the Sequelize documentation + # for available options: + # + # https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage + # + mysql: + clsi: + database: "clsi" + username: "clsi" + password: "" + dialect: "sqlite" + storage: Path.join(DATA_DIR, "db.sqlite") + + # File storage + # ------------ + + # ShareLaTeX can store binary files like images either locally or in Amazon + # S3. The default is locally: + filestore: + backend: "fs" + stores: + user_files: Path.join(DATA_DIR, "user_files") + + # To use Amazon S3 as a storage backend, comment out the above config, and + # uncomment the following, filling in your key, secret, and bucket name: + # + # filestore: + # backend: "s3" + # stores: + # user_files: "BUCKET_NAME" + # s3: + # key: "AWS_KEY" + # secret: "AWS_SECRET" + # + + # Local disk caching + # ------------------ + path: + # If we ever need to write something to disk (e.g. incoming requests + # that need processing but may be too big for memory), then write + # them to disk here: + dumpFolder: Path.join(TMP_DIR, "dumpFolder") + # Where to write uploads before they are processed + uploadFolder: Path.join(TMP_DIR, "uploads") + # Where to write the project to disk before running LaTeX on it + compilesDir: Path.join(DATA_DIR, "compiles") + # Where to cache downloaded URLs for the CLSI + clsiCacheDir: Path.join(DATA_DIR, "cache") + + # Server Config + # ------------- + + # Where your instance of ShareLaTeX can be found publicly. This is used + # when emails are sent out and in generated links: + siteUrl: siteUrl = process.env["SHARELATEX_SITE_URL"] or 'http://localhost:3000' + + # The websocket layer of ShareLaTeX runs as separate service. + # When running locally or in development, you can point the client to this + # service directly. If you are running behind a reverse proxy (Nginx, etc) + # then websocketsUrl should be the same as siteUrl, with your reverse + # proxy responible for sending websocket traffic to the websocket service + # rather than connecting directly. + websocketsUrl: siteUrl + + # If provided, a sessionSecret is used to sign cookies so that they cannot be + # spoofed. This is recommended. + security: + sessionSecret: "CRYPTO_RANDOM" # This was randomly generated for you + + # These credentials are used for authenticating api requests + # between services that may need to go over public channels + httpAuthUsers: httpAuthUsers + + # Should javascript assets be served minified or not. Note that you will + # need to run `grunt compile:minify` within the web-sharelatex directory + # to generate these. + useMinifiedJs: true + + # Should static assets be sent with a header to tell the browser to cache + # them. This should be false in development where changes are being made, + # but should be set to true in production. + cacheStaticAssets: true + + # If you are running ShareLaTeX over https, set this to true to send the + # cookie with a secure flag (recommended). + secureCookie: process.env["SHARELATEX_SECURE_COOKIE"]? + + # If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) + # then set this to true to allow it to correctly detect the forwarded IP + # address and http/https protocol information. + behindProxy: true + + # Sending Email + # ------------- + # + # You must configure a mail server to be able to send invite emails from + # ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer + # documentation for available options: + # + # http://www.nodemailer.com/docs/transports + # + # email: + # fromAddress: "" + # replyTo: "" + # transport: "SES" + # parameters: + # AWSAccessKeyID: "" + # AWSSecretKey: "" + + # Spell Check Languages + # --------------------- + # + # You must have the corresponding aspell dictionary installed to + # be able to use a language. Run `grunt check:aspell` to check which + # dictionaries you have installed. These should be set for the `code` for + # each language. + languages: [{ + "code":"en", + "name":"English (American)" + },{ + "code":"en_GB", + "name":"English (British)" + },{ + "code":"af", + "name":"Africaans" + },{ + "code":"am", + "name":"Amharic" + },{ + "code":"ar", + "name":"Arabic" + },{ + "code":"hy", + "name":"Armenian" + },{ + "code":"gl", + "name":"Galician" + },{ + "code":"eu", + "name":"Basque" + },{ + "code":"bn", + "name":"Bengali" + },{ + "code":"br", + "name":"Breton" + },{ + "code":"bg", + "name":"Bulgarian" + },{ + "code":"ca", + "name":"Catalan" + },{ + "code":"hr", + "name":"Croatian" + },{ + "code":"cs", + "name":"Czech" + },{ + "code":"da", + "name":"Danish" + },{ + "code":"nl", + "name":"Dutch" + },{ + "code":"eo", + "name":"Esperanto" + },{ + "code":"et", + "name":"Estonian" + },{ + "code":"fo", + "name":"Faroese" + },{ + "code":"fr", + "name":"French" + },{ + "code":"de", + "name":"German" + },{ + "code":"el", + "name":"Greek" + },{ + "code":"gu", + "name":"Gujarati" + },{ + "code":"he", + "name":"Hebrew" + },{ + "code":"hi", + "name":"Hindi" + },{ + "code":"hu", + "name":"Hungarian" + },{ + "code":"is", + "name":"Icelandic" + },{ + "code":"id", + "name":"Indonesian" + },{ + "code":"ga", + "name":"Irish" + },{ + "code":"it", + "name":"Italian" + },{ + "code":"kn", + "name":"Kannada" + },{ + "code":"kk", + "name":"Kazakh" + },{ + "code":"ku", + "name":"Kurdish" + },{ + "code":"lv", + "name":"Latvian" + },{ + "code":"lt", + "name":"Lithuanian" + },{ + "code":"ml", + "name":"Malayalam" + },{ + "code":"mr", + "name":"Marathi" + },{ + "code":"nr", + "name":"Ndebele" + },{ + "code":"ns", + "name":"Northern Sotho" + },{ + "code":"no", + "name":"Norwegian" + },{ + "code":"or", + "name":"Oriya" + },{ + "code":"fa", + "name":"Persian" + },{ + "code":"pl", + "name":"Polish" + },{ + "code":"pt_BR", + "name":"Portuguese (Brazilian)" + },{ + "code":"pt_PT", + "name":"Portuguese (European)" + },{ + "code":"pa", + "name":"Punjabi" + },{ + "code":"ro", + "name":"Romanian" + },{ + "code":"ru", + "name":"Russian" + },{ + "code":"sk", + "name":"Slovak" + },{ + "code":"sl", + "name":"Slovenian" + },{ + "code":"st", + "name":"Southern Sotho" + },{ + "code":"es", + "name":"Spanish" + },{ + "code":"ss", + "name":"Swazi" + },{ + "code":"sv", + "name":"Swedish" + },{ + "code":"tl", + "name":"Tagalog" + },{ + "code":"ta", + "name":"Tamil" + },{ + "code":"te", + "name":"Telugu" + },{ + "code":"ts", + "name":"Tsonga" + },{ + "code":"tn", + "name":"Tswana" + },{ + "code":"uk", + "name":"Ukrainian" + },{ + "code":"hsb", + "name":"Upper Sorbian" + },{ + "code":"uz", + "name":"Uzbek" + },{ + "code":"cy", + "name":"Welsh" + },{ + "code":"xh", + "name":"Xhosa" + },{ + "code":"zu", + "name":"Zulu" + } + ] + + # Service locations + # ----------------- + + # ShareLaTeX is comprised of many small services, which each expose + # an HTTP API running on a different port. Generally you + # can leave these as they are unless you have some other services + # running which conflict, or want to run the web process on port 80. + # internal: + # web: + # port: webPort = 3000 + # host: "localhost" + # documentupdater: + # port: docUpdaterPort = 3003 + # host: "localhost" + # filestore: + # port: filestorePort = 3009 + # host: "localhost" + # chat: + # port: chatPort = 3010 + # host: "localhost" + # tags: + # port: tagsPort = 3012 + # host: "localhost" + # clsi: + # port: clsiPort = 3013 + # host: "localhost" + # trackchanges: + # port: trackchangesPort = 3015 + # host: "localhost" + # docstore: + # port: docstorePort = 3016 + # host: "localhost" + # spelling: + # port: spellingPort = 3005 + # host: "localhost" + + # If you change the above config, or run some services on remote servers, + # you need to tell the other services where to find them: + apis: + web: + url: "http://localhost:3000" + user: httpAuthUser + pass: httpAuthPass + # documentupdater: + # url : "http://localhost:#{docUpdaterPort}" + # clsi: + # url: "http://localhost:#{clsiPort}" + # filestore: + # url: "http://localhost:#{filestorePort}" + # trackchanges: + # url: "http://localhost:#{trackchangesPort}" + # docstore: + # url: "http://localhost:#{docstorePort}" + # tags: + # url: "http://localhost:#{tagsPort}" + # spelling: + # url: "http://localhost:#{spellingPort}" + # chat: + # url: "http://localhost:#{chatPort}" + + +# With lots of incoming and outgoing HTTP connections to different services, +# sometimes long running, it is a good idea to increase the default number +# of sockets that Node will hold open. +http = require('http') +http.globalAgent.maxSockets = 300 +https = require('https') +https.globalAgent.maxSockets = 300 From 906919a86fabccd4f7657ef1b3059cb95f52d0d8 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 9 Feb 2015 16:18:58 +0000 Subject: [PATCH 128/525] Don't rely on --net=host --- server-ce/Dockerfile | 13 +++-- server-ce/README.md | 118 ++++++++++++++++++++++++++++++++------ server-ce/settings.coffee | 6 +- 3 files changed, 114 insertions(+), 23 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 77e6ea1aba..dbf7241c51 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -59,10 +59,6 @@ ADD runit/web-sharelatex.sh /etc/service/web-sharelatex/run RUN mkdir /etc/sharelatex ADD settings.coffee /etc/sharelatex/settings.coffee -# phusion/baseimage init script -ADD 00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh -ADD 00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh - # TexLive RUN apt-get install -y wget RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ @@ -71,6 +67,8 @@ RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile +RUN rm -r /install-tl-unx; \ + rm install-tl-unx.tar.gz ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2014/bin/x86_64-linux/ RUN tlmgr install latexmk @@ -78,4 +76,11 @@ RUN tlmgr install latexmk # Aspell RUN apt-get install -y aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu +# phusion/baseimage init script +ADD 00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh +ADD 00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh +ADD 00_set_docker_host_ipaddress.sh /etc/my_init.d/00_set_docker_host_ipaddress.sh + +EXPOSE 80 + ENTRYPOINT ["/sbin/my_init"] \ No newline at end of file diff --git a/server-ce/README.md b/server-ce/README.md index ba4eae9155..a9a0a729eb 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,32 +1,105 @@ ShareLaTeX Docker Image ======================= -*THIS IS A WORK IN PROGRESS AND THESE INSTRUCTIONS DO NOT WORK YET!* +**Please read this entire file before installing ShareLaTeX via Docker. It's only +short but contains some important information.** The recommended way to install and run ShareLaTeX Community Edition is via Docker: ``` -$ docker run -d -v /sharelatex-data:/var/lib/sharelatex --net=host --name=sharelatex sharelatex/sharelatex +$ docker run -d -v sharelatex:/var/lib/sharelatex --name=sharelatex sharelatex/sharelatex ``` This will download the ShareLaTeX image and start it running in the background. -**Which port does it listen on?**. +To stop ShareLaTeX: + +``` +docker stop sharelatex +``` + +and to start it again: + +``` +docker start sharelatex +``` + +If you want to permanently remove ShareLaTeX from your docker containers: + +``` +docker rm sharelatex +``` + +### Storing Data + +The `-v sharelatex:/var/lib/sharelatex` option in the `run` command tells +Docker to make the host directory `sharelatex` available inside the container for +ShareLaTeX to store data files in. This means that you can back up and access these +files manually outside of the ShareLaTeX container. If you would like to store ShareLaTeX data +in a different location, such as `/home/james/my_data`, just change this parameter: + +``` +$ docker run -d \ + -v /home/james/my_data:/var/lib/sharelatex \ + --name=sharelatex \ + sharelatex/sharelatex +``` + +Do not change the second part of this parameter (after the :). + +This is only where ShareLaTeX stores on-disk data. +Other data is also stored in Mongo and Redis. ### Mongo and Redis -The `--net=host` option to docker will allow the ShareLaTeX container to access -ports on the local system. By default it looks for an instance of -[MongoDB](http://www.mongodb.org/) (must be version 2.4 or later) running on port 27017, and -[Redis](http://redis.io/) (must be version 2.6.12 or later) running on port 6379. These are the default ports for -a standard installation of MongoDB and Redis. +ShareLaTeX depends on [MongoDB](http://www.mongodb.org/) (must be 2.4 or later), and +[Redis](http://redis.io/) (must be version 2.6.12 or later). +These should be running on the host system. -### Persisting and backing up data +By default the ShareLaTeX Docker container looks for these running on the host +machine at port 27017 (for Mongo) and port 6379 (for Redis). These are the defaults +ports for both databases so you shouldn't need to change them. -The `-v /sharelatex-data:/var/lib/sharelatex` option in the `run` command tells Docker to mount the local -directory `/sharelatex-data` in the container at `/var/lib/sharelatex`. This is -where ShareLaTeX will store user uploaded files, and allows you to make external backups -of these files, as well as persist them between updates to the ShareLaTeX image. +If you want to point ShareLaTeX at a database in a different location, you can +configure the container with environment variables. See the **Configuration Options** +section below. + +*Note that `localhost` in the container refers only to the container, so if you +want to access services on the host machine then you should use `dockerhost`.* For example: + +``` +$ docker run -d \ + -v sharelatex:/var/lib/sharelatex \ + --name=sharelatex \ + --env SHARELATEX_MONGO_URL=mongodb://dockerhost/sharelatex \ + sharelatex/sharelatex +``` + +### Backups + +To backup the ShareLaTeX data, you need to backup the directory you have attached +to the container, as above. You also need to backup the Mongo and Redis databases. + +### Running on a different port + +The container listens on port 80 by default so you should be able to access +ShareLaTeX at http://localhost/. If you would like to run ShareLaTeX on a different +port (perhaps you have another service running on port 80, or want to put a proxy +in front of ShareLaTeX), then you can forward port 80 from the Docker container +to any other port with the `-p :80` option. For example, to have ShareLaTeX +listen on port 5000: + +``` +$ docker run -d \ + -v sharelatex:/var/lib/sharelatex \ + --name=sharelatex \ + -p 5000:80 \ + --env SHARELATEX_SITE_URL=http://localhost:5000 \ + sharelatex/sharelatex +``` + +(Note that you also have to update the `SHARELATEX_SITE_URL` parameter so that +it knows where it is publicly available.) ### LaTeX environment @@ -38,7 +111,7 @@ $ docker exec sharelatex tlmgr install scheme-full ``` Or you can install packages manually as you need by replacing `scheme-full` by -the package name +the package name. ### Configuration Options @@ -63,8 +136,21 @@ configured correctly! * `SHARELATEX_REDIS_PORT`: The port of the Redis instance to use * `SHARELATEX_REDIS_PASS`: The password to use when connecting to Redis (if applicable) * `SHARELATEX_SECURE_COOKIE`: Set this to something non-zero to use a secure cookie. - This requires that your ShareLaTeX instance is running behind SSL. + Only use this if your ShareLaTeX instance is running behind a reverse proxy with SSL configured. ### Upgrading from older versions -*TODO: Just stop container, remove 'sharelatex' tag, and run with the new version.* \ No newline at end of file +*Please make sure to back up all Mongo, Redis and on-disk data before upgrading.* + +Stop and remove the currently running ShareLaTeX container: + +``` +$ docker stop sharelatex +$ docker rm sharelatex +``` + +Start a new container with the updated version of ShareLaTeX (to upgrade to version 1.4.0 for example): + +``` +$ docker run -d -v sharelatex:/var/lib/sharelatex --name=sharelatex sharelatex/sharelatex:1.4.0 +``` \ No newline at end of file diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index d4b6987f85..622529068a 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -21,7 +21,7 @@ module.exports = # # The following works out of the box with Mongo's default settings: mongo: - url : process.env["SHARELATEX_MONGO_URL"] or 'mongodb://127.0.0.1/sharelatex' + url : process.env["SHARELATEX_MONGO_URL"] or 'mongodb://dockerhost/sharelatex' # Redis is used in ShareLaTeX for high volume queries, like real-time # editing, and session management. @@ -29,7 +29,7 @@ module.exports = # The following config will work with Redis's default settings: redis: web: redisConfig = - host: process.env["SHARELATEX_REDIS_HOST"] or "localhost" + host: process.env["SHARELATEX_REDIS_HOST"] or "dockerhost" port: process.env["SHARELATEX_REDIS_PORT"] or "6379" password: process.env["SHARELATEX_REDIS_PASS"] or "" fairy: redisConfig @@ -92,7 +92,7 @@ module.exports = # Where your instance of ShareLaTeX can be found publicly. This is used # when emails are sent out and in generated links: - siteUrl: siteUrl = process.env["SHARELATEX_SITE_URL"] or 'http://localhost:3000' + siteUrl: siteUrl = process.env["SHARELATEX_SITE_URL"] or 'http://localhost' # The websocket layer of ShareLaTeX runs as separate service. # When running locally or in development, you can point the client to this From 820b6ad4e832b2d2c012727227d3595a184f7def Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 9 Feb 2015 16:27:44 +0000 Subject: [PATCH 129/525] Add missing file --- server-ce/00_set_docker_host_ipaddress.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 server-ce/00_set_docker_host_ipaddress.sh diff --git a/server-ce/00_set_docker_host_ipaddress.sh b/server-ce/00_set_docker_host_ipaddress.sh new file mode 100755 index 0000000000..afd31b69a1 --- /dev/null +++ b/server-ce/00_set_docker_host_ipaddress.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# See the bottom of http://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach +echo "`route -n | awk '/UG[ \t]/{print $2}'` dockerhost" >> /etc/hosts \ No newline at end of file From 897fa1b2237a0aec737c965cf664cb3002193216 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 10 Feb 2015 16:44:07 +0000 Subject: [PATCH 130/525] Create CHANGELOG --- server-ce/CHANGELOG | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 server-ce/CHANGELOG diff --git a/server-ce/CHANGELOG b/server-ce/CHANGELOG new file mode 100644 index 0000000000..2b5fe5d866 --- /dev/null +++ b/server-ce/CHANGELOG @@ -0,0 +1,10 @@ +v0.1.2 +------ + +* Re-brand open-source ShareLaTeX code as 'ShareLaTeX Community Edition'. +* The Dropbox and template code has been extracted out into a separate module and removed from the ShareLaTeX Community Edition. There should be no broken features due to lack of open source components now. +* Websockets and real-time data now go to a separate light-weight [real-time](https://github.com/sharelatex/real-time) service. +* Updated PDF viewer that loads page-by-page for much quicker loading times on large documents. +* Links are clickable in chat messages. +* Mathjax libraries are now served locally. +* Numerous small bug fixes. From b0ac16bc8534c0b0fb0fbadb484fc276aae9aea3 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 10 Feb 2015 16:44:21 +0000 Subject: [PATCH 131/525] Rename CHANGELOG to CHANGELOG.md --- server-ce/{CHANGELOG => CHANGELOG.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename server-ce/{CHANGELOG => CHANGELOG.md} (100%) diff --git a/server-ce/CHANGELOG b/server-ce/CHANGELOG.md similarity index 100% rename from server-ce/CHANGELOG rename to server-ce/CHANGELOG.md From dfa9751edde6f6681e8177da19fc4e3c01f6dd7e Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 10 Feb 2015 16:45:30 +0000 Subject: [PATCH 132/525] Update CHANGELOG.md --- server-ce/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/CHANGELOG.md b/server-ce/CHANGELOG.md index 2b5fe5d866..bc8167022b 100644 --- a/server-ce/CHANGELOG.md +++ b/server-ce/CHANGELOG.md @@ -7,4 +7,5 @@ v0.1.2 * Updated PDF viewer that loads page-by-page for much quicker loading times on large documents. * Links are clickable in chat messages. * Mathjax libraries are now served locally. +* Optimisation of Angular digest loop in editor should reduce CPU usage in certain cases. * Numerous small bug fixes. From 47405a0b31151d04be900c6f2b69cbe5c5476e2d Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 10 Feb 2015 16:49:34 +0000 Subject: [PATCH 133/525] Update to use release version of ShareLaTeX --- server-ce/Dockerfile | 16 ++++++++++------ server-ce/README.md | 34 ++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index dbf7241c51..9d750e5a2e 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -1,8 +1,8 @@ FROM phusion/baseimage:0.9.16 +# Install Node.js and Grunt RUN curl -sL https://deb.nodesource.com/setup | sudo bash - RUN apt-get install -y build-essential nodejs - RUN npm install -g grunt-cli # Set up sharelatex user and home directory @@ -12,8 +12,9 @@ RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharela mkdir -p /var/log/sharelatex; \ chown sharelatex:sharelatex /var/log/sharelatex; +# Install ShareLaTeX RUN apt-get install -y git python -RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex +RUN git clone -b release https://github.com/sharelatex/sharelatex.git /var/www/sharelatex # zlib1g-dev is needed to compile the synctex binaries in the CLSI during `grunt install`. RUN apt-get install -y zlib1g-dev @@ -25,7 +26,8 @@ RUN cd /var/www/sharelatex; \ # Minify js assets RUN cd /var/www/sharelatex/web; \ grunt compile:minify; - + +# Install Nginx as a reverse proxy RUN apt-get install -y nginx; RUN rm /etc/nginx/sites-enabled/default ADD nginx/nginx.conf /etc/nginx/nginx.conf @@ -33,7 +35,8 @@ ADD nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf RUN mkdir /etc/service/nginx ADD runit/nginx.sh /etc/service/nginx/run - + +# Set up ShareLaTeX services to run automatically on boot RUN mkdir /etc/service/chat-sharelatex; \ mkdir /etc/service/clsi-sharelatex; \ mkdir /etc/service/docstore-sharelatex; \ @@ -56,10 +59,11 @@ ADD runit/tags-sharelatex.sh /etc/service/tags-sharelatex/run ADD runit/track-changes-sharelatex.sh /etc/service/track-changes-sharelatex/run ADD runit/web-sharelatex.sh /etc/service/web-sharelatex/run +# Install ShareLaTeX settings file RUN mkdir /etc/sharelatex ADD settings.coffee /etc/sharelatex/settings.coffee -# TexLive +# Install TexLive RUN apt-get install -y wget RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ mkdir /install-tl-unx; \ @@ -73,7 +77,7 @@ RUN rm -r /install-tl-unx; \ ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2014/bin/x86_64-linux/ RUN tlmgr install latexmk -# Aspell +# Install Aspell RUN apt-get install -y aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu # phusion/baseimage init script diff --git a/server-ce/README.md b/server-ce/README.md index a9a0a729eb..5f1eea71f2 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -4,13 +4,13 @@ ShareLaTeX Docker Image **Please read this entire file before installing ShareLaTeX via Docker. It's only short but contains some important information.** -The recommended way to install and run ShareLaTeX Community Edition is via Docker: +The recommended way to install and run ShareLaTeX Community Edition is via [Docker](https://www.docker.com/): ``` -$ docker run -d -v sharelatex:/var/lib/sharelatex --name=sharelatex sharelatex/sharelatex +$ docker run -d -v ~/sharelatex_data:/var/lib/sharelatex -p 80 --name=sharelatex sharelatex/sharelatex ``` -This will download the ShareLaTeX image and start it running in the background. +This will download the ShareLaTeX image and start it running in the background on port 80. You should be able to access it at http://localhost/. To stop ShareLaTeX: @@ -32,8 +32,8 @@ docker rm sharelatex ### Storing Data -The `-v sharelatex:/var/lib/sharelatex` option in the `run` command tells -Docker to make the host directory `sharelatex` available inside the container for +The `-v ~/sharelatex_data:/var/lib/sharelatex` option in the `run` command tells +Docker to make the host directory `~/sharelatex_data` available inside the container for ShareLaTeX to store data files in. This means that you can back up and access these files manually outside of the ShareLaTeX container. If you would like to store ShareLaTeX data in a different location, such as `/home/james/my_data`, just change this parameter: @@ -41,6 +41,7 @@ in a different location, such as `/home/james/my_data`, just change this paramet ``` $ docker run -d \ -v /home/james/my_data:/var/lib/sharelatex \ + -p 80 \ --name=sharelatex \ sharelatex/sharelatex ``` @@ -69,7 +70,8 @@ want to access services on the host machine then you should use `dockerhost`.* F ``` $ docker run -d \ - -v sharelatex:/var/lib/sharelatex \ + -v ~/sharelatex_data:/var/lib/sharelatex \ + -p 80 \ --name=sharelatex \ --env SHARELATEX_MONGO_URL=mongodb://dockerhost/sharelatex \ sharelatex/sharelatex @@ -91,15 +93,15 @@ listen on port 5000: ``` $ docker run -d \ - -v sharelatex:/var/lib/sharelatex \ - --name=sharelatex \ + -v ~/sharelatex_data:/var/lib/sharelatex \ -p 5000:80 \ + --name=sharelatex \ --env SHARELATEX_SITE_URL=http://localhost:5000 \ sharelatex/sharelatex ``` -(Note that you also have to update the `SHARELATEX_SITE_URL` parameter so that -it knows where it is publicly available.) +**(Note that you also have to update the `SHARELATEX_SITE_URL` parameter so that +ShareLaTeX knows where to refer to scripts and links that need loading.)** ### LaTeX environment @@ -119,11 +121,11 @@ You can pass configuration options to ShareLaTeX as environment variables: ``` $ docker run -d \ - -v /sharelatex-data:/var/lib/sharelatex \ - --net=host \ - --name=sharelatex \ - --env SHARELATEX_MONGO_URL=mongodb://my.mongo.host/sharelatex \ - sharelatex/sharelatex + -v ~/sharelatex_data:/var/lib/sharelatex \ + -p 80 \ + --name=sharelatex \ + --env SHARELATEX_MONGO_URL=mongodb://my.mongo.host/sharelatex \ + sharelatex/sharelatex ``` The available configuration parameters are: @@ -152,5 +154,5 @@ $ docker rm sharelatex Start a new container with the updated version of ShareLaTeX (to upgrade to version 1.4.0 for example): ``` -$ docker run -d -v sharelatex:/var/lib/sharelatex --name=sharelatex sharelatex/sharelatex:1.4.0 +$ docker run -d -v ~/sharelatex_data:/var/lib/sharelatex --name=sharelatex sharelatex/sharelatex:1.4.0 ``` \ No newline at end of file From e6be54d087d47516d4bcee550af561175cccbb0b Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 11 Feb 2015 13:54:03 +0000 Subject: [PATCH 134/525] Update README.md --- server-ce/README.md | 61 +++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 5f1eea71f2..820b2ac49f 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -30,6 +30,39 @@ If you want to permanently remove ShareLaTeX from your docker containers: docker rm sharelatex ``` +### Mongo and Redis + +ShareLaTeX depends on [MongoDB](http://www.mongodb.org/) (must be 2.4 or later), and +[Redis](http://redis.io/) (must be version 2.6.12 or later). +These should be running on the host system. + +By default the ShareLaTeX Docker container looks for these running on the host +machine at port 27017 (for Mongo) and port 6379 (for Redis). These are the defaults +ports for both databases so you shouldn't need to change them. + +Note that Docker containers each come with their own network stack, and Mongo and Redis +often listen by default on `127.0.0.1` which is not accessible on the host +from inside the Docker container. Instead, you should configure Mongo and Redis to +also listen on `172.17.42.1` (or whatever ip iddress the docker0 interface has on your +host). This can be done in `/etc/mongod.conf` and `/etc/redis/redis.conf`. + +If you want to point ShareLaTeX at a database in a different location, you can +configure the container with environment variables. See the **Configuration Options** +section below. + +*Note that `localhost` in the container refers only to the container, so if you +want to access services on the host machine then you should use `dockerhost`. +`dockerhost` refers to the the `172.17.42.1` ip address mentioned above.* For example: + +``` +$ docker run -d \ + -v ~/sharelatex_data:/var/lib/sharelatex \ + -p 80 \ + --name=sharelatex \ + --env SHARELATEX_MONGO_URL=mongodb://dockerhost/sharelatex \ + sharelatex/sharelatex +``` + ### Storing Data The `-v ~/sharelatex_data:/var/lib/sharelatex` option in the `run` command tells @@ -51,32 +84,6 @@ Do not change the second part of this parameter (after the :). This is only where ShareLaTeX stores on-disk data. Other data is also stored in Mongo and Redis. -### Mongo and Redis - -ShareLaTeX depends on [MongoDB](http://www.mongodb.org/) (must be 2.4 or later), and -[Redis](http://redis.io/) (must be version 2.6.12 or later). -These should be running on the host system. - -By default the ShareLaTeX Docker container looks for these running on the host -machine at port 27017 (for Mongo) and port 6379 (for Redis). These are the defaults -ports for both databases so you shouldn't need to change them. - -If you want to point ShareLaTeX at a database in a different location, you can -configure the container with environment variables. See the **Configuration Options** -section below. - -*Note that `localhost` in the container refers only to the container, so if you -want to access services on the host machine then you should use `dockerhost`.* For example: - -``` -$ docker run -d \ - -v ~/sharelatex_data:/var/lib/sharelatex \ - -p 80 \ - --name=sharelatex \ - --env SHARELATEX_MONGO_URL=mongodb://dockerhost/sharelatex \ - sharelatex/sharelatex -``` - ### Backups To backup the ShareLaTeX data, you need to backup the directory you have attached @@ -155,4 +162,4 @@ Start a new container with the updated version of ShareLaTeX (to upgrade to vers ``` $ docker run -d -v ~/sharelatex_data:/var/lib/sharelatex --name=sharelatex sharelatex/sharelatex:1.4.0 -``` \ No newline at end of file +``` From 425823a5eb0add997c0adf916bfae9864045f85f Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 11 Feb 2015 13:56:01 +0000 Subject: [PATCH 135/525] Update README.md --- server-ce/README.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 820b2ac49f..1b91bf1ff5 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -36,16 +36,30 @@ ShareLaTeX depends on [MongoDB](http://www.mongodb.org/) (must be 2.4 or later), [Redis](http://redis.io/) (must be version 2.6.12 or later). These should be running on the host system. -By default the ShareLaTeX Docker container looks for these running on the host -machine at port 27017 (for Mongo) and port 6379 (for Redis). These are the defaults -ports for both databases so you shouldn't need to change them. - Note that Docker containers each come with their own network stack, and Mongo and Redis often listen by default on `127.0.0.1` which is not accessible on the host from inside the Docker container. Instead, you should configure Mongo and Redis to also listen on `172.17.42.1` (or whatever ip iddress the docker0 interface has on your host). This can be done in `/etc/mongod.conf` and `/etc/redis/redis.conf`. +``` +# /etc/mongod.conf +... +bind_ip = 172.17.42.1 +... +``` + +``` +# /etc/redis/redis.conf +... +bind 172.17.42.1 +... +``` + +By default the ShareLaTeX Docker container looks for these running on the host +machine at port 27017 (for Mongo) and port 6379 (for Redis). These are the defaults +ports for both databases so you shouldn't need to change them. + If you want to point ShareLaTeX at a database in a different location, you can configure the container with environment variables. See the **Configuration Options** section below. From 69104728ad3e8c7e82fe50ec2771f7a9fbfabf03 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 11 Feb 2015 14:34:39 +0000 Subject: [PATCH 136/525] Update README.md --- server-ce/README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 1b91bf1ff5..011daeb900 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -7,7 +7,11 @@ short but contains some important information.** The recommended way to install and run ShareLaTeX Community Edition is via [Docker](https://www.docker.com/): ``` -$ docker run -d -v ~/sharelatex_data:/var/lib/sharelatex -p 80 --name=sharelatex sharelatex/sharelatex +$ docker run -d \ + -v ~/sharelatex_data:/var/lib/sharelatex \ + -p 5000:80 \ + --name=sharelatex \ + sharelatex/sharelatex ``` This will download the ShareLaTeX image and start it running in the background on port 80. You should be able to access it at http://localhost/. @@ -71,7 +75,7 @@ want to access services on the host machine then you should use `dockerhost`. ``` $ docker run -d \ -v ~/sharelatex_data:/var/lib/sharelatex \ - -p 80 \ + -p 5000:80 \ --name=sharelatex \ --env SHARELATEX_MONGO_URL=mongodb://dockerhost/sharelatex \ sharelatex/sharelatex @@ -143,7 +147,7 @@ You can pass configuration options to ShareLaTeX as environment variables: ``` $ docker run -d \ -v ~/sharelatex_data:/var/lib/sharelatex \ - -p 80 \ + -p 5000:80 \ --name=sharelatex \ --env SHARELATEX_MONGO_URL=mongodb://my.mongo.host/sharelatex \ sharelatex/sharelatex From c0556a3b9e1f0736b97a2f7d3be1ec57bf547d6b Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 11 Feb 2015 14:34:53 +0000 Subject: [PATCH 137/525] Update README.md --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 011daeb900..73b66ff196 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -14,7 +14,7 @@ $ docker run -d \ sharelatex/sharelatex ``` -This will download the ShareLaTeX image and start it running in the background on port 80. You should be able to access it at http://localhost/. +This will download the ShareLaTeX image and start it running in the background on port 5000. You should be able to access it at http://localhost:5000/. To stop ShareLaTeX: From c9ab5f6e22f865a62126251f8c378e871f3ab236 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 11 Feb 2015 16:26:06 +0000 Subject: [PATCH 138/525] Update README.md --- server-ce/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 5592c47b73..816cf4958f 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -15,6 +15,11 @@ We have detailed installation instructions in our wiki: **If you have any problems, have a look at our page of [Frequent Problems and Questions](https://github.com/sharelatex/sharelatex/wiki/FAQ).** +Upgrading +--------- + +If you are upgrading from a previous version of ShareLaTeX, please see the [Release Notes section on the Wiki] (https://github.com/sharelatex/sharelatex/wiki/Home) for all of the versions between your current version and the version you are upgrading to. + Dependencies ------------ From caa785e76cff31d9dd951c9c2ff48771865b2ef6 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 16 Feb 2015 10:02:55 +0000 Subject: [PATCH 139/525] Create sharelatex-real-time --- .../package/upstart/sharelatex-real-time | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 server-ce/package/upstart/sharelatex-real-time diff --git a/server-ce/package/upstart/sharelatex-real-time b/server-ce/package/upstart/sharelatex-real-time new file mode 100644 index 0000000000..7d44f0c8e2 --- /dev/null +++ b/server-ce/package/upstart/sharelatex-real-time @@ -0,0 +1,28 @@ +description "sharelatex-web" +author "ShareLaTeX " + +start on (local-filesystems and net-device-up IFACE!=lo) +stop on shutdown + +respawn + +limit nofile 8192 8192 + +pre-start script + mkdir -p /var/log/sharelatex +end script + +script + SERVICE=real-time + USER=sharelatex + GROUP=sharelatex + # You may need to replace this with an absolute + # path to Node.js if it's not in your system PATH. + NODE=node + SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee + LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux + + echo $$ > /var/run/sharelatex-$SERVICE.pid + cd /var/www/sharelatex/$SERVICE + exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 +end script From d45a10ea359aa41c0fd9363425db82c4d32e7379 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 16 Feb 2015 10:05:14 +0000 Subject: [PATCH 140/525] Update settings.development.coffee.example --- server-ce/config/settings.development.coffee.example | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index c51e2be595..857c8ce2ad 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -93,6 +93,14 @@ module.exports = # when emails are sent out and in generated links: siteUrl : 'http://localhost:3000' + # The websocket layer of ShareLaTeX runs as separate service. + # When running locally or in development, you can point the client to this + # service directly on port 3026. If you are running behind a reverse proxy (Nginx, etc) + # then websocketsUrl should be the same as siteUrl, with your reverse + # proxy responible for sending websocket traffic to the websocket service + # rather than connecting directly. + websocketsUrl: 'http://localhost:3026' + # If provided, a sessionSecret is used to sign cookies so that they cannot be # spoofed. This is recommended. security: From 8512277819e2efc2b05226e59e8bcafaf6ee5710 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 18 Feb 2015 17:08:41 +0000 Subject: [PATCH 141/525] Install unzip in Docker container --- server-ce/Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 9d750e5a2e..19d4d82875 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -80,6 +80,9 @@ RUN tlmgr install latexmk # Install Aspell RUN apt-get install -y aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu +# Install unzip for file uploads +RUN apt-get install -y unzip + # phusion/baseimage init script ADD 00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh ADD 00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh @@ -87,4 +90,4 @@ ADD 00_set_docker_host_ipaddress.sh /etc/my_init.d/00_set_docker_host_ipaddress. EXPOSE 80 -ENTRYPOINT ["/sbin/my_init"] \ No newline at end of file +ENTRYPOINT ["/sbin/my_init"] From 58e12258f63f5c33befe276bbeba715ed74b0608 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 10 Feb 2015 17:25:13 +0000 Subject: [PATCH 142/525] added migrations with east package --- server-ce/Gruntfile.coffee | 9 +- ...71-doc-lines.coffee => 1_doc_lines.coffee} | 85 ++++++++++++------- server-ce/migrations/about_migrations.md | 2 + server-ce/package.json | 3 + 4 files changed, 64 insertions(+), 35 deletions(-) rename server-ce/migrations/{1422460849371-doc-lines.coffee => 1_doc_lines.coffee} (66%) create mode 100644 server-ce/migrations/about_migrations.md diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 3b3339e417..d8e5f5ee3c 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -7,6 +7,8 @@ semver = require "semver" knox = require "knox" crypto = require "crypto" async = require "async" +settings = require("settings-sharelatex") + SERVICES = [{ name: "web" @@ -56,6 +58,7 @@ module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-available-tasks' grunt.loadNpmTasks 'grunt-concurrent' grunt.loadNpmTasks "grunt-contrib-coffee" + grunt.loadNpmTasks "grunt-shell" execute = {} @@ -83,7 +86,9 @@ module.exports = (grunt) -> options: bare:true - + shell: + migrate: + command: "./node_modules/east/bin/east migrate --adapter east-mongo --url #{settings.mongo.url}" availabletasks: tasks: @@ -162,7 +167,7 @@ module.exports = (grunt) -> Helpers.buildUpstartScripts() - grunt.registerTask 'migrate', 'run migrations', ['coffee:migrate'] + grunt.registerTask 'migrate', "compile migrations and run them", ['coffee:migrate', 'shell:migrate'] Helpers = diff --git a/server-ce/migrations/1422460849371-doc-lines.coffee b/server-ce/migrations/1_doc_lines.coffee similarity index 66% rename from server-ce/migrations/1422460849371-doc-lines.coffee rename to server-ce/migrations/1_doc_lines.coffee index a97d2907ac..9e0f8ae7f6 100644 --- a/server-ce/migrations/1422460849371-doc-lines.coffee +++ b/server-ce/migrations/1_doc_lines.coffee @@ -1,8 +1,8 @@ - +Settings = require "settings-sharelatex" fs = require("fs") mongojs = require("mongojs") ObjectId = mongojs.ObjectId -db = mongojs('sharelatex', ['projects', 'docs']) +db = mongojs(Settings.mongo.url, ['projects', 'docs']) _ = require("lodash") async = require("async") exec = require("child_process").exec @@ -19,13 +19,13 @@ checkIfFileHasBeenProccessed = (project_id, callback)-> exec "grep #{project_id} #{finished_projects_path}", (error, results) -> hasBeenProcessed = _.include(results, project_id) #console.log hasBeenProcessed, project_id - callback(null, hasBeenProcessed) + callback(error, hasBeenProcessed) loadProjectIds = (callback)-> + console.log "loading project ids from #{all_projects_path}" fs.readFile all_projects_path, "utf-8", (err, data)-> - console.log data.length ids = data.split("\n") - console.log ids.length + console.log "loaded #{ids.length} project ids from #{all_projects_path}" callback err, ids getAndWriteProjectids = (callback)-> @@ -52,7 +52,6 @@ getAllDocs = (project_id, callback = (error, docs) ->) -> db.projects.findOne _id:ObjectId(project_id), (error, project) -> return callback(error) if error? if !project? - console.error("No such project: #{project_id}") return callback("no such project #{project_id}") findAllDocsInProject project, (error, docs) -> return callback(error) if error? @@ -82,17 +81,34 @@ _findAllDocsInFolder = (folder = {}) -> return docs insertDocIntoDocCollection = (project_id, doc_id, lines, oldRev, callback)-> + if !project_id? + return callback("no project id") + if !doc_id? + return callback("no doc id. project=#{project_id}") + if !lines? + return callback("no lines") update = {} - update["_id"] = ObjectId(doc_id) + update["_id"] = ObjectId(doc_id.toString()) update["lines"] = lines update["project_id"] = ObjectId(project_id) - update["rev"] = oldRev - db.docs.insert _id: ObjectId(doc_id), callback + update["rev"] = oldRev || 0 + # console.log update + db.docs.insert update, callback saveDocsIntoMongo = (project_id, docs, callback)-> jobs = _.map docs, (doc)-> (cb)-> - insertDocIntoDocCollection project_id, doc._id, project_id.lines, doc.rev, cb + if !doc? + console.error "null doc in project #{project_id}" + return cb() + insertDocIntoDocCollection project_id, doc._id, doc.lines, doc.rev, (err)-> + if err?.code == 11000 #duplicate key, doc already in there so its not a problem. + err = undefined + if err? + console.log "error inserting doc into doc collection", err + cb(err) + + async.series jobs, callback @@ -101,33 +117,36 @@ processNext = (project_id, callback)-> if hasBeenProcessed console.log "#{project_id} already procssed, skipping" return callback() + console.log "#{project_id} processing" getAllDocs project_id, (err, docs)-> if err? console.error err, project_id, "could not get all docs" - return callback() - saveDocsIntoMongo project_id, docs, -> - if err? - console.error err, project_id, "could not save docs into mongo" - return callback() - markProjectAsProcessed project_id, -> - callback() + return callback(err) + else + saveDocsIntoMongo project_id, docs, (err)-> + if err? + console.error err, project_id, "could not save docs into mongo" + return callback(err) + markProjectAsProcessed project_id, (err)-> + setTimeout( + -> callback(err) + ,100) + -getProjectIds (err, ids)-> - printProgress() - jobs = _.map ids, (id)-> - return (cb)-> - processNext(id, cb) - async.series jobs, (err)-> - if err? - console.error err, "at end of jobs" - else - console.log "finished" - process.exit() -exports.up = (next)-> +exports.migrate = (client, done)-> + getProjectIds (err, ids)-> + printProgress() + jobs = _.map ids, (id)-> + return (cb)-> + processNext(id, cb) + async.series jobs, (err)-> + if err? + console.error err, "at end of jobs" + else + console.log "finished" + done(err) - next() - - -exports.down = (next)-> + +exports.rollback = (next)-> next() diff --git a/server-ce/migrations/about_migrations.md b/server-ce/migrations/about_migrations.md new file mode 100644 index 0000000000..146cb9c047 --- /dev/null +++ b/server-ce/migrations/about_migrations.md @@ -0,0 +1,2 @@ +* if migration is stopped mid way it will start at the beginging next time +* to see the run migrations do db.getCollection('_migrations').find() you can't do db._migrations.find() \ No newline at end of file diff --git a/server-ce/package.json b/server-ce/package.json index a50146f3ef..cee7ffc776 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -4,6 +4,9 @@ "description": "An online collaborative LaTeX editor", "dependencies": { "async": "^0.9.0", + "east": "^0.2.3", + "east-mongo": "^0.1.2", + "grunt-shell": "^1.1.1", "lodash": "^3.0.0", "mongojs": "^0.18.1", "rimraf": "~2.2.6", From 123ba63ed4bbac16c50767e9ba9edb1d2a6dbc64 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 20 Feb 2015 15:40:11 +0000 Subject: [PATCH 143/525] finished migration script --- server-ce/.gitignore | 1 + server-ce/migrations/1_doc_lines.coffee | 33 ++++++++++++++++--------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/server-ce/.gitignore b/server-ce/.gitignore index b2cbe4ce63..abf5d3ff2f 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -12,6 +12,7 @@ tags chat spelling real-time +migrations/*.js data tmp diff --git a/server-ce/migrations/1_doc_lines.coffee b/server-ce/migrations/1_doc_lines.coffee index 9e0f8ae7f6..9589b67f4c 100644 --- a/server-ce/migrations/1_doc_lines.coffee +++ b/server-ce/migrations/1_doc_lines.coffee @@ -2,6 +2,7 @@ Settings = require "settings-sharelatex" fs = require("fs") mongojs = require("mongojs") ObjectId = mongojs.ObjectId +console.log Settings.mongo.url db = mongojs(Settings.mongo.url, ['projects', 'docs']) _ = require("lodash") async = require("async") @@ -9,16 +10,16 @@ exec = require("child_process").exec finished_projects_path = "/tmp/finished-projects" all_projects_path = "/tmp/all-projects" +project_too_large_path = "/tmp/large_projects" + printProgress = -> exec "wc #{finished_projects_path}", (error, results) -> - #console.log results setTimeout printProgress, 1000 * 30 checkIfFileHasBeenProccessed = (project_id, callback)-> exec "grep #{project_id} #{finished_projects_path}", (error, results) -> hasBeenProcessed = _.include(results, project_id) - #console.log hasBeenProcessed, project_id callback(error, hasBeenProcessed) loadProjectIds = (callback)-> @@ -38,9 +39,14 @@ getAndWriteProjectids = (callback)-> fs.writeFile all_projects_path, fileData, -> callback(err, ids) +markProjectAsToLargeAndFinished = (project_id, callback)-> + console.log "#{project_id} too large" + markProjectAsProcessed project_id, (err)-> + fs.appendFile project_too_large_path, "#{project_id}\n", callback + getProjectIds = (callback)-> exists = fs.existsSync all_projects_path - if exists + if exists loadProjectIds callback else getAndWriteProjectids callback @@ -52,7 +58,11 @@ getAllDocs = (project_id, callback = (error, docs) ->) -> db.projects.findOne _id:ObjectId(project_id), (error, project) -> return callback(error) if error? if !project? - return callback("no such project #{project_id}") + console.log "no such project #{project_id}" + return callback() + size = require("../node_modules/mongojs/node_modules/mongodb/node_modules/bson/").BSONPure.BSON.calculateObjectSize(project) + if size > 12000000 #12mb + return markProjectAsToLargeAndFinished project_id, callback findAllDocsInProject project, (error, docs) -> return callback(error) if error? return callback null, docs @@ -84,27 +94,26 @@ insertDocIntoDocCollection = (project_id, doc_id, lines, oldRev, callback)-> if !project_id? return callback("no project id") if !doc_id? - return callback("no doc id. project=#{project_id}") + return callback() if !lines? - return callback("no lines") + lines = [""] update = {} update["_id"] = ObjectId(doc_id.toString()) update["lines"] = lines update["project_id"] = ObjectId(project_id) update["rev"] = oldRev || 0 - # console.log update db.docs.insert update, callback saveDocsIntoMongo = (project_id, docs, callback)-> jobs = _.map docs, (doc)-> (cb)-> if !doc? - console.error "null doc in project #{project_id}" + console.error "null doc in project #{project_id}" #just skip it, not a big deal return cb() insertDocIntoDocCollection project_id, doc._id, doc.lines, doc.rev, (err)-> if err?.code == 11000 #duplicate key, doc already in there so its not a problem. err = undefined - if err? + if err? console.log "error inserting doc into doc collection", err cb(err) @@ -130,11 +139,11 @@ processNext = (project_id, callback)-> markProjectAsProcessed project_id, (err)-> setTimeout( -> callback(err) - ,100) + ,500) - -exports.migrate = (client, done)-> + +exports.migrate = (client, done = ->)-> getProjectIds (err, ids)-> printProgress() jobs = _.map ids, (id)-> From 6d64d6b57e6f44e8236bdc7aa35c7892da59e9bb Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 20 Feb 2015 15:45:36 +0000 Subject: [PATCH 144/525] commented out the migrate command so people don't run it yet --- server-ce/Gruntfile.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index d8e5f5ee3c..df8cf03045 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -167,7 +167,7 @@ module.exports = (grunt) -> Helpers.buildUpstartScripts() - grunt.registerTask 'migrate', "compile migrations and run them", ['coffee:migrate', 'shell:migrate'] + #grunt.registerTask 'migrate', "compile migrations and run them", ['coffee:migrate', 'shell:migrate'] Helpers = From 049c4d49c1a48e5f5eea449ca01e4c1186891c82 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 26 Feb 2015 12:13:56 +0000 Subject: [PATCH 145/525] Don't blow up on missing settings --- server-ce/Gruntfile.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index df8cf03045..b843b374be 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -88,7 +88,7 @@ module.exports = (grunt) -> shell: migrate: - command: "./node_modules/east/bin/east migrate --adapter east-mongo --url #{settings.mongo.url}" + command: "./node_modules/east/bin/east migrate --adapter east-mongo --url #{settings?.mongo?.url}" availabletasks: tasks: From 983f9bb8706fcc9296b5b64cd3c388ba9bcb80e3 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 4 Mar 2015 22:42:11 +0000 Subject: [PATCH 146/525] Use nodejs 0.10.x --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 816cf4958f..d96591d77a 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -26,7 +26,7 @@ Dependencies ShareLaTeX should run on OS X and Linux. You need: -* [Node.js](http://nodejs.org/) 0.10 or greater. We recommend that you use [nvm](https://github.com/creationix/nvm) to install it. +* [Node.js](http://nodejs.org/) 0.10.x. We recommend that you use [nvm](https://github.com/creationix/nvm) to install it. * The [grunt](http://gruntjs.com/) command line tools (Run `npm install -g grunt-cli` to install them) * A local instance of [Redis](http://redis.io/topics/quickstart) (version 2.6.12 or later) and [MongoDB](http://docs.mongodb.org/manual/installation/) running on their standard ports. * [TeXLive](https://www.tug.org/texlive/) 2013 or later with the `latexmk` program installed. From 1bd2404be18f5e3b24b405c9b6f22da7924251ac Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 5 Mar 2015 18:06:06 +0000 Subject: [PATCH 147/525] remove whitespace before internal settings and add realtime config to settings.development.coffee.example --- .../settings.development.coffee.example | 103 +++++++++--------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example index 857c8ce2ad..ccc1487605 100644 --- a/server-ce/config/settings.development.coffee.example +++ b/server-ce/config/settings.development.coffee.example @@ -63,13 +63,13 @@ module.exports = # To use Amazon S3 as a storage backend, comment out the above config, and # uncomment the following, filling in your key, secret, and bucket name: # - # filestore: - # backend: "s3" - # stores: - # user_files: "BUCKET_NAME" - # s3: - # key: "AWS_KEY" - # secret: "AWS_SECRET" + #filestore: + # backend: "s3" + # stores: + # user_files: "BUCKET_NAME" + # s3: + # key: "AWS_KEY" + # secret: "AWS_SECRET" # # Local disk caching @@ -164,34 +164,37 @@ module.exports = # an HTTP API running on a different port. Generally you # can leave these as they are unless you have some other services # running which conflict, or want to run the web process on port 80. - # internal: - # web: - # port: webPort = 3000 - # host: "localhost" - # documentupdater: - # port: docUpdaterPort = 3003 - # host: "localhost" - # filestore: - # port: filestorePort = 3009 - # host: "localhost" - # chat: - # port: chatPort = 3010 - # host: "localhost" - # tags: - # port: tagsPort = 3012 - # host: "localhost" - # clsi: - # port: clsiPort = 3013 - # host: "localhost" - # trackchanges: - # port: trackchangesPort = 3015 - # host: "localhost" - # docstore: - # port: docstorePort = 3016 - # host: "localhost" - # spelling: + #internal: + # web: + # port: webPort = 3000 + # host: "localhost" + # documentupdater: + # port: docUpdaterPort = 3003 + # host: "localhost" + # filestore: + # port: filestorePort = 3009 + # host: "localhost" + # chat: + # port: chatPort = 3010 + # host: "localhost" + # tags: + # port: tagsPort = 3012 + # host: "localhost" + # clsi: + # port: clsiPort = 3013 + # host: "localhost" + # trackchanges: + # port: trackchangesPort = 3015 + # host: "localhost" + # docstore: + # port: docstorePort = 3016 + # host: "localhost" + # spelling: # port: spellingPort = 3005 - # host: "localhost" + # host: "localhost" + # realTime: + # port: realTimeport = 3026 + # host: "localhost" # If you change the above config, or run some services on remote servers, # you need to tell the other services where to find them: @@ -200,22 +203,22 @@ module.exports = url: "http://localhost:3000" user: httpAuthUser pass: httpAuthPass - # documentupdater: - # url : "http://localhost:#{docUpdaterPort}" - # clsi: - # url: "http://localhost:#{clsiPort}" - # filestore: - # url: "http://localhost:#{filestorePort}" - # trackchanges: - # url: "http://localhost:#{trackchangesPort}" - # docstore: - # url: "http://localhost:#{docstorePort}" - # tags: - # url: "http://localhost:#{tagsPort}" - # spelling: - # url: "http://localhost:#{spellingPort}" - # chat: - # url: "http://localhost:#{chatPort}" + # documentupdater: + # url : "http://localhost:#{docUpdaterPort}" + # clsi: + # url: "http://localhost:#{clsiPort}" + # filestore: + # url: "http://localhost:#{filestorePort}" + # trackchanges: + # url: "http://localhost:#{trackchangesPort}" + # docstore: + # url: "http://localhost:#{docstorePort}" + # tags: + # url: "http://localhost:#{tagsPort}" + # spelling: + # url: "http://localhost:#{spellingPort}" + # chat: + # url: "http://localhost:#{chatPort}" # With lots of incoming and outgoing HTTP connections to different services, From a48a9234ce4fc86238f99b10ab78b1053508612c Mon Sep 17 00:00:00 2001 From: Dennis Chen Date: Fri, 20 Mar 2015 01:31:03 -0700 Subject: [PATCH 148/525] Update NGINX Configuration --- server-ce/package/nginx/sharelatex | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/server-ce/package/nginx/sharelatex b/server-ce/package/nginx/sharelatex index f484240893..0e4fbd1c87 100644 --- a/server-ce/package/nginx/sharelatex +++ b/server-ce/package/nginx/sharelatex @@ -14,6 +14,18 @@ server { proxy_read_timeout 3m; proxy_send_timeout 3m; } + + location /socket.io { + proxy_pass http://localhost:3026; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_x_forwarded_host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_read_timeout 3m; + proxy_send_timeout 3m; + } location /stylesheets { expires 1y; From 56d3a832476bfda1fb7aa1df758e3d34fca1e84b Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 20 Mar 2015 15:32:28 +0000 Subject: [PATCH 149/525] Remove unused/deprecated package files and put .conf in upstart script names --- server-ce/Gruntfile.coffee | 92 +------- server-ce/package/config/settings.coffee | 219 ------------------ server-ce/package/nginx/sharelatex | 44 ---- server-ce/package/scripts/after_install.sh | 26 --- .../{sharelatex-chat => sharelatex-chat.conf} | 0 .../{sharelatex-clsi => sharelatex-clsi.conf} | 0 ...atex-docstore => sharelatex-docstore.conf} | 0 ...dater => sharelatex-document-updater.conf} | 0 ...ex-filestore => sharelatex-filestore.conf} | 0 ...ex-real-time => sharelatex-real-time.conf} | 2 +- ...atex-spelling => sharelatex-spelling.conf} | 0 .../{sharelatex-tags => sharelatex-tags.conf} | 0 ...atex-template => sharelatex-template.conf} | 0 ...-changes => sharelatex-track-changes.conf} | 0 .../{sharelatex-web => sharelatex-web.conf} | 0 15 files changed, 3 insertions(+), 380 deletions(-) delete mode 100644 server-ce/package/config/settings.coffee delete mode 100644 server-ce/package/nginx/sharelatex delete mode 100644 server-ce/package/scripts/after_install.sh rename server-ce/package/upstart/{sharelatex-chat => sharelatex-chat.conf} (100%) rename server-ce/package/upstart/{sharelatex-clsi => sharelatex-clsi.conf} (100%) rename server-ce/package/upstart/{sharelatex-docstore => sharelatex-docstore.conf} (100%) rename server-ce/package/upstart/{sharelatex-document-updater => sharelatex-document-updater.conf} (100%) rename server-ce/package/upstart/{sharelatex-filestore => sharelatex-filestore.conf} (100%) rename server-ce/package/upstart/{sharelatex-real-time => sharelatex-real-time.conf} (98%) rename server-ce/package/upstart/{sharelatex-spelling => sharelatex-spelling.conf} (100%) rename server-ce/package/upstart/{sharelatex-tags => sharelatex-tags.conf} (100%) rename server-ce/package/upstart/{sharelatex-template => sharelatex-template.conf} (100%) rename server-ce/package/upstart/{sharelatex-track-changes => sharelatex-track-changes.conf} (100%) rename server-ce/package/upstart/{sharelatex-web => sharelatex-web.conf} (100%) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index b843b374be..d82427221c 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -161,8 +161,6 @@ module.exports = (grunt) -> Helpers.checkMake @async() grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3", "check:fs", "check:aspell"] - grunt.registerTask "build:deb", "Build an installable .deb file from the current directory", () -> - Helpers.buildDeb @async() grunt.registerTask "build:upstart_scripts", "Create upstart scripts for each service", () -> Helpers.buildUpstartScripts() @@ -457,93 +455,7 @@ module.exports = (grunt) -> return callback() buildUpstartScripts: () -> - template = fs.readFileSync("package/upstart/sharelatex-template").toString() + template = fs.readFileSync("package/upstart/sharelatex-template.conf").toString() for service in SERVICES - fs.writeFileSync "package/upstart/sharelatex-#{service.name}", template.replace(/__SERVICE__/g, service.name) - - buildPackageSettingsFile: () -> - config = fs.readFileSync("config/settings.development.coffee.example").toString() - config = config.replace /DATA_DIR.*/, "DATA_DIR = '/var/lib/sharelatex/data'" - config = config.replace /TMP_DIR.*/, "TMP_DIR = '/var/lib/sharelatex/tmp'" - fs.writeFileSync "package/config/settings.coffee", config - - buildDeb: (callback = (error) ->) -> - command = ["-s", "dir", "-t", "deb", "-n", "sharelatex", "-v", "0.0.1", "--verbose"] - command.push( - "--maintainer", "ShareLaTeX " - "--config-files", "/etc/sharelatex/settings.coffee" - "--config-files", "/etc/nginx/conf.d/sharelatex.conf" - "--directories", "/var/lib/sharelatex" - "--directories", "/var/log/sharelatex" - ) - - command.push( - "--depends", "redis-server > 2.6.12" - "--depends", "mongodb-org > 2.4.0" - "--depends", "nodejs > 0.10.0" - ) - - @buildPackageSettingsFile() - - @buildUpstartScripts() - for service in SERVICES - command.push( - "--deb-upstart", "package/upstart/sharelatex-#{service.name}" - ) - - after_install_script = """ - #!/bin/sh - # Create random secret keys (twice, once for http auth pass, once for cookie secret). - sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee - sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee - - sudo adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex - - mkdir -p /var/log/sharelatex - chown sharelatex:sharelatex /var/log/sharelatex - - mkdir -p /var/lib/sharelatex - - """ - - for dir in ["data/user_files", "tmp/uploads", "data/compiles", "data/cache", "tmp/dumpFolder"] - after_install_script += """ - mkdir -p /var/lib/sharelatex/#{dir} - - """ - - after_install_script += """ - chown -R sharelatex:sharelatex /var/lib/sharelatex - - """ - - for service in SERVICES - after_install_script += "service sharelatex-#{service.name} restart\n" - fs.writeFileSync "package/scripts/after_install.sh", after_install_script - command.push("--after-install", "package/scripts/after_install.sh") - - command.push("--exclude", "**/.git") - command.push("--exclude", "**/node_modules/grunt-*") - for path in ["filestore/user_files", "filestore/uploads", "clsi/cache", "clsi/compiles"] - command.push "--exclude", path - - for service in SERVICES - command.push "#{service.name}=/var/www/sharelatex/" - - command.push( - "package/config/settings.coffee=/etc/sharelatex/settings.coffee" - "package/nginx/sharelatex=/etc/nginx/conf.d/sharelatex.conf" - ) - console.log "fpm " + command.join(" ") - proc = spawn "fpm", command, stdio: "inherit" - proc.on "close", (code) -> - if code != 0 - callback(new Error("exit code: #{code}")) - else - callback() - - - - - + fs.writeFileSync "package/upstart/sharelatex-#{service.name}.conf", template.replace(/__SERVICE__/g, service.name) diff --git a/server-ce/package/config/settings.coffee b/server-ce/package/config/settings.coffee deleted file mode 100644 index bfefca8715..0000000000 --- a/server-ce/package/config/settings.coffee +++ /dev/null @@ -1,219 +0,0 @@ -Path = require('path') - -# These credentials are used for authenticating api requests -# between services that may need to go over public channels -httpAuthUser = "sharelatex" -httpAuthPass = "CRYPTO_RANDOM" # Randomly generated for you -httpAuthUsers = {} -httpAuthUsers[httpAuthUser] = httpAuthPass - -DATA_DIR = '/var/lib/sharelatex/data' -TMP_DIR = '/var/lib/sharelatex/tmp' - -module.exports = - # Databases - # --------- - - # ShareLaTeX's main persistant data store is MongoDB (http://www.mongodb.org/) - # Documentation about the URL connection string format can be found at: - # - # http://docs.mongodb.org/manual/reference/connection-string/ - # - # The following works out of the box with Mongo's default settings: - mongo: - url : 'mongodb://127.0.0.1/sharelatex' - - # Redis is used in ShareLaTeX for high volume queries, like real-time - # editing, and session management. - # - # The following config will work with Redis's default settings: - redis: - web: - host: "localhost" - port: "6379" - password: "" - - # The compile server (the clsi) uses a SQL database to cache files and - # meta-data. sqllite is the default, and the load is low enough that this will - # be fine in production (we use sqllite at sharelatex.com). - # - # If you want to configure a different database, see the Sequelize documentation - # for available options: - # - # https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage - # - mysql: - clsi: - database: "clsi" - username: "clsi" - password: "" - dialect: "sqlite" - storage: Path.join(DATA_DIR, "db.sqlite") - - # File storage - # ------------ - - # ShareLaTeX can store binary files like images either locally or in Amazon - # S3. The default is locally: - filestore: - backend: "fs" - stores: - user_files: Path.join(DATA_DIR, "user_files") - - # To use Amazon S3 as a storage backend, comment out the above config, and - # uncomment the following, filling in your key, secret, and bucket name: - # - # filestore: - # backend: "s3" - # stores: - # user_files: "BUCKET_NAME" - # s3: - # key: "AWS_KEY" - # secret: "AWS_SECRET" - # - - # Local disk caching - # ------------------ - path: - # If we ever need to write something to disk (e.g. incoming requests - # that need processing but may be too big for memory), then write - # them to disk here: - dumpFolder: Path.join(TMP_DIR, "dumpFolder") - # Where to write uploads before they are processed - uploadFolder: Path.join(TMP_DIR, "uploads") - # Where to write the project to disk before running LaTeX on it - compilesDir: Path.join(DATA_DIR, "compiles") - # Where to cache downloaded URLs for the CLSI - clsiCacheDir: Path.join(DATA_DIR, "cache") - - # Server Config - # ------------- - - # Where your instance of ShareLaTeX can be found publicly. This is used - # when emails are sent out and in generated links: - siteUrl : 'http://localhost:3000' - - # If provided, a sessionSecret is used to sign cookies so that they cannot be - # spoofed. This is recommended. - security: - sessionSecret: "CRYPTO_RANDOM" # This was randomly generated for you - - # These credentials are used for authenticating api requests - # between services that may need to go over public channels - httpAuthUsers: httpAuthUsers - - # Should javascript assets be served minified or not. Note that you will - # need to run `grunt compile:minify` within the web-sharelatex directory - # to generate these. - useMinifiedJs: false - - # Should static assets be sent with a header to tell the browser to cache - # them. This should be false in development where changes are being made, - # but should be set to true in production. - cacheStaticAssets: false - - # If you are running ShareLaTeX over https, set this to true to send the - # cookie with a secure flag (recommended). - secureCookie: false - - # If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) - # then set this to true to allow it to correctly detect the forwarded IP - # address and http/https protocol information. - behindProxy: false - - # Sending Email - # ------------- - # - # You must configure a mail server to be able to send invite emails from - # ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer - # documentation for available options: - # - # http://www.nodemailer.com/docs/transports - # - # email: - # fromAddress: "" - # replyTo: "" - # transport: "SES" - # parameters: - # AWSAccessKeyID: "" - # AWSSecretKey: "" - - # Spell Check Languages - # --------------------- - # - # You must have the corresponding aspell dictionary installed to - # be able to use a language. Run `grunt check:aspell` to check which - # dictionaries you have installed. These should be set for the `code` for - # each language. - languages: [ - {name: "English", code: "en"} - ] - - # Service locations - # ----------------- - - # ShareLaTeX is comprised of many small services, which each expose - # an HTTP API running on a different port. Generally you - # can leave these as they are unless you have some other services - # running which conflict, or want to run the web process on port 80. - # internal: - # web: - # port: webPort = 3000 - # host: "localhost" - # documentupdater: - # port: docUpdaterPort = 3003 - # host: "localhost" - # filestore: - # port: filestorePort = 3009 - # host: "localhost" - # chat: - # port: chatPort = 3010 - # host: "localhost" - # tags: - # port: tagsPort = 3012 - # host: "localhost" - # clsi: - # port: clsiPort = 3013 - # host: "localhost" - # trackchanges: - # port: trackchangesPort = 3015 - # host: "localhost" - # docstore: - # port: docstorePort = 3016 - # host: "localhost" - # spelling: - # port: spellingPort = 3005 - # host: "localhost" - - # If you change the above config, or run some services on remote servers, - # you need to tell the other services where to find them: - apis: - web: - url: "http://localhost:3000" - user: httpAuthUser - pass: httpAuthPass - # documentupdater: - # url : "http://localhost:#{docUpdaterPort}" - # clsi: - # url: "http://localhost:#{clsiPort}" - # filestore: - # url: "http://localhost:#{filestorePort}" - # trackchanges: - # url: "http://localhost:#{trackchangesPort}" - # docstore: - # url: "http://localhost:#{docstorePort}" - # tags: - # url: "http://localhost:#{tagsPort}" - # spelling: - # url: "http://localhost:#{spellingPort}" - # chat: - # url: "http://localhost:#{chatPort}" - - -# With lots of incoming and outgoing HTTP connections to different services, -# sometimes long running, it is a good idea to increase the default number -# of sockets that Node will hold open. -http = require('http') -http.globalAgent.maxSockets = 300 -https = require('https') -https.globalAgent.maxSockets = 300 diff --git a/server-ce/package/nginx/sharelatex b/server-ce/package/nginx/sharelatex deleted file mode 100644 index 0e4fbd1c87..0000000000 --- a/server-ce/package/nginx/sharelatex +++ /dev/null @@ -1,44 +0,0 @@ -server { - listen 80; - server_name _; # Catch all, see http://nginx.org/en/docs/http/server_names.html - - set $static_path /var/www/sharelatex/web/public; - - location / { - proxy_pass http://localhost:3000; - proxy_set_header Host $http_x_forwarded_host; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_read_timeout 3m; - proxy_send_timeout 3m; - } - - location /socket.io { - proxy_pass http://localhost:3026; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Host $http_x_forwarded_host; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_read_timeout 3m; - proxy_send_timeout 3m; - } - - location /stylesheets { - expires 1y; - root $static_path/; - } - - location /minjs { - expires 1y; - root $static_path/; - } - - location /img { - expires 1y; - root $static_path/; - } -} diff --git a/server-ce/package/scripts/after_install.sh b/server-ce/package/scripts/after_install.sh deleted file mode 100644 index 034a5bf655..0000000000 --- a/server-ce/package/scripts/after_install.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -# Create random secret keys (twice, once for http auth pass, once for cookie secret). -sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee -sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 64 | head -n 1)/" /etc/sharelatex/settings.coffee - -sudo adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex - -mkdir -p /var/log/sharelatex -chown sharelatex:sharelatex /var/log/sharelatex - -mkdir -p /var/lib/sharelatex -mkdir -p /var/lib/sharelatex/data/user_files -mkdir -p /var/lib/sharelatex/tmp/uploads -mkdir -p /var/lib/sharelatex/data/compiles -mkdir -p /var/lib/sharelatex/data/cache -mkdir -p /var/lib/sharelatex/tmp/dumpFolder -chown -R sharelatex:sharelatex /var/lib/sharelatex -service sharelatex-web restart -service sharelatex-document-updater restart -service sharelatex-clsi restart -service sharelatex-filestore restart -service sharelatex-track-changes restart -service sharelatex-docstore restart -service sharelatex-chat restart -service sharelatex-tags restart -service sharelatex-spelling restart diff --git a/server-ce/package/upstart/sharelatex-chat b/server-ce/package/upstart/sharelatex-chat.conf similarity index 100% rename from server-ce/package/upstart/sharelatex-chat rename to server-ce/package/upstart/sharelatex-chat.conf diff --git a/server-ce/package/upstart/sharelatex-clsi b/server-ce/package/upstart/sharelatex-clsi.conf similarity index 100% rename from server-ce/package/upstart/sharelatex-clsi rename to server-ce/package/upstart/sharelatex-clsi.conf diff --git a/server-ce/package/upstart/sharelatex-docstore b/server-ce/package/upstart/sharelatex-docstore.conf similarity index 100% rename from server-ce/package/upstart/sharelatex-docstore rename to server-ce/package/upstart/sharelatex-docstore.conf diff --git a/server-ce/package/upstart/sharelatex-document-updater b/server-ce/package/upstart/sharelatex-document-updater.conf similarity index 100% rename from server-ce/package/upstart/sharelatex-document-updater rename to server-ce/package/upstart/sharelatex-document-updater.conf diff --git a/server-ce/package/upstart/sharelatex-filestore b/server-ce/package/upstart/sharelatex-filestore.conf similarity index 100% rename from server-ce/package/upstart/sharelatex-filestore rename to server-ce/package/upstart/sharelatex-filestore.conf diff --git a/server-ce/package/upstart/sharelatex-real-time b/server-ce/package/upstart/sharelatex-real-time.conf similarity index 98% rename from server-ce/package/upstart/sharelatex-real-time rename to server-ce/package/upstart/sharelatex-real-time.conf index 7d44f0c8e2..df199c2d9f 100644 --- a/server-ce/package/upstart/sharelatex-real-time +++ b/server-ce/package/upstart/sharelatex-real-time.conf @@ -25,4 +25,4 @@ script echo $$ > /var/run/sharelatex-$SERVICE.pid cd /var/www/sharelatex/$SERVICE exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script +end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-spelling b/server-ce/package/upstart/sharelatex-spelling.conf similarity index 100% rename from server-ce/package/upstart/sharelatex-spelling rename to server-ce/package/upstart/sharelatex-spelling.conf diff --git a/server-ce/package/upstart/sharelatex-tags b/server-ce/package/upstart/sharelatex-tags.conf similarity index 100% rename from server-ce/package/upstart/sharelatex-tags rename to server-ce/package/upstart/sharelatex-tags.conf diff --git a/server-ce/package/upstart/sharelatex-template b/server-ce/package/upstart/sharelatex-template.conf similarity index 100% rename from server-ce/package/upstart/sharelatex-template rename to server-ce/package/upstart/sharelatex-template.conf diff --git a/server-ce/package/upstart/sharelatex-track-changes b/server-ce/package/upstart/sharelatex-track-changes.conf similarity index 100% rename from server-ce/package/upstart/sharelatex-track-changes rename to server-ce/package/upstart/sharelatex-track-changes.conf diff --git a/server-ce/package/upstart/sharelatex-web b/server-ce/package/upstart/sharelatex-web.conf similarity index 100% rename from server-ce/package/upstart/sharelatex-web rename to server-ce/package/upstart/sharelatex-web.conf From 2ab9b1ca264115f1f7d7954f52003f1629f4fef2 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 20 Mar 2015 15:33:36 +0000 Subject: [PATCH 150/525] Add missed nginx file --- server-ce/package/nginx/sharelatex.conf | 44 +++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 server-ce/package/nginx/sharelatex.conf diff --git a/server-ce/package/nginx/sharelatex.conf b/server-ce/package/nginx/sharelatex.conf new file mode 100644 index 0000000000..0e4fbd1c87 --- /dev/null +++ b/server-ce/package/nginx/sharelatex.conf @@ -0,0 +1,44 @@ +server { + listen 80; + server_name _; # Catch all, see http://nginx.org/en/docs/http/server_names.html + + set $static_path /var/www/sharelatex/web/public; + + location / { + proxy_pass http://localhost:3000; + proxy_set_header Host $http_x_forwarded_host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_read_timeout 3m; + proxy_send_timeout 3m; + } + + location /socket.io { + proxy_pass http://localhost:3026; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_x_forwarded_host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_read_timeout 3m; + proxy_send_timeout 3m; + } + + location /stylesheets { + expires 1y; + root $static_path/; + } + + location /minjs { + expires 1y; + root $static_path/; + } + + location /img { + expires 1y; + root $static_path/; + } +} From 044ae86866fb7098575cbceac172005712ab2f7f Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 20 Mar 2015 20:32:07 +0000 Subject: [PATCH 151/525] Update CHANGELOG.md --- server-ce/CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/server-ce/CHANGELOG.md b/server-ce/CHANGELOG.md index bc8167022b..baac4bcc25 100644 --- a/server-ce/CHANGELOG.md +++ b/server-ce/CHANGELOG.md @@ -1,3 +1,23 @@ +v0.1.4 +------ + +* Move to a private registration scheme where users must be added by an admin. +* Proxy websockets connection through web to real-time service so no websocketsUrl parameter is needed. +* Use worker aspell processes in spelling to prevent excessing forking. +* Properly clean up after long running ImageMagick conversions in the filestore. +* Allow a configurable app name and email contact address. +* Switch to new PDF viewer with partial page loading for immediate preview of visible page. + +v0.1.3 +------ + +* Fix bug with large files being corrupted when downloaded. +* Update Ace editor to lastest release. +* Lots of added null checks in the front-end javascript. +* Don't crash if 'unzip' program isn't present. +* Allow track-changes history to be packed into compressed 'packs'. This must be done manually for now. +* Escape any shell special characters in the CLSI root path. + v0.1.2 ------ From 5e00d8d3b4df0c3af9cffea4d2c74f1aedf2fb47 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 25 Mar 2015 16:28:06 +0000 Subject: [PATCH 152/525] Update to use latest ShareLaTeX release --- server-ce/Dockerfile | 9 +++++---- server-ce/README.md | 16 ++++++++++++++++ server-ce/settings.coffee | 15 +++++++-------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 19d4d82875..a8d6d9be82 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -59,10 +59,6 @@ ADD runit/tags-sharelatex.sh /etc/service/tags-sharelatex/run ADD runit/track-changes-sharelatex.sh /etc/service/track-changes-sharelatex/run ADD runit/web-sharelatex.sh /etc/service/web-sharelatex/run -# Install ShareLaTeX settings file -RUN mkdir /etc/sharelatex -ADD settings.coffee /etc/sharelatex/settings.coffee - # Install TexLive RUN apt-get install -y wget RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ @@ -88,6 +84,11 @@ ADD 00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.s ADD 00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh ADD 00_set_docker_host_ipaddress.sh /etc/my_init.d/00_set_docker_host_ipaddress.sh +# Install ShareLaTeX settings file +RUN mkdir /etc/sharelatex +ADD settings.coffee /etc/sharelatex/settings.coffee +ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee + EXPOSE 80 ENTRYPOINT ["/sbin/my_init"] diff --git a/server-ce/README.md b/server-ce/README.md index 73b66ff196..2ac12723b6 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -158,6 +158,8 @@ The available configuration parameters are: * `SHARELATEX_SITE_URL`: Where your instance of ShareLaTeX is publically available. This is used in public links, and when connecting over websockets, so much be configured correctly! +* `SHARELATEX_ADMIN_EMAIL`: The email address where users can reach the person who runs the site. +* `SHARELATEX_APP_NAME`: The name to display when talking about the running app. Defaults to 'ShareLaTex (Community Edition)'. * `SHARELATEX_MONGO_URL`: The URL of the Mongo database to use * `SHARELATEX_REDIS_HOST`: The host name of the Redis instance to use * `SHARELATEX_REDIS_PORT`: The port of the Redis instance to use @@ -165,6 +167,20 @@ configured correctly! * `SHARELATEX_SECURE_COOKIE`: Set this to something non-zero to use a secure cookie. Only use this if your ShareLaTeX instance is running behind a reverse proxy with SSL configured. +### Creating and Managing users + +Uun the following command to create your first user and make them an admin: + +``` +$ docker exec sharelatex /bin/bash -c "cd /var/www/sharelatex/web; grunt create-admin-user --email joe@example.com" +``` + +This will create a user with the given email address if they don't already exist, and make them an admin user. You will be given a URL to visit where you can set the password for this user and log in for the first time. + +**Creating normal users** + +Once you are logged in as an admin user, you can visit `/admin/register` on your ShareLaTeX instance and create a new users. If you have an email backend configured in your settings file, the new users will be sent an email with a URL to set their password. If not, you will have to distribute the password reset URLs manually. These are shown when you create a user. + ### Upgrading from older versions *Please make sure to back up all Mongo, Redis and on-disk data before upgrading.* diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 622529068a..440b59f7fb 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -93,14 +93,13 @@ module.exports = # Where your instance of ShareLaTeX can be found publicly. This is used # when emails are sent out and in generated links: siteUrl: siteUrl = process.env["SHARELATEX_SITE_URL"] or 'http://localhost' - - # The websocket layer of ShareLaTeX runs as separate service. - # When running locally or in development, you can point the client to this - # service directly. If you are running behind a reverse proxy (Nginx, etc) - # then websocketsUrl should be the same as siteUrl, with your reverse - # proxy responible for sending websocket traffic to the websocket service - # rather than connecting directly. - websocketsUrl: siteUrl + + # The name this is used to describe your ShareLaTeX Installation + appName: process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX (Community Edition)" + + # The email address which users will be directed to as the main point of + # contact for this installation of ShareLaTeX. + adminEmail: process.env["SHARELATEX_ADMIN_EMAIL"] or "placeholder@example.com" # If provided, a sessionSecret is used to sign cookies so that they cannot be # spoofed. This is recommended. From 2d012db4208102b6ed55b97af47a4526ab08beb4 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 14 Apr 2015 15:21:07 +0100 Subject: [PATCH 153/525] added migration 2 to clean up projects, removing the doc lines --- .../2_doc_lines_delete_from_project.coffee | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 server-ce/migrations/2_doc_lines_delete_from_project.coffee diff --git a/server-ce/migrations/2_doc_lines_delete_from_project.coffee b/server-ce/migrations/2_doc_lines_delete_from_project.coffee new file mode 100644 index 0000000000..49e7eb0918 --- /dev/null +++ b/server-ce/migrations/2_doc_lines_delete_from_project.coffee @@ -0,0 +1,194 @@ +Settings = require "settings-sharelatex" +fs = require("fs") +mongojs = require("mongojs") +ObjectId = mongojs.ObjectId +console.log Settings.mongo.url +db = mongojs(Settings.mongo.url, ['projects', 'docs']) +_ = require("lodash") +async = require("async") +exec = require("child_process").exec + +finished_projects_path = "/home/sharelatex/finished-projects" +all_projects_path = "/home/sharelatex/all-projects" +unmigrated_docs_path = "/home/sharelatex/unmigrated" + +processedFiles = fs.readFileSync finished_projects_path + +printProgress = -> + exec "wc #{finished_projects_path}", (error, results) -> + setTimeout printProgress, 1000 * 30 + +checkIfFileHasBeenProccessed = (project_id, callback)-> + hasBeenProcessed = _.include processedFiles, project + callback null, hasBeenProcessed + # exec "grep #{project_id} #{finished_projects_path}", (error, results) -> + # hasBeenProcessed = _.include(results, project_id) + # callback(error, hasBeenProcessed) + +loadProjectIds = (callback)-> + console.log "loading project ids from #{all_projects_path}" + fs.readFile all_projects_path, "utf-8", (err, data)-> + ids = data.split("\n") + console.log "loaded #{ids.length} project ids from #{all_projects_path}" + callback err, ids + +getAndWriteProjectids = (callback)-> + console.log "finding all project id's - #{new Date().toString()}" + db.projects.find {}, {_id:1}, (err, ids)-> + console.log "total found projects in mongo #{ids.length} - #{new Date().toString()}" + ids = _.pluck ids, '_id' + ids = _.filter ids, (id)-> id? + fileData = ids.join("\n") + fs.writeFile all_projects_path, fileData, -> + callback(err, ids) + +markDocAsUnmigrated = (project_id, doc_id, callback)-> + console.log "#{project_id} #{doc_id} unmigrated" + markProjectAsProcessed project_id, (err)-> + fs.appendFile unmigrated_docs_path, "#{project_id} #{doc_id}\n", callback + +markUnmigratedDocs = (project_id, docs, callback)-> + console.log docs.length, project_id, "unmigrated" + jobs = _.map docs, (doc)-> + (cb)-> + markDocAsUnmigrated project_id, doc._id, cb + async.series jobs, callback + +getProjectIds = (callback)-> + exists = fs.existsSync all_projects_path + if exists + loadProjectIds callback + else + getAndWriteProjectids callback + +markProjectAsProcessed = (project_id, callback)-> + fs.appendFile finished_projects_path, "#{project_id}\n", callback + +getAllDocs = (project_id, callback = (error, docs) ->) -> + excludes = {} + for i in [0..12] + excludes["rootFolder#{Array(i).join(".folders")}.docs.lines"] = 0 + db.projects.findOne _id: ObjectId(project_id.toString()), excludes, (error, project) -> + return callback(error) if error? + if !project? + console.log "no such project #{project_id}" + return callback() + findAllDocsInProject project, (error, docs) -> + return callback(error) if error? + return callback null, docs, project + +findAllDocsInProject = (project, callback = (error, docs) ->) -> + callback null, _findAllDocsInFolder project.rootFolder[0] + +findDocInProject = (project, doc_id, callback = (error, doc, mongoPath) ->) -> + result = _findDocInFolder project.rootFolder[0], doc_id, "rootFolder.0" + if result? + callback null, result.doc, result.mongoPath + else + callback null, null, null + +_findDocInFolder = (folder = {}, doc_id, currentPath) -> + for doc, i in folder.docs or [] + if doc?._id? and doc._id.toString() == doc_id.toString() + return { + doc: doc + mongoPath: "#{currentPath}.docs.#{i}" + } + for childFolder, i in folder.folders or [] + result = _findDocInFolder childFolder, doc_id, "#{currentPath}.folders.#{i}" + return result if result? + + return null + +_findAllDocsInFolder = (folder = {}) -> + docs = folder.docs or [] + for childFolder in folder.folders or [] + docs = docs.concat _findAllDocsInFolder childFolder + return docs + +isDocInDocCollection = (doc, callback)-> + if !doc?._id? or doc._id.length == 0 + return callback(null, true) + db.docs.find({_id: ObjectId(doc._id+"")}, {_id: 1}).limit 1, (err, foundDocs)-> + exists = foundDocs.length > 0 + console.log doc._id, "Exits = "+exists + callback err, exists + +getWhichDocsCanBeDeleted = (docs, callback = (err, docsToBeDeleted, unmigratedDocs)->)-> + docsToBeDeleted = [] + unmigratedDocs = [] + + jobs = _.map docs, (doc)-> + return (cb)-> + isDocInDocCollection doc, (err, exists)-> + if exists + docsToBeDeleted.push doc + else + unmigratedDocs.push doc + cb(err) + async.series jobs, (err)-> + callback err, docsToBeDeleted, unmigratedDocs + +whipeDocLines = (project_id, mongoPath, callback)-> + update = + $unset: {} + update.$unset["#{mongoPath}.lines"] = "" + update.$unset["#{mongoPath}.rev"] = "" + console.log "project id = #{ObjectId(project_id+'')}", update + #callback() + db.projects.update _id: ObjectId(project_id+''), update, callback + + +removeDocLinesFromProject = (docs, project, callback)-> + jobs = _.map docs, (doc)-> + (cb)-> + findDocInProject project, doc._id, (err, doc, mongoPath)-> + whipeDocLines project._id, mongoPath, cb + async.parallelLimit jobs, 5, callback + +processNext = (project_id, callback)-> + if !project_id? or project_id.length == 0 + return callback() + checkIfFileHasBeenProccessed project_id, (err, hasBeenProcessed)-> + if hasBeenProcessed + console.log "#{project_id} already procssed, skipping" + return callback() + console.log "#{project_id} processing" + getAllDocs project_id, (err, docs, project)-> + if err? + console.error err, project_id, "could not get all docs" + return callback(err) + else + getWhichDocsCanBeDeleted docs, (err, docsToBeDeleted, unmigratedDocs)-> + if err? + console.error err, project_id, "could not save docs into mongo" + return callback(err) + markUnmigratedDocs project_id, unmigratedDocs, (err)-> + removeDocLinesFromProject docsToBeDeleted, project, (err)-> + if err? + return callback(err) + markProjectAsProcessed project_id, (err)-> + setTimeout( + -> callback(err) + ,5000) + +exports.migrate = (client, done = ->)-> + getProjectIds (err, ids)-> + printProgress() + jobs = _.map ids, (id)-> + return (cb)-> + processNext(id, cb) + async.series jobs, (err)-> + if err? + console.error err, "at end of jobs" + process.exit() + else + console.log "finished" + process.exit() + done(err) + + +exports.rollback = (next)-> + next() + +exports.migrate() From 2ee81d6c50323f6dd83216311236a56f84308d7b Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 16 Apr 2015 13:45:16 +0100 Subject: [PATCH 154/525] improved migration script to delete docs --- .../2_doc_lines_delete_from_project.coffee | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/server-ce/migrations/2_doc_lines_delete_from_project.coffee b/server-ce/migrations/2_doc_lines_delete_from_project.coffee index 49e7eb0918..bc413d8134 100644 --- a/server-ce/migrations/2_doc_lines_delete_from_project.coffee +++ b/server-ce/migrations/2_doc_lines_delete_from_project.coffee @@ -8,22 +8,19 @@ _ = require("lodash") async = require("async") exec = require("child_process").exec -finished_projects_path = "/home/sharelatex/finished-projects" -all_projects_path = "/home/sharelatex/all-projects" -unmigrated_docs_path = "/home/sharelatex/unmigrated" +finished_projects_path = "./finished-projects" +all_projects_path = "./all-projects" +unmigrated_docs_path = "./unmigrated" -processedFiles = fs.readFileSync finished_projects_path printProgress = -> exec "wc #{finished_projects_path}", (error, results) -> setTimeout printProgress, 1000 * 30 checkIfFileHasBeenProccessed = (project_id, callback)-> - hasBeenProcessed = _.include processedFiles, project - callback null, hasBeenProcessed - # exec "grep #{project_id} #{finished_projects_path}", (error, results) -> - # hasBeenProcessed = _.include(results, project_id) - # callback(error, hasBeenProcessed) + exec "grep #{project_id} #{finished_projects_path}", (error, results) -> + hasBeenProcessed = _.include(results, project_id) + callback(error, hasBeenProcessed) loadProjectIds = (callback)-> console.log "loading project ids from #{all_projects_path}" @@ -191,4 +188,3 @@ exports.migrate = (client, done = ->)-> exports.rollback = (next)-> next() -exports.migrate() From 0218f9624e0f35c5f337fe8df31f7b53a62d1a89 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 16 Sep 2015 13:41:09 +0100 Subject: [PATCH 155/525] add the migrate task into grunt --- server-ce/Gruntfile.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index d82427221c..9ed6ff9275 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -165,7 +165,7 @@ module.exports = (grunt) -> Helpers.buildUpstartScripts() - #grunt.registerTask 'migrate', "compile migrations and run them", ['coffee:migrate', 'shell:migrate'] + grunt.registerTask 'migrate', "compile migrations and run them", ['coffee:migrate', 'shell:migrate'] Helpers = From 856404099b0ffcca4a86046522eb49893fcf7519 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 16 Sep 2015 14:22:54 +0100 Subject: [PATCH 156/525] renamed first migration to move_doc_lines_to_doc_collection --- ...doc_lines.coffee => 1_move_doc_lines_to_doc_collection.coffee} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename server-ce/migrations/{1_doc_lines.coffee => 1_move_doc_lines_to_doc_collection.coffee} (100%) diff --git a/server-ce/migrations/1_doc_lines.coffee b/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee similarity index 100% rename from server-ce/migrations/1_doc_lines.coffee rename to server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee From 0ef14ce759ac216674798135832e4e0c46ff59d8 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 16 Sep 2015 14:44:53 +0100 Subject: [PATCH 157/525] bring down migration timeout in delete doc lines to 0ms --- server-ce/migrations/2_doc_lines_delete_from_project.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/migrations/2_doc_lines_delete_from_project.coffee b/server-ce/migrations/2_doc_lines_delete_from_project.coffee index bc413d8134..ee0b74b914 100644 --- a/server-ce/migrations/2_doc_lines_delete_from_project.coffee +++ b/server-ce/migrations/2_doc_lines_delete_from_project.coffee @@ -167,7 +167,7 @@ processNext = (project_id, callback)-> markProjectAsProcessed project_id, (err)-> setTimeout( -> callback(err) - ,5000) + ,0) exports.migrate = (client, done = ->)-> getProjectIds (err, ids)-> From da42dff40ef9e08c90180a2b3bc290cf24d8eb37 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 16 Sep 2015 15:58:38 +0100 Subject: [PATCH 158/525] change timeout in migrations-1 to 0ms --- server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee b/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee index 9589b67f4c..d1f94638b3 100644 --- a/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee +++ b/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee @@ -139,7 +139,7 @@ processNext = (project_id, callback)-> markProjectAsProcessed project_id, (err)-> setTimeout( -> callback(err) - ,500) + ,0) From ffd21cd0805860bef0fb20b5306a1f9e30b13adf Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 16 Sep 2015 16:26:51 +0100 Subject: [PATCH 159/525] remove process.exit from migrations --- server-ce/migrations/2_doc_lines_delete_from_project.coffee | 2 -- 1 file changed, 2 deletions(-) diff --git a/server-ce/migrations/2_doc_lines_delete_from_project.coffee b/server-ce/migrations/2_doc_lines_delete_from_project.coffee index ee0b74b914..96c8d5b334 100644 --- a/server-ce/migrations/2_doc_lines_delete_from_project.coffee +++ b/server-ce/migrations/2_doc_lines_delete_from_project.coffee @@ -178,10 +178,8 @@ exports.migrate = (client, done = ->)-> async.series jobs, (err)-> if err? console.error err, "at end of jobs" - process.exit() else console.log "finished" - process.exit() done(err) From 40f9a59507d620cc17b286e7a8ec0e805f2592b7 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 16 Sep 2015 16:27:47 +0100 Subject: [PATCH 160/525] remove extra logging in migration and change file paths in migration 2 --- .../migrations/2_doc_lines_delete_from_project.coffee | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/server-ce/migrations/2_doc_lines_delete_from_project.coffee b/server-ce/migrations/2_doc_lines_delete_from_project.coffee index 96c8d5b334..1e6a13dbf7 100644 --- a/server-ce/migrations/2_doc_lines_delete_from_project.coffee +++ b/server-ce/migrations/2_doc_lines_delete_from_project.coffee @@ -2,15 +2,14 @@ Settings = require "settings-sharelatex" fs = require("fs") mongojs = require("mongojs") ObjectId = mongojs.ObjectId -console.log Settings.mongo.url db = mongojs(Settings.mongo.url, ['projects', 'docs']) _ = require("lodash") async = require("async") exec = require("child_process").exec -finished_projects_path = "./finished-projects" -all_projects_path = "./all-projects" -unmigrated_docs_path = "./unmigrated" +finished_projects_path = "/tmp/finished-projects-2" +all_projects_path = "/tmp/all-projects-2" +unmigrated_docs_path = "/tmp/unmigrated-2" printProgress = -> @@ -108,7 +107,6 @@ isDocInDocCollection = (doc, callback)-> return callback(null, true) db.docs.find({_id: ObjectId(doc._id+"")}, {_id: 1}).limit 1, (err, foundDocs)-> exists = foundDocs.length > 0 - console.log doc._id, "Exits = "+exists callback err, exists getWhichDocsCanBeDeleted = (docs, callback = (err, docsToBeDeleted, unmigratedDocs)->)-> @@ -131,8 +129,6 @@ whipeDocLines = (project_id, mongoPath, callback)-> $unset: {} update.$unset["#{mongoPath}.lines"] = "" update.$unset["#{mongoPath}.rev"] = "" - console.log "project id = #{ObjectId(project_id+'')}", update - #callback() db.projects.update _id: ObjectId(project_id+''), update, callback From 195e22b45ec8ad317c79460f1c06f9546ae92276 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 17 Sep 2015 14:07:50 +0000 Subject: [PATCH 161/525] added mongodb migrations added imagemagick make sure release is up to date --- server-ce/99_migrate.sh | 5 +++++ server-ce/Dockerfile | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100755 server-ce/99_migrate.sh diff --git a/server-ce/99_migrate.sh b/server-ce/99_migrate.sh new file mode 100755 index 0000000000..762aae2806 --- /dev/null +++ b/server-ce/99_migrate.sh @@ -0,0 +1,5 @@ +#!/bin/sh +which node +which grunt +ls -al /var/www/sharelatex/migrations +cd /var/www/sharelatex && grunt migrate -v diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index a8d6d9be82..ff52a33198 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -15,6 +15,7 @@ RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharela # Install ShareLaTeX RUN apt-get install -y git python RUN git clone -b release https://github.com/sharelatex/sharelatex.git /var/www/sharelatex +RUN cd /var/www/sharelatex && git pull origin release # zlib1g-dev is needed to compile the synctex binaries in the CLSI during `grunt install`. RUN apt-get install -y zlib1g-dev @@ -28,6 +29,7 @@ RUN cd /var/www/sharelatex/web; \ grunt compile:minify; # Install Nginx as a reverse proxy +run apt-get update RUN apt-get install -y nginx; RUN rm /etc/nginx/sites-enabled/default ADD nginx/nginx.conf /etc/nginx/nginx.conf @@ -70,7 +72,8 @@ RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ RUN rm -r /install-tl-unx; \ rm install-tl-unx.tar.gz -ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2014/bin/x86_64-linux/ +ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2015/bin/x86_64-linux/ +RUN apt-get update RUN tlmgr install latexmk # Install Aspell @@ -79,10 +82,14 @@ RUN apt-get install -y aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar- # Install unzip for file uploads RUN apt-get install -y unzip +# Install imagemagick for image conversions +RUN apt-get install -y imagemagick optipng + # phusion/baseimage init script ADD 00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh ADD 00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh ADD 00_set_docker_host_ipaddress.sh /etc/my_init.d/00_set_docker_host_ipaddress.sh +ADD 99_migrate.sh /etc/my_init.d/99_migrate.sh # Install ShareLaTeX settings file RUN mkdir /etc/sharelatex From 62908092b9ea672bd06b5a7d8a54590838ece193 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 1 Dec 2015 16:17:15 +0000 Subject: [PATCH 162/525] Added tip for copying the database when upgrading --- server-ce/README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 2ac12723b6..405ba6406f 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -185,7 +185,17 @@ Once you are logged in as an admin user, you can visit `/admin/register` on your *Please make sure to back up all Mongo, Redis and on-disk data before upgrading.* -Stop and remove the currently running ShareLaTeX container: +#### Migrations +Data stored in Mongodb will be automatically migrated to the latest schemea when upgrading docker releases. **This can make downgrades impossible.** One recommended technique is to test the migration first. This can be done by copying the mongodb database and doing a test run against the copied data. + +``` +db.copyDatabase(sharelatex,sharelatex-copy) +# start the container up pointing at the new db +--env SHARELATEX_MONGO_URL=mongodb://dockerhost/sharelatex-copy +``` + +#### Upgrade process +To use the new docker container stop and remove the currently running ShareLaTeX container: ``` $ docker stop sharelatex From f4dc80804b607d9da304f1327fb0c9a69648c7d9 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 16 Dec 2015 13:05:12 +0000 Subject: [PATCH 163/525] dropbox is not shown any more, remove appology --- server-ce/README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index d96591d77a..be36942f3e 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -85,11 +85,6 @@ The backend API for managing project tags (folders). An API for running server-side spelling checking on ShareLaTeX documents. -Dropbox -------- - -Please note that certain features like Dropbox integration are not functional in the open source code base yet, despite appearing in the user interface. We're working on this, sorry! - Contributing ------------ From 2e779f0ed79acbbf741b15fdff594b71e405bd88 Mon Sep 17 00:00:00 2001 From: mattcollier Date: Mon, 28 Dec 2015 16:27:46 -0500 Subject: [PATCH 164/525] Correct typo. --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 405ba6406f..eac83edd43 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -156,7 +156,7 @@ $ docker run -d \ The available configuration parameters are: * `SHARELATEX_SITE_URL`: Where your instance of ShareLaTeX is publically available. -This is used in public links, and when connecting over websockets, so much be +This is used in public links, and when connecting over websockets, so must be configured correctly! * `SHARELATEX_ADMIN_EMAIL`: The email address where users can reach the person who runs the site. * `SHARELATEX_APP_NAME`: The name to display when talking about the running app. Defaults to 'ShareLaTex (Community Edition)'. From e5a7bf947be2cb464c3c75398b621cd450959784 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 13 Jan 2016 15:10:31 +0000 Subject: [PATCH 165/525] set nginx to 50mb limit which is upper side of what ShareLaTeX can handle --- server-ce/nginx/nginx.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/nginx/nginx.conf b/server-ce/nginx/nginx.conf index 03d228c622..c4311103b0 100644 --- a/server-ce/nginx/nginx.conf +++ b/server-ce/nginx/nginx.conf @@ -41,6 +41,8 @@ http { gzip on; gzip_disable "msie6"; + client_max_body_size 50m; + # gzip_vary on; # gzip_proxied any; # gzip_comp_level 6; From 553e059a08a926aaa03dbd23b745001f023a8cf2 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Fri, 29 Jan 2016 16:55:26 +0000 Subject: [PATCH 166/525] migration script for dochistory packing --- .../3_pack_docHistory_collection.coffee | 291 ++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 server-ce/migrations/3_pack_docHistory_collection.coffee diff --git a/server-ce/migrations/3_pack_docHistory_collection.coffee b/server-ce/migrations/3_pack_docHistory_collection.coffee new file mode 100644 index 0000000000..dd8d750115 --- /dev/null +++ b/server-ce/migrations/3_pack_docHistory_collection.coffee @@ -0,0 +1,291 @@ +Settings = require "settings-sharelatex" +fs = require("fs") +mongojs = require("mongojs") +ObjectId = mongojs.ObjectId +db = mongojs(Settings.mongo.url, ['docs','docHistory', 'docHistoryStats']) +_ = require("lodash") +async = require("async") +exec = require("child_process").exec +BSON = db.bson.BSON + +logger = { + log: -> + err: -> +} + +finished_docs_path = "/tmp/finished-docs-3" +all_docs_path = "/tmp/all-docs-3" +unmigrated_docs_path = "/tmp/unmigrated-docs-3" + +finished_docs = {} +if fs.existsSync(finished_docs_path) + for id in fs.readFileSync(finished_docs_path,'utf-8').split("\n") + finished_docs[id] = true + +getAndWriteDocids = (callback)-> + console.log "finding all doc id's - #{new Date().toString()}" + db.docs.find {}, {_id:1}, (err, ids)-> + console.log "total found docs in mongo #{ids.length} - #{new Date().toString()}" + ids = _.pluck ids, '_id' + ids = _.filter ids, (id)-> id? + fileData = ids.join("\n") + fs.writeFileSync all_docs_path + ".tmp", fileData + fs.renameSync all_docs_path + ".tmp", all_docs_path + callback(err, ids) + +loadDocIds = (callback)-> + console.log "loading doc ids from #{all_docs_path}" + data = fs.readFileSync all_docs_path, "utf-8" + ids = data.split("\n") + console.log "loaded #{ids.length} doc ids from #{all_docs_path}" + callback null, ids + +getDocIds = (callback)-> + exists = fs.existsSync all_docs_path + if exists + loadDocIds callback + else + getAndWriteDocids callback + +markDocAsProcessed = (doc_id, callback)-> + finished_docs[doc_id] = true + fs.appendFile finished_docs_path, "#{doc_id}\n", callback + +markDocAsUnmigrated = (doc_id, callback)-> + console.log "#{doc_id} unmigrated" + markDocAsProcessed doc_id, (err)-> + fs.appendFile unmigrated_docs_path, "#{doc_id}\n", callback + +printProgress = -> + count = Object.keys(finished_docs).length + console.log "completed", count + +checkIfDocHasBeenProccessed = (doc_id, callback)-> + callback(null, finished_docs[doc_id]) + +processNext = (doc_id, callback)-> + if !doc_id? or doc_id.length == 0 + return callback() + checkIfDocHasBeenProccessed doc_id, (err, hasBeenProcessed)-> + if hasBeenProcessed + console.log "#{doc_id} already processed, skipping" + return callback() + console.log "#{doc_id} processing" + PackManager._packDocHistory doc_id, {}, (err) -> + markDocAsProcessed doc_id, callback + +exports.migrate = (client, done = ->)-> + getDocIds (err, ids)-> + interval = setInterval printProgress, 3*1000 + jobs = _.map ids, (id)-> + return (cb)-> + processNext(id, cb) + async.series jobs, (err)-> + if err? + console.error err, "at end of jobs" + else + console.log "finished" + clearInterval interval + done(err) + +exports.rollback = (client, done)-> + done() + +DAYS = 24 * 3600 * 1000 # one day in milliseconds + +# copied from track-changes/app/coffee/PackManager.coffee + +PackManager = + MAX_SIZE: 1024*1024 # make these configurable parameters + MAX_COUNT: 512 + + convertDocsToPacks: (docs, callback) -> + packs = [] + top = null + docs.forEach (d,i) -> + # skip existing packs + if d.pack? + top = null + return + sz = BSON.calculateObjectSize(d) + # decide if this doc can be added to the current pack + validLength = top? && (top.pack.length < PackManager.MAX_COUNT) + validSize = top? && (top.sz + sz < PackManager.MAX_SIZE) + bothPermanent = top? && (top.expiresAt? is false) && (d.expiresAt? is false) + bothTemporary = top? && (top.expiresAt? is true) && (d.expiresAt? is true) + within1Day = bothTemporary && (d.meta.start_ts - top.meta.start_ts < 24 * 3600 * 1000) + if top? && validLength && validSize && (bothPermanent || (bothTemporary && within1Day)) + top.pack = top.pack.concat {v: d.v, meta: d.meta, op: d.op, _id: d._id} + top.sz += sz + top.n += 1 + top.v_end = d.v + top.meta.end_ts = d.meta.end_ts + top.expiresAt = d.expiresAt if top.expiresAt? + return + else + # create a new pack + top = _.clone(d) + top.pack = [ {v: d.v, meta: d.meta, op: d.op, _id: d._id} ] + top.meta = { start_ts: d.meta.start_ts, end_ts: d.meta.end_ts } + top.sz = sz + top.n = 1 + top.v_end = d.v + delete top.op + delete top._id + packs.push top + + callback(null, packs) + + checkHistory: (docs, callback) -> + errors = [] + prev = null + error = (args...) -> + errors.push args + docs.forEach (d,i) -> + if d.pack? + n = d.pack.length + last = d.pack[n-1] + error('bad pack v_end', d) if d.v_end != last.v + error('bad pack start_ts', d) if d.meta.start_ts != d.pack[0].meta.start_ts + error('bad pack end_ts', d) if d.meta.end_ts != last.meta.end_ts + d.pack.forEach (p, i) -> + prev = v + v = p.v + error('bad version', v, 'in', p) if v <= prev + #error('expired op', p, 'in pack') if p.expiresAt? + else + prev = v + v = d.v + error('bad version', v, 'in', d) if v <= prev + if errors.length + callback(errors) + else + callback() + + insertPack: (packObj, callback) -> + bulk = db.docHistory.initializeOrderedBulkOp() + doc_id = packObj.doc_id + expect_nInserted = 1 + expect_nRemoved = packObj.pack.length + logger.log {doc_id: doc_id}, "adding pack, removing #{expect_nRemoved} ops" + bulk.insert packObj + ids = (op._id for op in packObj.pack) + bulk.find({_id:{$in:ids}}).remove() + bulk.execute (err, result) -> + if err? + logger.error {doc_id: doc_id}, "error adding pack" + callback(err, result) + else if result.nInserted != expect_nInserted or result.nRemoved != expect_nRemoved + logger.error {doc_id: doc_id, result}, "unexpected result adding pack" + callback(new Error( + msg: 'unexpected result' + expected: {expect_nInserted, expect_nRemoved} + ), result) + else + db.docHistoryStats.update {doc_id:doc_id}, { + $inc:{update_count:-expect_nRemoved}, + $currentDate:{last_packed:true} + }, {upsert:true}, () -> + callback(err, result) + + # retrieve document ops/packs and check them + getDocHistory: (doc_id, callback) -> + db.docHistory.find({doc_id:ObjectId(doc_id)}).sort {v:1}, (err, docs) -> + return callback(err) if err? + # for safety, do a consistency check of the history + logger.log {doc_id}, "checking history for document" + PackManager.checkHistory docs, (err) -> + return callback(err) if err? + callback(err, docs) + #PackManager.deleteExpiredPackOps docs, (err) -> + # return callback(err) if err? + # callback err, docs + + packDocHistory: (doc_id, options, callback) -> + if typeof callback == "undefined" and typeof options == 'function' + callback = options + options = {} + LockManager.runWithLock( + "HistoryLock:#{doc_id}", + (releaseLock) -> + PackManager._packDocHistory(doc_id, options, releaseLock) + , callback + ) + + _packDocHistory: (doc_id, options, callback) -> + logger.log {doc_id},"starting pack operation for document history" + + PackManager.getDocHistory doc_id, (err, docs) -> + return callback(err) if err? + origDocs = 0 + origPacks = 0 + for d in docs + if d.pack? then origPacks++ else origDocs++ + PackManager.convertDocsToPacks docs, (err, packs) -> + return callback(err) if err? + total = 0 + for p in packs + total = total + p.pack.length + logger.log {doc_id, origDocs, origPacks, newPacks: packs.length, totalOps: total}, "document stats" + if packs.length + if options['dry-run'] + logger.log {doc_id}, 'dry-run, skipping write packs' + return callback() + PackManager.savePacks packs, (err) -> + return callback(err) if err? + # check the history again + PackManager.getDocHistory doc_id, callback + else + logger.log {doc_id}, "no packs to write" + # keep a record that we checked this one to avoid rechecking it + db.docHistoryStats.update {doc_id:doc_id}, { + $currentDate:{last_checked:true} + }, {upsert:true}, () -> + callback null, null + + DB_WRITE_DELAY: 100 + + savePacks: (packs, callback) -> + async.eachSeries packs, PackManager.safeInsert, (err, result) -> + if err? + logger.log {err, result}, "error writing packs" + callback err, result + else + callback() + + safeInsert: (packObj, callback) -> + PackManager.insertPack packObj, (err, result) -> + setTimeout () -> + callback(err,result) + , PackManager.DB_WRITE_DELAY + + deleteExpiredPackOps: (docs, callback) -> + now = Date.now() + toRemove = [] + toUpdate = [] + docs.forEach (d,i) -> + if d.pack? + newPack = d.pack.filter (op) -> + if op.expiresAt? then op.expiresAt > now else true + if newPack.length == 0 + toRemove.push d + else if newPack.length < d.pack.length + # adjust the pack properties + d.pack = newPack + first = d.pack[0] + last = d.pack[d.pack.length - 1] + d.v_end = last.v + d.meta.start_ts = first.meta.start_ts + d.meta.end_ts = last.meta.end_ts + toUpdate.push d + if toRemove.length or toUpdate.length + bulk = db.docHistory.initializeOrderedBulkOp() + toRemove.forEach (pack) -> + console.log "would remove", pack + #bulk.find({_id:pack._id}).removeOne() + toUpdate.forEach (pack) -> + console.log "would update", pack + #bulk.find({_id:pack._id}).updateOne(pack); + bulk.execute callback + else + callback() From c4618e795eb54b81a3e0a906fcb2b91c5b5af444 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Mon, 1 Feb 2016 16:51:43 +0000 Subject: [PATCH 167/525] include commands to update indexes in docHistory migration - not called --- .../3_pack_docHistory_collection.coffee | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/server-ce/migrations/3_pack_docHistory_collection.coffee b/server-ce/migrations/3_pack_docHistory_collection.coffee index dd8d750115..14656d8b43 100644 --- a/server-ce/migrations/3_pack_docHistory_collection.coffee +++ b/server-ce/migrations/3_pack_docHistory_collection.coffee @@ -74,6 +74,21 @@ processNext = (doc_id, callback)-> PackManager._packDocHistory doc_id, {}, (err) -> markDocAsProcessed doc_id, callback +updateIndexes = (callback) -> + async.series [ + (cb) -> + console.log "create index" + db.docHistory.ensureIndex { project_id: 1, "meta.end_ts": 1, "meta.start_ts": -1 }, { background: true }, cb + (cb) -> + console.log "drop index" + db.docHistory.dropIndex { project_id: 1, "meta.end_ts": 1 }, cb + (cb) -> + console.log "drop index" + db.docHistory.dropIndex { project_id: 1, "pack.0.meta.end_ts": 1, "meta.end_ts": 1}, cb + ], (err, results) -> + console.log "all done" + callback(err) + exports.migrate = (client, done = ->)-> getDocIds (err, ids)-> interval = setInterval printProgress, 3*1000 From 799c38a64678510e1706cb9b0cf0bba3204b6e44 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 3 Feb 2016 14:56:11 +0000 Subject: [PATCH 168/525] Update README.md --- server-ce/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index eac83edd43..ffda2e1dfb 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -142,7 +142,7 @@ the package name. ### Configuration Options -You can pass configuration options to ShareLaTeX as environment variables: +You can pass the core configuration options to ShareLaTeX as environment variables: ``` $ docker run -d \ @@ -167,6 +167,8 @@ configured correctly! * `SHARELATEX_SECURE_COOKIE`: Set this to something non-zero to use a secure cookie. Only use this if your ShareLaTeX instance is running behind a reverse proxy with SSL configured. +Other settings such as email setup need to be edited in the docker container at /etc/sharelatex/settings.coffee. We realise this is not an ideal solution and are working on a more streamlined settings file approach. + ### Creating and Managing users Uun the following command to create your first user and make them an admin: From 5079ea2bc5ef0c7a40866dd5d20713651b80eafa Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 3 Feb 2016 15:13:17 +0000 Subject: [PATCH 169/525] Update README.md --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index be36942f3e..530cb7e93f 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -10,7 +10,7 @@ Installation We have detailed installation instructions in our wiki: -* [Installing ShareLaTeX in Production](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) +* [Installing ShareLaTeX in Production using docker](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) * [Setting up a ShareLaTeX Development Environment](https://github.com/sharelatex/sharelatex/wiki/Setting-up-a-Development-Environment) **If you have any problems, have a look at our page of [Frequent Problems and Questions](https://github.com/sharelatex/sharelatex/wiki/FAQ).** From ac5dc0938cbc388796e7beb5ed2e6f4181e14bf7 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 9 Feb 2016 12:57:05 +0000 Subject: [PATCH 170/525] Update README.md --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index ffda2e1dfb..93e330a74f 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,4 +1,4 @@ -ShareLaTeX Docker Image +ShareLaTeX Comunity Docker Image ======================= **Please read this entire file before installing ShareLaTeX via Docker. It's only From a179b74ae64577ba75deea8c7f5766ac64214fe7 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 9 Feb 2016 17:19:48 +0000 Subject: [PATCH 171/525] Update README.md --- server-ce/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 530cb7e93f..1457bcdb4f 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -5,6 +5,10 @@ ShareLaTeX *[If you want help installing and maintaining ShareLaTeX at your university or workplace, we offer an officially supported version called ShareLaTeX Server Pro. It also comes with extra security and admin features. Click here to find out more!](https://www.sharelatex.com/university/onsite.html)* +Keeping up to date +------------ +Sign up to the [mailing list](http://eepurl.com/bPWeiH) to get updates on ShareLaTeX Releases and development + Installation ------------ From f764f77b30be9ea551291294cb7d96fc5f410848 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Thu, 4 Feb 2016 16:31:38 +0000 Subject: [PATCH 172/525] improve logging and interrupt handling --- .../3_pack_docHistory_collection.coffee | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/server-ce/migrations/3_pack_docHistory_collection.coffee b/server-ce/migrations/3_pack_docHistory_collection.coffee index 14656d8b43..1eaf1539a6 100644 --- a/server-ce/migrations/3_pack_docHistory_collection.coffee +++ b/server-ce/migrations/3_pack_docHistory_collection.coffee @@ -3,7 +3,7 @@ fs = require("fs") mongojs = require("mongojs") ObjectId = mongojs.ObjectId db = mongojs(Settings.mongo.url, ['docs','docHistory', 'docHistoryStats']) -_ = require("lodash") +_ = require("underscore") async = require("async") exec = require("child_process").exec BSON = db.bson.BSON @@ -13,6 +13,14 @@ logger = { err: -> } +needToExit = false +handleExit = () -> + needToExit = true + console.log('Got signal. Shutting down.') + +process.on 'SIGINT', handleExit +process.on 'SIGHUP', handleExit + finished_docs_path = "/tmp/finished-docs-3" all_docs_path = "/tmp/all-docs-3" unmigrated_docs_path = "/tmp/unmigrated-docs-3" @@ -56,23 +64,24 @@ markDocAsUnmigrated = (doc_id, callback)-> markDocAsProcessed doc_id, (err)-> fs.appendFile unmigrated_docs_path, "#{doc_id}\n", callback -printProgress = -> - count = Object.keys(finished_docs).length - console.log "completed", count - checkIfDocHasBeenProccessed = (doc_id, callback)-> callback(null, finished_docs[doc_id]) processNext = (doc_id, callback)-> if !doc_id? or doc_id.length == 0 return callback() + if needToExit + return callback(new Error("graceful shutdown")) checkIfDocHasBeenProccessed doc_id, (err, hasBeenProcessed)-> if hasBeenProcessed console.log "#{doc_id} already processed, skipping" return callback() - console.log "#{doc_id} processing" PackManager._packDocHistory doc_id, {}, (err) -> - markDocAsProcessed doc_id, callback + if err? + console.log "error processing #{doc_id}" + markDocAsUnmigrated doc_id, callback + else + markDocAsProcessed doc_id, callback updateIndexes = (callback) -> async.series [ @@ -91,15 +100,27 @@ updateIndexes = (callback) -> exports.migrate = (client, done = ->)-> getDocIds (err, ids)-> + totalDocCount = ids.length + alreadyFinishedCount = Object.keys(finished_docs).length + t0 = Date.now() + printProgress = () -> + count = Object.keys(finished_docs).length + processedFraction = (count-alreadyFinishedCount)/totalDocCount + remainingFraction = (totalDocCount-count)/totalDocCount + t = Date.now() + dt = (t-t0)*remainingFraction/processedFraction + estFinishTime = new Date(t + dt) + console.log "completed #{count}/#{totalDocCount} processed=#{processedFraction.toFixed(2)} remaining=#{remainingFraction.toFixed(2)} elapsed=#{(t-t0)/1000} est Finish=#{estFinishTime}" interval = setInterval printProgress, 3*1000 - jobs = _.map ids, (id)-> + + jobs = _.map _.filter(ids, (id) -> not finished_docs[id]), (id)-> return (cb)-> processNext(id, cb) async.series jobs, (err)-> if err? console.error err, "at end of jobs" else - console.log "finished" + console.log "finished at #{new Date}" clearInterval interval done(err) From 39e10c88c1361300210c2e589a4de94db8ca1df3 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Wed, 10 Feb 2016 14:45:47 +0000 Subject: [PATCH 173/525] improve performance for migrating large dochistory collections --- .../3_pack_docHistory_collection.coffee | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/server-ce/migrations/3_pack_docHistory_collection.coffee b/server-ce/migrations/3_pack_docHistory_collection.coffee index 1eaf1539a6..c5febea0c2 100644 --- a/server-ce/migrations/3_pack_docHistory_collection.coffee +++ b/server-ce/migrations/3_pack_docHistory_collection.coffee @@ -113,10 +113,20 @@ exports.migrate = (client, done = ->)-> console.log "completed #{count}/#{totalDocCount} processed=#{processedFraction.toFixed(2)} remaining=#{remainingFraction.toFixed(2)} elapsed=#{(t-t0)/1000} est Finish=#{estFinishTime}" interval = setInterval printProgress, 3*1000 - jobs = _.map _.filter(ids, (id) -> not finished_docs[id]), (id)-> - return (cb)-> - processNext(id, cb) - async.series jobs, (err)-> + nextId = null + + testFn = () -> + return false if needToExit + id = ids.shift() + while id? and finished_docs[id] # skip finished + id = ids.shift() + nextId = id + return nextId? + + executeFn = (cb) -> + processNext nextId, cb + + async.whilst testFn, executeFn, (err)-> if err? console.error err, "at end of jobs" else @@ -127,6 +137,10 @@ exports.migrate = (client, done = ->)-> exports.rollback = (client, done)-> done() +# process.nextTick () -> +# exports.migrate () -> +# console.log "done" + DAYS = 24 * 3600 * 1000 # one day in milliseconds # copied from track-changes/app/coffee/PackManager.coffee From 4ce4cc596ff9be80c952e44ff3a3012fcd4fdf8a Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 8 Mar 2016 16:05:42 +0000 Subject: [PATCH 174/525] change localhost to 127.0.0.1 which should help with ipv6 --- server-ce/nginx/sharelatex.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/nginx/sharelatex.conf b/server-ce/nginx/sharelatex.conf index e9d6566ffd..0111797967 100644 --- a/server-ce/nginx/sharelatex.conf +++ b/server-ce/nginx/sharelatex.conf @@ -5,7 +5,7 @@ server { set $static_path /var/www/sharelatex/web/public; location / { - proxy_pass http://localhost:3000; + proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; @@ -17,7 +17,7 @@ server { } location /socket.io { - proxy_pass http://localhost:3026; + proxy_pass http://127.0.0.1:3026; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; From 07ed8854aad4dd81a0a5d954432ed47bb1cb607e Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 6 Apr 2016 15:42:01 +0000 Subject: [PATCH 175/525] add session secret as env varx --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 440b59f7fb..e2ee828a79 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -104,7 +104,7 @@ module.exports = # If provided, a sessionSecret is used to sign cookies so that they cannot be # spoofed. This is recommended. security: - sessionSecret: "CRYPTO_RANDOM" # This was randomly generated for you + sessionSecret: process.env["SHARELATEX_SESSION_SECRET"] or "CRYPTO_RANDOM" # This was randomly generated for you # These credentials are used for authenticating api requests # between services that may need to go over public channels From 30c9dba44e23804be9ac6354a994e0f5adfd4860 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 6 Apr 2016 17:07:59 +0100 Subject: [PATCH 176/525] made email and ldap configurable from env vars --- server-ce/settings.coffee | 107 +++++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 20 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 440b59f7fb..f385becb12 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -10,7 +10,8 @@ httpAuthUsers[httpAuthUser] = httpAuthPass DATA_DIR = '/var/lib/sharelatex/data' TMP_DIR = '/var/lib/sharelatex/tmp' -module.exports = +settings = + # Databases # --------- @@ -60,6 +61,7 @@ module.exports = backend: "fs" stores: user_files: Path.join(DATA_DIR, "user_files") + template_files: Path.join(DATA_DIR, "template_files") # To use Amazon S3 as a storage backend, comment out the above config, and # uncomment the following, filling in your key, secret, and bucket name: @@ -97,6 +99,11 @@ module.exports = # The name this is used to describe your ShareLaTeX Installation appName: process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX (Community Edition)" + + nav: + title: process.env["SHARELATEX_NAV_TITLE"] or process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX Comunity Edition" + + # The email address which users will be directed to as the main point of # contact for this installation of ShareLaTeX. adminEmail: process.env["SHARELATEX_ADMIN_EMAIL"] or "placeholder@example.com" @@ -104,7 +111,7 @@ module.exports = # If provided, a sessionSecret is used to sign cookies so that they cannot be # spoofed. This is recommended. security: - sessionSecret: "CRYPTO_RANDOM" # This was randomly generated for you + sessionSecret: process.env["SHARELATEX_SESSION_SECRET"] or "CRYPTO_RANDOM" # This was randomly generated for you # These credentials are used for authenticating api requests # between services that may need to go over public channels @@ -127,29 +134,13 @@ module.exports = # If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) # then set this to true to allow it to correctly detect the forwarded IP # address and http/https protocol information. - behindProxy: true + behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] or false - # Sending Email - # ------------- - # - # You must configure a mail server to be able to send invite emails from - # ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer - # documentation for available options: - # - # http://www.nodemailer.com/docs/transports - # - # email: - # fromAddress: "" - # replyTo: "" - # transport: "SES" - # parameters: - # AWSAccessKeyID: "" - # AWSSecretKey: "" # Spell Check Languages # --------------------- # - # You must have the corresponding aspell dictionary installed to + # You must have the corresponding aspell dictionary installed to # be able to use a language. Run `grunt check:aspell` to check which # dictionaries you have installed. These should be set for the `code` for # each language. @@ -386,6 +377,9 @@ module.exports = # spelling: # port: spellingPort = 3005 # host: "localhost" + # templates: + # port: templatesPort = 3007 + # host: "localhost" # If you change the above config, or run some services on remote servers, # you need to tell the other services where to find them: @@ -410,7 +404,78 @@ module.exports = # url: "http://localhost:#{spellingPort}" # chat: # url: "http://localhost:#{chatPort}" + # templates: + # url: "http://localhost:#{templatesPort}" + + +#### OPTIONAL CONFIGERABLE SETTINGS + + +# Sending Email +# ------------- +# +# You must configure a mail server to be able to send invite emails from +# ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer +# documentation for available options: +# +# http://www.nodemailer.com/docs/transports + + +if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] + settings.email: + fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] + replyTo: process.env["SHARELATEX_EMAIL_REPLY_TO"] or "" + parameters: + #AWS Creds + AWSAccessKeyID: process.env["SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID"] + AWSSecretKey: process.env["SHARELATEX_EMAIL_AWS_SES_SECRET_KEY"] + + #SMTP Creds + host: process.env["SHARELATEX_EMAIL_SMTP_HOST"] + port: process.env["SHARELATEX_EMAIL_SMTP_PORT"], + secure: process.env["SHARELATEX_EMAIL_SMTP_SECURE"] + auth: + user: process.env["SHARELATEX_EMAIL_SMTP_USER"] + pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"] + + +# Password Settings +# ----------- +# These restrict the passwords users can use when registering +# opts are from http://antelle.github.io/passfield +if process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] + + settings.passwordStrengthOptions: + pattern: process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or "aA$3" + length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] or 50} + + +# LDAP - SERVER PRO ONLY +# ---------- +# Settings below use a working LDAP test server kindly provided by forumsys.com +# When testing with forumsys.com use username = einstein and password = password + + +if process.env["SHARELATEX_LDAP_HOST"] + settings.ldap : + host: process.env["SHARELATEX_LDAP_HOST"] + dn: process.env["SHARELATEX_LDAP_DN"] + baseSearch: process.env["SHARELATEX_LDAP_BASE_SEARCH"] + filter: process.env["SHARELATEX_LDAP_FILTER"] + failMessage: process.env["SHARELATEX_LDAP_FAIL_MESSAGE"] or 'LDAP User Fail' + fieldName: process.env["SHARELATEX_LDAP_FIELD_NAME"] or 'LDAP User' + placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"] or 'LDAP User ID' + emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"] or 'mail' + anonymous: process.env["SHARELATEX_LDAP_ANONYMOUS"] or false + adminDN: process.env["SHARELATEX_LDAP_ADMIN_DN"] + adminPW: process.env["SHARELATEX_LDAP_ADMIN_PW"] + + + + + + # With lots of incoming and outgoing HTTP connections to different services, # sometimes long running, it is a good idea to increase the default number @@ -419,3 +484,5 @@ http = require('http') http.globalAgent.maxSockets = 300 https = require('https') https.globalAgent.maxSockets = 300 + +module.exports = settings \ No newline at end of file From 98a0c1cdf1c81ad3aca88aaec454b36a728b9411 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 6 Apr 2016 17:10:43 +0100 Subject: [PATCH 177/525] added tls as env vars --- server-ce/settings.coffee | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index f385becb12..165d4c16d0 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -469,9 +469,11 @@ if process.env["SHARELATEX_LDAP_HOST"] emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"] or 'mail' anonymous: process.env["SHARELATEX_LDAP_ANONYMOUS"] or false adminDN: process.env["SHARELATEX_LDAP_ADMIN_DN"] - adminPW: process.env["SHARELATEX_LDAP_ADMIN_PW"] - - + adminPW: process.env["SHARELATEX_LDAP_ADMIN_PW"] + starttls: process.env["SHARELATEX_LDAP_TLS"] or false + tlsOptions: + rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] or false + ca: process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] # e.g.'/etc/ldap/ca_certs.pem' From 9e77f28bf6da9175d18962b9f5ced63510ec9f05 Mon Sep 17 00:00:00 2001 From: Vincent von Hof Date: Wed, 20 Apr 2016 12:54:11 +0200 Subject: [PATCH 178/525] Fix a typo in README.md nothing here...moving on --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 93e330a74f..af2b50a377 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,4 +1,4 @@ -ShareLaTeX Comunity Docker Image +ShareLaTeX Community Docker Image ======================= **Please read this entire file before installing ShareLaTeX via Docker. It's only From e994ac8f1f514090eee5291c526ff5212feca64b Mon Sep 17 00:00:00 2001 From: Henrique Santos Date: Wed, 20 Apr 2016 21:55:47 -0300 Subject: [PATCH 179/525] add support for grunt build --- server-ce/Dockerfile | 11 ++++++++-- server-ce/Gruntfile.coffee | 38 +++++++++++++++++++++++++++++++++ server-ce/git-revision.js | 22 +++++++++++++++++++ server-ce/package.json | 11 ++++++++++ server-ce/services.js | 43 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 server-ce/Gruntfile.coffee create mode 100644 server-ce/git-revision.js create mode 100644 server-ce/package.json create mode 100644 server-ce/services.js diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index ff52a33198..7d813bd5d5 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -14,15 +14,22 @@ RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharela # Install ShareLaTeX RUN apt-get install -y git python -RUN git clone -b release https://github.com/sharelatex/sharelatex.git /var/www/sharelatex -RUN cd /var/www/sharelatex && git pull origin release +RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex # zlib1g-dev is needed to compile the synctex binaries in the CLSI during `grunt install`. RUN apt-get install -y zlib1g-dev + +ADD services.js /var/www/sharelatex/config/services.js +ADD package.json /var/www/package.json +ADD git-revision.js /var/www/git-revision.js +RUN cd /var/www && npm install + RUN cd /var/www/sharelatex; \ npm install; \ grunt install; + +RUN cd /var/www && node git-revision > revisions.txt # Minify js assets RUN cd /var/www/sharelatex/web; \ diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee new file mode 100644 index 0000000000..0f1d222059 --- /dev/null +++ b/server-ce/Gruntfile.coffee @@ -0,0 +1,38 @@ +services = require('./services') + +module.exports = (grunt) -> + + tag = grunt.option("tag") or 'latest' + repos = [] + for service in services + url = service.repo.split('/') + owner = url[3] + repo = url[4].replace('.git','') + repos.push "/repos/#{owner}/#{repo}/git/refs/heads/#{service.version}" + + grunt.initConfig + docker_io: + default_options: + options: + dockerFileLocation: '.' + buildName: 'sharelatex' + tag: grunt.option('tag') or 'latest' + push: grunt.option('push') or false + force: true + + github: + combinedRevisions: + options: + #oAuth: + # access_token: '' + concat: true + src: repos + dest: 'version/' + tag + '.json' + + grunt.loadNpmTasks 'grunt-docker-io' + grunt.loadNpmTasks 'grunt-github-api' + + grunt.registerTask 'build', ['docker_io', 'github'] + grunt.registerTask 'gitrev', ['github'] + + grunt.registerTask 'default', ['build'] diff --git a/server-ce/git-revision.js b/server-ce/git-revision.js new file mode 100644 index 0000000000..89359cea2e --- /dev/null +++ b/server-ce/git-revision.js @@ -0,0 +1,22 @@ +var simple = require('simple-git'); +var services = require('./sharelatex/config/services'); +const fs = require('fs'); + +function print_latest(repoDir) { + git = simple(repoDir); + opt = []; + opt['max-count'] = 1; + git.log(opt, function(err, log) { + if (!err) { + console.log(repoDir + ',' + log.latest.hash); + } + }) +} + +for (id in services) { + service = services[id]; + dirPath = __dirname + '/sharelatex/'+service.name; + if (fs.existsSync(dirPath)) { + print_latest(dirPath); + } +} diff --git a/server-ce/package.json b/server-ce/package.json new file mode 100644 index 0000000000..329169d96d --- /dev/null +++ b/server-ce/package.json @@ -0,0 +1,11 @@ +{ + "name": "none", + "author": "none", + "description": "none", + "dependencies": { + "grunt": "^0.4.5", + "grunt-docker-io": "^0.7.0", + "simple-git": "^1.32.1", + "grunt-github-api": "^0.2.3" + } +} diff --git a/server-ce/services.js b/server-ce/services.js new file mode 100644 index 0000000000..be4da8698a --- /dev/null +++ b/server-ce/services.js @@ -0,0 +1,43 @@ +module.exports = + +[{ + name: "web", + repo: "https://github.com/sharelatex/web-sharelatex.git", + version: "master" +}, { + name: "real-time", + repo: "https://github.com/sharelatex/real-time-sharelatex.git", + version: "master" +}, { + name: "document-updater", + repo: "https://github.com/sharelatex/document-updater-sharelatex.git", + version: "master" +}, { + name: "clsi", + repo: "https://github.com/sharelatex/clsi-sharelatex.git", + version: "master" +}, { + name: "filestore", + repo: "https://github.com/sharelatex/filestore-sharelatex.git", + version: "master" +}, { + name: "track-changes", + repo: "https://github.com/sharelatex/track-changes-sharelatex.git", + version: "master" +}, { + name: "docstore", + repo: "https://github.com/sharelatex/docstore-sharelatex.git", + version: "master" +}, { + name: "chat", + repo: "https://github.com/sharelatex/chat-sharelatex.git", + version: "master" +}, { + name: "tags", + repo: "https://github.com/sharelatex/tags-sharelatex.git", + version: "master" +}, { + name: "spelling", + repo: "https://github.com/sharelatex/spelling-sharelatex.git", + version: "master" +}] From ffab13d43ab6bbff4cfcbe2b4808fa7f56917156 Mon Sep 17 00:00:00 2001 From: Henrique Santos Date: Wed, 20 Apr 2016 21:57:19 -0300 Subject: [PATCH 180/525] add services file --- server-ce/Gruntfile.coffee | 42 +---------------------------------- server-ce/config/services.js | 43 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 41 deletions(-) create mode 100644 server-ce/config/services.js diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 9ed6ff9275..e1eba4ef32 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -10,47 +10,7 @@ async = require "async" settings = require("settings-sharelatex") -SERVICES = [{ - name: "web" - repo: "https://github.com/sharelatex/web-sharelatex.git" - version: "master" -}, { - name: "real-time" - repo: "https://github.com/sharelatex/real-time-sharelatex.git" - version: "master" -}, { - name: "document-updater" - repo: "https://github.com/sharelatex/document-updater-sharelatex.git" - version: "master" -}, { - name: "clsi" - repo: "https://github.com/sharelatex/clsi-sharelatex.git" - version: "master" -}, { - name: "filestore" - repo: "https://github.com/sharelatex/filestore-sharelatex.git" - version: "master" -}, { - name: "track-changes" - repo: "https://github.com/sharelatex/track-changes-sharelatex.git" - version: "master" -}, { - name: "docstore" - repo: "https://github.com/sharelatex/docstore-sharelatex.git" - version: "master" -}, { - name: "chat" - repo: "https://github.com/sharelatex/chat-sharelatex.git" - version: "master" -}, { - name: "tags" - repo: "https://github.com/sharelatex/tags-sharelatex.git" - version: "master" -}, { - name: "spelling" - repo: "https://github.com/sharelatex/spelling-sharelatex.git" - version: "master" -}] +SERVICES = require("./config/services") module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-bunyan' diff --git a/server-ce/config/services.js b/server-ce/config/services.js new file mode 100644 index 0000000000..be4da8698a --- /dev/null +++ b/server-ce/config/services.js @@ -0,0 +1,43 @@ +module.exports = + +[{ + name: "web", + repo: "https://github.com/sharelatex/web-sharelatex.git", + version: "master" +}, { + name: "real-time", + repo: "https://github.com/sharelatex/real-time-sharelatex.git", + version: "master" +}, { + name: "document-updater", + repo: "https://github.com/sharelatex/document-updater-sharelatex.git", + version: "master" +}, { + name: "clsi", + repo: "https://github.com/sharelatex/clsi-sharelatex.git", + version: "master" +}, { + name: "filestore", + repo: "https://github.com/sharelatex/filestore-sharelatex.git", + version: "master" +}, { + name: "track-changes", + repo: "https://github.com/sharelatex/track-changes-sharelatex.git", + version: "master" +}, { + name: "docstore", + repo: "https://github.com/sharelatex/docstore-sharelatex.git", + version: "master" +}, { + name: "chat", + repo: "https://github.com/sharelatex/chat-sharelatex.git", + version: "master" +}, { + name: "tags", + repo: "https://github.com/sharelatex/tags-sharelatex.git", + version: "master" +}, { + name: "spelling", + repo: "https://github.com/sharelatex/spelling-sharelatex.git", + version: "master" +}] From 5fe0deab6dff1b29ccd6ff6fb8d2d43734731d00 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 28 Apr 2016 12:01:30 +0100 Subject: [PATCH 181/525] recommend mongodb 3.x --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index af2b50a377..e1a0c228b3 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -36,7 +36,7 @@ docker rm sharelatex ### Mongo and Redis -ShareLaTeX depends on [MongoDB](http://www.mongodb.org/) (must be 2.4 or later), and +ShareLaTeX depends on [MongoDB](http://www.mongodb.org/) (must be 2.4 or later, 3.x is recommended), and [Redis](http://redis.io/) (must be version 2.6.12 or later). These should be running on the host system. From 3e7595f3f2784e9dd63c4991a2fa0bacc6baf3eb Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 20 Apr 2016 21:55:47 -0300 Subject: [PATCH 182/525] add support for grunt build --- server-ce/Dockerfile | 11 ++++++++-- server-ce/Gruntfile.coffee | 38 +++++++++++++++++++++++++++++++++ server-ce/git-revision.js | 22 +++++++++++++++++++ server-ce/package.json | 11 ++++++++++ server-ce/services.js | 43 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 server-ce/Gruntfile.coffee create mode 100644 server-ce/git-revision.js create mode 100644 server-ce/package.json create mode 100644 server-ce/services.js diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index ff52a33198..7d813bd5d5 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -14,15 +14,22 @@ RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharela # Install ShareLaTeX RUN apt-get install -y git python -RUN git clone -b release https://github.com/sharelatex/sharelatex.git /var/www/sharelatex -RUN cd /var/www/sharelatex && git pull origin release +RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex # zlib1g-dev is needed to compile the synctex binaries in the CLSI during `grunt install`. RUN apt-get install -y zlib1g-dev + +ADD services.js /var/www/sharelatex/config/services.js +ADD package.json /var/www/package.json +ADD git-revision.js /var/www/git-revision.js +RUN cd /var/www && npm install + RUN cd /var/www/sharelatex; \ npm install; \ grunt install; + +RUN cd /var/www && node git-revision > revisions.txt # Minify js assets RUN cd /var/www/sharelatex/web; \ diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee new file mode 100644 index 0000000000..0f1d222059 --- /dev/null +++ b/server-ce/Gruntfile.coffee @@ -0,0 +1,38 @@ +services = require('./services') + +module.exports = (grunt) -> + + tag = grunt.option("tag") or 'latest' + repos = [] + for service in services + url = service.repo.split('/') + owner = url[3] + repo = url[4].replace('.git','') + repos.push "/repos/#{owner}/#{repo}/git/refs/heads/#{service.version}" + + grunt.initConfig + docker_io: + default_options: + options: + dockerFileLocation: '.' + buildName: 'sharelatex' + tag: grunt.option('tag') or 'latest' + push: grunt.option('push') or false + force: true + + github: + combinedRevisions: + options: + #oAuth: + # access_token: '' + concat: true + src: repos + dest: 'version/' + tag + '.json' + + grunt.loadNpmTasks 'grunt-docker-io' + grunt.loadNpmTasks 'grunt-github-api' + + grunt.registerTask 'build', ['docker_io', 'github'] + grunt.registerTask 'gitrev', ['github'] + + grunt.registerTask 'default', ['build'] diff --git a/server-ce/git-revision.js b/server-ce/git-revision.js new file mode 100644 index 0000000000..89359cea2e --- /dev/null +++ b/server-ce/git-revision.js @@ -0,0 +1,22 @@ +var simple = require('simple-git'); +var services = require('./sharelatex/config/services'); +const fs = require('fs'); + +function print_latest(repoDir) { + git = simple(repoDir); + opt = []; + opt['max-count'] = 1; + git.log(opt, function(err, log) { + if (!err) { + console.log(repoDir + ',' + log.latest.hash); + } + }) +} + +for (id in services) { + service = services[id]; + dirPath = __dirname + '/sharelatex/'+service.name; + if (fs.existsSync(dirPath)) { + print_latest(dirPath); + } +} diff --git a/server-ce/package.json b/server-ce/package.json new file mode 100644 index 0000000000..329169d96d --- /dev/null +++ b/server-ce/package.json @@ -0,0 +1,11 @@ +{ + "name": "none", + "author": "none", + "description": "none", + "dependencies": { + "grunt": "^0.4.5", + "grunt-docker-io": "^0.7.0", + "simple-git": "^1.32.1", + "grunt-github-api": "^0.2.3" + } +} diff --git a/server-ce/services.js b/server-ce/services.js new file mode 100644 index 0000000000..be4da8698a --- /dev/null +++ b/server-ce/services.js @@ -0,0 +1,43 @@ +module.exports = + +[{ + name: "web", + repo: "https://github.com/sharelatex/web-sharelatex.git", + version: "master" +}, { + name: "real-time", + repo: "https://github.com/sharelatex/real-time-sharelatex.git", + version: "master" +}, { + name: "document-updater", + repo: "https://github.com/sharelatex/document-updater-sharelatex.git", + version: "master" +}, { + name: "clsi", + repo: "https://github.com/sharelatex/clsi-sharelatex.git", + version: "master" +}, { + name: "filestore", + repo: "https://github.com/sharelatex/filestore-sharelatex.git", + version: "master" +}, { + name: "track-changes", + repo: "https://github.com/sharelatex/track-changes-sharelatex.git", + version: "master" +}, { + name: "docstore", + repo: "https://github.com/sharelatex/docstore-sharelatex.git", + version: "master" +}, { + name: "chat", + repo: "https://github.com/sharelatex/chat-sharelatex.git", + version: "master" +}, { + name: "tags", + repo: "https://github.com/sharelatex/tags-sharelatex.git", + version: "master" +}, { + name: "spelling", + repo: "https://github.com/sharelatex/spelling-sharelatex.git", + version: "master" +}] From 9ae564b1051e18e9999e2953bbf15468e8c1563b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 2 May 2016 23:55:53 +0000 Subject: [PATCH 183/525] add baseDir for Dockerfile --- server-ce/Dockerfile | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 7d813bd5d5..2f9766efaa 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -1,5 +1,7 @@ FROM phusion/baseimage:0.9.16 +ENV baseDir . + # Install Node.js and Grunt RUN curl -sL https://deb.nodesource.com/setup | sudo bash - RUN apt-get install -y build-essential nodejs @@ -20,9 +22,9 @@ RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex RUN apt-get install -y zlib1g-dev -ADD services.js /var/www/sharelatex/config/services.js -ADD package.json /var/www/package.json -ADD git-revision.js /var/www/git-revision.js +ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js +ADD ${baseDir}/package.json /var/www/package.json +ADD ${baseDir}/git-revision.js /var/www/git-revision.js RUN cd /var/www && npm install RUN cd /var/www/sharelatex; \ @@ -39,11 +41,11 @@ RUN cd /var/www/sharelatex/web; \ run apt-get update RUN apt-get install -y nginx; RUN rm /etc/nginx/sites-enabled/default -ADD nginx/nginx.conf /etc/nginx/nginx.conf -ADD nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf +ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf +ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf RUN mkdir /etc/service/nginx -ADD runit/nginx.sh /etc/service/nginx/run +ADD ${baseDir}/runit/nginx.sh /etc/service/nginx/run # Set up ShareLaTeX services to run automatically on boot RUN mkdir /etc/service/chat-sharelatex; \ @@ -57,16 +59,16 @@ RUN mkdir /etc/service/chat-sharelatex; \ mkdir /etc/service/track-changes-sharelatex; \ mkdir /etc/service/web-sharelatex; -ADD runit/chat-sharelatex.sh /etc/service/chat-sharelatex/run -ADD runit/clsi-sharelatex.sh /etc/service/clsi-sharelatex/run -ADD runit/docstore-sharelatex.sh /etc/service/docstore-sharelatex/run -ADD runit/document-updater-sharelatex.sh /etc/service/document-updater-sharelatex/run -ADD runit/filestore-sharelatex.sh /etc/service/filestore-sharelatex/run -ADD runit/real-time-sharelatex.sh /etc/service/real-time-sharelatex/run -ADD runit/spelling-sharelatex.sh /etc/service/spelling-sharelatex/run -ADD runit/tags-sharelatex.sh /etc/service/tags-sharelatex/run -ADD runit/track-changes-sharelatex.sh /etc/service/track-changes-sharelatex/run -ADD runit/web-sharelatex.sh /etc/service/web-sharelatex/run +ADD ${baseDir}/runit/chat-sharelatex.sh /etc/service/chat-sharelatex/run +ADD ${baseDir}/runit/clsi-sharelatex.sh /etc/service/clsi-sharelatex/run +ADD ${baseDir}/runit/docstore-sharelatex.sh /etc/service/docstore-sharelatex/run +ADD ${baseDir}/runit/document-updater-sharelatex.sh /etc/service/document-updater-sharelatex/run +ADD ${baseDir}/runit/filestore-sharelatex.sh /etc/service/filestore-sharelatex/run +ADD ${baseDir}/runit/real-time-sharelatex.sh /etc/service/real-time-sharelatex/run +ADD ${baseDir}/runit/spelling-sharelatex.sh /etc/service/spelling-sharelatex/run +ADD ${baseDir}/runit/tags-sharelatex.sh /etc/service/tags-sharelatex/run +ADD ${baseDir}/runit/track-changes-sharelatex.sh /etc/service/track-changes-sharelatex/run +ADD ${baseDir}/runit/web-sharelatex.sh /etc/service/web-sharelatex/run # Install TexLive RUN apt-get install -y wget @@ -93,14 +95,14 @@ RUN apt-get install -y unzip RUN apt-get install -y imagemagick optipng # phusion/baseimage init script -ADD 00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh -ADD 00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh -ADD 00_set_docker_host_ipaddress.sh /etc/my_init.d/00_set_docker_host_ipaddress.sh -ADD 99_migrate.sh /etc/my_init.d/99_migrate.sh +ADD ${baseDir}/00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh +ADD ${baseDir}/00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh +ADD ${baseDir}/00_set_docker_host_ipaddress.sh /etc/my_init.d/00_set_docker_host_ipaddress.sh +ADD ${baseDir}/99_migrate.sh /etc/my_init.d/99_migrate.sh # Install ShareLaTeX settings file RUN mkdir /etc/sharelatex -ADD settings.coffee /etc/sharelatex/settings.coffee +ADD ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee EXPOSE 80 From b4f2eeec7fa882e35c8402d48e2378e0e54eebd4 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 9 May 2016 16:08:51 +0100 Subject: [PATCH 184/525] recommend debian/ubuntu --- server-ce/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index e1a0c228b3..5d6956d7f6 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -34,6 +34,9 @@ If you want to permanently remove ShareLaTeX from your docker containers: docker rm sharelatex ``` +### Operating systems +We recommend a debian based operating system such as Ubuntu for ShareLaTeX, this is what the software has been developed using and most people use when running ShareLaTeX. + ### Mongo and Redis ShareLaTeX depends on [MongoDB](http://www.mongodb.org/) (must be 2.4 or later, 3.x is recommended), and From 7eebc60aa59e07c863cb052d17de30bffe178c9f Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 23 May 2016 11:30:25 +0100 Subject: [PATCH 185/525] added docker and and templates options for server pro --- server-ce/settings.coffee | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 165d4c16d0..06d34c567a 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -451,6 +451,15 @@ if process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or process.env["SHARELA length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] or 50} + + +####################### +# ShareLaTeX Server Pro +####################### + + + + # LDAP - SERVER PRO ONLY # ---------- # Settings below use a working LDAP test server kindly provided by forumsys.com @@ -475,6 +484,26 @@ if process.env["SHARELATEX_LDAP_HOST"] rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] or false ca: process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] # e.g.'/etc/ldap/ca_certs.pem' +# Compiler +# -------- + +if process.env["DOCKER_IN_DOCKER"] + clsi: + commandRunner: "docker-runner-sharelatex" + docker: + image: "sharelatex-texlive" + env: + PATH: process.env["COMPILER_PATH"] or "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + user: "tex" + + +# Templates +# --------- +if process.env["SHARELATEX_TEMPLATES_USER_ID"] + templates: + mountPointUrl: "/templates" + user_id: process.env["SHARELATEX_TEMPLATES_USER_ID"] + From fc11c63ac196b8742a17e68d2fa1f46b6786be2f Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 23 May 2016 11:37:43 +0100 Subject: [PATCH 186/525] add git ignore --- server-ce/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 server-ce/.gitignore diff --git a/server-ce/.gitignore b/server-ce/.gitignore new file mode 100644 index 0000000000..c2658d7d1b --- /dev/null +++ b/server-ce/.gitignore @@ -0,0 +1 @@ +node_modules/ From 82e00ce700c74f115d53b82767b87e3a66c468eb Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 23 May 2016 11:38:09 +0000 Subject: [PATCH 187/525] ignore api-data --- server-ce/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/.gitignore b/server-ce/.gitignore index c2658d7d1b..84b9efb392 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -1 +1,2 @@ node_modules/ +api-data From f33d82088e7e7e4bc2eb99cd50bb4cfff6f43bec Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 23 May 2016 12:39:06 +0100 Subject: [PATCH 188/525] use dir of versions not version --- server-ce/Gruntfile.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 0f1d222059..fad7fc82da 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -27,7 +27,7 @@ module.exports = (grunt) -> # access_token: '' concat: true src: repos - dest: 'version/' + tag + '.json' + dest: 'versions/' + tag + '.json' grunt.loadNpmTasks 'grunt-docker-io' grunt.loadNpmTasks 'grunt-github-api' From ba2ef4f6bda035f07f519a624149fa3f81ffc5dd Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 23 May 2016 12:43:26 +0100 Subject: [PATCH 189/525] move init scripts to init dir --- server-ce/Dockerfile | 8 ++++---- .../{ => init_scripts}/00_make_sharelatex_data_dirs.sh | 0 .../{ => init_scripts}/00_regen_sharelatex_secrets.sh | 0 .../{ => init_scripts}/00_set_docker_host_ipaddress.sh | 0 server-ce/{ => init_scripts}/99_migrate.sh | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename server-ce/{ => init_scripts}/00_make_sharelatex_data_dirs.sh (100%) rename server-ce/{ => init_scripts}/00_regen_sharelatex_secrets.sh (100%) rename server-ce/{ => init_scripts}/00_set_docker_host_ipaddress.sh (100%) rename server-ce/{ => init_scripts}/99_migrate.sh (100%) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 2f9766efaa..ca42eb7fc3 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -95,10 +95,10 @@ RUN apt-get install -y unzip RUN apt-get install -y imagemagick optipng # phusion/baseimage init script -ADD ${baseDir}/00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh -ADD ${baseDir}/00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh -ADD ${baseDir}/00_set_docker_host_ipaddress.sh /etc/my_init.d/00_set_docker_host_ipaddress.sh -ADD ${baseDir}/99_migrate.sh /etc/my_init.d/99_migrate.sh +ADD ${baseDir}/init_scripts/00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh +ADD ${baseDir}/init_scripts/00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh +ADD ${baseDir}/init_scripts/00_set_docker_host_ipaddress.sh /etc/my_init.d/00_set_docker_host_ipaddress.sh +ADD ${baseDir}/init_scripts/99_migrate.sh /etc/my_init.d/99_migrate.sh # Install ShareLaTeX settings file RUN mkdir /etc/sharelatex diff --git a/server-ce/00_make_sharelatex_data_dirs.sh b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh similarity index 100% rename from server-ce/00_make_sharelatex_data_dirs.sh rename to server-ce/init_scripts/00_make_sharelatex_data_dirs.sh diff --git a/server-ce/00_regen_sharelatex_secrets.sh b/server-ce/init_scripts/00_regen_sharelatex_secrets.sh similarity index 100% rename from server-ce/00_regen_sharelatex_secrets.sh rename to server-ce/init_scripts/00_regen_sharelatex_secrets.sh diff --git a/server-ce/00_set_docker_host_ipaddress.sh b/server-ce/init_scripts/00_set_docker_host_ipaddress.sh similarity index 100% rename from server-ce/00_set_docker_host_ipaddress.sh rename to server-ce/init_scripts/00_set_docker_host_ipaddress.sh diff --git a/server-ce/99_migrate.sh b/server-ce/init_scripts/99_migrate.sh similarity index 100% rename from server-ce/99_migrate.sh rename to server-ce/init_scripts/99_migrate.sh From 5759c381b1e78eb99c61a827eaa34d164e1392ae Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 23 May 2016 12:51:49 +0100 Subject: [PATCH 190/525] create templates dir --- server-ce/Dockerfile | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index ca42eb7fc3..006c9503f8 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -12,7 +12,11 @@ RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharela mkdir -p /var/lib/sharelatex; \ chown sharelatex:sharelatex /var/lib/sharelatex; \ mkdir -p /var/log/sharelatex; \ - chown sharelatex:sharelatex /var/log/sharelatex; + chown sharelatex:sharelatex /var/log/sharelatex; \ + mkdir -p /var/lib/sharelatex/data/template_files; \ + chown sharelatex:sharelatex /var/lib/sharelatex/data/template_files; + + # Install ShareLaTeX RUN apt-get install -y git python @@ -57,7 +61,11 @@ RUN mkdir /etc/service/chat-sharelatex; \ mkdir /etc/service/spelling-sharelatex; \ mkdir /etc/service/tags-sharelatex; \ mkdir /etc/service/track-changes-sharelatex; \ - mkdir /etc/service/web-sharelatex; + mkdir /etc/service/web-sharelatex; + + + + ADD ${baseDir}/runit/chat-sharelatex.sh /etc/service/chat-sharelatex/run ADD ${baseDir}/runit/clsi-sharelatex.sh /etc/service/clsi-sharelatex/run From c852ff16d7f6491d57c2beb0c201f121ce23fa2b Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 23 May 2016 13:26:45 +0100 Subject: [PATCH 191/525] fixed bad coffeescript in settings file --- server-ce/settings.coffee | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index f479c13350..765c6c3354 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -423,7 +423,7 @@ settings = if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] - settings.email: + settings.email = fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] replyTo: process.env["SHARELATEX_EMAIL_REPLY_TO"] or "" parameters: @@ -446,7 +446,7 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] # opts are from http://antelle.github.io/passfield if process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] - settings.passwordStrengthOptions: + settings.passwordStrengthOptions = pattern: process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or "aA$3" length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] or 50} @@ -467,7 +467,7 @@ if process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or process.env["SHARELA if process.env["SHARELATEX_LDAP_HOST"] - settings.ldap : + settings.ldap = host: process.env["SHARELATEX_LDAP_HOST"] dn: process.env["SHARELATEX_LDAP_DN"] baseSearch: process.env["SHARELATEX_LDAP_BASE_SEARCH"] @@ -486,7 +486,6 @@ if process.env["SHARELATEX_LDAP_HOST"] # Compiler # -------- - if process.env["DOCKER_IN_DOCKER"] clsi: commandRunner: "docker-runner-sharelatex" From 35105269636ed23cf31f63e8cebf82bad4ab77bf Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 23 May 2016 14:27:24 +0100 Subject: [PATCH 192/525] added strace and time --- server-ce/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 006c9503f8..c7081288f4 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -25,6 +25,9 @@ RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex # zlib1g-dev is needed to compile the synctex binaries in the CLSI during `grunt install`. RUN apt-get install -y zlib1g-dev +RUN apt-get install -y time +RUN apt-get install -y strace + ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js ADD ${baseDir}/package.json /var/www/package.json @@ -64,9 +67,6 @@ RUN mkdir /etc/service/chat-sharelatex; \ mkdir /etc/service/web-sharelatex; - - - ADD ${baseDir}/runit/chat-sharelatex.sh /etc/service/chat-sharelatex/run ADD ${baseDir}/runit/clsi-sharelatex.sh /etc/service/clsi-sharelatex/run ADD ${baseDir}/runit/docstore-sharelatex.sh /etc/service/docstore-sharelatex/run From a5d1c45c539c452289be9ab5fb082ebebf0d66cf Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 24 May 2016 12:12:26 +0100 Subject: [PATCH 193/525] added missing ldap settings --- server-ce/settings.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 765c6c3354..7e4f88a327 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -480,7 +480,11 @@ if process.env["SHARELATEX_LDAP_HOST"] adminDN: process.env["SHARELATEX_LDAP_ADMIN_DN"] adminPW: process.env["SHARELATEX_LDAP_ADMIN_PW"] starttls: process.env["SHARELATEX_LDAP_TLS"] or false - tlsOptions: + nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"] + lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"] + + if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] + settings.ldap.tlsOptions = rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] or false ca: process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] # e.g.'/etc/ldap/ca_certs.pem' From 291602996be8e58ec5b672cc100316d502f47bc6 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 24 May 2016 15:47:13 +0100 Subject: [PATCH 194/525] moved guide to official wiki --- server-ce/README.md | 215 +------------------------------------------- 1 file changed, 3 insertions(+), 212 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 5d6956d7f6..e5980183ac 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,214 +1,5 @@ -ShareLaTeX Community Docker Image -======================= +## Install +Please see the (offical wiki for install guides)[https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions] -**Please read this entire file before installing ShareLaTeX via Docker. It's only -short but contains some important information.** -The recommended way to install and run ShareLaTeX Community Edition is via [Docker](https://www.docker.com/): - -``` -$ docker run -d \ - -v ~/sharelatex_data:/var/lib/sharelatex \ - -p 5000:80 \ - --name=sharelatex \ - sharelatex/sharelatex -``` - -This will download the ShareLaTeX image and start it running in the background on port 5000. You should be able to access it at http://localhost:5000/. - -To stop ShareLaTeX: - -``` -docker stop sharelatex -``` - -and to start it again: - -``` -docker start sharelatex -``` - -If you want to permanently remove ShareLaTeX from your docker containers: - -``` -docker rm sharelatex -``` - -### Operating systems -We recommend a debian based operating system such as Ubuntu for ShareLaTeX, this is what the software has been developed using and most people use when running ShareLaTeX. - -### Mongo and Redis - -ShareLaTeX depends on [MongoDB](http://www.mongodb.org/) (must be 2.4 or later, 3.x is recommended), and -[Redis](http://redis.io/) (must be version 2.6.12 or later). -These should be running on the host system. - -Note that Docker containers each come with their own network stack, and Mongo and Redis -often listen by default on `127.0.0.1` which is not accessible on the host -from inside the Docker container. Instead, you should configure Mongo and Redis to -also listen on `172.17.42.1` (or whatever ip iddress the docker0 interface has on your -host). This can be done in `/etc/mongod.conf` and `/etc/redis/redis.conf`. - -``` -# /etc/mongod.conf -... -bind_ip = 172.17.42.1 -... -``` - -``` -# /etc/redis/redis.conf -... -bind 172.17.42.1 -... -``` - -By default the ShareLaTeX Docker container looks for these running on the host -machine at port 27017 (for Mongo) and port 6379 (for Redis). These are the defaults -ports for both databases so you shouldn't need to change them. - -If you want to point ShareLaTeX at a database in a different location, you can -configure the container with environment variables. See the **Configuration Options** -section below. - -*Note that `localhost` in the container refers only to the container, so if you -want to access services on the host machine then you should use `dockerhost`. -`dockerhost` refers to the the `172.17.42.1` ip address mentioned above.* For example: - -``` -$ docker run -d \ - -v ~/sharelatex_data:/var/lib/sharelatex \ - -p 5000:80 \ - --name=sharelatex \ - --env SHARELATEX_MONGO_URL=mongodb://dockerhost/sharelatex \ - sharelatex/sharelatex -``` - -### Storing Data - -The `-v ~/sharelatex_data:/var/lib/sharelatex` option in the `run` command tells -Docker to make the host directory `~/sharelatex_data` available inside the container for -ShareLaTeX to store data files in. This means that you can back up and access these -files manually outside of the ShareLaTeX container. If you would like to store ShareLaTeX data -in a different location, such as `/home/james/my_data`, just change this parameter: - -``` -$ docker run -d \ - -v /home/james/my_data:/var/lib/sharelatex \ - -p 80 \ - --name=sharelatex \ - sharelatex/sharelatex -``` - -Do not change the second part of this parameter (after the :). - -This is only where ShareLaTeX stores on-disk data. -Other data is also stored in Mongo and Redis. - -### Backups - -To backup the ShareLaTeX data, you need to backup the directory you have attached -to the container, as above. You also need to backup the Mongo and Redis databases. - -### Running on a different port - -The container listens on port 80 by default so you should be able to access -ShareLaTeX at http://localhost/. If you would like to run ShareLaTeX on a different -port (perhaps you have another service running on port 80, or want to put a proxy -in front of ShareLaTeX), then you can forward port 80 from the Docker container -to any other port with the `-p :80` option. For example, to have ShareLaTeX -listen on port 5000: - -``` -$ docker run -d \ - -v ~/sharelatex_data:/var/lib/sharelatex \ - -p 5000:80 \ - --name=sharelatex \ - --env SHARELATEX_SITE_URL=http://localhost:5000 \ - sharelatex/sharelatex -``` - -**(Note that you also have to update the `SHARELATEX_SITE_URL` parameter so that -ShareLaTeX knows where to refer to scripts and links that need loading.)** - -### LaTeX environment - -To save bandwidth, the ShareLaTeX image only comes with a minimal install of -TeXLive. To upgrade to a complete TeXLive installation, run the following command: - -``` -$ docker exec sharelatex tlmgr install scheme-full -``` - -Or you can install packages manually as you need by replacing `scheme-full` by -the package name. - -### Configuration Options - -You can pass the core configuration options to ShareLaTeX as environment variables: - -``` -$ docker run -d \ - -v ~/sharelatex_data:/var/lib/sharelatex \ - -p 5000:80 \ - --name=sharelatex \ - --env SHARELATEX_MONGO_URL=mongodb://my.mongo.host/sharelatex \ - sharelatex/sharelatex -``` - -The available configuration parameters are: - -* `SHARELATEX_SITE_URL`: Where your instance of ShareLaTeX is publically available. -This is used in public links, and when connecting over websockets, so must be -configured correctly! -* `SHARELATEX_ADMIN_EMAIL`: The email address where users can reach the person who runs the site. -* `SHARELATEX_APP_NAME`: The name to display when talking about the running app. Defaults to 'ShareLaTex (Community Edition)'. -* `SHARELATEX_MONGO_URL`: The URL of the Mongo database to use -* `SHARELATEX_REDIS_HOST`: The host name of the Redis instance to use -* `SHARELATEX_REDIS_PORT`: The port of the Redis instance to use -* `SHARELATEX_REDIS_PASS`: The password to use when connecting to Redis (if applicable) -* `SHARELATEX_SECURE_COOKIE`: Set this to something non-zero to use a secure cookie. - Only use this if your ShareLaTeX instance is running behind a reverse proxy with SSL configured. - -Other settings such as email setup need to be edited in the docker container at /etc/sharelatex/settings.coffee. We realise this is not an ideal solution and are working on a more streamlined settings file approach. - -### Creating and Managing users - -Uun the following command to create your first user and make them an admin: - -``` -$ docker exec sharelatex /bin/bash -c "cd /var/www/sharelatex/web; grunt create-admin-user --email joe@example.com" -``` - -This will create a user with the given email address if they don't already exist, and make them an admin user. You will be given a URL to visit where you can set the password for this user and log in for the first time. - -**Creating normal users** - -Once you are logged in as an admin user, you can visit `/admin/register` on your ShareLaTeX instance and create a new users. If you have an email backend configured in your settings file, the new users will be sent an email with a URL to set their password. If not, you will have to distribute the password reset URLs manually. These are shown when you create a user. - -### Upgrading from older versions - -*Please make sure to back up all Mongo, Redis and on-disk data before upgrading.* - -#### Migrations -Data stored in Mongodb will be automatically migrated to the latest schemea when upgrading docker releases. **This can make downgrades impossible.** One recommended technique is to test the migration first. This can be done by copying the mongodb database and doing a test run against the copied data. - -``` -db.copyDatabase(sharelatex,sharelatex-copy) -# start the container up pointing at the new db ---env SHARELATEX_MONGO_URL=mongodb://dockerhost/sharelatex-copy -``` - -#### Upgrade process -To use the new docker container stop and remove the currently running ShareLaTeX container: - -``` -$ docker stop sharelatex -$ docker rm sharelatex -``` - -Start a new container with the updated version of ShareLaTeX (to upgrade to version 1.4.0 for example): - -``` -$ docker run -d -v ~/sharelatex_data:/var/lib/sharelatex --name=sharelatex sharelatex/sharelatex:1.4.0 -``` +The docker files can be built with grunt. We do this as there are some other tasks which are done using grunt such as marking the versions of each repo used. From 28add83bca3521350a14686968e1010e977afb2b Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 24 May 2016 15:47:46 +0100 Subject: [PATCH 195/525] Update README.md --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index e5980183ac..0b11b2b198 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,5 +1,5 @@ ## Install -Please see the (offical wiki for install guides)[https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions] +Please see the [offical wiki for install guides](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) The docker files can be built with grunt. We do this as there are some other tasks which are done using grunt such as marking the versions of each repo used. From 252cbed435b96003f66704ca0335e69633ad295c Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 24 May 2016 15:48:02 +0100 Subject: [PATCH 196/525] Update README.md --- server-ce/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/README.md b/server-ce/README.md index 0b11b2b198..04a117bcb7 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,5 +1,6 @@ ## Install Please see the [offical wiki for install guides](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) +## Building image The docker files can be built with grunt. We do this as there are some other tasks which are done using grunt such as marking the versions of each repo used. From a6cabbb6920070f124856e6f660f9551d9c4ad98 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 24 May 2016 16:10:07 +0100 Subject: [PATCH 197/525] Update README.md --- server-ce/README.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 1457bcdb4f..63b87a2138 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -15,9 +15,7 @@ Installation We have detailed installation instructions in our wiki: * [Installing ShareLaTeX in Production using docker](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) -* [Setting up a ShareLaTeX Development Environment](https://github.com/sharelatex/sharelatex/wiki/Setting-up-a-Development-Environment) -**If you have any problems, have a look at our page of [Frequent Problems and Questions](https://github.com/sharelatex/sharelatex/wiki/FAQ).** Upgrading --------- @@ -25,18 +23,6 @@ Upgrading If you are upgrading from a previous version of ShareLaTeX, please see the [Release Notes section on the Wiki] (https://github.com/sharelatex/sharelatex/wiki/Home) for all of the versions between your current version and the version you are upgrading to. -Dependencies ------------- - -ShareLaTeX should run on OS X and Linux. You need: - -* [Node.js](http://nodejs.org/) 0.10.x. We recommend that you use [nvm](https://github.com/creationix/nvm) to install it. -* The [grunt](http://gruntjs.com/) command line tools (Run `npm install -g grunt-cli` to install them) -* A local instance of [Redis](http://redis.io/topics/quickstart) (version 2.6.12 or later) and [MongoDB](http://docs.mongodb.org/manual/installation/) running on their standard ports. -* [TeXLive](https://www.tug.org/texlive/) 2013 or later with the `latexmk` program installed. - -ShareLaTeX needs a minimum of 2gb of memory, it is likely to be more than that though depending on usage. - Other repositories ------------------ From 879a23c8573f1c83bb78077fec80d7fdcddc5de7 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 24 May 2016 16:43:08 +0100 Subject: [PATCH 198/525] fix templates & clsi set dynamically. and more robust bool vals from env vars --- server-ce/settings.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 7e4f88a327..2e2c738acb 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -476,22 +476,22 @@ if process.env["SHARELATEX_LDAP_HOST"] fieldName: process.env["SHARELATEX_LDAP_FIELD_NAME"] or 'LDAP User' placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"] or 'LDAP User ID' emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"] or 'mail' - anonymous: process.env["SHARELATEX_LDAP_ANONYMOUS"] or false + anonymous: process.env["SHARELATEX_LDAP_ANONYMOUS"] == "true" adminDN: process.env["SHARELATEX_LDAP_ADMIN_DN"] adminPW: process.env["SHARELATEX_LDAP_ADMIN_PW"] - starttls: process.env["SHARELATEX_LDAP_TLS"] or false + starttls: process.env["SHARELATEX_LDAP_TLS"] == "true" nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"] lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"] if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] settings.ldap.tlsOptions = - rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] or false + rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true" ca: process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] # e.g.'/etc/ldap/ca_certs.pem' # Compiler # -------- -if process.env["DOCKER_IN_DOCKER"] - clsi: +if process.env["DOCKER_IN_DOCKER"] == "true" + settings.clsi = commandRunner: "docker-runner-sharelatex" docker: image: "sharelatex-texlive" @@ -503,7 +503,7 @@ if process.env["DOCKER_IN_DOCKER"] # Templates # --------- if process.env["SHARELATEX_TEMPLATES_USER_ID"] - templates: + settings.templates = mountPointUrl: "/templates" user_id: process.env["SHARELATEX_TEMPLATES_USER_ID"] From 61b8e67447874bfa8d83d4e8e6ec537a5526f19e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 26 May 2016 11:01:21 +0100 Subject: [PATCH 199/525] build latex first for faster images and compile clsi synctex --- server-ce/Dockerfile | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index c7081288f4..7fd51f7e01 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -2,6 +2,15 @@ FROM phusion/baseimage:0.9.16 ENV baseDir . +# Install TexLive +RUN apt-get install -y wget +RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ + mkdir /install-tl-unx; \ + tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 + +RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ + /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile + # Install Node.js and Grunt RUN curl -sL https://deb.nodesource.com/setup | sudo bash - RUN apt-get install -y build-essential nodejs @@ -17,7 +26,6 @@ RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharela chown sharelatex:sharelatex /var/lib/sharelatex/data/template_files; - # Install ShareLaTeX RUN apt-get install -y git python RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex @@ -44,6 +52,9 @@ RUN cd /var/www && node git-revision > revisions.txt RUN cd /var/www/sharelatex/web; \ grunt compile:minify; +RUN cd /var/www/sharelatex/clsi; \ + grunt compile:bin + # Install Nginx as a reverse proxy run apt-get update RUN apt-get install -y nginx; @@ -78,14 +89,8 @@ ADD ${baseDir}/runit/tags-sharelatex.sh /etc/service/tags-sharelatex ADD ${baseDir}/runit/track-changes-sharelatex.sh /etc/service/track-changes-sharelatex/run ADD ${baseDir}/runit/web-sharelatex.sh /etc/service/web-sharelatex/run -# Install TexLive -RUN apt-get install -y wget -RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ - mkdir /install-tl-unx; \ - tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 -RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ - /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile + RUN rm -r /install-tl-unx; \ rm install-tl-unx.tar.gz @@ -113,6 +118,8 @@ RUN mkdir /etc/sharelatex ADD ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee + + EXPOSE 80 ENTRYPOINT ["/sbin/my_init"] From 93ae1e015ff6cb2dd9a3eb165bab948c74db8bf8 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 26 May 2016 11:22:51 +0100 Subject: [PATCH 200/525] build things that don't change at the start for quicker build time --- server-ce/Dockerfile | 53 +++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 7fd51f7e01..9cfd8edc51 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -2,6 +2,10 @@ FROM phusion/baseimage:0.9.16 ENV baseDir . +RUN apt-get update +RUN curl -sL https://deb.nodesource.com/setup | sudo bash - +RUN apt-get install -y build-essential nodejs + # Install TexLive RUN apt-get install -y wget RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ @@ -12,10 +16,26 @@ RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile # Install Node.js and Grunt -RUN curl -sL https://deb.nodesource.com/setup | sudo bash - -RUN apt-get install -y build-essential nodejs RUN npm install -g grunt-cli +# Install Aspell +RUN apt-get install -y aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu + +# Install unzip for file uploads +RUN apt-get install -y unzip + +# Install imagemagick for image conversions +RUN apt-get install -y imagemagick optipng + +# zlib1g-dev is needed to compile the synctex binaries in the CLSI during `grunt install`. +RUN apt-get install -y zlib1g-dev + +RUN apt-get install -y time +RUN apt-get install -y strace +RUN apt-get install -y nginx +RUN apt-get install -y git +RUN apt-get install -y python + # Set up sharelatex user and home directory RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex; \ mkdir -p /var/lib/sharelatex; \ @@ -27,16 +47,8 @@ RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharela # Install ShareLaTeX -RUN apt-get install -y git python RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex -# zlib1g-dev is needed to compile the synctex binaries in the CLSI during `grunt install`. -RUN apt-get install -y zlib1g-dev - -RUN apt-get install -y time -RUN apt-get install -y strace - - ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js ADD ${baseDir}/package.json /var/www/package.json ADD ${baseDir}/git-revision.js /var/www/git-revision.js @@ -55,13 +67,6 @@ RUN cd /var/www/sharelatex/web; \ RUN cd /var/www/sharelatex/clsi; \ grunt compile:bin -# Install Nginx as a reverse proxy -run apt-get update -RUN apt-get install -y nginx; -RUN rm /etc/nginx/sites-enabled/default -ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf -ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf - RUN mkdir /etc/service/nginx ADD ${baseDir}/runit/nginx.sh /etc/service/nginx/run @@ -89,7 +94,9 @@ ADD ${baseDir}/runit/tags-sharelatex.sh /etc/service/tags-sharelatex ADD ${baseDir}/runit/track-changes-sharelatex.sh /etc/service/track-changes-sharelatex/run ADD ${baseDir}/runit/web-sharelatex.sh /etc/service/web-sharelatex/run - +RUN rm /etc/nginx/sites-enabled/default +ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf +ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf RUN rm -r /install-tl-unx; \ rm install-tl-unx.tar.gz @@ -98,15 +105,6 @@ ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local RUN apt-get update RUN tlmgr install latexmk -# Install Aspell -RUN apt-get install -y aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu - -# Install unzip for file uploads -RUN apt-get install -y unzip - -# Install imagemagick for image conversions -RUN apt-get install -y imagemagick optipng - # phusion/baseimage init script ADD ${baseDir}/init_scripts/00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh ADD ${baseDir}/init_scripts/00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh @@ -119,7 +117,6 @@ ADD ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee - EXPOSE 80 ENTRYPOINT ["/sbin/my_init"] From 9646654c481bfee3a504ab718e1b76fa47b2da21 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 27 May 2016 12:12:28 +0100 Subject: [PATCH 201/525] put apt-get installs on same line and set $TEX_LIVE_DOCKER_IMAGE via env var --- server-ce/Dockerfile | 20 +++----------------- server-ce/settings.coffee | 2 +- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 9cfd8edc51..929528f274 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -4,10 +4,11 @@ ENV baseDir . RUN apt-get update RUN curl -sL https://deb.nodesource.com/setup | sudo bash - -RUN apt-get install -y build-essential nodejs +RUN apt-get install -y build-essential wget nodejs unzip time imagemagick optipng strace nginx git python zlib1g-dev; \ + install -y aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu + # Install TexLive -RUN apt-get install -y wget RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ mkdir /install-tl-unx; \ tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 @@ -18,23 +19,8 @@ RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ # Install Node.js and Grunt RUN npm install -g grunt-cli -# Install Aspell -RUN apt-get install -y aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu -# Install unzip for file uploads -RUN apt-get install -y unzip -# Install imagemagick for image conversions -RUN apt-get install -y imagemagick optipng - -# zlib1g-dev is needed to compile the synctex binaries in the CLSI during `grunt install`. -RUN apt-get install -y zlib1g-dev - -RUN apt-get install -y time -RUN apt-get install -y strace -RUN apt-get install -y nginx -RUN apt-get install -y git -RUN apt-get install -y python # Set up sharelatex user and home directory RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex; \ diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 2e2c738acb..f3066da8ed 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -494,7 +494,7 @@ if process.env["DOCKER_IN_DOCKER"] == "true" settings.clsi = commandRunner: "docker-runner-sharelatex" docker: - image: "sharelatex-texlive" + image: process.env["TEX_LIVE_DOCKER_IMAGE"] env: PATH: process.env["COMPILER_PATH"] or "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" user: "tex" From ab61d05e4af5dd4e9833d6739bf1d9b46f45f103 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 27 May 2016 12:55:18 +0100 Subject: [PATCH 202/525] run as www-data --- server-ce/Dockerfile | 6 +++--- server-ce/runit/chat-sharelatex.sh | 2 +- server-ce/runit/clsi-sharelatex.sh | 2 +- server-ce/runit/docstore-sharelatex.sh | 2 +- server-ce/runit/document-updater-sharelatex.sh | 2 +- server-ce/runit/filestore-sharelatex.sh | 2 +- server-ce/runit/real-time-sharelatex.sh | 2 +- server-ce/runit/spelling-sharelatex.sh | 2 +- server-ce/runit/tags-sharelatex.sh | 2 +- server-ce/runit/track-changes-sharelatex.sh | 2 +- server-ce/runit/web-sharelatex.sh | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 929528f274..eac17b83c1 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -25,11 +25,11 @@ RUN npm install -g grunt-cli # Set up sharelatex user and home directory RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex; \ mkdir -p /var/lib/sharelatex; \ - chown sharelatex:sharelatex /var/lib/sharelatex; \ + chown www-data:www-data /var/lib/sharelatex; \ mkdir -p /var/log/sharelatex; \ - chown sharelatex:sharelatex /var/log/sharelatex; \ + chown www-data:www-data /var/log/sharelatex; \ mkdir -p /var/lib/sharelatex/data/template_files; \ - chown sharelatex:sharelatex /var/lib/sharelatex/data/template_files; + chown www-data:www-data /var/lib/sharelatex/data/template_files; # Install ShareLaTeX diff --git a/server-ce/runit/chat-sharelatex.sh b/server-ce/runit/chat-sharelatex.sh index 509ff8588e..1b8533bb86 100755 --- a/server-ce/runit/chat-sharelatex.sh +++ b/server-ce/runit/chat-sharelatex.sh @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/chat/app.js >> /var/log/sharelatex/chat.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/chat/app.js >> /var/log/sharelatex/chat.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/clsi-sharelatex.sh b/server-ce/runit/clsi-sharelatex.sh index 59298743c8..1c6974cd2a 100755 --- a/server-ce/runit/clsi-sharelatex.sh +++ b/server-ce/runit/clsi-sharelatex.sh @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/clsi/app.js >> /var/log/sharelatex/clsi.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/clsi/app.js >> /var/log/sharelatex/clsi.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/docstore-sharelatex.sh b/server-ce/runit/docstore-sharelatex.sh index ba7a96c8d7..0de82ccf20 100755 --- a/server-ce/runit/docstore-sharelatex.sh +++ b/server-ce/runit/docstore-sharelatex.sh @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/docstore/app.js >> /var/log/sharelatex/docstore.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/docstore/app.js >> /var/log/sharelatex/docstore.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/document-updater-sharelatex.sh b/server-ce/runit/document-updater-sharelatex.sh index 8f692ecdbe..274b7f9998 100755 --- a/server-ce/runit/document-updater-sharelatex.sh +++ b/server-ce/runit/document-updater-sharelatex.sh @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/document-updater/app.js >> /var/log/sharelatex/document-updater.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/document-updater/app.js >> /var/log/sharelatex/document-updater.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/filestore-sharelatex.sh b/server-ce/runit/filestore-sharelatex.sh index b02695f747..e0858c01ce 100755 --- a/server-ce/runit/filestore-sharelatex.sh +++ b/server-ce/runit/filestore-sharelatex.sh @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/filestore/app.js >> /var/log/sharelatex/filestore.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/filestore/app.js >> /var/log/sharelatex/filestore.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/real-time-sharelatex.sh b/server-ce/runit/real-time-sharelatex.sh index 19aaed457b..c57d1d489e 100755 --- a/server-ce/runit/real-time-sharelatex.sh +++ b/server-ce/runit/real-time-sharelatex.sh @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/real-time/app.js >> /var/log/sharelatex/real-time.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/real-time/app.js >> /var/log/sharelatex/real-time.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/spelling-sharelatex.sh b/server-ce/runit/spelling-sharelatex.sh index 848c6ac7d1..4466bcfcf5 100755 --- a/server-ce/runit/spelling-sharelatex.sh +++ b/server-ce/runit/spelling-sharelatex.sh @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/spelling/app.js >> /var/log/sharelatex/spelling.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/spelling/app.js >> /var/log/sharelatex/spelling.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/tags-sharelatex.sh b/server-ce/runit/tags-sharelatex.sh index 8616c1356c..a5630ed4ff 100755 --- a/server-ce/runit/tags-sharelatex.sh +++ b/server-ce/runit/tags-sharelatex.sh @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/tags/app.js >> /var/log/sharelatex/tags.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/tags/app.js >> /var/log/sharelatex/tags.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/track-changes-sharelatex.sh b/server-ce/runit/track-changes-sharelatex.sh index 347d8f021a..aeb812ef38 100755 --- a/server-ce/runit/track-changes-sharelatex.sh +++ b/server-ce/runit/track-changes-sharelatex.sh @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/track-changes/app.js >> /var/log/sharelatex/track-changes.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/track-changes/app.js >> /var/log/sharelatex/track-changes.log 2>&1 \ No newline at end of file diff --git a/server-ce/runit/web-sharelatex.sh b/server-ce/runit/web-sharelatex.sh index b0bda54c81..053a55a326 100755 --- a/server-ce/runit/web-sharelatex.sh +++ b/server-ce/runit/web-sharelatex.sh @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser sharelatex /usr/bin/node /var/www/sharelatex/web/app.js >> /var/log/sharelatex/web.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/web/app.js >> /var/log/sharelatex/web.log 2>&1 \ No newline at end of file From 9760850d87b264cda62c62754c976f680195770b Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 27 May 2016 13:12:22 +0100 Subject: [PATCH 203/525] one line the apt-get --- server-ce/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index eac17b83c1..e3ca178741 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -4,8 +4,7 @@ ENV baseDir . RUN apt-get update RUN curl -sL https://deb.nodesource.com/setup | sudo bash - -RUN apt-get install -y build-essential wget nodejs unzip time imagemagick optipng strace nginx git python zlib1g-dev; \ - install -y aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu +RUN apt-get install -y build-essential wget nodejs unzip time imagemagick optipng strace nginx git python zlib1g-dev aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu # Install TexLive From 4560a5ded1ffb9da484e7a841891b5a560372ecf Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 27 May 2016 15:46:51 +0100 Subject: [PATCH 204/525] run everything as www-data --- .../00_make_sharelatex_data_dirs.sh | 17 ++++++++++------- server-ce/settings.coffee | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh index f8d424f201..f48a95fde7 100755 --- a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh +++ b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh @@ -1,21 +1,24 @@ #!/bin/sh mkdir -p /var/lib/sharelatex/data -chown sharelatex:sharelatex /var/lib/sharelatex/data +chown www-data:www-data /var/lib/sharelatex/data mkdir -p /var/lib/sharelatex/data/user_files -chown sharelatex:sharelatex /var/lib/sharelatex/data/user_files +chown www-data:www-data /var/lib/sharelatex/data/user_files mkdir -p /var/lib/sharelatex/data/compiles -chown sharelatex:sharelatex /var/lib/sharelatex/data/compiles +chown www-data:www-data /var/lib/sharelatex/data/compiles mkdir -p /var/lib/sharelatex/data/cache -chown sharelatex:sharelatex /var/lib/sharelatex/data/cache +chown www-data:www-data /var/lib/sharelatex/data/cache mkdir -p /var/lib/sharelatex/tmp -chown sharelatex:sharelatex /var/lib/sharelatex/tmp +chown www-data:www-data /var/lib/sharelatex/tmp mkdir -p /var/lib/sharelatex/tmp/uploads -chown sharelatex:sharelatex /var/lib/sharelatex/tmp/uploads +chown www-data:www-data /var/lib/sharelatex/tmp/uploads mkdir -p /var/lib/sharelatex/tmp/dumpFolder -chown sharelatex:sharelatex /var/lib/sharelatex/tmp/dumpFolder \ No newline at end of file +chown www-data:www-data /var/lib/sharelatex/tmp/dumpFolder + + +chown www-data:www-data /var/lib/sharelatex/data/db.sqlite \ No newline at end of file diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index f3066da8ed..f6d48b3dc4 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -497,7 +497,7 @@ if process.env["DOCKER_IN_DOCKER"] == "true" image: process.env["TEX_LIVE_DOCKER_IMAGE"] env: PATH: process.env["COMPILER_PATH"] or "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - user: "tex" + user: "www-data" # Templates From 2c53672dbd5af99ea05778dafa2b7c19367d7ef6 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 31 May 2016 14:15:24 +0000 Subject: [PATCH 205/525] install qpdf v6 --- server-ce/Dockerfile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index e3ca178741..91fa6e4c4d 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -4,8 +4,12 @@ ENV baseDir . RUN apt-get update RUN curl -sL https://deb.nodesource.com/setup | sudo bash - -RUN apt-get install -y build-essential wget nodejs unzip time imagemagick optipng strace nginx git python zlib1g-dev aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu +RUN apt-get install -y build-essential wget nodejs unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu +WORKDIR /opt +RUN wget https://s3.amazonaws.com/sharelatex-random-files/qpdf-6.0.0.tar.gz && tar xzf qpdf-6.0.0.tar.gz +WORKDIR /opt/qpdf-6.0.0 +RUN ./configure && make && make install && ldconfig # Install TexLive RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ @@ -19,8 +23,6 @@ RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ RUN npm install -g grunt-cli - - # Set up sharelatex user and home directory RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex; \ mkdir -p /var/lib/sharelatex; \ @@ -105,3 +107,4 @@ ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee EXPOSE 80 ENTRYPOINT ["/sbin/my_init"] + From 8a25755b8a949687de4a09cdbda68f017619e13a Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 31 May 2016 15:16:31 +0100 Subject: [PATCH 206/525] set synctexBaseDir: () -> "/compile" if using docker in docker --- server-ce/Dockerfile | 2 ++ server-ce/settings.coffee | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 91fa6e4c4d..d7ca93d357 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -106,5 +106,7 @@ ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee EXPOSE 80 +WORKDIR / + ENTRYPOINT ["/sbin/my_init"] diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index f6d48b3dc4..e1b5c2ca5e 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -499,6 +499,10 @@ if process.env["DOCKER_IN_DOCKER"] == "true" PATH: process.env["COMPILER_PATH"] or "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" user: "www-data" + if !settings.path? + settings.path = {} + settings.path.synctexBaseDir = () -> "/compile" + # Templates # --------- From 73e4b42df72e2f867d33b76a488db059f02747e9 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 31 May 2016 15:21:26 +0100 Subject: [PATCH 207/525] use SANDBOXED_COMPILES not DOCKER_IN_DOCKER --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index e1b5c2ca5e..55c964012b 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -490,7 +490,7 @@ if process.env["SHARELATEX_LDAP_HOST"] # Compiler # -------- -if process.env["DOCKER_IN_DOCKER"] == "true" +if process.env["SANDBOXED_COMPILES"] == "true" settings.clsi = commandRunner: "docker-runner-sharelatex" docker: From 2870b6a460e9edfc94f031eb82557a4557530371 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 31 May 2016 16:37:50 +0100 Subject: [PATCH 208/525] try cicule ci --- server-ce/circle.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 server-ce/circle.yml diff --git a/server-ce/circle.yml b/server-ce/circle.yml new file mode 100644 index 0000000000..6df3bd992e --- /dev/null +++ b/server-ce/circle.yml @@ -0,0 +1,13 @@ +# circle.yml +machine: + services: + - docker + +dependencies: + pre: + - grunt + +test: + post: + - docker run -d -v --name=sharelatex -p 5000:80 -; sleep 20 + - curl --retry 10 --retry-delay 5 -v http://localhost:5000/status From b0743a3c2a39463cea8a6e6a2c3a7db461dd3aea Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 6 Jun 2016 14:25:51 +0100 Subject: [PATCH 209/525] added realtime to list of repos --- server-ce/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 63b87a2138..70c32d9e76 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -53,6 +53,10 @@ documents. An API for performing CRUD (Create, Read, Update and Delete) operations on text files stored in ShareLaTeX. +### [realtime](https://github.com/sharelatex/real-time-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/real-time-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/real-time-sharelatex) + +The websocket process clients connect to + ### [filestore](https://github.com/sharelatex/filestore-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/filestore-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/filestore-sharelatex) An API for performing CRUD (Create, Read, Update and Delete) operations on binary files From 2fa60e86f3c2eefba8aaa13272d784a03416af49 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 8 Jun 2016 17:03:19 +0100 Subject: [PATCH 210/525] removed old files no longer used --- server-ce/Vagrantfile | 55 ---- server-ce/cache/.gitignore | 0 server-ce/chef/.chef/knife.rb | 3 - server-ce/chef/cookbooks/apt/CHANGELOG.md | 173 ----------- server-ce/chef/cookbooks/apt/README.md | 248 ---------------- .../chef/cookbooks/apt/attributes/default.rb | 28 -- .../apt/files/default/apt-proxy-v2.conf | 50 ---- .../chef/cookbooks/apt/libraries/helpers.rb | 48 --- .../chef/cookbooks/apt/libraries/matchers.rb | 17 -- .../chef/cookbooks/apt/libraries/network.rb | 31 -- server-ce/chef/cookbooks/apt/metadata.json | 54 ---- server-ce/chef/cookbooks/apt/metadata.rb | 34 --- .../cookbooks/apt/providers/preference.rb | 63 ---- .../cookbooks/apt/providers/repository.rb | 150 ---------- .../cookbooks/apt/recipes/cacher-client.rb | 81 ------ .../chef/cookbooks/apt/recipes/cacher-ng.rb | 43 --- .../chef/cookbooks/apt/recipes/default.rb | 82 ------ .../cookbooks/apt/resources/preference.rb | 32 -- .../cookbooks/apt/resources/repository.rb | 43 --- .../apt/templates/debian-6.0/acng.conf.erb | 173 ----------- .../apt/templates/default/01proxy.erb | 5 - .../apt/templates/default/acng.conf.erb | 275 ------------------ .../apt/templates/ubuntu-10.04/acng.conf.erb | 269 ----------------- server-ce/chef/cookbooks/mongodb/CHANGELOG.md | 12 - server-ce/chef/cookbooks/mongodb/README.md | 68 ----- server-ce/chef/cookbooks/mongodb/metadata.rb | 8 - .../chef/cookbooks/mongodb/recipes/default.rb | 19 -- server-ce/chef/cookbooks/nodejs/CHANGELOG.md | 12 - server-ce/chef/cookbooks/nodejs/README.md | 68 ----- server-ce/chef/cookbooks/nodejs/metadata.rb | 8 - .../chef/cookbooks/nodejs/recipes/default.rb | 24 -- server-ce/chef/cookbooks/packages/README.md | 68 ----- server-ce/chef/cookbooks/packages/metadata.rb | 7 - .../cookbooks/packages/recipes/default.rb | 10 - .../chef/cookbooks/redis-server/CHANGELOG.md | 12 - .../chef/cookbooks/redis-server/README.md | 68 ----- .../chef/cookbooks/redis-server/metadata.rb | 8 - .../cookbooks/redis-server/recipes/default.rb | 20 -- server-ce/chef/cookbooks/texlive/CHANGELOG.md | 12 - server-ce/chef/cookbooks/texlive/README.md | 68 ----- .../cookbooks/texlive/attributes/default.rb | 2 - server-ce/chef/cookbooks/texlive/metadata.rb | 7 - .../chef/cookbooks/texlive/recipes/default.rb | 42 --- .../settings.development.coffee.example | 230 --------------- server-ce/package/nginx/sharelatex.conf | 44 --- .../package/upstart/sharelatex-chat.conf | 28 -- .../package/upstart/sharelatex-clsi.conf | 28 -- .../package/upstart/sharelatex-docstore.conf | 28 -- .../upstart/sharelatex-document-updater.conf | 28 -- .../package/upstart/sharelatex-filestore.conf | 28 -- .../package/upstart/sharelatex-real-time.conf | 28 -- .../package/upstart/sharelatex-spelling.conf | 28 -- .../package/upstart/sharelatex-tags.conf | 28 -- .../package/upstart/sharelatex-template.conf | 28 -- .../upstart/sharelatex-track-changes.conf | 28 -- server-ce/package/upstart/sharelatex-web.conf | 28 -- 56 files changed, 3082 deletions(-) delete mode 100644 server-ce/Vagrantfile delete mode 100644 server-ce/cache/.gitignore delete mode 100644 server-ce/chef/.chef/knife.rb delete mode 100644 server-ce/chef/cookbooks/apt/CHANGELOG.md delete mode 100644 server-ce/chef/cookbooks/apt/README.md delete mode 100644 server-ce/chef/cookbooks/apt/attributes/default.rb delete mode 100644 server-ce/chef/cookbooks/apt/files/default/apt-proxy-v2.conf delete mode 100644 server-ce/chef/cookbooks/apt/libraries/helpers.rb delete mode 100644 server-ce/chef/cookbooks/apt/libraries/matchers.rb delete mode 100644 server-ce/chef/cookbooks/apt/libraries/network.rb delete mode 100644 server-ce/chef/cookbooks/apt/metadata.json delete mode 100644 server-ce/chef/cookbooks/apt/metadata.rb delete mode 100644 server-ce/chef/cookbooks/apt/providers/preference.rb delete mode 100644 server-ce/chef/cookbooks/apt/providers/repository.rb delete mode 100644 server-ce/chef/cookbooks/apt/recipes/cacher-client.rb delete mode 100644 server-ce/chef/cookbooks/apt/recipes/cacher-ng.rb delete mode 100644 server-ce/chef/cookbooks/apt/recipes/default.rb delete mode 100644 server-ce/chef/cookbooks/apt/resources/preference.rb delete mode 100644 server-ce/chef/cookbooks/apt/resources/repository.rb delete mode 100644 server-ce/chef/cookbooks/apt/templates/debian-6.0/acng.conf.erb delete mode 100644 server-ce/chef/cookbooks/apt/templates/default/01proxy.erb delete mode 100644 server-ce/chef/cookbooks/apt/templates/default/acng.conf.erb delete mode 100644 server-ce/chef/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb delete mode 100644 server-ce/chef/cookbooks/mongodb/CHANGELOG.md delete mode 100644 server-ce/chef/cookbooks/mongodb/README.md delete mode 100644 server-ce/chef/cookbooks/mongodb/metadata.rb delete mode 100644 server-ce/chef/cookbooks/mongodb/recipes/default.rb delete mode 100644 server-ce/chef/cookbooks/nodejs/CHANGELOG.md delete mode 100644 server-ce/chef/cookbooks/nodejs/README.md delete mode 100644 server-ce/chef/cookbooks/nodejs/metadata.rb delete mode 100644 server-ce/chef/cookbooks/nodejs/recipes/default.rb delete mode 100644 server-ce/chef/cookbooks/packages/README.md delete mode 100644 server-ce/chef/cookbooks/packages/metadata.rb delete mode 100644 server-ce/chef/cookbooks/packages/recipes/default.rb delete mode 100644 server-ce/chef/cookbooks/redis-server/CHANGELOG.md delete mode 100644 server-ce/chef/cookbooks/redis-server/README.md delete mode 100644 server-ce/chef/cookbooks/redis-server/metadata.rb delete mode 100644 server-ce/chef/cookbooks/redis-server/recipes/default.rb delete mode 100644 server-ce/chef/cookbooks/texlive/CHANGELOG.md delete mode 100644 server-ce/chef/cookbooks/texlive/README.md delete mode 100644 server-ce/chef/cookbooks/texlive/attributes/default.rb delete mode 100644 server-ce/chef/cookbooks/texlive/metadata.rb delete mode 100644 server-ce/chef/cookbooks/texlive/recipes/default.rb delete mode 100644 server-ce/config/settings.development.coffee.example delete mode 100644 server-ce/package/nginx/sharelatex.conf delete mode 100644 server-ce/package/upstart/sharelatex-chat.conf delete mode 100644 server-ce/package/upstart/sharelatex-clsi.conf delete mode 100644 server-ce/package/upstart/sharelatex-docstore.conf delete mode 100644 server-ce/package/upstart/sharelatex-document-updater.conf delete mode 100644 server-ce/package/upstart/sharelatex-filestore.conf delete mode 100644 server-ce/package/upstart/sharelatex-real-time.conf delete mode 100644 server-ce/package/upstart/sharelatex-spelling.conf delete mode 100644 server-ce/package/upstart/sharelatex-tags.conf delete mode 100644 server-ce/package/upstart/sharelatex-template.conf delete mode 100644 server-ce/package/upstart/sharelatex-track-changes.conf delete mode 100644 server-ce/package/upstart/sharelatex-web.conf diff --git a/server-ce/Vagrantfile b/server-ce/Vagrantfile deleted file mode 100644 index 63ddd3b205..0000000000 --- a/server-ce/Vagrantfile +++ /dev/null @@ -1,55 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! -VAGRANTFILE_API_VERSION = "2" - -Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - config.vm.box = "ubuntu-12.04" - config.vm.box_url = "http://files.vagrantup.com/precise64.box" - - config.vm.network :forwarded_port, guest: 3000, host: 3000 - config.vm.network :forwarded_port, guest: 80, host: 8080 - - config.ssh.forward_agent = true - - config.vm.provider "virtualbox" do |v| - v.memory = 1024 - end - - config.vm.provision :chef_solo do |chef| - chef.cookbooks_path = "chef/cookbooks" - chef.add_recipe 'apt' - chef.add_recipe 'redis-server' - chef.add_recipe 'mongodb' - chef.add_recipe 'nodejs' - chef.add_recipe 'texlive' - chef.add_recipe 'packages' - - # You may also specify custom JSON attributes: - chef.json = {} - end - - # Enable provisioning with chef server, specifying the chef server URL, - # and the path to the validation key (relative to this Vagrantfile). - # - # The Opscode Platform uses HTTPS. Substitute your organization for - # ORGNAME in the URL and validation key. - # - # If you have your own Chef Server, use the appropriate URL, which may be - # HTTP instead of HTTPS depending on your configuration. Also change the - # validation key to validation.pem. - # - # config.vm.provision :chef_client do |chef| - # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME" - # chef.validation_key_path = "ORGNAME-validator.pem" - # end - # - # If you're using the Opscode platform, your validator client is - # ORGNAME-validator, replacing ORGNAME with your organization name. - # - # If you have your own Chef Server, the default validation client name is - # chef-validator, unless you changed the configuration. - # - # chef.validation_client_name = "ORGNAME-validator" -end diff --git a/server-ce/cache/.gitignore b/server-ce/cache/.gitignore deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server-ce/chef/.chef/knife.rb b/server-ce/chef/.chef/knife.rb deleted file mode 100644 index 6a49a42b89..0000000000 --- a/server-ce/chef/.chef/knife.rb +++ /dev/null @@ -1,3 +0,0 @@ -current_dir = File.dirname(__FILE__) -cookbook_path ["#{current_dir}/../cookbooks"] - diff --git a/server-ce/chef/cookbooks/apt/CHANGELOG.md b/server-ce/chef/cookbooks/apt/CHANGELOG.md deleted file mode 100644 index 769fd7ef91..0000000000 --- a/server-ce/chef/cookbooks/apt/CHANGELOG.md +++ /dev/null @@ -1,173 +0,0 @@ -apt Cookbook CHANGELOG -====================== -This file is used to list changes made in each version of the apt cookbook. - -v2.3.8 (2014-02-14) -------------------- -### Bug -- **[COOK-4287](https://tickets.opscode.com/browse/COOK-4287)** - Cleanup the Kitchen - - -v2.3.6 ------- -* [COOK-4154] - Add chefspec matchers.rb file to apt cookbook -* [COOK-4102] - Only index created repository - - -v2.3.6 ------- -* [COOK-4154] - Add chefspec matchers.rb file to apt cookbook -* [COOK-4102] - Only index created repository - - -v2.3.4 ------- -No change. Version bump for toolchain sanity - - -v2.3.2 ------- -- [COOK-3905] apt-get-update-periodic: configuration for the update period -- Updating style for rubocops -- Updating test-kitchen harness - - -v2.3.0 ------- -### Bug -- **[COOK-3812](https://tickets.opscode.com/browse/COOK-3812)** - Add a way to bypass the apt existence check - -### Improvement -- **[COOK-3567](https://tickets.opscode.com/browse/COOK-3567)** - Allow users to bypass apt-cache via attributes - - -v2.2.1 ------- -### Improvement -- **[COOK-664](https://tickets.opscode.com/browse/COOK-664)** - Check platform before running apt-specific commands - - -v2.2.0 ------- -### Bug -- **[COOK-3707](https://tickets.opscode.com/browse/COOK-3707)** - multiple nics confuse apt::cacher-client - -v2.1.2 ------- -### Improvement -- **[COOK-3551](https://tickets.opscode.com/browse/COOK-3551)** - Allow user to set up a trusted APT repository - -v2.1.1 ------- -### Bug -- **[COOK-1856](https://tickets.opscode.com/browse/COOK-1856)** - Match GPG keys without case sensitivity - -v2.1.0 ------- -- [COOK-3426]: cacher-ng fails with restrict_environment set to true -- [COOK-2859]: cacher-client executes out of order -- [COOK-3052]: Long GPG keys are downloaded on every run -- [COOK-1856]: apt cookbook should match keys without case sensitivity -- [COOK-3255]: Attribute name incorrect in README -- [COOK-3225]: Call use_inline_resources only if defined -- [COOK-3386]: Cache dir for apt-cacher-ng -- [COOK-3291]: apt_repository: enable usage of a keyserver on port 80 -- Greatly expanded test coverage with ChefSpec and Test-Kitchen - -v2.0.0 ------- -### Bug - -- [COOK-2258]: apt: LWRP results in error under why-run mode in apt 1.9.0 cookbook - -v1.10.0 -------- -### Improvement - -- [COOK-2885]: Improvements for apt cache server search - -### Bug - -- [COOK-2441]: Apt recipe broken in new chef version -- [COOK-2660]: Create Debian 6.0 "squeeze" specific template for - apt-cacher-ng - -v1.9.2 ------- -- [COOK-2631] - Create Ubuntu 10.04 specific template for apt-cacher-ng - -v1.9.0 ------- -- [COOK-2185] - Proxy for apt-key -- [COOK-2338] - Support pinning by glob() or regexp - -v1.8.4 ------- -- [COOK-2171] - Update README to clarify required Chef version: 10.18.0 - or higher. - -v1.8.2 ------- -- [COOK-2112] - need [] around "arch" in sources.list entries -- [COOK-2171] - fixes a regression in the notification - -v1.8.0 ------- -- [COOK-2143] - Allow for a custom cacher-ng port -- [COOK-2171] - On `apt_repository.run_action(:add)` the source file - is not created. -- [COOK-2184] - apt::cacher-ng, use `cacher_port` attribute in - acng.conf - -v1.7.0 ------- -- [COOK-2082] - add "arch" parameter to apt_repository LWRP - -v1.6.0 ------- -- [COOK-1893] - `apt_preference` use "`package_name`" resource instead of "name" -- [COOK-1894] - change filename for sources.list.d files -- [COOK-1914] - Wrong dir permissions for /etc/apt/preferences.d/ -- [COOK-1942] - README.md has wrong name for the keyserver attribute -- [COOK-2019] - create 01proxy before any other apt-get updates get executed - -v1.5.2 ------- -- [COOK-1682] - use template instead of file resource in apt::cacher-client -- [COOK-1875] - cacher-client should be Environment-aware - -V1.5.0 ------- -- [COOK-1500] - Avoid triggering apt-get update -- [COOK-1548] - Add execute commands for autoclean and autoremove -- [COOK-1591] - Setting up the apt proxy should leave https - connections direct -- [COOK-1596] - execute[apt-get-update-periodic] never runs -- [COOK-1762] - create /etc/apt/preferences.d directory -- [COOK-1776] - apt key check isn't idempotent - -v1.4.8 ------- -* Adds test-kitchen support -- [COOK-1435] - repository lwrp is not idempotent with http key - -v1.4.6 ------- -- [COOK-1530] - apt_repository isn't aware of update-success-stamp - file (also reverts COOK-1382 patch). - -v1.4.4 ------- -- [COOK-1229] - Allow cacher IP to be set manually in non-Chef Solo - environments -- [COOK-1530] - Immediately update apt-cache when sources.list file is dropped off - -v1.4.2 ------- -- [COOK-1155] - LWRP for apt pinning - -v1.4.0 ------- -- [COOK-889] - overwrite existing repo source files -- [COOK-921] - optionally use cookbook\_file or remote\_file for key -- [COOK-1032] - fixes problem with apt repository key installation diff --git a/server-ce/chef/cookbooks/apt/README.md b/server-ce/chef/cookbooks/apt/README.md deleted file mode 100644 index f23212a1df..0000000000 --- a/server-ce/chef/cookbooks/apt/README.md +++ /dev/null @@ -1,248 +0,0 @@ -apt Cookbook -============ -This cookbook includes recipes to execute apt-get update to ensure the local APT package cache is up to date. There are recipes for managing the apt-cacher-ng caching proxy and proxy clients. It also includes a LWRP for managing APT repositories in /etc/apt/sources.list.d as well as an LWRP for pinning packages via /etc/apt/preferences.d. - - -Requirements ------------- -**Version 2.0.0+ of this cookbook requires Chef 11.0.0 or later**. If your Chef version is earlier than 11.0.0, use version 1.10.0 of this cookbook. - -Version 1.8.2 to 1.10.0 of this cookbook requires **Chef 10.16.4** or later. - -If your Chef version is earlier than 10.16.4, use version 1.7.0 of this cookbook. - -### Platform -Please refer to the [TESTING file](TESTING.md) to see the currently (and passing) tested platforms. The release was tested on: - -* Ubuntu 10.04 -* Ubuntu 12.04 -* Ubuntu 13.04 -* Debian 7.1 -* Debian 6.0 (have with manual testing) - -May work with or without modification on other Debian derivatives. - - -------- -### default -This recipe installs the `update-notifier-common` package to provide the timestamp file used to only run `apt-get update` if the cache is more than one day old. - -This recipe should appear first in the run list of Debian or Ubuntu nodes to ensure that the package cache is up to date before managing any `package` resources with Chef. - -This recipe also sets up a local cache directory for preseeding packages. - -**Including the default recipe on a node that does not support apt (such as Windows) results in a noop.** - -### cacher-client -Configures the node to use the `apt-cacher-ng` server as a client. - -#### Bypassing the cache -Occasionally you may come across repositories that do not play nicely when the node is using an `apt-cacher-ng` server. You can configure `cacher-client` to bypass the server and connect directly to the repository with the `cache_bypass` attribute. - -To do this, you need to override the `cache_bypass` attribute with an array of repositories, with each array key as the repository URL and value as the protocol to use: - -```json -{ - ..., - 'apt': { - ..., - 'cache_bypass': { - URL: PROTOCOL - } - } -} -``` - -For example, to prevent caching and directly connect to the repository at `download.oracle.com` via http: - -```json -{ - 'apt': { - 'cache_bypass': { - 'download.oracle.com': 'http' - } - } -} -``` - -### cacher-ng -Installs the `apt-cacher-ng` package and service so the system can provide APT caching. You can check the usage report at http://{hostname}:3142/acng-report.html. - -If you wish to help the `cacher-ng` recipe seed itself, you must now explicitly include the `cacher-client` recipe in your run list **after** `cacher-ng` or you will block your ability to install any packages (ie. `apt-cacher-ng`). - - -Attributes ----------- -* `['apt']['cacher_ipaddress']` - use a cacher server (or standard proxy server) not available via search -* `['apt']['cacher_interface]` - interface to connect to the cacher-ng service, no default. -* `['apt']['cacher_port']` - port for the cacher-ng service (either client or server), default is '3142' -* `['apt']['cacher_dir']` - directory used by cacher-ng service, default is '/var/cache/apt-cacher-ng' -* `['apt']['cacher-client']['restrict_environment']` - restrict your node to using the `apt-cacher-ng` server in your Environment, default is 'false' -* `['apt']['compiletime']` - force the `cacher-client` recipe to run before other recipes. It forces apt to use the proxy before other recipes run. Useful if your nodes have limited access to public apt repositories. This is overridden if the `cacher-ng` recipe is in your run list. Default is 'false' -* `['apt']['cache_bypass']` - array of URLs to bypass the cache. Accepts the URL and protocol to fetch directly from the remote repository and not attempt to cache -* `['apt']['periodic_update_min_delay']` - minimum delay (in seconds) beetween two actual executions of `apt-get update` by the `execute[apt-get-update-periodic]` resource, default is '86400' (24 hours) - -Libraries ---------- -There is an `interface_ipaddress` method that returns the IP address for a particular host and interface, used by the `cacher-client` recipe. To enable it on the server use the `['apt']['cacher_interface']` attribute. - -Resources/Providers -------------------- -### `apt_repository` -This LWRP provides an easy way to manage additional APT repositories. Adding a new repository will notify running the `execute[apt-get-update]` resource immediately. - -#### Actions -- :add: creates a repository file and builds the repository listing -- :remove: removes the repository file - -#### Attribute Parameters -- repo_name: name attribute. The name of the channel to discover -- uri: the base of the Debian distribution -- distribution: this is usually your release's codename...ie something like `karmic`, `lucid` or `maverick` -- components: package groupings..when it doubt use `main` -- arch: constrain package to a particular arch like `i386`, `amd64` or even `armhf` or `powerpc`. Defaults to nil. -- trusted: treat all packages from this repository as authenticated regardless of signature -- deb_src: whether or not to add the repository as a source repo as well - value can be `true` or `false`, default `false`. -- keyserver: the GPG keyserver where the key for the repo should be retrieved -- key: if a `keyserver` is provided, this is assumed to be the fingerprint, otherwise it can be either the URI to the GPG key for the repo, or a cookbook_file. -- key_proxy: if set, pass the specified proxy via `http-proxy=` to GPG. -- cookbook: if key should be a cookbook_file, specify a cookbook where the key is located for files/default. Defaults to nil, so it will use the cookbook where the resource is used. - -#### Examples - -Add the Zenoss repo: - -```ruby -apt_repository 'zenoss' do - uri 'http://dev.zenoss.org/deb' - components ['main', 'stable'] -end -``` - -Add the Nginx PPA, grabbing the key from keyserver: - -```ruby -apt_repository 'nginx-php' do - uri 'http://ppa.launchpad.net/nginx/php5/ubuntu' - distribution node['lsb']['codename'] - components ['main'] - keyserver 'keyserver.ubuntu.com' - key 'C300EE8C' -end -``` - -Add the Nginx PPA, grab the key from the keyserver, and add source repo: - -```ruby -apt_repository 'nginx-php' do - uri 'http://ppa.launchpad.net/nginx/php5/ubuntu' - distribution node['lsb']['codename'] - components ['main'] - keyserver 'keyserver.ubuntu.com' - key 'C300EE8C' - deb_src true -end -``` - -Add the Cloudera Repo of CDH4 packages for Ubuntu 12.04 on AMD64: - -```ruby -apt_repository 'cloudera' do - uri 'http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh' - arch 'amd64' - distribution 'precise-cdh4' - components ['contrib'] - key 'http://archive.cloudera.com/debian/archive.key' -end -``` - -Remove Zenoss repo: - -```ruby -apt_repository 'zenoss' do - action :remove -end -``` - -### `apt_preference` -This LWRP provides an easy way to pin packages in /etc/apt/preferences.d. Although apt-pinning is quite helpful from time to time please note that Debian does not encourage its use without thorough consideration. - -Further information regarding apt-pinning is available via http://wiki.debian.org/AptPreferences. - -#### Actions -- :add: creates a preferences file under /etc/apt/preferences.d -- :remove: Removes the file, therefore unpin the package - -#### Attribute Parameters -- package_name: name attribute. The name of the package -- glob: Pin by glob() expression or regexp surrounded by /. -- pin: The package version/repository to pin -- pin_priority: The pinning priority aka "the highest package version wins" - -#### Examples -Pin libmysqlclient16 to version 5.1.49-3: - -```ruby -apt_preference 'libmysqlclient16' do - pin 'version 5.1.49-3' - pin_priority '700' -end -``` - -Unpin libmysqlclient16: - -```ruby -apt_preference 'libmysqlclient16' do - action :remove -end -``` - -Pin all packages from dotdeb.org: - -```ruby -apt_preference 'dotdeb' do - glob '*' - pin 'origin packages.dotdeb.org' - pin_priority '700' -end -``` - - -Usage ------ -Put `recipe[apt]` first in the run list. If you have other recipes that you want to use to configure how apt behaves, like new sources, notify the execute resource to run, e.g.: - -```ruby -template '/etc/apt/sources.list.d/my_apt_sources.list' do - notifies :run, 'execute[apt-get update]', :immediately -end -``` - -The above will run during execution phase since it is a normal template resource, and should appear before other package resources that need the sources in the template. - -Put `recipe[apt::cacher-ng]` in the run_list for a server to provide APT caching and add `recipe[apt::cacher-client]` on the rest of the Debian-based nodes to take advantage of the caching server. - -If you want to cleanup unused packages, there is also the `apt-get autoclean` and `apt-get autoremove` resources provided for automated cleanup. - - -License & Authors ------------------ -- Author:: Joshua Timberman (joshua@opscode.com) -- Author:: Matt Ray (matt@opscode.com) -- Author:: Seth Chisamore (schisamo@opscode.com) - -```text -Copyright 2009-2013, Opscode, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -``` diff --git a/server-ce/chef/cookbooks/apt/attributes/default.rb b/server-ce/chef/cookbooks/apt/attributes/default.rb deleted file mode 100644 index 2f6b4e1444..0000000000 --- a/server-ce/chef/cookbooks/apt/attributes/default.rb +++ /dev/null @@ -1,28 +0,0 @@ -# -# Cookbook Name:: apt -# Attributes:: default -# -# Copyright 2009-2013, Opscode, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -default['apt']['cacher-client']['restrict_environment'] = false -default['apt']['cacher_dir'] = '/var/cache/apt-cacher-ng' -default['apt']['cacher_interface'] = nil -default['apt']['cacher_port'] = 3142 -default['apt']['caching_server'] = false -default['apt']['compiletime'] = false -default['apt']['key_proxy'] = '' -default['apt']['cache_bypass'] = {} -default['apt']['periodic_update_min_delay'] = 86_400 diff --git a/server-ce/chef/cookbooks/apt/files/default/apt-proxy-v2.conf b/server-ce/chef/cookbooks/apt/files/default/apt-proxy-v2.conf deleted file mode 100644 index 69540047d1..0000000000 --- a/server-ce/chef/cookbooks/apt/files/default/apt-proxy-v2.conf +++ /dev/null @@ -1,50 +0,0 @@ -[DEFAULT] -;; All times are in seconds, but you can add a suffix -;; for minutes(m), hours(h) or days(d) - -;; commented out address so apt-proxy will listen on all IPs -;; address = 127.0.0.1 -port = 9999 -cache_dir = /var/cache/apt-proxy - -;; Control files (Packages/Sources/Contents) refresh rate -min_refresh_delay = 1s -complete_clientless_downloads = 1 - -;; Debugging settings. -debug = all:4 db:0 - -time = 30 -passive_ftp = on - -;;-------------------------------------------------------------- -;; Cache housekeeping - -cleanup_freq = 1d -max_age = 120d -max_versions = 3 - -;;--------------------------------------------------------------- -;; Backend servers -;; -;; Place each server in its own [section] - -[ubuntu] -; Ubuntu archive -backends = - http://us.archive.ubuntu.com/ubuntu - -[ubuntu-security] -; Ubuntu security updates -backends = http://security.ubuntu.com/ubuntu - -[debian] -;; Backend servers, in order of preference -backends = - http://debian.osuosl.org/debian/ - -[security] -;; Debian security archive -backends = - http://security.debian.org/debian-security - http://ftp2.de.debian.org/debian-security diff --git a/server-ce/chef/cookbooks/apt/libraries/helpers.rb b/server-ce/chef/cookbooks/apt/libraries/helpers.rb deleted file mode 100644 index 6fe95a97ad..0000000000 --- a/server-ce/chef/cookbooks/apt/libraries/helpers.rb +++ /dev/null @@ -1,48 +0,0 @@ -# -# Cookbook Name:: apt -# Library:: helpers -# -# Copyright 2013 Opscode, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -module Apt - # Helpers for apt - module Helpers - # Determines if apt is installed on a system. - # - # @return [Boolean] - def apt_installed? - !which('apt-get').nil? - end - - # Finds a command in $PATH - # - # @return [String, nil] - def which(cmd) - paths = (ENV['PATH'].split(::File::PATH_SEPARATOR) + %w(/bin /usr/bin /sbin /usr/sbin)) - - paths.each do |path| - possible = File.join(path, cmd) - return possible if File.executable?(possible) - end - - nil - end - end -end - -Chef::Recipe.send(:include, ::Apt::Helpers) -Chef::Resource.send(:include, ::Apt::Helpers) -Chef::Provider.send(:include, ::Apt::Helpers) diff --git a/server-ce/chef/cookbooks/apt/libraries/matchers.rb b/server-ce/chef/cookbooks/apt/libraries/matchers.rb deleted file mode 100644 index aafce4da7a..0000000000 --- a/server-ce/chef/cookbooks/apt/libraries/matchers.rb +++ /dev/null @@ -1,17 +0,0 @@ -if defined?(ChefSpec) - def add_apt_preference(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:apt_preference, :add, resource_name) - end - - def remove_apt_preference(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:apt_preference, :remove, resource_name) - end - - def add_apt_repository(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:apt_repository, :add, resource_name) - end - - def remove_apt_repository(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:apt_repository, :remove, resource_name) - end -end diff --git a/server-ce/chef/cookbooks/apt/libraries/network.rb b/server-ce/chef/cookbooks/apt/libraries/network.rb deleted file mode 100644 index 8535d6dce1..0000000000 --- a/server-ce/chef/cookbooks/apt/libraries/network.rb +++ /dev/null @@ -1,31 +0,0 @@ -# -# Cookbook Name:: apt -# library:: network -# -# Copyright 2013, Opscode, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -module ::Apt - def interface_ipaddress(host, interface) - if interface - addresses = host['network']['interfaces'][interface]['addresses'] - addresses.select do |ip, data| - return ip if data['family'].eql?('inet') - end - else - return host.ipaddress - end - end -end diff --git a/server-ce/chef/cookbooks/apt/metadata.json b/server-ce/chef/cookbooks/apt/metadata.json deleted file mode 100644 index 7a5316e229..0000000000 --- a/server-ce/chef/cookbooks/apt/metadata.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "apt", - "version": "2.3.8", - "description": "Configures apt and apt services and LWRPs for managing apt repositories and preferences", - "long_description": "apt Cookbook\n============\nThis cookbook includes recipes to execute apt-get update to ensure the local APT package cache is up to date. There are recipes for managing the apt-cacher-ng caching proxy and proxy clients. It also includes a LWRP for managing APT repositories in /etc/apt/sources.list.d as well as an LWRP for pinning packages via /etc/apt/preferences.d.\n\n\nRequirements\n------------\n**Version 2.0.0+ of this cookbook requires Chef 11.0.0 or later**. If your Chef version is earlier than 11.0.0, use version 1.10.0 of this cookbook.\n\nVersion 1.8.2 to 1.10.0 of this cookbook requires **Chef 10.16.4** or later.\n\nIf your Chef version is earlier than 10.16.4, use version 1.7.0 of this cookbook.\n\n### Platform\nPlease refer to the [TESTING file](TESTING.md) to see the currently (and passing) tested platforms. The release was tested on:\n\n* Ubuntu 10.04\n* Ubuntu 12.04\n* Ubuntu 13.04\n* Debian 7.1\n* Debian 6.0 (have with manual testing)\n\nMay work with or without modification on other Debian derivatives.\n\n\n-------\n### default\nThis recipe installs the `update-notifier-common` package to provide the timestamp file used to only run `apt-get update` if the cache is more than one day old.\n\nThis recipe should appear first in the run list of Debian or Ubuntu nodes to ensure that the package cache is up to date before managing any `package` resources with Chef.\n\nThis recipe also sets up a local cache directory for preseeding packages.\n\n**Including the default recipe on a node that does not support apt (such as Windows) results in a noop.**\n\n### cacher-client\nConfigures the node to use the `apt-cacher-ng` server as a client.\n\n#### Bypassing the cache\nOccasionally you may come across repositories that do not play nicely when the node is using an `apt-cacher-ng` server. You can configure `cacher-client` to bypass the server and connect directly to the repository with the `cache_bypass` attribute.\n\nTo do this, you need to override the `cache_bypass` attribute with an array of repositories, with each array key as the repository URL and value as the protocol to use:\n\n```json\n{\n ...,\n 'apt': {\n ...,\n 'cache_bypass': {\n URL: PROTOCOL\n }\n }\n}\n```\n\nFor example, to prevent caching and directly connect to the repository at `download.oracle.com` via http:\n\n```json\n{\n 'apt': {\n 'cache_bypass': {\n 'download.oracle.com': 'http'\n }\n }\n}\n```\n\n### cacher-ng\nInstalls the `apt-cacher-ng` package and service so the system can provide APT caching. You can check the usage report at http://{hostname}:3142/acng-report.html.\n\nIf you wish to help the `cacher-ng` recipe seed itself, you must now explicitly include the `cacher-client` recipe in your run list **after** `cacher-ng` or you will block your ability to install any packages (ie. `apt-cacher-ng`).\n\n\nAttributes\n----------\n* `['apt']['cacher_ipaddress']` - use a cacher server (or standard proxy server) not available via search\n* `['apt']['cacher_interface]` - interface to connect to the cacher-ng service, no default.\n* `['apt']['cacher_port']` - port for the cacher-ng service (either client or server), default is '3142'\n* `['apt']['cacher_dir']` - directory used by cacher-ng service, default is '/var/cache/apt-cacher-ng'\n* `['apt']['cacher-client']['restrict_environment']` - restrict your node to using the `apt-cacher-ng` server in your Environment, default is 'false'\n* `['apt']['compiletime']` - force the `cacher-client` recipe to run before other recipes. It forces apt to use the proxy before other recipes run. Useful if your nodes have limited access to public apt repositories. This is overridden if the `cacher-ng` recipe is in your run list. Default is 'false'\n* `['apt']['cache_bypass']` - array of URLs to bypass the cache. Accepts the URL and protocol to fetch directly from the remote repository and not attempt to cache\n* `['apt']['periodic_update_min_delay']` - minimum delay (in seconds) beetween two actual executions of `apt-get update` by the `execute[apt-get-update-periodic]` resource, default is '86400' (24 hours)\n\nLibraries\n---------\nThere is an `interface_ipaddress` method that returns the IP address for a particular host and interface, used by the `cacher-client` recipe. To enable it on the server use the `['apt']['cacher_interface']` attribute.\n\nResources/Providers\n-------------------\n### `apt_repository`\nThis LWRP provides an easy way to manage additional APT repositories. Adding a new repository will notify running the `execute[apt-get-update]` resource immediately.\n\n#### Actions\n- :add: creates a repository file and builds the repository listing\n- :remove: removes the repository file\n\n#### Attribute Parameters\n- repo_name: name attribute. The name of the channel to discover\n- uri: the base of the Debian distribution\n- distribution: this is usually your release's codename...ie something like `karmic`, `lucid` or `maverick`\n- components: package groupings..when it doubt use `main`\n- arch: constrain package to a particular arch like `i386`, `amd64` or even `armhf` or `powerpc`. Defaults to nil.\n- trusted: treat all packages from this repository as authenticated regardless of signature\n- deb_src: whether or not to add the repository as a source repo as well - value can be `true` or `false`, default `false`.\n- keyserver: the GPG keyserver where the key for the repo should be retrieved\n- key: if a `keyserver` is provided, this is assumed to be the fingerprint, otherwise it can be either the URI to the GPG key for the repo, or a cookbook_file.\n- key_proxy: if set, pass the specified proxy via `http-proxy=` to GPG.\n- cookbook: if key should be a cookbook_file, specify a cookbook where the key is located for files/default. Defaults to nil, so it will use the cookbook where the resource is used.\n\n#### Examples\n\nAdd the Zenoss repo:\n\n```ruby\napt_repository 'zenoss' do\n uri 'http://dev.zenoss.org/deb'\n components ['main', 'stable']\nend\n```\n\nAdd the Nginx PPA, grabbing the key from keyserver:\n\n```ruby\napt_repository 'nginx-php' do\n uri 'http://ppa.launchpad.net/nginx/php5/ubuntu'\n distribution node['lsb']['codename']\n components ['main']\n keyserver 'keyserver.ubuntu.com'\n key 'C300EE8C'\nend\n```\n\nAdd the Nginx PPA, grab the key from the keyserver, and add source repo:\n\n```ruby\napt_repository 'nginx-php' do\n uri 'http://ppa.launchpad.net/nginx/php5/ubuntu'\n distribution node['lsb']['codename']\n components ['main']\n keyserver 'keyserver.ubuntu.com'\n key 'C300EE8C'\n deb_src true\nend\n```\n\nAdd the Cloudera Repo of CDH4 packages for Ubuntu 12.04 on AMD64:\n\n```ruby\napt_repository 'cloudera' do\n uri 'http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh'\n arch 'amd64'\n distribution 'precise-cdh4'\n components ['contrib']\n key 'http://archive.cloudera.com/debian/archive.key'\nend\n```\n\nRemove Zenoss repo:\n\n```ruby\napt_repository 'zenoss' do\n action :remove\nend\n```\n\n### `apt_preference`\nThis LWRP provides an easy way to pin packages in /etc/apt/preferences.d. Although apt-pinning is quite helpful from time to time please note that Debian does not encourage its use without thorough consideration.\n\nFurther information regarding apt-pinning is available via http://wiki.debian.org/AptPreferences.\n\n#### Actions\n- :add: creates a preferences file under /etc/apt/preferences.d\n- :remove: Removes the file, therefore unpin the package\n\n#### Attribute Parameters\n- package_name: name attribute. The name of the package\n- glob: Pin by glob() expression or regexp surrounded by /.\n- pin: The package version/repository to pin\n- pin_priority: The pinning priority aka \"the highest package version wins\"\n\n#### Examples\nPin libmysqlclient16 to version 5.1.49-3:\n\n```ruby\napt_preference 'libmysqlclient16' do\n pin 'version 5.1.49-3'\n pin_priority '700'\nend\n```\n\nUnpin libmysqlclient16:\n\n```ruby\napt_preference 'libmysqlclient16' do\n action :remove\nend\n```\n\nPin all packages from dotdeb.org:\n\n```ruby\napt_preference 'dotdeb' do\n glob '*'\n pin 'origin packages.dotdeb.org'\n pin_priority '700'\nend\n```\n\n\nUsage\n-----\nPut `recipe[apt]` first in the run list. If you have other recipes that you want to use to configure how apt behaves, like new sources, notify the execute resource to run, e.g.:\n\n```ruby\ntemplate '/etc/apt/sources.list.d/my_apt_sources.list' do\n notifies :run, 'execute[apt-get update]', :immediately\nend\n```\n\nThe above will run during execution phase since it is a normal template resource, and should appear before other package resources that need the sources in the template.\n\nPut `recipe[apt::cacher-ng]` in the run_list for a server to provide APT caching and add `recipe[apt::cacher-client]` on the rest of the Debian-based nodes to take advantage of the caching server.\n\nIf you want to cleanup unused packages, there is also the `apt-get autoclean` and `apt-get autoremove` resources provided for automated cleanup.\n\n\nLicense & Authors\n-----------------\n- Author:: Joshua Timberman (joshua@opscode.com)\n- Author:: Matt Ray (matt@opscode.com)\n- Author:: Seth Chisamore (schisamo@opscode.com)\n\n```text\nCopyright 2009-2013, Opscode, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n", - "maintainer": "Opscode, Inc.", - "maintainer_email": "cookbooks@opscode.com", - "license": "Apache 2.0", - "platforms": { - "ubuntu": ">= 0.0.0", - "debian": ">= 0.0.0" - }, - "dependencies": { - }, - "recommendations": { - }, - "suggestions": { - }, - "conflicting": { - }, - "providing": { - }, - "replacing": { - }, - "attributes": { - "apt/cacher-client/restrict_environment": { - "description": "Whether to restrict the search for the caching server to the same environment as this node", - "default": "false" - }, - "apt/cacher_port": { - "description": "Default listen port for the caching server", - "default": "3142" - }, - "apt/cacher_interface": { - "description": "Default listen interface for the caching server", - "default": null - }, - "apt/key_proxy": { - "description": "Passed as the proxy passed to GPG for the apt_repository resource", - "default": "" - }, - "apt/caching_server": { - "description": "Set this to true if the node is a caching server", - "default": "false" - } - }, - "groupings": { - }, - "recipes": { - "apt": "Runs apt-get update during compile phase and sets up preseed directories", - "apt::cacher-ng": "Set up an apt-cacher-ng caching proxy", - "apt::cacher-client": "Client for the apt::cacher-ng caching proxy" - } -} \ No newline at end of file diff --git a/server-ce/chef/cookbooks/apt/metadata.rb b/server-ce/chef/cookbooks/apt/metadata.rb deleted file mode 100644 index 4ca3ffce63..0000000000 --- a/server-ce/chef/cookbooks/apt/metadata.rb +++ /dev/null @@ -1,34 +0,0 @@ -name 'apt' -maintainer 'Opscode, Inc.' -maintainer_email 'cookbooks@opscode.com' -license 'Apache 2.0' -description 'Configures apt and apt services and LWRPs for managing apt repositories and preferences' -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '2.3.8' -recipe 'apt', 'Runs apt-get update during compile phase and sets up preseed directories' -recipe 'apt::cacher-ng', 'Set up an apt-cacher-ng caching proxy' -recipe 'apt::cacher-client', 'Client for the apt::cacher-ng caching proxy' - -%w{ ubuntu debian }.each do |os| - supports os -end - -attribute 'apt/cacher-client/restrict_environment', - :description => 'Whether to restrict the search for the caching server to the same environment as this node', - :default => 'false' - -attribute 'apt/cacher_port', - :description => 'Default listen port for the caching server', - :default => '3142' - -attribute 'apt/cacher_interface', - :description => 'Default listen interface for the caching server', - :default => nil - -attribute 'apt/key_proxy', - :description => 'Passed as the proxy passed to GPG for the apt_repository resource', - :default => '' - -attribute 'apt/caching_server', - :description => 'Set this to true if the node is a caching server', - :default => 'false' diff --git a/server-ce/chef/cookbooks/apt/providers/preference.rb b/server-ce/chef/cookbooks/apt/providers/preference.rb deleted file mode 100644 index fd9f62413e..0000000000 --- a/server-ce/chef/cookbooks/apt/providers/preference.rb +++ /dev/null @@ -1,63 +0,0 @@ -# -# Cookbook Name:: apt -# Provider:: preference -# -# Copyright 2010-2011, Opscode, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Build preferences.d file contents -def build_pref(package_name, pin, pin_priority) - "Package: #{package_name}\nPin: #{pin}\nPin-Priority: #{pin_priority}\n" -end - -action :add do - new_resource.updated_by_last_action(false) - - preference = build_pref( - new_resource.glob || new_resource.package_name, - new_resource.pin, - new_resource.pin_priority - ) - - preference_dir = directory '/etc/apt/preferences.d' do - owner 'root' - group 'root' - mode 00755 - recursive true - action :nothing - end - - preference_file = file "/etc/apt/preferences.d/#{new_resource.name}" do - owner 'root' - group 'root' - mode 00644 - content preference - action :nothing - end - - preference_dir.run_action(:create) - # write out the preference file, replace it if it already exists - preference_file.run_action(:create) -end - -action :remove do - if ::File.exists?("/etc/apt/preferences.d/#{new_resource.name}") - Chef::Log.info "Un-pinning #{new_resource.name} from /etc/apt/preferences.d/" - file "/etc/apt/preferences.d/#{new_resource.name}" do - action :delete - end - new_resource.updated_by_last_action(true) - end -end diff --git a/server-ce/chef/cookbooks/apt/providers/repository.rb b/server-ce/chef/cookbooks/apt/providers/repository.rb deleted file mode 100644 index a48105071e..0000000000 --- a/server-ce/chef/cookbooks/apt/providers/repository.rb +++ /dev/null @@ -1,150 +0,0 @@ -# -# Cookbook Name:: apt -# Provider:: repository -# -# Copyright 2010-2011, Opscode, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use_inline_resources if defined?(use_inline_resources) - -def whyrun_supported? - true -end - -# install apt key from keyserver -def install_key_from_keyserver(key, keyserver) - execute "install-key #{key}" do - if !node['apt']['key_proxy'].empty? - command "apt-key adv --keyserver-options http-proxy=#{node['apt']['key_proxy']} --keyserver hkp://#{keyserver}:80 --recv #{key}" - else - command "apt-key adv --keyserver #{keyserver} --recv #{key}" - end - action :run - not_if do - extract_fingerprints_from_cmd('apt-key finger').any? do |fingerprint| - fingerprint.end_with?(key.upcase) - end - end - end -end - -# run command and extract gpg ids -def extract_fingerprints_from_cmd(cmd) - so = Mixlib::ShellOut.new(cmd) - so.run_command - so.stdout.split(/\n/).map do |t| - if z = t.match(/^ +Key fingerprint = ([0-9A-F ]+)/) - z[1].split.join - end - end.compact -end - -# install apt key from URI -def install_key_from_uri(uri) - key_name = uri.split(/\//).last - cached_keyfile = "#{Chef::Config[:file_cache_path]}/#{key_name}" - if new_resource.key =~ /http/ - remote_file cached_keyfile do - source new_resource.key - mode 00644 - action :create - end - else - cookbook_file cached_keyfile do - source new_resource.key - cookbook new_resource.cookbook - mode 00644 - action :create - end - end - - execute "install-key #{key_name}" do - command "apt-key add #{cached_keyfile}" - action :run - not_if do - installed_keys = extract_fingerprints_from_cmd('apt-key finger') - proposed_keys = extract_fingerprints_from_cmd("gpg --with-fingerprint #{cached_keyfile}") - (installed_keys & proposed_keys).sort == proposed_keys.sort - end - end -end - -# build repo file contents -def build_repo(uri, distribution, components, trusted, arch, add_deb_src) - components = components.join(' ') if components.respond_to?(:join) - repo_options = [] - repo_options << "arch=#{arch}" if arch - repo_options << 'trusted=yes' if trusted - repo_options = '[' + repo_options.join(' ') + ']' unless repo_options.empty? - repo_info = "#{uri} #{distribution} #{components}\n" - repo_info = "#{repo_options} #{repo_info}" unless repo_options.empty? - repo = "deb #{repo_info}" - repo << "deb-src #{repo_info}" if add_deb_src - repo -end - -action :add do - # add key - if new_resource.keyserver && new_resource.key - install_key_from_keyserver(new_resource.key, new_resource.keyserver) - elsif new_resource.key - install_key_from_uri(new_resource.key) - end - - file '/var/lib/apt/periodic/update-success-stamp' do - action :nothing - end - - execute 'apt-cache gencaches' do - ignore_failure true - action :nothing - end - - execute 'apt-get update' do - command "apt-get update -o Dir::Etc::sourcelist='sources.list.d/#{new_resource.name}.list' -o Dir::Etc::sourceparts='-' -o APT::Get::List-Cleanup='0'" - ignore_failure true - action :nothing - notifies :run, 'execute[apt-cache gencaches]', :immediately - end - - # build repo file - repository = build_repo( - new_resource.uri, - new_resource.distribution, - new_resource.components, - new_resource.trusted, - new_resource.arch, - new_resource.deb_src - ) - - file "/etc/apt/sources.list.d/#{new_resource.name}.list" do - owner 'root' - group 'root' - mode 00644 - content repository - action :create - notifies :delete, 'file[/var/lib/apt/periodic/update-success-stamp]', :immediately - notifies :run, 'execute[apt-get update]', :immediately if new_resource.cache_rebuild - end -end - -action :remove do - if ::File.exists?("/etc/apt/sources.list.d/#{new_resource.name}.list") - Chef::Log.info "Removing #{new_resource.name} repository from /etc/apt/sources.list.d/" - file "/etc/apt/sources.list.d/#{new_resource.name}.list" do - action :delete - end - end -end diff --git a/server-ce/chef/cookbooks/apt/recipes/cacher-client.rb b/server-ce/chef/cookbooks/apt/recipes/cacher-client.rb deleted file mode 100644 index bee010f115..0000000000 --- a/server-ce/chef/cookbooks/apt/recipes/cacher-client.rb +++ /dev/null @@ -1,81 +0,0 @@ -# -# Cookbook Name:: apt -# Recipe:: cacher-client -# -# Copyright 2011-2013 Opscode, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -class ::Chef::Recipe - include ::Apt -end - -# remove Acquire::http::Proxy lines from /etc/apt/apt.conf since we use 01proxy -# these are leftover from preseed installs -execute 'Remove proxy from /etc/apt/apt.conf' do - command "sed --in-place '/^Acquire::http::Proxy/d' /etc/apt/apt.conf" - only_if 'grep Acquire::http::Proxy /etc/apt/apt.conf' -end - -servers = [] -if node['apt'] - if node['apt']['cacher_ipaddress'] - cacher = Chef::Node.new - cacher.default.name = node['apt']['cacher_ipaddress'] - cacher.default.ipaddress = node['apt']['cacher_ipaddress'] - cacher.default.apt.cacher_port = node['apt']['cacher_port'] - cacher.default.apt_cacher_interface = node['apt']['cacher_interface'] - servers << cacher - elsif node['apt']['caching_server'] - node.override['apt']['compiletime'] = false - servers << node - end -end - -unless Chef::Config[:solo] || servers.length > 0 - query = 'apt_caching_server:true' - query += " AND chef_environment:#{node.chef_environment}" if node['apt']['cacher-client']['restrict_environment'] - Chef::Log.debug("apt::cacher-client searching for '#{query}'") - servers += search(:node, query) -end - -if servers.length > 0 - Chef::Log.info("apt-cacher-ng server found on #{servers[0]}.") - if servers[0]['apt']['cacher_interface'] - cacher_ipaddress = interface_ipaddress(servers[0], servers[0]['apt']['cacher_interface']) - else - cacher_ipaddress = servers[0].ipaddress - end - t = template '/etc/apt/apt.conf.d/01proxy' do - source '01proxy.erb' - owner 'root' - group 'root' - mode 00644 - variables( - :proxy => cacher_ipaddress, - :port => servers[0]['apt']['cacher_port'], - :bypass => node['apt']['cache_bypass'] - ) - action(node['apt']['compiletime'] ? :nothing : :create) - notifies :run, 'execute[apt-get update]', :immediately - end - t.run_action(:create) if node['apt']['compiletime'] -else - Chef::Log.info('No apt-cacher-ng server found.') - file '/etc/apt/apt.conf.d/01proxy' do - action :delete - end -end - -include_recipe 'apt::default' diff --git a/server-ce/chef/cookbooks/apt/recipes/cacher-ng.rb b/server-ce/chef/cookbooks/apt/recipes/cacher-ng.rb deleted file mode 100644 index 8629dcfabf..0000000000 --- a/server-ce/chef/cookbooks/apt/recipes/cacher-ng.rb +++ /dev/null @@ -1,43 +0,0 @@ -# -# Cookbook Name:: apt -# Recipe:: cacher-ng -# -# Copyright 2008-2013, Opscode, Inc. -# -# Licensed under the Apache License, Version 2.0 (the 'License'); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -node.set['apt']['caching_server'] = true - -package 'apt-cacher-ng' do - action :install -end - -directory node['apt']['cacher_dir'] do - owner 'apt-cacher-ng' - group 'apt-cacher-ng' - mode 0755 -end - -template '/etc/apt-cacher-ng/acng.conf' do - source 'acng.conf.erb' - owner 'root' - group 'root' - mode 00644 - notifies :restart, 'service[apt-cacher-ng]', :immediately -end - -service 'apt-cacher-ng' do - supports :restart => true, :status => false - action [:enable, :start] -end diff --git a/server-ce/chef/cookbooks/apt/recipes/default.rb b/server-ce/chef/cookbooks/apt/recipes/default.rb deleted file mode 100644 index 9ce8cbe8ce..0000000000 --- a/server-ce/chef/cookbooks/apt/recipes/default.rb +++ /dev/null @@ -1,82 +0,0 @@ -# -# Cookbook Name:: apt -# Recipe:: default -# -# Copyright 2008-2013, Opscode, Inc. -# Copyright 2009, Bryan McLellan -# -# Licensed under the Apache License, Version 2.0 (the 'License'); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# On systems where apt is not installed, the resources in this recipe are not -# executed. However, they _must_ still be present in the resource collection -# or other cookbooks which notify these resources will fail on non-apt-enabled -# systems. - -Chef::Log.debug 'apt is not installed. Apt-specific resources will not be executed.' unless apt_installed? - -# Run apt-get update to create the stamp file -execute 'apt-get-update' do - command 'apt-get update' - ignore_failure true - only_if { apt_installed? } - not_if { ::File.exists?('/var/lib/apt/periodic/update-success-stamp') } -end - -# For other recipes to call to force an update -execute 'apt-get update' do - command 'apt-get update' - ignore_failure true - only_if { apt_installed? } - action :nothing -end - -# Automatically remove packages that are no longer needed for dependencies -execute 'apt-get autoremove' do - command 'apt-get -y autoremove' - only_if { apt_installed? } - action :nothing -end - -# Automatically remove .deb files for packages no longer on your system -execute 'apt-get autoclean' do - command 'apt-get -y autoclean' - only_if { apt_installed? } - action :nothing -end - -# provides /var/lib/apt/periodic/update-success-stamp on apt-get update -package 'update-notifier-common' do - notifies :run, 'execute[apt-get-update]', :immediately - only_if { apt_installed? } -end - -execute 'apt-get-update-periodic' do - command 'apt-get update' - ignore_failure true - only_if do - apt_installed? && - ::File.exists?('/var/lib/apt/periodic/update-success-stamp') && - ::File.mtime('/var/lib/apt/periodic/update-success-stamp') < Time.now - node['apt']['periodic_update_min_delay'] - end -end - -%w{/var/cache/local /var/cache/local/preseeding}.each do |dirname| - directory dirname do - owner 'root' - group 'root' - mode 00755 - action :create - only_if { apt_installed? } - end -end diff --git a/server-ce/chef/cookbooks/apt/resources/preference.rb b/server-ce/chef/cookbooks/apt/resources/preference.rb deleted file mode 100644 index 21589eec4b..0000000000 --- a/server-ce/chef/cookbooks/apt/resources/preference.rb +++ /dev/null @@ -1,32 +0,0 @@ -# -# Cookbook Name:: apt -# Resource:: preference -# -# Copyright 2010-2013, Opscode, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :add, :remove -default_action :add if defined?(default_action) # Chef > 10.8 - -# Needed for Chef versions < 0.10.10 -def initialize(*args) - super - @action = :add -end - -attribute :package_name, :kind_of => String, :name_attribute => true -attribute :glob, :kind_of => String -attribute :pin, :kind_of => String -attribute :pin_priority, :kind_of => String diff --git a/server-ce/chef/cookbooks/apt/resources/repository.rb b/server-ce/chef/cookbooks/apt/resources/repository.rb deleted file mode 100644 index be737fee7b..0000000000 --- a/server-ce/chef/cookbooks/apt/resources/repository.rb +++ /dev/null @@ -1,43 +0,0 @@ -# -# Cookbook Name:: apt -# Resource:: repository -# -# Copyright 2010-2013, Opscode, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -actions :add, :remove -default_action :add if defined?(default_action) # Chef > 10.8 - -# Needed for Chef versions < 0.10.10 -def initialize(*args) - super - @action = :add -end - -# name of the repo, used for source.list filename -attribute :repo_name, :kind_of => String, :name_attribute => true -attribute :uri, :kind_of => String -attribute :distribution, :kind_of => String -attribute :components, :kind_of => Array, :default => [] -attribute :arch, :kind_of => String, :default => nil -attribute :trusted, :kind_of => [TrueClass, FalseClass], :default => false -# whether or not to add the repository as a source repo as well -attribute :deb_src, :default => false -attribute :keyserver, :kind_of => String, :default => nil -attribute :key, :kind_of => String, :default => nil -attribute :cookbook, :kind_of => String, :default => nil -# trigger cache rebuild -# If not you can trigger in the recipe itself after checking the status of resource.updated{_by_last_action}? -attribute :cache_rebuild, :kind_of => [TrueClass, FalseClass], :default => true diff --git a/server-ce/chef/cookbooks/apt/templates/debian-6.0/acng.conf.erb b/server-ce/chef/cookbooks/apt/templates/debian-6.0/acng.conf.erb deleted file mode 100644 index 98a681c2c3..0000000000 --- a/server-ce/chef/cookbooks/apt/templates/debian-6.0/acng.conf.erb +++ /dev/null @@ -1,173 +0,0 @@ -# Letter case in directive names does not matter. Must be separated with colons. -# Valid boolean values are a zero number for false, non-zero numbers for true. - -CacheDir: <%= node['apt']['cacher_dir'] %> - -# set empty to disable logging -LogDir: /var/log/apt-cacher-ng - -# TCP (http) port -# Set to 9999 to emulate apt-proxy -Port:<%= node['apt']['cacher_port'] %> - -# Addresses or hostnames to listen on. Multiple addresses must be separated by -# spaces. Each entry must be associated with a local interface. DNS resolution -# is performed using getaddrinfo(3) for all available protocols (i.e. IPv4 and -# IPv6 if available). -# -# Default: not set, will listen on all interfaces. -# -# BindAddress: localhost 192.168.7.254 publicNameOnMainInterface - -#Proxy: http://www-proxy.example.net:80 -#proxy: http://username:proxypassword@proxy.example.net:3128 - -# Repository remapping. See manual for details. -# In this example, backends file is generated during package installation. -Remap-debrep: file:deb_mirror*.gz /debian ; file:backends_debian -Remap-uburep: file:ubuntu_mirrors /ubuntu ; file:backends_ubuntu -Remap-debvol: file:debvol_mirror*.gz /debian-volatile ; file:backends_debvol -Remap-cygwin: file:cygwin_mirrors /cygwin # ; file:backends_cygwin # incomplete, please create this file - -# Virtual page accessible in a web browser to see statistics and status -# information, i.e. under http://localhost:3142/acng-report.html -ReportPage: acng-report.html - -# Socket file for accessing through local UNIX socket instead of TCP/IP. Can be -# used with inetd bridge or cron client. -# SocketPath:/var/run/apt-cacher-ng/socket - -# Forces log file to be written to disk after every line when set to 1. Default -# is 0, buffer flush happens after client disconnects. -# -# (technically, this is an alias to the Debug option provided for convenience) -# -# UnbufferLogs: 0 - -# Set to 0 to store only type, time and transfer sizes. -# 1 -> client IP and relative local path are logged too -# VerboseLog: 1 - -# Don't detach from the console -# ForeGround: 0 - -# Store the pid of the daemon process therein -# PidFile: /var/run/apt-cacher-ng/pid - -# Forbid outgoing connections, work around them or respond with 503 error -# offlinemode:0 - -# Forbid all downloads that don't run through preconfigured backends (.where) -#ForceManaged: 0 - -# Days before considering an unreferenced file expired (to be deleted). -# Warning: if the value is set too low and particular index files are not -# available for some days (mirror downtime) there is a risk of deletion of -# still usefull package files. -ExTreshold: 4 - -# Stop expiration when a critical problem appeared. Currently only failed -# refresh of an index file is considered as critical. -# -# WARNING: don't touch this option or set to a non-zero number. -# Anything else is DANGEROUS and may cause data loss. -# -# ExAbortOnProblems: 1 - -# Replace some Windows/DOS-FS incompatible chars when storing -# StupidFs: 0 - -# Experimental feature for apt-listbugs: pass-through SOAP requests and -# responses to/from bugs.debian.org. If not set, default is true if -# ForceManaged is enabled and false otherwise. -# ForwardBtsSoap: 1 - -# The daemon has a small cache for DNS data, to speed up resolution. The -# expiration time of the DNS entries can be configured in seconds. -# DnsCacheSeconds: 3600 - -# Don't touch the following values without good consideration! -# -# Max. count of connection threads kept ready (for faster response in the -# future). Should be a sane value between 0 and average number of connections, -# and depend on the amount of spare RAM. -# MaxStandbyConThreads: 8 -# -# Hard limit of active thread count for incomming connections, i.e. operation -# is refused when this value is reached (below zero = unlimited). -# MaxConThreads: -1 -# -#VfilePattern = (^|.*?/)(Index|Packages\.bz2|Packages\.gz|Packages|Release|Release\.gpg|Sources\.bz2|Sources\.gz|Sources|release|index\.db-.*\.gz|Contents-[^/]*\.gz|pkglist[^/]*\.bz2|rclist[^/]*\.bz2|/meta-release[^/]*|Translation[^/]*\.bz2)$ -#PfilePattern = .*(\.deb|\.rpm|\.dsc|\.tar\.gz\.gpg|\.tar\.gz|\.diff\.gz|\.diff\.bz2|\.jigdo|\.template|changelog|copyright|\.udeb|\.diff/.*\.gz|vmlinuz|initrd\.gz|(Devel)?ReleaseAnnouncement(\\?.*)?)$ -# Whitelist for expiration, file types not to be removed even when being -# unreferenced. Default: same as VfilePattern which is a safe bed. When and -# only when the only used mirrors are official repositories (with working -# Release files) then it might be set to something more restrictive, like -# (^|.*?/)(Release|Release\.gpg|release|meta-release|Translation[^/]*\.bz2)$ -#WfilePattern = (^|.*?/)(Index|Packages\.bz2|Packages\.gz|Packages|Release|Release\.gpg|Sources\.bz2|Sources\.gz|Sources|release|index\.db-.*\.gz|Contents-[^/]*\.gz|pkglist[^/]*\.bz2|rclist[^/]*\.bz2|/meta-release[^/]*|Translation[^/]*\.bz2)$ - -# Higher modes only working with the debug version -# Warning, writes a lot into apt-cacher.err logfile -# Value overwrites UnbufferLogs setting (aliased) -# Debug:3 - -# Usually, general purpose proxies like Squid expose the IP adress of the -# client user to the remote server using the X-Forwarded-For HTTP header. This -# behaviour can be optionally turned on with the Expose-Origin option. -# ExposeOrigin: 0 - -# When logging the originating IP address, trust the information supplied by -# the client in the X-Forwarded-For header. -# LogSubmittedOrigin: 0 - -# The version string reported to the peer, to be displayed as HTTP client (and -# version) in the logs of the mirror. -# WARNING: some archives use this header to detect/guess capabilities of the -# client (i.e. redirection support) and change the behaviour accordingly, while -# ACNG might not support the expected features. Expect side effects. -# -# UserAgent: Yet Another HTTP Client/1.2.3p4 - -# In some cases the Import and Expiration tasks might create fresh volatile -# data for internal use by reconstructing them using patch files. This -# by-product might be recompressed with bzip2 and with some luck the resulting -# file becomes identical to the *.bz2 file on the server, usable for APT -# clients trying to fetch the full .bz2 compressed version. Injection of the -# generated files into the cache has however a disadvantage on underpowered -# servers: bzip2 compession can create high load on the server system and the -# visible download of the busy .bz2 files also becomes slower. -# -# RecompBz2: 0 - -# Network timeout for outgoing connections. -# NetworkTimeout: 60 - -# Sometimes it makes sense to not store the data in cache and just return the -# package data to client as it comes in. DontCache parameters can enable this -# behaviour for certain URL types. The tokens are extended regular expressions -# that URLs are matched against. -# -# DontCacheRequested is applied to the URL as it comes in from the client. -# Example: exclude packages built with kernel-package for x86 -# DontCacheRequested: linux-.*_10\...\.Custo._i386 -# Example usecase: exclude popular private IP ranges from caching -# DontCacheRequested: 192.168.0 ^10\..* 172.30 -# -# DontCacheResolved is applied to URLs after mapping to the target server. If -# multiple backend servers are specified then it's only matched against the -# download link for the FIRST possible source (due to implementation limits). -# Example usecase: all Ubuntu stuff comes from a local mirror (specified as -# backend), don't cache it again: -# DontCacheResolved: ubuntumirror.local.net -# -# DontCache directive sets (overrides) both, DontCacheResolved and -# DontCacheRequested. Provided for convenience, see those directives for -# details. -# -# Default permission set of freshly created files and directories, as octal -# numbers (see chmod(1) for details). -# Can by limited by the umask value (see umask(2) for details) if it's set in -# the environment of the starting shell, e.g. in apt-cacher-ng init script or -# in its configuration file. -# DirPerms: 00755 -# FilePerms: 00664 diff --git a/server-ce/chef/cookbooks/apt/templates/default/01proxy.erb b/server-ce/chef/cookbooks/apt/templates/default/01proxy.erb deleted file mode 100644 index 37bce8770d..0000000000 --- a/server-ce/chef/cookbooks/apt/templates/default/01proxy.erb +++ /dev/null @@ -1,5 +0,0 @@ -Acquire::http::Proxy "http://<%= @proxy %>:<%= @port %>"; -Acquire::https::Proxy "DIRECT"; -<% @bypass.each do |bypass, type| %> -Acquire::<%= type %>::Proxy::<%= bypass %> "DIRECT"; -<% end %> diff --git a/server-ce/chef/cookbooks/apt/templates/default/acng.conf.erb b/server-ce/chef/cookbooks/apt/templates/default/acng.conf.erb deleted file mode 100644 index 3aa0c92a4b..0000000000 --- a/server-ce/chef/cookbooks/apt/templates/default/acng.conf.erb +++ /dev/null @@ -1,275 +0,0 @@ -# Letter case in directive names does not matter. Must be separated with colons. -# Valid boolean values are a zero number for false, non-zero numbers for true. - -CacheDir: <%= node['apt']['cacher_dir'] %> - -# set empty to disable logging -LogDir: /var/log/apt-cacher-ng - -# place to look for additional configuration and resource files if they are not -# found in the configuration directory -# SupportDir: /usr/lib/apt-cacher-ng - -# TCP (http) port -# Set to 9999 to emulate apt-proxy -Port:<%= node['apt']['cacher_port'] %> - -# Addresses or hostnames to listen on. Multiple addresses must be separated by -# spaces. Each entry must be an exact local address which is associated with a -# local interface. DNS resolution is performed using getaddrinfo(3) for all -# available protocols (IPv4, IPv6, ...). Using a protocol specific format will -# create binding(s) only on protocol specific socket(s) (e.g. 0.0.0.0 will listen -# only to IPv4). -# -# Default: not set, will listen on all interfaces and protocols -# -# BindAddress: localhost 192.168.7.254 publicNameOnMainInterface - -# The specification of another proxy which shall be used for downloads. -# Username and password are, and see manual for limitations. -# -#Proxy: http://www-proxy.example.net:80 -#proxy: username:proxypassword@proxy.example.net:3128 - -# Repository remapping. See manual for details. -# In this example, some backends files might be generated during package -# installation using information collected on the system. -Remap-debrep: file:deb_mirror*.gz /debian ; file:backends_debian # Debian Archives -Remap-uburep: file:ubuntu_mirrors /ubuntu ; file:backends_ubuntu # Ubuntu Archives -Remap-debvol: file:debvol_mirror*.gz /debian-volatile ; file:backends_debvol # Debian Volatile Archives -Remap-cygwin: file:cygwin_mirrors /cygwin # ; file:backends_cygwin # incomplete, please create this file or specify preferred mirrors here -Remap-sfnet: file:sfnet_mirrors # ; file:backends_sfnet # incomplete, please create this file or specify preferred mirrors here -Remap-alxrep: file:archlx_mirrors /archlinux # ; file:backend_archlx # Arch Linux -Remap-fedora: file:fedora_mirrors # Fedora Linux -Remap-epel: file:epel_mirrors # Fedora EPEL -Remap-slrep: file:sl_mirrors # Scientific Linux - -# This is usually not needed for security.debian.org because it's always the -# same DNS hostname. However, it might be enabled in order to use hooks, -# ForceManaged mode or special flags in this context. -# Remap-secdeb: security.debian.org - -# Virtual page accessible in a web browser to see statistics and status -# information, i.e. under http://localhost:3142/acng-report.html -ReportPage: acng-report.html - -# Socket file for accessing through local UNIX socket instead of TCP/IP. Can be -# used with inetd bridge or cron client. -# SocketPath:/var/run/apt-cacher-ng/socket - -# Forces log file to be written to disk after every line when set to 1. Default -# is 0, buffers are flushed when the client disconnects. -# -# (technically, alias to the Debug option, see its documentation for details) -# -# UnbufferLogs: 0 - -# Set to 0 to store only type, time and transfer sizes. -# 1 -> client IP and relative local path are logged too -# VerboseLog: 1 - -# Don't detach from the console -# ForeGround: 0 - -# Store the pid of the daemon process therein -# PidFile: /var/run/apt-cacher-ng/pid - -# Forbid outgoing connections, work around them or respond with 503 error -# offlinemode:0 - -# Forbid all downloads that don't run through preconfigured backends (.where) -#ForceManaged: 0 - -# Days before considering an unreferenced file expired (to be deleted). -# Warning: if the value is set too low and particular index files are not -# available for some days (mirror downtime) there is a risk of deletion of -# still useful package files. -ExTreshold: 4 - -# Stop expiration when a critical problem appeared. Currently only failed -# refresh of an index file is considered as critical. -# -# WARNING: don't touch this option or set to zero. -# Anything else is DANGEROUS and may cause data loss. -# -# ExAbortOnProblems: 1 - -# Replace some Windows/DOS-FS incompatible chars when storing -# StupidFs: 0 - -# Experimental feature for apt-listbugs: pass-through SOAP requests and -# responses to/from bugs.debian.org. If not set, default is true if -# ForceManaged is enabled and false otherwise. -# ForwardBtsSoap: 1 - -# The daemon has a small cache for DNS data, to speed up resolution. The -# expiration time of the DNS entries can be configured in seconds. -# DnsCacheSeconds: 3600 - -# Don't touch the following values without good consideration! -# -# Max. count of connection threads kept ready (for faster response in the -# future). Should be a sane value between 0 and average number of connections, -# and depend on the amount of spare RAM. -# MaxStandbyConThreads: 8 -# -# Hard limit of active thread count for incoming connections, i.e. operation -# is refused when this value is reached (below zero = unlimited). -# MaxConThreads: -1 -# -# Pigeonholing files with regular expressions (static/volatile). Can be -# overriden here but not should not be done permanently because future update -# of default settings would not be applied later. -# VfilePattern = (^|.*?/)(Index|Packages(\.gz|\.bz2|\.lzma|\.xz)?|InRelease|Release|Release\.gpg|Sources(\.gz|\.bz2|\.lzma|\.xz)?|release|index\.db-.*\.gz|Contents-[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|pkglist[^/]*\.bz2|rclist[^/]*\.bz2|/meta-release[^/]*|Translation[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|MD5SUMS|SHA1SUMS|((setup|setup-legacy)(\.ini|\.bz2|\.hint)(\.sig)?)|mirrors\.lst|repo(index|md)\.xml(\.asc|\.key)?|directory\.yast|products|content(\.asc|\.key)?|media|filelists\.xml\.gz|filelists\.sqlite\.bz2|repomd\.xml|packages\.[a-zA-Z][a-zA-Z]\.gz|info\.txt|license\.tar\.gz|license\.zip|.*\.db(\.tar\.gz)?|.*\.files\.tar\.gz|.*\.abs\.tar\.gz|metalink\?repo|.*prestodelta\.xml\.gz)$|/dists/.*/installer-[^/]+/[^0-9][^/]+/images/.* -# PfilePattern = .*(\.d?deb|\.rpm|\.dsc|\.tar(\.gz|\.bz2|\.lzma|\.xz)(\.gpg)?|\.diff(\.gz|\.bz2|\.lzma|\.xz)|\.jigdo|\.template|changelog|copyright|\.udeb|\.debdelta|\.diff/.*\.gz|(Devel)?ReleaseAnnouncement(\?.*)?|[a-f0-9]+-(susedata|updateinfo|primary|deltainfo).xml.gz|fonts/(final/)?[a-z]+32.exe(\?download.*)?|/dists/.*/installer-[^/]+/[0-9][^/]+/images/.*)$ -# Whitelist for expiration, file types not to be removed even when being -# unreferenced. Default: many parts from VfilePattern where no parent index -# exists or might be unknown. -# WfilePattern = (^|.*?/)(Release|InRelease|Release\.gpg|(Packages|Sources)(\.gz|\.bz2|\.lzma|\.xz)?|Translation[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|MD5SUMS|SHA1SUMS|.*\.xml|.*\.db\.tar\.gz|.*\.files\.tar\.gz|.*\.abs\.tar\.gz|[a-z]+32.exe)$|/dists/.*/installer-.*/images/.* - -# Higher modes only working with the debug version -# Warning, writes a lot into apt-cacher.err logfile -# Value overwrites UnbufferLogs setting (aliased) -# Debug:3 - -# Usually, general purpose proxies like Squid expose the IP address of the -# client user to the remote server using the X-Forwarded-For HTTP header. This -# behaviour can be optionally turned on with the Expose-Origin option. -# ExposeOrigin: 0 - -# When logging the originating IP address, trust the information supplied by -# the client in the X-Forwarded-For header. -# LogSubmittedOrigin: 0 - -# The version string reported to the peer, to be displayed as HTTP client (and -# version) in the logs of the mirror. -# WARNING: some archives use this header to detect/guess capabilities of the -# client (i.e. redirection support) and change the behaviour accordingly, while -# ACNG might not support the expected features. Expect side effects. -# -# UserAgent: Yet Another HTTP Client/1.2.3p4 - -# In some cases the Import and Expiration tasks might create fresh volatile -# data for internal use by reconstructing them using patch files. This -# by-product might be recompressed with bzip2 and with some luck the resulting -# file becomes identical to the *.bz2 file on the server, usable for APT -# clients trying to fetch the full .bz2 compressed version. Injection of the -# generated files into the cache has however a disadvantage on underpowered -# servers: bzip2 compression can create high load on the server system and the -# visible download of the busy .bz2 files also becomes slower. -# -# RecompBz2: 0 - -# Network timeout for outgoing connections. -# NetworkTimeout: 60 - -# Sometimes it makes sense to not store the data in cache and just return the -# package data to client as it comes in. DontCache parameters can enable this -# behaviour for certain URL types. The tokens are extended regular expressions -# that URLs are matched against. -# -# DontCacheRequested is applied to the URL as it comes in from the client. -# Example: exclude packages built with kernel-package for x86 -# DontCacheRequested: linux-.*_10\...\.Custo._i386 -# Example usecase: exclude popular private IP ranges from caching -# DontCacheRequested: 192.168.0 ^10\..* 172.30 -# -# DontCacheResolved is applied to URLs after mapping to the target server. If -# multiple backend servers are specified then it's only matched against the -# download link for the FIRST possible source (due to implementation limits). -# Example usecase: all Ubuntu stuff comes from a local mirror (specified as -# backend), don't cache it again: -# DontCacheResolved: ubuntumirror.local.net -# -# DontCache directive sets (overrides) both, DontCacheResolved and -# DontCacheRequested. Provided for convenience, see those directives for -# details. -# -# Default permission set of freshly created files and directories, as octal -# numbers (see chmod(1) for details). -# Can by limited by the umask value (see umask(2) for details) if it's set in -# the environment of the starting shell, e.g. in apt-cacher-ng init script or -# in its configuration file. -# DirPerms: 00755 -# FilePerms: 00664 -# -# -# It's possible to use use apt-cacher-ng as a regular web server with limited -# feature set, i.e. -# including directory browsing and download of any file; -# excluding sorting, mime types/encodings, CGI execution, index page -# redirection and other funny things. -# To get this behavior, mappings between virtual directories and real -# directories on the server must be defined with the LocalDirs directive. -# Virtual and real dirs are separated by spaces, multiple pairs are separated -# by semi-colons. Real directories must be absolute paths. -# NOTE: Since the names of that key directories share the same namespace as -# repository names (see Remap-...) it's administrators job to avoid such -# collisions on them (unless created deliberately). -# -# LocalDirs: woo /data/debarchive/woody ; hamm /data/debarchive/hamm - -# Precache a set of files referenced by specified index files. This can be used -# to create a partial mirror usable for offline work. There are certain limits -# and restrictions on the path specification, see manual for details. A list of -# (maybe) relevant index files could be retrieved via -# "apt-get --print-uris update" on a client machine. -# -# PrecacheFor: debrep/dists/unstable/*/source/Sources* debrep/dists/unstable/*/binary-amd64/Packages* - -# Arbitrary set of data to append to request headers sent over the wire. Should -# be a well formated HTTP headers part including newlines (DOS style) which -# can be entered as escape sequences (\r\n). -# RequestAppendix: X-Tracking-Choice: do-not-track\r\n - -# Specifies the IP protocol families to use for remote connections. Order does -# matter, first specified are considered first. Possible combinations: -# v6 v4 -# v4 v6 -# v6 -# v4 -# (empty or not set: use system default) -# -# ConnectProto: v6 v4 - -# Regular expiration algorithm finds package files which are no longer listed -# in any index file and removes them of them after a safety period. -# This option allows to keep more versions of a package in the cache after -# safety period is over. -# KeepExtraVersions: 1 - -# Optionally uses TCP access control provided by libwrap, see hosts_access(5) -# for details. Daemon name is apt-cacher-ng. Default if not set: decided on -# startup by looking for explicit mentioning of apt-cacher-ng in -# /etc/hosts.allow or /etc/hosts.deny files. -# UseWrap: 0 - -# If many machines from the same local network attempt to update index files -# (apt-get update) at nearly the same time, the known state of these index file -# is temporarily frozen and multiple requests receive the cached response -# without contacting the server. This parameter (in seconds) specifies the -# length of this period before the files are considered outdated. -# Setting it too low transfers more data and increases remote server load, -# setting it too high (more than a couple of minutes) increases the risk of -# delivering inconsistent responses to the clients. -# FreshIndexMaxAge: 27 - -# Usually the users are not allowed to specify custom TCP ports of remote -# mirrors in the requests, only the default HTTP port can be used (instead, -# proxy administrator can create Remap- rules with custom ports). This -# restriction can be disabled by specifying a list of allowed ports or 0 for -# any port. -# -# AllowUserPorts: 80 - -# Normally the HTTP redirection responses are forwarded to the original caller -# (i.e. APT) which starts a new download attempt from the new URL. This -# solution is ok for client configurations with proxy mode but doesn't work -# well with configurations using URL prefixes. To work around this the server -# can restart its own download with another URL. However, this might be used to -# circumvent download source policies by malicious users. -# The RedirMax option specifies how many such redirects the server should -# follow per request, 0 disables the internal redirection. If not set, -# default value is 0 if ForceManaged is used and 5 otherwise. -# -# RedirMax: 5 diff --git a/server-ce/chef/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb b/server-ce/chef/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb deleted file mode 100644 index 0e7c779b3a..0000000000 --- a/server-ce/chef/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb +++ /dev/null @@ -1,269 +0,0 @@ -# Letter case in directive names does not matter. Must be separated with colons. -# Valid boolean values are a zero number for false, non-zero numbers for true. - -CacheDir: <%= node['apt']['cacher_dir'] %> - -# set empty to disable logging -LogDir: /var/log/apt-cacher-ng - -# place to look for additional configuration and resource files if they are not -# found in the configuration directory -# SupportDir: /usr/lib/apt-cacher-ng - -# TCP (http) port -# Set to 9999 to emulate apt-proxy -Port:<%= node['apt']['cacher_port'] %> - -# Addresses or hostnames to listen on. Multiple addresses must be separated by -# spaces. Each entry must be an exact local address which is associated with a -# local interface. DNS resolution is performed using getaddrinfo(3) for all -# available protocols (IPv4, IPv6, ...). Using a protocol specific format will -# create binding(s) only on protocol specific socket(s) (e.g. 0.0.0.0 will listen -# only to IPv4). -# -# Default: not set, will listen on all interfaces and protocols -# -# BindAddress: localhost 192.168.7.254 publicNameOnMainInterface - -# The specification of another proxy which shall be used for downloads. -# Username and password are, and see manual for limitations. -# -#Proxy: http://www-proxy.example.net:80 -#proxy: username:proxypassword@proxy.example.net:3128 - -# Repository remapping. See manual for details. -# In this example, some backends files might be generated during package -# installation using information collected on the system. -Remap-debrep: file:deb_mirror*.gz /debian ; file:backends_debian # Debian Archives -Remap-uburep: file:ubuntu_mirrors /ubuntu ; file:backends_ubuntu # Ubuntu Archives -Remap-debvol: file:debvol_mirror*.gz /debian-volatile ; file:backends_debvol # Debian Volatile Archives - -# This is usually not needed for security.debian.org because it's always the -# same DNS hostname. However, it might be enabled in order to use hooks, -# ForceManaged mode or special flags in this context. -# Remap-secdeb: security.debian.org - -# Virtual page accessible in a web browser to see statistics and status -# information, i.e. under http://localhost:3142/acng-report.html -ReportPage: acng-report.html - -# Socket file for accessing through local UNIX socket instead of TCP/IP. Can be -# used with inetd bridge or cron client. -# SocketPath:/var/run/apt-cacher-ng/socket - -# Forces log file to be written to disk after every line when set to 1. Default -# is 0, buffers are flushed when the client disconnects. -# -# (technically, alias to the Debug option, see its documentation for details) -# -# UnbufferLogs: 0 - -# Set to 0 to store only type, time and transfer sizes. -# 1 -> client IP and relative local path are logged too -# VerboseLog: 1 - -# Don't detach from the console -# ForeGround: 0 - -# Store the pid of the daemon process therein -# PidFile: /var/run/apt-cacher-ng/pid - -# Forbid outgoing connections, work around them or respond with 503 error -# offlinemode:0 - -# Forbid all downloads that don't run through preconfigured backends (.where) -#ForceManaged: 0 - -# Days before considering an unreferenced file expired (to be deleted). -# Warning: if the value is set too low and particular index files are not -# available for some days (mirror downtime) there is a risk of deletion of -# still useful package files. -ExTreshold: 4 - -# Stop expiration when a critical problem appeared. Currently only failed -# refresh of an index file is considered as critical. -# -# WARNING: don't touch this option or set to zero. -# Anything else is DANGEROUS and may cause data loss. -# -# ExAbortOnProblems: 1 - -# Replace some Windows/DOS-FS incompatible chars when storing -# StupidFs: 0 - -# Experimental feature for apt-listbugs: pass-through SOAP requests and -# responses to/from bugs.debian.org. If not set, default is true if -# ForceManaged is enabled and false otherwise. -# ForwardBtsSoap: 1 - -# The daemon has a small cache for DNS data, to speed up resolution. The -# expiration time of the DNS entries can be configured in seconds. -# DnsCacheSeconds: 3600 - -# Don't touch the following values without good consideration! -# -# Max. count of connection threads kept ready (for faster response in the -# future). Should be a sane value between 0 and average number of connections, -# and depend on the amount of spare RAM. -# MaxStandbyConThreads: 8 -# -# Hard limit of active thread count for incoming connections, i.e. operation -# is refused when this value is reached (below zero = unlimited). -# MaxConThreads: -1 -# -# Pigeonholing files with regular expressions (static/volatile). Can be -# overriden here but not should not be done permanently because future update -# of default settings would not be applied later. -# VfilePattern = (^|.*?/)(Index|Packages(\.gz|\.bz2|\.lzma|\.xz)?|InRelease|Release|Release\.gpg|Sources(\.gz|\.bz2|\.lzma|\.xz)?|release|index\.db-.*\.gz|Contents-[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|pkglist[^/]*\.bz2|rclist[^/]*\.bz2|/meta-release[^/]*|Translation[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|MD5SUMS|SHA1SUMS|((setup|setup-legacy)(\.ini|\.bz2|\.hint)(\.sig)?)|mirrors\.lst|repo(index|md)\.xml(\.asc|\.key)?|directory\.yast|products|content(\.asc|\.key)?|media|filelists\.xml\.gz|filelists\.sqlite\.bz2|repomd\.xml|packages\.[a-zA-Z][a-zA-Z]\.gz|info\.txt|license\.tar\.gz|license\.zip|.*\.db(\.tar\.gz)?|.*\.files\.tar\.gz|.*\.abs\.tar\.gz|metalink\?repo|.*prestodelta\.xml\.gz)$|/dists/.*/installer-[^/]+/[^0-9][^/]+/images/.* -# PfilePattern = .*(\.d?deb|\.rpm|\.dsc|\.tar(\.gz|\.bz2|\.lzma|\.xz)(\.gpg)?|\.diff(\.gz|\.bz2|\.lzma|\.xz)|\.jigdo|\.template|changelog|copyright|\.udeb|\.debdelta|\.diff/.*\.gz|(Devel)?ReleaseAnnouncement(\?.*)?|[a-f0-9]+-(susedata|updateinfo|primary|deltainfo).xml.gz|fonts/(final/)?[a-z]+32.exe(\?download.*)?|/dists/.*/installer-[^/]+/[0-9][^/]+/images/.*)$ -# Whitelist for expiration, file types not to be removed even when being -# unreferenced. Default: many parts from VfilePattern where no parent index -# exists or might be unknown. -# WfilePattern = (^|.*?/)(Release|InRelease|Release\.gpg|(Packages|Sources)(\.gz|\.bz2|\.lzma|\.xz)?|Translation[^/]*(\.gz|\.bz2|\.lzma|\.xz)?|MD5SUMS|SHA1SUMS|.*\.xml|.*\.db\.tar\.gz|.*\.files\.tar\.gz|.*\.abs\.tar\.gz|[a-z]+32.exe)$|/dists/.*/installer-.*/images/.* - -# Higher modes only working with the debug version -# Warning, writes a lot into apt-cacher.err logfile -# Value overwrites UnbufferLogs setting (aliased) -# Debug:3 - -# Usually, general purpose proxies like Squid expose the IP address of the -# client user to the remote server using the X-Forwarded-For HTTP header. This -# behaviour can be optionally turned on with the Expose-Origin option. -# ExposeOrigin: 0 - -# When logging the originating IP address, trust the information supplied by -# the client in the X-Forwarded-For header. -# LogSubmittedOrigin: 0 - -# The version string reported to the peer, to be displayed as HTTP client (and -# version) in the logs of the mirror. -# WARNING: some archives use this header to detect/guess capabilities of the -# client (i.e. redirection support) and change the behaviour accordingly, while -# ACNG might not support the expected features. Expect side effects. -# -# UserAgent: Yet Another HTTP Client/1.2.3p4 - -# In some cases the Import and Expiration tasks might create fresh volatile -# data for internal use by reconstructing them using patch files. This -# by-product might be recompressed with bzip2 and with some luck the resulting -# file becomes identical to the *.bz2 file on the server, usable for APT -# clients trying to fetch the full .bz2 compressed version. Injection of the -# generated files into the cache has however a disadvantage on underpowered -# servers: bzip2 compression can create high load on the server system and the -# visible download of the busy .bz2 files also becomes slower. -# -# RecompBz2: 0 - -# Network timeout for outgoing connections. -# NetworkTimeout: 60 - -# Sometimes it makes sense to not store the data in cache and just return the -# package data to client as it comes in. DontCache parameters can enable this -# behaviour for certain URL types. The tokens are extended regular expressions -# that URLs are matched against. -# -# DontCacheRequested is applied to the URL as it comes in from the client. -# Example: exclude packages built with kernel-package for x86 -# DontCacheRequested: linux-.*_10\...\.Custo._i386 -# Example usecase: exclude popular private IP ranges from caching -# DontCacheRequested: 192.168.0 ^10\..* 172.30 -# -# DontCacheResolved is applied to URLs after mapping to the target server. If -# multiple backend servers are specified then it's only matched against the -# download link for the FIRST possible source (due to implementation limits). -# Example usecase: all Ubuntu stuff comes from a local mirror (specified as -# backend), don't cache it again: -# DontCacheResolved: ubuntumirror.local.net -# -# DontCache directive sets (overrides) both, DontCacheResolved and -# DontCacheRequested. Provided for convenience, see those directives for -# details. -# -# Default permission set of freshly created files and directories, as octal -# numbers (see chmod(1) for details). -# Can by limited by the umask value (see umask(2) for details) if it's set in -# the environment of the starting shell, e.g. in apt-cacher-ng init script or -# in its configuration file. -# DirPerms: 00755 -# FilePerms: 00664 -# -# -# It's possible to use use apt-cacher-ng as a regular web server with limited -# feature set, i.e. -# including directory browsing and download of any file; -# excluding sorting, mime types/encodings, CGI execution, index page -# redirection and other funny things. -# To get this behavior, mappings between virtual directories and real -# directories on the server must be defined with the LocalDirs directive. -# Virtual and real dirs are separated by spaces, multiple pairs are separated -# by semi-colons. Real directories must be absolute paths. -# NOTE: Since the names of that key directories share the same namespace as -# repository names (see Remap-...) it's administrators job to avoid such -# collisions on them (unless created deliberately). -# -# LocalDirs: woo /data/debarchive/woody ; hamm /data/debarchive/hamm - -# Precache a set of files referenced by specified index files. This can be used -# to create a partial mirror usable for offline work. There are certain limits -# and restrictions on the path specification, see manual for details. A list of -# (maybe) relevant index files could be retrieved via -# "apt-get --print-uris update" on a client machine. -# -# PrecacheFor: debrep/dists/unstable/*/source/Sources* debrep/dists/unstable/*/binary-amd64/Packages* - -# Arbitrary set of data to append to request headers sent over the wire. Should -# be a well formated HTTP headers part including newlines (DOS style) which -# can be entered as escape sequences (\r\n). -# RequestAppendix: X-Tracking-Choice: do-not-track\r\n - -# Specifies the IP protocol families to use for remote connections. Order does -# matter, first specified are considered first. Possible combinations: -# v6 v4 -# v4 v6 -# v6 -# v4 -# (empty or not set: use system default) -# -# ConnectProto: v6 v4 - -# Regular expiration algorithm finds package files which are no longer listed -# in any index file and removes them of them after a safety period. -# This option allows to keep more versions of a package in the cache after -# safety period is over. -# KeepExtraVersions: 1 - -# Optionally uses TCP access control provided by libwrap, see hosts_access(5) -# for details. Daemon name is apt-cacher-ng. Default if not set: decided on -# startup by looking for explicit mentioning of apt-cacher-ng in -# /etc/hosts.allow or /etc/hosts.deny files. -# UseWrap: 0 - -# If many machines from the same local network attempt to update index files -# (apt-get update) at nearly the same time, the known state of these index file -# is temporarily frozen and multiple requests receive the cached response -# without contacting the server. This parameter (in seconds) specifies the -# length of this period before the files are considered outdated. -# Setting it too low transfers more data and increases remote server load, -# setting it too high (more than a couple of minutes) increases the risk of -# delivering inconsistent responses to the clients. -# FreshIndexMaxAge: 27 - -# Usually the users are not allowed to specify custom TCP ports of remote -# mirrors in the requests, only the default HTTP port can be used (instead, -# proxy administrator can create Remap- rules with custom ports). This -# restriction can be disabled by specifying a list of allowed ports or 0 for -# any port. -# -# AllowUserPorts: 80 - -# Normally the HTTP redirection responses are forwarded to the original caller -# (i.e. APT) which starts a new download attempt from the new URL. This -# solution is ok for client configurations with proxy mode but doesn't work -# well with configurations using URL prefixes. To work around this the server -# can restart its own download with another URL. However, this might be used to -# circumvent download source policies by malicious users. -# The RedirMax option specifies how many such redirects the server should -# follow per request, 0 disables the internal redirection. If not set, -# default value is 0 if ForceManaged is used and 5 otherwise. -# -# RedirMax: 5 diff --git a/server-ce/chef/cookbooks/mongodb/CHANGELOG.md b/server-ce/chef/cookbooks/mongodb/CHANGELOG.md deleted file mode 100644 index 5be9eb31c9..0000000000 --- a/server-ce/chef/cookbooks/mongodb/CHANGELOG.md +++ /dev/null @@ -1,12 +0,0 @@ -# CHANGELOG for mongodb - -This file is used to list changes made in each version of mongodb. - -## 0.1.0: - -* Initial release of mongodb - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/server-ce/chef/cookbooks/mongodb/README.md b/server-ce/chef/cookbooks/mongodb/README.md deleted file mode 100644 index 8ea30c6ce4..0000000000 --- a/server-ce/chef/cookbooks/mongodb/README.md +++ /dev/null @@ -1,68 +0,0 @@ -mongodb Cookbook -================ -TODO: Enter the cookbook description here. - -e.g. -This cookbook makes your favorite breakfast sandwhich. - -Requirements ------------- -TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. - -e.g. -#### packages -- `toaster` - mongodb needs toaster to brown your bagel. - -Attributes ----------- -TODO: List you cookbook attributes here. - -e.g. -#### mongodb::default -
KeyDefault
['sharelatex']['bacon']['redis']['bacon'] Boolean whether to include bacon true
- - - - - - - - - - - - -
KeyTypeDescriptionDefault
['mongodb']['bacon']Booleanwhether to include bacontrue
- -Usage ------ -#### mongodb::default -TODO: Write usage instructions for each cookbook. - -e.g. -Just include `mongodb` in your node's `run_list`: - -```json -{ - "name":"my_node", - "run_list": [ - "recipe[mongodb]" - ] -} -``` - -Contributing ------------- -TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. - -e.g. -1. Fork the repository on Github -2. Create a named feature branch (like `add_component_x`) -3. Write you change -4. Write tests for your change (if applicable) -5. Run the tests, ensuring they all pass -6. Submit a Pull Request using Github - -License and Authors -------------------- -Authors: TODO: List authors diff --git a/server-ce/chef/cookbooks/mongodb/metadata.rb b/server-ce/chef/cookbooks/mongodb/metadata.rb deleted file mode 100644 index 2a39cb29c8..0000000000 --- a/server-ce/chef/cookbooks/mongodb/metadata.rb +++ /dev/null @@ -1,8 +0,0 @@ -name 'mongodb' -maintainer 'ShareLaTeX' -maintainer_email 'team@sharelatex.com' -license 'AGPLv3' -description 'Installs/Configures mongodb' -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '0.1.0' -depends 'apt' diff --git a/server-ce/chef/cookbooks/mongodb/recipes/default.rb b/server-ce/chef/cookbooks/mongodb/recipes/default.rb deleted file mode 100644 index f1a8a4f6be..0000000000 --- a/server-ce/chef/cookbooks/mongodb/recipes/default.rb +++ /dev/null @@ -1,19 +0,0 @@ -# -# Cookbook Name:: mongodb -# Recipe:: default -# -# Copyright 2014, ShareLaTeX -# - -# See http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/ -apt_repository 'mongodb-org' do - uri 'http://downloads-distro.mongodb.org/repo/ubuntu-upstart' - distribution 'dist' - components ['10gen'] - keyserver 'keyserver.ubuntu.com' - key '7F0CEB10' -end - -package 'mongodb-org' do - action :install -end \ No newline at end of file diff --git a/server-ce/chef/cookbooks/nodejs/CHANGELOG.md b/server-ce/chef/cookbooks/nodejs/CHANGELOG.md deleted file mode 100644 index 8267e4fa26..0000000000 --- a/server-ce/chef/cookbooks/nodejs/CHANGELOG.md +++ /dev/null @@ -1,12 +0,0 @@ -# CHANGELOG for nodejs - -This file is used to list changes made in each version of nodejs. - -## 0.1.0: - -* Initial release of nodejs - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/server-ce/chef/cookbooks/nodejs/README.md b/server-ce/chef/cookbooks/nodejs/README.md deleted file mode 100644 index daec67045d..0000000000 --- a/server-ce/chef/cookbooks/nodejs/README.md +++ /dev/null @@ -1,68 +0,0 @@ -nodejs Cookbook -=============== -TODO: Enter the cookbook description here. - -e.g. -This cookbook makes your favorite breakfast sandwhich. - -Requirements ------------- -TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. - -e.g. -#### packages -- `toaster` - nodejs needs toaster to brown your bagel. - -Attributes ----------- -TODO: List you cookbook attributes here. - -e.g. -#### nodejs::default - - - - - - - - - - - - - -
KeyTypeDescriptionDefault
['nodejs']['bacon']Booleanwhether to include bacontrue
- -Usage ------ -#### nodejs::default -TODO: Write usage instructions for each cookbook. - -e.g. -Just include `nodejs` in your node's `run_list`: - -```json -{ - "name":"my_node", - "run_list": [ - "recipe[nodejs]" - ] -} -``` - -Contributing ------------- -TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. - -e.g. -1. Fork the repository on Github -2. Create a named feature branch (like `add_component_x`) -3. Write you change -4. Write tests for your change (if applicable) -5. Run the tests, ensuring they all pass -6. Submit a Pull Request using Github - -License and Authors -------------------- -Authors: TODO: List authors diff --git a/server-ce/chef/cookbooks/nodejs/metadata.rb b/server-ce/chef/cookbooks/nodejs/metadata.rb deleted file mode 100644 index 9a3d03ffdf..0000000000 --- a/server-ce/chef/cookbooks/nodejs/metadata.rb +++ /dev/null @@ -1,8 +0,0 @@ -name 'nodejs' -maintainer 'YOUR_COMPANY_NAME' -maintainer_email 'YOUR_EMAIL' -license 'AGPLv3' -description 'Installs/Configures nodejs' -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '0.1.0' -depends 'apt' diff --git a/server-ce/chef/cookbooks/nodejs/recipes/default.rb b/server-ce/chef/cookbooks/nodejs/recipes/default.rb deleted file mode 100644 index 3da73c4764..0000000000 --- a/server-ce/chef/cookbooks/nodejs/recipes/default.rb +++ /dev/null @@ -1,24 +0,0 @@ -# -# Cookbook Name:: nodejs -# Recipe:: default -# -# Copyright 2014, ShareLaTeX -# - -# See https://launchpad.net/~chris-lea/+archive/nodejs -apt_repository 'node.js' do - uri 'http://ppa.launchpad.net/chris-lea/node.js/ubuntu' - distribution node['lsb']['codename'] - components ['main'] - keyserver 'keyserver.ubuntu.com' - key 'C7917B12' -end - -package 'nodejs' do - action :install -end - -execute 'install grunt' do - command "npm install -g grunt-cli" - not_if "npm --no-color -g ls 'grunt-cli' 2> /dev/null | grep 'grunt-cli'" -end \ No newline at end of file diff --git a/server-ce/chef/cookbooks/packages/README.md b/server-ce/chef/cookbooks/packages/README.md deleted file mode 100644 index d344c7a185..0000000000 --- a/server-ce/chef/cookbooks/packages/README.md +++ /dev/null @@ -1,68 +0,0 @@ -redis Cookbook -============== -TODO: Enter the cookbook description here. - -e.g. -This cookbook makes your favorite breakfast sandwhich. - -Requirements ------------- -TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. - -e.g. -#### packages -- `toaster` - redis needs toaster to brown your bagel. - -Attributes ----------- -TODO: List you cookbook attributes here. - -e.g. -#### redis::default - - - - - - - - - - - - - -
KeyTypeDescriptionDefault
['redis']['bacon']Booleanwhether to include bacontrue
- -Usage ------ -#### redis::default -TODO: Write usage instructions for each cookbook. - -e.g. -Just include `redis` in your node's `run_list`: - -```json -{ - "name":"my_node", - "run_list": [ - "recipe[redis]" - ] -} -``` - -Contributing ------------- -TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. - -e.g. -1. Fork the repository on Github -2. Create a named feature branch (like `add_component_x`) -3. Write you change -4. Write tests for your change (if applicable) -5. Run the tests, ensuring they all pass -6. Submit a Pull Request using Github - -License and Authors -------------------- -Authors: TODO: List authors diff --git a/server-ce/chef/cookbooks/packages/metadata.rb b/server-ce/chef/cookbooks/packages/metadata.rb deleted file mode 100644 index d3a750d846..0000000000 --- a/server-ce/chef/cookbooks/packages/metadata.rb +++ /dev/null @@ -1,7 +0,0 @@ -name 'packages' -maintainer 'ShareLaTeX' -maintainer_email 'team@sharelatex.com' -license 'AGPLv3' -description 'Installs/Configures packages' -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '0.1.0' diff --git a/server-ce/chef/cookbooks/packages/recipes/default.rb b/server-ce/chef/cookbooks/packages/recipes/default.rb deleted file mode 100644 index f1c9024aad..0000000000 --- a/server-ce/chef/cookbooks/packages/recipes/default.rb +++ /dev/null @@ -1,10 +0,0 @@ -# -# Cookbook Name:: packages -# Recipe:: default -# -# Copyright 2014, ShareLaTeX -# - -package 'git' -package 'vim' -package 'build-essential' \ No newline at end of file diff --git a/server-ce/chef/cookbooks/redis-server/CHANGELOG.md b/server-ce/chef/cookbooks/redis-server/CHANGELOG.md deleted file mode 100644 index 7e2b5bbee2..0000000000 --- a/server-ce/chef/cookbooks/redis-server/CHANGELOG.md +++ /dev/null @@ -1,12 +0,0 @@ -# CHANGELOG for redis - -This file is used to list changes made in each version of redis. - -## 0.1.0: - -* Initial release of redis - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/server-ce/chef/cookbooks/redis-server/README.md b/server-ce/chef/cookbooks/redis-server/README.md deleted file mode 100644 index d344c7a185..0000000000 --- a/server-ce/chef/cookbooks/redis-server/README.md +++ /dev/null @@ -1,68 +0,0 @@ -redis Cookbook -============== -TODO: Enter the cookbook description here. - -e.g. -This cookbook makes your favorite breakfast sandwhich. - -Requirements ------------- -TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. - -e.g. -#### packages -- `toaster` - redis needs toaster to brown your bagel. - -Attributes ----------- -TODO: List you cookbook attributes here. - -e.g. -#### redis::default - - - - - - - - - - - - - -
KeyTypeDescriptionDefault
['redis']['bacon']Booleanwhether to include bacontrue
- -Usage ------ -#### redis::default -TODO: Write usage instructions for each cookbook. - -e.g. -Just include `redis` in your node's `run_list`: - -```json -{ - "name":"my_node", - "run_list": [ - "recipe[redis]" - ] -} -``` - -Contributing ------------- -TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. - -e.g. -1. Fork the repository on Github -2. Create a named feature branch (like `add_component_x`) -3. Write you change -4. Write tests for your change (if applicable) -5. Run the tests, ensuring they all pass -6. Submit a Pull Request using Github - -License and Authors -------------------- -Authors: TODO: List authors diff --git a/server-ce/chef/cookbooks/redis-server/metadata.rb b/server-ce/chef/cookbooks/redis-server/metadata.rb deleted file mode 100644 index 41d0512ede..0000000000 --- a/server-ce/chef/cookbooks/redis-server/metadata.rb +++ /dev/null @@ -1,8 +0,0 @@ -name 'redis-server' -maintainer 'ShareLaTeX' -maintainer_email 'team@sharelatex.com' -license 'AGPLv3' -description 'Installs/Configures redis-server' -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '0.1.0' -depends 'apt' diff --git a/server-ce/chef/cookbooks/redis-server/recipes/default.rb b/server-ce/chef/cookbooks/redis-server/recipes/default.rb deleted file mode 100644 index 886c6475c4..0000000000 --- a/server-ce/chef/cookbooks/redis-server/recipes/default.rb +++ /dev/null @@ -1,20 +0,0 @@ -# -# Cookbook Name:: redis -# Recipe:: default -# -# Copyright 2014, ShareLaTeX -# - -# See https://launchpad.net/~chris-lea/+archive/redis-server -apt_repository 'redis-server' do - uri 'http://ppa.launchpad.net/chris-lea/redis-server/ubuntu' - distribution node['lsb']['codename'] - components ['main'] - keyserver 'keyserver.ubuntu.com' - key 'C7917B12' -end - -package 'redis-server' do - action :upgrade - options "--force-yes" -end \ No newline at end of file diff --git a/server-ce/chef/cookbooks/texlive/CHANGELOG.md b/server-ce/chef/cookbooks/texlive/CHANGELOG.md deleted file mode 100644 index e1b59f6e0c..0000000000 --- a/server-ce/chef/cookbooks/texlive/CHANGELOG.md +++ /dev/null @@ -1,12 +0,0 @@ -# CHANGELOG for latex - -This file is used to list changes made in each version of latex. - -## 0.1.0: - -* Initial release of latex - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/server-ce/chef/cookbooks/texlive/README.md b/server-ce/chef/cookbooks/texlive/README.md deleted file mode 100644 index 06f25ec5e4..0000000000 --- a/server-ce/chef/cookbooks/texlive/README.md +++ /dev/null @@ -1,68 +0,0 @@ -latex Cookbook -============== -TODO: Enter the cookbook description here. - -e.g. -This cookbook makes your favorite breakfast sandwhich. - -Requirements ------------- -TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. - -e.g. -#### packages -- `toaster` - latex needs toaster to brown your bagel. - -Attributes ----------- -TODO: List you cookbook attributes here. - -e.g. -#### latex::default - - - - - - - - - - - - - -
KeyTypeDescriptionDefault
['latex']['bacon']Booleanwhether to include bacontrue
- -Usage ------ -#### latex::default -TODO: Write usage instructions for each cookbook. - -e.g. -Just include `latex` in your node's `run_list`: - -```json -{ - "name":"my_node", - "run_list": [ - "recipe[latex]" - ] -} -``` - -Contributing ------------- -TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. - -e.g. -1. Fork the repository on Github -2. Create a named feature branch (like `add_component_x`) -3. Write you change -4. Write tests for your change (if applicable) -5. Run the tests, ensuring they all pass -6. Submit a Pull Request using Github - -License and Authors -------------------- -Authors: TODO: List authors diff --git a/server-ce/chef/cookbooks/texlive/attributes/default.rb b/server-ce/chef/cookbooks/texlive/attributes/default.rb deleted file mode 100644 index b9941626e4..0000000000 --- a/server-ce/chef/cookbooks/texlive/attributes/default.rb +++ /dev/null @@ -1,2 +0,0 @@ -default[:texlive][:schema] = "small" -default[:texlive][:bin_dir] = "/usr/local/texlive/2014/bin/x86_64-linux" diff --git a/server-ce/chef/cookbooks/texlive/metadata.rb b/server-ce/chef/cookbooks/texlive/metadata.rb deleted file mode 100644 index ceaaaf2e9c..0000000000 --- a/server-ce/chef/cookbooks/texlive/metadata.rb +++ /dev/null @@ -1,7 +0,0 @@ -name 'texlive' -maintainer 'ShareLaTeX' -maintainer_email 'team@sharelatex.com' -license 'All rights reserved' -description 'Installs/Configures texlive' -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '0.1.0' diff --git a/server-ce/chef/cookbooks/texlive/recipes/default.rb b/server-ce/chef/cookbooks/texlive/recipes/default.rb deleted file mode 100644 index 7aab8ef32b..0000000000 --- a/server-ce/chef/cookbooks/texlive/recipes/default.rb +++ /dev/null @@ -1,42 +0,0 @@ -# -# Cookbook Name:: texlive -# Recipe:: default -# -# Copyright 2014, YOUR_COMPANY_NAME -# -# All rights reserved - Do Not Redistribute -# - -remote_file "#{Chef::Config[:file_cache_path]}/install-tl-unx.tar.gz" do - source "http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz" - action :create_if_missing -end - -directory "/install-tl-unx" -bash "extract install-tl" do - cwd Chef::Config[:file_cache_path] - code <<-EOH - tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 - EOH - creates "/install-tl-unx/install-tl" -end - -file "/install-tl-unx/texlive.profile" do - content "selected_scheme scheme-#{node[:texlive][:schema]}" -end - -bash "install texlive" do - cwd "/install-tl-unx" - code <<-EOH - /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile - EOH - creates "#{node[:texlive][:bin_dir]}/pdflatex" -end - -bash "install latexmk" do - environment({ - "PATH" => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:#{node[:texlive][:bin_dir]}" - }) - code "tlmgr install latexmk" - creates "#{node[:texlive][:bin_dir]}/latexmk" -end \ No newline at end of file diff --git a/server-ce/config/settings.development.coffee.example b/server-ce/config/settings.development.coffee.example deleted file mode 100644 index ccc1487605..0000000000 --- a/server-ce/config/settings.development.coffee.example +++ /dev/null @@ -1,230 +0,0 @@ -Path = require('path') - -# These credentials are used for authenticating api requests -# between services that may need to go over public channels -httpAuthUser = "sharelatex" -httpAuthPass = "CRYPTO_RANDOM" # Randomly generated for you -httpAuthUsers = {} -httpAuthUsers[httpAuthUser] = httpAuthPass - -DATA_DIR = Path.resolve(Path.join(__dirname, "..", "data")) -TMP_DIR = Path.resolve(Path.join(__dirname, "..", "tmp")) - -module.exports = - # Databases - # --------- - - # ShareLaTeX's main persistant data store is MongoDB (http://www.mongodb.org/) - # Documentation about the URL connection string format can be found at: - # - # http://docs.mongodb.org/manual/reference/connection-string/ - # - # The following works out of the box with Mongo's default settings: - mongo: - url : 'mongodb://127.0.0.1/sharelatex' - - # Redis is used in ShareLaTeX for high volume queries, like real-time - # editing, and session management. - # - # The following config will work with Redis's default settings: - redis: - web: - host: "localhost" - port: "6379" - password: "" - - # The compile server (the clsi) uses a SQL database to cache files and - # meta-data. sqllite is the default, and the load is low enough that this will - # be fine in production (we use sqllite at sharelatex.com). - # - # If you want to configure a different database, see the Sequelize documentation - # for available options: - # - # https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage - # - mysql: - clsi: - database: "clsi" - username: "clsi" - password: "" - dialect: "sqlite" - storage: Path.join(DATA_DIR, "db.sqlite") - - # File storage - # ------------ - - # ShareLaTeX can store binary files like images either locally or in Amazon - # S3. The default is locally: - filestore: - backend: "fs" - stores: - user_files: Path.join(DATA_DIR, "user_files") - - # To use Amazon S3 as a storage backend, comment out the above config, and - # uncomment the following, filling in your key, secret, and bucket name: - # - #filestore: - # backend: "s3" - # stores: - # user_files: "BUCKET_NAME" - # s3: - # key: "AWS_KEY" - # secret: "AWS_SECRET" - # - - # Local disk caching - # ------------------ - path: - # If we ever need to write something to disk (e.g. incoming requests - # that need processing but may be too big for memory), then write - # them to disk here: - dumpFolder: Path.join(TMP_DIR, "dumpFolder") - # Where to write uploads before they are processed - uploadFolder: Path.join(TMP_DIR, "uploads") - # Where to write the project to disk before running LaTeX on it - compilesDir: Path.join(DATA_DIR, "compiles") - # Where to cache downloaded URLs for the CLSI - clsiCacheDir: Path.join(DATA_DIR, "cache") - - # Server Config - # ------------- - - # Where your instance of ShareLaTeX can be found publicly. This is used - # when emails are sent out and in generated links: - siteUrl : 'http://localhost:3000' - - # The websocket layer of ShareLaTeX runs as separate service. - # When running locally or in development, you can point the client to this - # service directly on port 3026. If you are running behind a reverse proxy (Nginx, etc) - # then websocketsUrl should be the same as siteUrl, with your reverse - # proxy responible for sending websocket traffic to the websocket service - # rather than connecting directly. - websocketsUrl: 'http://localhost:3026' - - # If provided, a sessionSecret is used to sign cookies so that they cannot be - # spoofed. This is recommended. - security: - sessionSecret: "CRYPTO_RANDOM" # This was randomly generated for you - - # These credentials are used for authenticating api requests - # between services that may need to go over public channels - httpAuthUsers: httpAuthUsers - - # Should javascript assets be served minified or not. Note that you will - # need to run `grunt compile:minify` within the web-sharelatex directory - # to generate these. - useMinifiedJs: false - - # Should static assets be sent with a header to tell the browser to cache - # them. This should be false in development where changes are being made, - # but should be set to true in production. - cacheStaticAssets: false - - # If you are running ShareLaTeX over https, set this to true to send the - # cookie with a secure flag (recommended). - secureCookie: false - - # If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) - # then set this to true to allow it to correctly detect the forwarded IP - # address and http/https protocol information. - behindProxy: false - - # Sending Email - # ------------- - # - # You must configure a mail server to be able to send invite emails from - # ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer - # documentation for available options: - # - # http://www.nodemailer.com/docs/transports - # - # email: - # fromAddress: "" - # replyTo: "" - # transport: "SES" - # parameters: - # AWSAccessKeyID: "" - # AWSSecretKey: "" - - # Spell Check Languages - # --------------------- - # - # You must have the corresponding aspell dictionary installed to - # be able to use a language. Run `grunt check:aspell` to check which - # dictionaries you have installed. These should be set for the `code` for - # each language. - languages: [ - {name: "English", code: "en"} - ] - - # Service locations - # ----------------- - - # ShareLaTeX is comprised of many small services, which each expose - # an HTTP API running on a different port. Generally you - # can leave these as they are unless you have some other services - # running which conflict, or want to run the web process on port 80. - #internal: - # web: - # port: webPort = 3000 - # host: "localhost" - # documentupdater: - # port: docUpdaterPort = 3003 - # host: "localhost" - # filestore: - # port: filestorePort = 3009 - # host: "localhost" - # chat: - # port: chatPort = 3010 - # host: "localhost" - # tags: - # port: tagsPort = 3012 - # host: "localhost" - # clsi: - # port: clsiPort = 3013 - # host: "localhost" - # trackchanges: - # port: trackchangesPort = 3015 - # host: "localhost" - # docstore: - # port: docstorePort = 3016 - # host: "localhost" - # spelling: - # port: spellingPort = 3005 - # host: "localhost" - # realTime: - # port: realTimeport = 3026 - # host: "localhost" - - # If you change the above config, or run some services on remote servers, - # you need to tell the other services where to find them: - apis: - web: - url: "http://localhost:3000" - user: httpAuthUser - pass: httpAuthPass - # documentupdater: - # url : "http://localhost:#{docUpdaterPort}" - # clsi: - # url: "http://localhost:#{clsiPort}" - # filestore: - # url: "http://localhost:#{filestorePort}" - # trackchanges: - # url: "http://localhost:#{trackchangesPort}" - # docstore: - # url: "http://localhost:#{docstorePort}" - # tags: - # url: "http://localhost:#{tagsPort}" - # spelling: - # url: "http://localhost:#{spellingPort}" - # chat: - # url: "http://localhost:#{chatPort}" - - -# With lots of incoming and outgoing HTTP connections to different services, -# sometimes long running, it is a good idea to increase the default number -# of sockets that Node will hold open. -http = require('http') -http.globalAgent.maxSockets = 300 -https = require('https') -https.globalAgent.maxSockets = 300 diff --git a/server-ce/package/nginx/sharelatex.conf b/server-ce/package/nginx/sharelatex.conf deleted file mode 100644 index 0e4fbd1c87..0000000000 --- a/server-ce/package/nginx/sharelatex.conf +++ /dev/null @@ -1,44 +0,0 @@ -server { - listen 80; - server_name _; # Catch all, see http://nginx.org/en/docs/http/server_names.html - - set $static_path /var/www/sharelatex/web/public; - - location / { - proxy_pass http://localhost:3000; - proxy_set_header Host $http_x_forwarded_host; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_read_timeout 3m; - proxy_send_timeout 3m; - } - - location /socket.io { - proxy_pass http://localhost:3026; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Host $http_x_forwarded_host; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_read_timeout 3m; - proxy_send_timeout 3m; - } - - location /stylesheets { - expires 1y; - root $static_path/; - } - - location /minjs { - expires 1y; - root $static_path/; - } - - location /img { - expires 1y; - root $static_path/; - } -} diff --git a/server-ce/package/upstart/sharelatex-chat.conf b/server-ce/package/upstart/sharelatex-chat.conf deleted file mode 100644 index c9abcf64d0..0000000000 --- a/server-ce/package/upstart/sharelatex-chat.conf +++ /dev/null @@ -1,28 +0,0 @@ -description "sharelatex-web" -author "ShareLaTeX " - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on shutdown - -respawn - -limit nofile 8192 8192 - -pre-start script - mkdir -p /var/log/sharelatex -end script - -script - SERVICE=chat - USER=sharelatex - GROUP=sharelatex - # You may need to replace this with an absolute - # path to Node.js if it's not in your system PATH. - NODE=node - SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux - - echo $$ > /var/run/sharelatex-$SERVICE.pid - cd /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-clsi.conf b/server-ce/package/upstart/sharelatex-clsi.conf deleted file mode 100644 index 577392a124..0000000000 --- a/server-ce/package/upstart/sharelatex-clsi.conf +++ /dev/null @@ -1,28 +0,0 @@ -description "sharelatex-web" -author "ShareLaTeX " - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on shutdown - -respawn - -limit nofile 8192 8192 - -pre-start script - mkdir -p /var/log/sharelatex -end script - -script - SERVICE=clsi - USER=sharelatex - GROUP=sharelatex - # You may need to replace this with an absolute - # path to Node.js if it's not in your system PATH. - NODE=node - SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux - - echo $$ > /var/run/sharelatex-$SERVICE.pid - cd /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-docstore.conf b/server-ce/package/upstart/sharelatex-docstore.conf deleted file mode 100644 index 4a93d74afb..0000000000 --- a/server-ce/package/upstart/sharelatex-docstore.conf +++ /dev/null @@ -1,28 +0,0 @@ -description "sharelatex-web" -author "ShareLaTeX " - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on shutdown - -respawn - -limit nofile 8192 8192 - -pre-start script - mkdir -p /var/log/sharelatex -end script - -script - SERVICE=docstore - USER=sharelatex - GROUP=sharelatex - # You may need to replace this with an absolute - # path to Node.js if it's not in your system PATH. - NODE=node - SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux - - echo $$ > /var/run/sharelatex-$SERVICE.pid - cd /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-document-updater.conf b/server-ce/package/upstart/sharelatex-document-updater.conf deleted file mode 100644 index 3cd58e3661..0000000000 --- a/server-ce/package/upstart/sharelatex-document-updater.conf +++ /dev/null @@ -1,28 +0,0 @@ -description "sharelatex-web" -author "ShareLaTeX " - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on shutdown - -respawn - -limit nofile 8192 8192 - -pre-start script - mkdir -p /var/log/sharelatex -end script - -script - SERVICE=document-updater - USER=sharelatex - GROUP=sharelatex - # You may need to replace this with an absolute - # path to Node.js if it's not in your system PATH. - NODE=node - SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux - - echo $$ > /var/run/sharelatex-$SERVICE.pid - cd /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-filestore.conf b/server-ce/package/upstart/sharelatex-filestore.conf deleted file mode 100644 index 2cefd29ce5..0000000000 --- a/server-ce/package/upstart/sharelatex-filestore.conf +++ /dev/null @@ -1,28 +0,0 @@ -description "sharelatex-web" -author "ShareLaTeX " - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on shutdown - -respawn - -limit nofile 8192 8192 - -pre-start script - mkdir -p /var/log/sharelatex -end script - -script - SERVICE=filestore - USER=sharelatex - GROUP=sharelatex - # You may need to replace this with an absolute - # path to Node.js if it's not in your system PATH. - NODE=node - SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux - - echo $$ > /var/run/sharelatex-$SERVICE.pid - cd /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-real-time.conf b/server-ce/package/upstart/sharelatex-real-time.conf deleted file mode 100644 index df199c2d9f..0000000000 --- a/server-ce/package/upstart/sharelatex-real-time.conf +++ /dev/null @@ -1,28 +0,0 @@ -description "sharelatex-web" -author "ShareLaTeX " - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on shutdown - -respawn - -limit nofile 8192 8192 - -pre-start script - mkdir -p /var/log/sharelatex -end script - -script - SERVICE=real-time - USER=sharelatex - GROUP=sharelatex - # You may need to replace this with an absolute - # path to Node.js if it's not in your system PATH. - NODE=node - SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux - - echo $$ > /var/run/sharelatex-$SERVICE.pid - cd /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-spelling.conf b/server-ce/package/upstart/sharelatex-spelling.conf deleted file mode 100644 index cdad8b20ea..0000000000 --- a/server-ce/package/upstart/sharelatex-spelling.conf +++ /dev/null @@ -1,28 +0,0 @@ -description "sharelatex-web" -author "ShareLaTeX " - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on shutdown - -respawn - -limit nofile 8192 8192 - -pre-start script - mkdir -p /var/log/sharelatex -end script - -script - SERVICE=spelling - USER=sharelatex - GROUP=sharelatex - # You may need to replace this with an absolute - # path to Node.js if it's not in your system PATH. - NODE=node - SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux - - echo $$ > /var/run/sharelatex-$SERVICE.pid - cd /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-tags.conf b/server-ce/package/upstart/sharelatex-tags.conf deleted file mode 100644 index 340bad2748..0000000000 --- a/server-ce/package/upstart/sharelatex-tags.conf +++ /dev/null @@ -1,28 +0,0 @@ -description "sharelatex-web" -author "ShareLaTeX " - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on shutdown - -respawn - -limit nofile 8192 8192 - -pre-start script - mkdir -p /var/log/sharelatex -end script - -script - SERVICE=tags - USER=sharelatex - GROUP=sharelatex - # You may need to replace this with an absolute - # path to Node.js if it's not in your system PATH. - NODE=node - SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux - - echo $$ > /var/run/sharelatex-$SERVICE.pid - cd /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-template.conf b/server-ce/package/upstart/sharelatex-template.conf deleted file mode 100644 index e9b58d9838..0000000000 --- a/server-ce/package/upstart/sharelatex-template.conf +++ /dev/null @@ -1,28 +0,0 @@ -description "sharelatex-web" -author "ShareLaTeX " - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on shutdown - -respawn - -limit nofile 8192 8192 - -pre-start script - mkdir -p /var/log/sharelatex -end script - -script - SERVICE=__SERVICE__ - USER=sharelatex - GROUP=sharelatex - # You may need to replace this with an absolute - # path to Node.js if it's not in your system PATH. - NODE=node - SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux - - echo $$ > /var/run/sharelatex-$SERVICE.pid - cd /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-track-changes.conf b/server-ce/package/upstart/sharelatex-track-changes.conf deleted file mode 100644 index 95c9f57b4c..0000000000 --- a/server-ce/package/upstart/sharelatex-track-changes.conf +++ /dev/null @@ -1,28 +0,0 @@ -description "sharelatex-web" -author "ShareLaTeX " - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on shutdown - -respawn - -limit nofile 8192 8192 - -pre-start script - mkdir -p /var/log/sharelatex -end script - -script - SERVICE=track-changes - USER=sharelatex - GROUP=sharelatex - # You may need to replace this with an absolute - # path to Node.js if it's not in your system PATH. - NODE=node - SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux - - echo $$ > /var/run/sharelatex-$SERVICE.pid - cd /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script \ No newline at end of file diff --git a/server-ce/package/upstart/sharelatex-web.conf b/server-ce/package/upstart/sharelatex-web.conf deleted file mode 100644 index 92cbf0cb0b..0000000000 --- a/server-ce/package/upstart/sharelatex-web.conf +++ /dev/null @@ -1,28 +0,0 @@ -description "sharelatex-web" -author "ShareLaTeX " - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on shutdown - -respawn - -limit nofile 8192 8192 - -pre-start script - mkdir -p /var/log/sharelatex -end script - -script - SERVICE=web - USER=sharelatex - GROUP=sharelatex - # You may need to replace this with an absolute - # path to Node.js if it's not in your system PATH. - NODE=node - SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - LATEX_PATH=/usr/local/texlive/2014/bin/x86_64-linux - - echo $$ > /var/run/sharelatex-$SERVICE.pid - cd /var/www/sharelatex/$SERVICE - exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1 -end script \ No newline at end of file From dad3a74a7f2bf10f17d1ffd80c90ce5261290894 Mon Sep 17 00:00:00 2001 From: ShareLaTeX Date: Thu, 9 Jun 2016 11:36:00 +0000 Subject: [PATCH 211/525] add grunt cut task --- server-ce/.gitignore | 1 + server-ce/Gruntfile.coffee | 7 +++++++ server-ce/package.json | 5 +++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/server-ce/.gitignore b/server-ce/.gitignore index 84b9efb392..023b43469e 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -1,2 +1,3 @@ node_modules/ api-data +versions/ diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index fad7fc82da..502fc13c36 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -3,6 +3,7 @@ services = require('./services') module.exports = (grunt) -> tag = grunt.option("tag") or 'latest' + to = grunt.option("to") or 'latest' repos = [] for service in services url = service.repo.split('/') @@ -29,10 +30,16 @@ module.exports = (grunt) -> src: repos dest: 'versions/' + tag + '.json' + rename: + main: + files: [{ src: ['versions/latest.json'], dest: 'versions/' + to + '.json'}] + grunt.loadNpmTasks 'grunt-docker-io' grunt.loadNpmTasks 'grunt-github-api' + grunt.loadNpmTasks 'grunt-contrib-rename' grunt.registerTask 'build', ['docker_io', 'github'] grunt.registerTask 'gitrev', ['github'] + grunt.registerTask 'cut', ['rename'] grunt.registerTask 'default', ['build'] diff --git a/server-ce/package.json b/server-ce/package.json index 329169d96d..e1efb9b159 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -4,8 +4,9 @@ "description": "none", "dependencies": { "grunt": "^0.4.5", + "grunt-contrib-rename": "0.0.3", "grunt-docker-io": "^0.7.0", - "simple-git": "^1.32.1", - "grunt-github-api": "^0.2.3" + "grunt-github-api": "^0.2.3", + "simple-git": "^1.32.1" } } From a40360feafe6483b9592c7d2c80999065a6ccc9a Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 9 Jun 2016 16:21:54 +0100 Subject: [PATCH 212/525] allow header and footer to be configured via env vars --- server-ce/settings.coffee | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 55c964012b..1f782a68c6 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -136,6 +136,14 @@ settings = # address and http/https protocol information. behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] or false + if process.env["SHARELATEX_LEFT_FOOTER"] + left_footer: process.env["SHARELATEX_LEFT_FOOTER"] + + if process.env["SHARELATEX_RIGHT_FOOTER"] + right_footer: process.env["SHARELATEX_RIGHT_FOOTER"] + + if process.env["SHARELATEX_HEADER"] + header: process.env["SHARELATEX_HEADER"] # Spell Check Languages # --------------------- From 342ab43c6b09a19dcaaff19ad1b6f10c5644fbaf Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 9 Jun 2016 16:22:27 +0100 Subject: [PATCH 213/525] point to texlive 2016 --- server-ce/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index d7ca93d357..097de9a123 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -88,7 +88,7 @@ ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf RUN rm -r /install-tl-unx; \ rm install-tl-unx.tar.gz -ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2015/bin/x86_64-linux/ +ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2016/bin/x86_64-linux/ RUN apt-get update RUN tlmgr install latexmk From 7d5382f66885dd286fc0aba42cd746b6afd994b0 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 9 Jun 2016 16:43:18 +0100 Subject: [PATCH 214/525] don't instal config with grunt --- server-ce/Gruntfile.coffee | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 9ed6ff9275..f65d28c893 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -264,19 +264,6 @@ module.exports = (grunt) -> exec "mkdir -p #{path}", callback async.series jobs, callback - installConfig: (callback = (error) ->) -> - src = "config/settings.development.coffee.example" - dest = "config/settings.development.coffee" - if !fs.existsSync(dest) - grunt.log.writeln "Creating config at #{dest}" - config = fs.readFileSync(src).toString() - config = config.replace /CRYPTO_RANDOM/g, () -> - crypto.randomBytes(64).toString("hex") - fs.writeFileSync dest, config - callback() - else - grunt.log.writeln "Config file already exists. Skipping." - callback() runGruntInstall: (service, callback = (error) ->) -> dir = service.name From 240280a0aefbf28373a493e0cbb9fa774d07a809 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 9 Jun 2016 16:59:57 +0100 Subject: [PATCH 215/525] get rid of config commands --- server-ce/Gruntfile.coffee | 42 +++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index f65d28c893..01a31e5370 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -51,7 +51,6 @@ SERVICES = [{ repo: "https://github.com/sharelatex/spelling-sharelatex.git" version: "master" }] - module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-bunyan' grunt.loadNpmTasks 'grunt-execute' @@ -76,7 +75,7 @@ module.exports = (grunt) -> limit: SERVICES.length logConcurrentOutput: true coffee: - migrate: + migrate: expand: true, flatten: false, cwd: './', @@ -109,9 +108,8 @@ module.exports = (grunt) -> "Misc": [ "help" ] - "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install", "install:dirs", "install:config"]) + "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install", "install:dirs"]) "Update tasks": ("update:#{service.name}" for service in SERVICES).concat(["update:all", "update"]) - "Config tasks": ["install:config"] "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make"] for service in SERVICES @@ -127,14 +125,13 @@ module.exports = (grunt) -> done = @async() Helpers.createNewRelease(service, grunt.option("release"), done) - grunt.registerTask 'install:config', "Copy the example config into the real config", () -> - Helpers.installConfig @async() + grunt.registerTask 'install:dirs', "Copy the example config into the real config", () -> Helpers.createDataDirs @async() grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", ["check:make"].concat( ("install:#{service.name}" for service in SERVICES) - ).concat(["install:config", "install:dirs"]) + ).concat([ "install:dirs"]) grunt.registerTask 'install', 'install:all' grunt.registerTask 'update:all', "Checkout and update all ShareLaTeX services", ["check:make"].concat( @@ -214,7 +211,7 @@ module.exports = (grunt) -> proc = spawn "git", ["pull"], cwd: dir, stdio: "inherit" proc.on "close", () -> callback() - + createNewRelease: (service, version, callback = (error) ->) -> dir = service.name proc = spawn "sed", [ @@ -307,9 +304,9 @@ module.exports = (grunt) -> latexmk comes with TexLive 2013, and must be a version from 2013 or later. If you have already have TeXLive installed, then make sure it is included in your PATH (example for 64-bit linux): - + export PATH=$PATH:/usr/local/texlive/2014/bin/x86_64-linux/ - + This is a not a fatal error, but compiling will not work without latexmk. """ return callback(error) @@ -334,7 +331,7 @@ module.exports = (grunt) -> """ error = new Error("latexmk is too old") callback(error) - + checkAspell: (callback = (error) ->) -> grunt.log.write "Checking aspell is installed... " exec "aspell dump dicts", (error, stdout, stderr) -> @@ -342,15 +339,15 @@ module.exports = (grunt) -> grunt.log.error "FAIL." grunt.log.errorlns """ Either aspell is not installed or is not in your PATH. - + On Ubuntu you can install aspell with: - + sudo apt-get install aspell - + Or on a mac: - + brew install aspell - + This is not a fatal error, but the spell-checker will not work without aspell """ return callback(error) @@ -382,11 +379,11 @@ module.exports = (grunt) -> Please configure your Amazon S3 credentials in config/settings.development.coffee Amazon S3 (Simple Storage Service) is a cloud storage service provided by - Amazon. ShareLaTeX uses S3 for storing binary files like images. You can + Amazon. ShareLaTeX uses S3 for storing binary files like images. You can sign up for an account and find out more at: http://aws.amazon.com/s3/ - + """ return callback() client.getFile "does-not-exist", (error, response) -> @@ -413,7 +410,7 @@ module.exports = (grunt) -> else grunt.log.error "FAIL." grunt.log.errorlns """ - Could not find directory "#{Settings.filestore.stores.user_files}". + Could not find directory "#{Settings.filestore.stores.user_files}". Please check your configuration. """ callback() @@ -428,11 +425,11 @@ module.exports = (grunt) -> grunt.log.error "FAIL." grunt.log.errorlns """ Either make is not installed or is not in your path. - + On Ubuntu you can install make with: - + sudo apt-get install build-essential - + """ return callback(error) else if error? @@ -445,4 +442,3 @@ module.exports = (grunt) -> template = fs.readFileSync("package/upstart/sharelatex-template.conf").toString() for service in SERVICES fs.writeFileSync "package/upstart/sharelatex-#{service.name}.conf", template.replace(/__SERVICE__/g, service.name) - From 1519329dac84a21a530ac4f14f0e05971cafdbb5 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 9 Jun 2016 18:29:27 +0100 Subject: [PATCH 216/525] move left_footer and co to bottom of settings file --- server-ce/settings.coffee | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 1f782a68c6..0b0242e7fb 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -134,17 +134,9 @@ settings = # If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) # then set this to true to allow it to correctly detect the forwarded IP # address and http/https protocol information. + behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] or false - if process.env["SHARELATEX_LEFT_FOOTER"] - left_footer: process.env["SHARELATEX_LEFT_FOOTER"] - - if process.env["SHARELATEX_RIGHT_FOOTER"] - right_footer: process.env["SHARELATEX_RIGHT_FOOTER"] - - if process.env["SHARELATEX_HEADER"] - header: process.env["SHARELATEX_HEADER"] - # Spell Check Languages # --------------------- # @@ -419,6 +411,16 @@ settings = #### OPTIONAL CONFIGERABLE SETTINGS +if process.env["SHARELATEX_LEFT_FOOTER"]? + settings.left_footer = process.env["SHARELATEX_LEFT_FOOTER"] + +if process.env["SHARELATEX_RIGHT_FOOTER"]? + settings.right_footer = process.env["SHARELATEX_RIGHT_FOOTER"] + +if process.env["SHARELATEX_HEADER"]? + settingsheader = process.env["SHARELATEX_HEADER"] + + # Sending Email # ------------- # From 8b8dbb588c4670dcb5817de75800024ca62830f3 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 15 Jun 2016 17:08:21 +0100 Subject: [PATCH 217/525] remove grunfile and circule.yml file, consolodate in server pro --- server-ce/Gruntfile.coffee | 45 -------------------------------------- server-ce/README.md | 6 +---- server-ce/circle.yml | 13 ----------- 3 files changed, 1 insertion(+), 63 deletions(-) delete mode 100644 server-ce/Gruntfile.coffee delete mode 100644 server-ce/circle.yml diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee deleted file mode 100644 index 502fc13c36..0000000000 --- a/server-ce/Gruntfile.coffee +++ /dev/null @@ -1,45 +0,0 @@ -services = require('./services') - -module.exports = (grunt) -> - - tag = grunt.option("tag") or 'latest' - to = grunt.option("to") or 'latest' - repos = [] - for service in services - url = service.repo.split('/') - owner = url[3] - repo = url[4].replace('.git','') - repos.push "/repos/#{owner}/#{repo}/git/refs/heads/#{service.version}" - - grunt.initConfig - docker_io: - default_options: - options: - dockerFileLocation: '.' - buildName: 'sharelatex' - tag: grunt.option('tag') or 'latest' - push: grunt.option('push') or false - force: true - - github: - combinedRevisions: - options: - #oAuth: - # access_token: '' - concat: true - src: repos - dest: 'versions/' + tag + '.json' - - rename: - main: - files: [{ src: ['versions/latest.json'], dest: 'versions/' + to + '.json'}] - - grunt.loadNpmTasks 'grunt-docker-io' - grunt.loadNpmTasks 'grunt-github-api' - grunt.loadNpmTasks 'grunt-contrib-rename' - - grunt.registerTask 'build', ['docker_io', 'github'] - grunt.registerTask 'gitrev', ['github'] - grunt.registerTask 'cut', ['rename'] - - grunt.registerTask 'default', ['build'] diff --git a/server-ce/README.md b/server-ce/README.md index 04a117bcb7..8e5cd84b8e 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,6 +1,2 @@ ## Install -Please see the [offical wiki for install guides](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) - -## Building image - -The docker files can be built with grunt. We do this as there are some other tasks which are done using grunt such as marking the versions of each repo used. +Please see the [offical wiki for install guides](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) \ No newline at end of file diff --git a/server-ce/circle.yml b/server-ce/circle.yml deleted file mode 100644 index 6df3bd992e..0000000000 --- a/server-ce/circle.yml +++ /dev/null @@ -1,13 +0,0 @@ -# circle.yml -machine: - services: - - docker - -dependencies: - pre: - - grunt - -test: - post: - - docker run -d -v --name=sharelatex -p 5000:80 -; sleep 20 - - curl --retry 10 --retry-delay 5 -v http://localhost:5000/status From e4cb26b58997f97fc57098e4ccafeb5ac1500a9b Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 15 Jun 2016 17:08:48 +0100 Subject: [PATCH 218/525] fix spelling mistake with community --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 0b0242e7fb..e5b775e298 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -101,7 +101,7 @@ settings = nav: - title: process.env["SHARELATEX_NAV_TITLE"] or process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX Comunity Edition" + title: process.env["SHARELATEX_NAV_TITLE"] or process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX Community Edition" # The email address which users will be directed to as the main point of From ce9659a43b00cdd36ae756fe7cc453a7c30c98af Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 17 Jun 2016 12:34:38 +0100 Subject: [PATCH 219/525] settings.header ! settingsheader --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index e5b775e298..e813342ebd 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -418,7 +418,7 @@ if process.env["SHARELATEX_RIGHT_FOOTER"]? settings.right_footer = process.env["SHARELATEX_RIGHT_FOOTER"] if process.env["SHARELATEX_HEADER"]? - settingsheader = process.env["SHARELATEX_HEADER"] + settings.header = process.env["SHARELATEX_HEADER"] # Sending Email From 19179086f0926886ad4521648cfb5a4dfb681c7c Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 17 Jun 2016 13:05:03 +0100 Subject: [PATCH 220/525] parse left and right footers as json --- server-ce/settings.coffee | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index e813342ebd..9e81e644a1 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -410,15 +410,22 @@ settings = #### OPTIONAL CONFIGERABLE SETTINGS - if process.env["SHARELATEX_LEFT_FOOTER"]? - settings.left_footer = process.env["SHARELATEX_LEFT_FOOTER"] + try + settings.nav.left_footer = JSON.parse(process.env["SHARELATEX_LEFT_FOOTER"]) + catch e + console.error("could not parse SHARELATEX_LEFT_FOOTER, not valid JSON") if process.env["SHARELATEX_RIGHT_FOOTER"]? - settings.right_footer = process.env["SHARELATEX_RIGHT_FOOTER"] + settings.nav.right_footer = process.env["SHARELATEX_RIGHT_FOOTER"] + try + settings.nav.right_footer = JSON.parse(process.env["SHARELATEX_RIGHT_FOOTER"]) + catch e + console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON") + if process.env["SHARELATEX_HEADER"]? - settings.header = process.env["SHARELATEX_HEADER"] + settings.nav.header = process.env["SHARELATEX_HEADER"] # Sending Email From 3061c5d41a387a08b0b022f60c4f9f037e0257fd Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 22 Jun 2016 11:47:17 +0100 Subject: [PATCH 221/525] parse ca paths as json --- server-ce/settings.coffee | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 9e81e644a1..bfcf232267 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -422,7 +422,12 @@ if process.env["SHARELATEX_RIGHT_FOOTER"]? settings.nav.right_footer = JSON.parse(process.env["SHARELATEX_RIGHT_FOOTER"]) catch e console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON") - + +if process.env["SHARELATEX_HEADER_IMAGE_URL"]? + settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"] + +settings.nav.custom_logo = "http://www.bbc.co.uk/news/special/2015/newsspec_10857/bbc_news_logo.png" + if process.env["SHARELATEX_HEADER"]? settings.nav.header = process.env["SHARELATEX_HEADER"] @@ -501,9 +506,21 @@ if process.env["SHARELATEX_LDAP_HOST"] lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"] if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] + try + ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]) + catch e + console.error "could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON" + + if typeof(ca) == 'string' + ca_paths = [ca] + else if typeof(ca) == 'object' && ca.length? + ca_paths = ca + else + console.error "problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH" + settings.ldap.tlsOptions = rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true" - ca: process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] # e.g.'/etc/ldap/ca_certs.pem' + ca:ca_paths # e.g.'/etc/ldap/ca_certs.pem' # Compiler # -------- From ba493c73224d8facf635f55f5a7c838a4c0f9f1e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 22 Jun 2016 11:56:29 +0100 Subject: [PATCH 222/525] remove debugging line --- server-ce/settings.coffee | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index bfcf232267..b610bad137 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -426,9 +426,6 @@ if process.env["SHARELATEX_RIGHT_FOOTER"]? if process.env["SHARELATEX_HEADER_IMAGE_URL"]? settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"] -settings.nav.custom_logo = "http://www.bbc.co.uk/news/special/2015/newsspec_10857/bbc_news_logo.png" - - if process.env["SHARELATEX_HEADER"]? settings.nav.header = process.env["SHARELATEX_HEADER"] @@ -510,7 +507,7 @@ if process.env["SHARELATEX_LDAP_HOST"] ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]) catch e console.error "could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON" - + if typeof(ca) == 'string' ca_paths = [ca] else if typeof(ca) == 'object' && ca.length? From 88246ebd8e6a4669e29e41c4f2c3afb4a13ebbaa Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 23 Jun 2016 16:47:56 +0100 Subject: [PATCH 223/525] set smtp auth to null if not set --- server-ce/settings.coffee | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index b610bad137..a5c590edab 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -454,9 +454,11 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] host: process.env["SHARELATEX_EMAIL_SMTP_HOST"] port: process.env["SHARELATEX_EMAIL_SMTP_PORT"], secure: process.env["SHARELATEX_EMAIL_SMTP_SECURE"] - auth: - user: process.env["SHARELATEX_EMAIL_SMTP_USER"] - pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"] + +if process.env["SHARELATEX_EMAIL_SMTP_USER"] or process.env["SHARELATEX_EMAIL_SMTP_PASS"] + settings.email.parameters.auth = + user: process.env["SHARELATEX_EMAIL_SMTP_USER"] + pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"] # Password Settings From 11fd4bd479424266eeea51d56a4297351014d1ed Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 23 Jun 2016 16:48:05 +0100 Subject: [PATCH 224/525] set references to undefined so its not used yet --- server-ce/settings.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index a5c590edab..5fb1050505 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -388,6 +388,7 @@ settings = url: "http://localhost:3000" user: httpAuthUser pass: httpAuthPass + references:undefined # documentupdater: # url : "http://localhost:#{docUpdaterPort}" # clsi: From 62eddf8982d9d1c50ed74b2c365e2fb7bcc73564 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 23 Jun 2016 17:13:12 +0100 Subject: [PATCH 225/525] checkout the correct version --- server-ce/Gruntfile.coffee | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 01a31e5370..1d3957f16f 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -132,7 +132,9 @@ module.exports = (grunt) -> ["check:make"].concat( ("install:#{service.name}" for service in SERVICES) ).concat([ "install:dirs"]) + grunt.registerTask 'install', 'install:all' + grunt.registerTask 'update:all', "Checkout and update all ShareLaTeX services", ["check:make"].concat( ("update:#{service.name}" for service in SERVICES) @@ -194,16 +196,21 @@ module.exports = (grunt) -> if !fs.existsSync(dir) proc = spawn "git", [ "clone", - "-b", service.version, repo_src, dir ], stdio: "inherit" proc.on "close", () -> - callback() + Helpers.checkoutVersion service, callback else console.log "#{dir} already installed, skipping." callback() + checkoutVersion: (service, callback = (error) ->) -> + dir = service.name + proc = spawn "git", ["checkout", service.version], stdio: "inherit", cwd: dir + proc.on "close", () -> + callback() + updateGitRepo: (service, callback = (error) ->) -> dir = service.name proc = spawn "git", ["checkout", service.version], cwd: dir, stdio: "inherit" From 49eb1c6ac4d4b9902ea2f1697f4858fe73406c3d Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 23 Jun 2016 20:47:44 +0100 Subject: [PATCH 226/525] don't clone via branch --- server-ce/Gruntfile.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 8083450ab6..90408abd23 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -155,7 +155,6 @@ module.exports = (grunt) -> if !fs.existsSync(dir) proc = spawn "git", [ "clone", - "-b", service.version, repo_src, dir ], stdio: "inherit" From 3d116334e04cefe085e274992873a9cb8ec3d7c4 Mon Sep 17 00:00:00 2001 From: ShareLaTeX Date: Thu, 23 Jun 2016 22:07:30 +0000 Subject: [PATCH 227/525] touch sqlite file if it does not exist --- server-ce/init_scripts/00_make_sharelatex_data_dirs.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh index f48a95fde7..6269f1b2a9 100755 --- a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh +++ b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh @@ -20,5 +20,8 @@ chown www-data:www-data /var/lib/sharelatex/tmp/uploads mkdir -p /var/lib/sharelatex/tmp/dumpFolder chown www-data:www-data /var/lib/sharelatex/tmp/dumpFolder +if [ ! -e "/var/lib/sharelatex/data/db.sqlite" ]; then + touch /var/lib/sharelatex/data/db.sqlite +fi -chown www-data:www-data /var/lib/sharelatex/data/db.sqlite \ No newline at end of file +chown www-data:www-data /var/lib/sharelatex/data/db.sqlite From 330fe90a9a12be46217c8df9ce6ea813c2ad0382 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 24 Jun 2016 14:06:50 +0100 Subject: [PATCH 228/525] don't call notifications --- server-ce/settings.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 5fb1050505..94fd2939b4 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -389,6 +389,8 @@ settings = user: httpAuthUser pass: httpAuthPass references:undefined + notifications:undefined + # documentupdater: # url : "http://localhost:#{docUpdaterPort}" # clsi: From 4a81192f709115138a1f6e60256a275183e83826 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 27 Jun 2016 14:50:46 +0100 Subject: [PATCH 229/525] added SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH and SHARELATEX_EMAIL_SMTP_IGNORE_TLS --- server-ce/settings.coffee | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 94fd2939b4..c7e9d1e873 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -443,7 +443,7 @@ if process.env["SHARELATEX_HEADER"]? # http://www.nodemailer.com/docs/transports -if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] +if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? settings.email = fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] @@ -457,12 +457,16 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] host: process.env["SHARELATEX_EMAIL_SMTP_HOST"] port: process.env["SHARELATEX_EMAIL_SMTP_PORT"], secure: process.env["SHARELATEX_EMAIL_SMTP_SECURE"] + ignoreTLS: process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"] -if process.env["SHARELATEX_EMAIL_SMTP_USER"] or process.env["SHARELATEX_EMAIL_SMTP_PASS"] +if process.env["SHARELATEX_EMAIL_SMTP_USER"]? or process.env["SHARELATEX_EMAIL_SMTP_PASS"]? settings.email.parameters.auth = - user: process.env["SHARELATEX_EMAIL_SMTP_USER"] - pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"] + user: process.env["SHARELATEX_EMAIL_SMTP_USER"] + pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"] +if process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]? + settings.email.parameters.tls = + rejectUnauthorized: process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"] # Password Settings # ----------- From 926e6fee41cc4a7de230a243ea51b01fdd4d578c Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 27 Jun 2016 15:19:43 +0100 Subject: [PATCH 230/525] don't try and put properties on email if basic email is not configured --- server-ce/settings.coffee | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index c7e9d1e873..fe4b9303a1 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -459,14 +459,14 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? secure: process.env["SHARELATEX_EMAIL_SMTP_SECURE"] ignoreTLS: process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"] -if process.env["SHARELATEX_EMAIL_SMTP_USER"]? or process.env["SHARELATEX_EMAIL_SMTP_PASS"]? - settings.email.parameters.auth = - user: process.env["SHARELATEX_EMAIL_SMTP_USER"] - pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"] + if process.env["SHARELATEX_EMAIL_SMTP_USER"]? or process.env["SHARELATEX_EMAIL_SMTP_PASS"]? + settings.email.parameters.auth = + user: process.env["SHARELATEX_EMAIL_SMTP_USER"] + pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"] -if process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]? - settings.email.parameters.tls = - rejectUnauthorized: process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"] + if process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]? + settings.email.parameters.tls = + rejectUnauthorized: process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"] # Password Settings # ----------- From 5786162e0934ab252886fc05b42e33256260212e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 28 Jun 2016 10:07:50 +0100 Subject: [PATCH 231/525] added learn wiki option and parse helper method --- server-ce/settings.coffee | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index fe4b9303a1..b396d37f66 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -7,6 +7,16 @@ httpAuthPass = "CRYPTO_RANDOM" # Randomly generated for you httpAuthUsers = {} httpAuthUsers[httpAuthUser] = httpAuthPass +parse = (option)-> + if option? + try + opt = JSON.parse(option) + return opt + catch err + console.error "problem parsing #{option}, invalid JSON" + return undefined + + DATA_DIR = '/var/lib/sharelatex/data' TMP_DIR = '/var/lib/sharelatex/tmp' @@ -456,9 +466,9 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? #SMTP Creds host: process.env["SHARELATEX_EMAIL_SMTP_HOST"] port: process.env["SHARELATEX_EMAIL_SMTP_PORT"], - secure: process.env["SHARELATEX_EMAIL_SMTP_SECURE"] - ignoreTLS: process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"] - + secure: parse(process.env["SHARELATEX_EMAIL_SMTP_SECURE"]) + ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"]) + if process.env["SHARELATEX_EMAIL_SMTP_USER"]? or process.env["SHARELATEX_EMAIL_SMTP_PASS"]? settings.email.parameters.auth = user: process.env["SHARELATEX_EMAIL_SMTP_USER"] @@ -466,7 +476,7 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? if process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]? settings.email.parameters.tls = - rejectUnauthorized: process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"] + rejectUnauthorized: parse(process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]) # Password Settings # ----------- @@ -504,10 +514,10 @@ if process.env["SHARELATEX_LDAP_HOST"] fieldName: process.env["SHARELATEX_LDAP_FIELD_NAME"] or 'LDAP User' placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"] or 'LDAP User ID' emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"] or 'mail' - anonymous: process.env["SHARELATEX_LDAP_ANONYMOUS"] == "true" + anonymous: parse(process.env["SHARELATEX_LDAP_ANONYMOUS"]) adminDN: process.env["SHARELATEX_LDAP_ADMIN_DN"] adminPW: process.env["SHARELATEX_LDAP_ADMIN_PW"] - starttls: process.env["SHARELATEX_LDAP_TLS"] == "true" + starttls: parse(process.env["SHARELATEX_LDAP_TLS"]) nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"] lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"] @@ -552,6 +562,10 @@ if process.env["SHARELATEX_TEMPLATES_USER_ID"] user_id: process.env["SHARELATEX_TEMPLATES_USER_ID"] +# /Learn +# ------- +if process.env["SHARELATEX_PROXY_LEARN"]? + settings.proxyLearn = parse(process.env["SHARELATEX_PROXY_LEARN"]) From d58ebb2dd488c13a36275267cd4718926284e75f Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 28 Jun 2016 17:08:00 +0100 Subject: [PATCH 232/525] added custom footer for email option --- server-ce/settings.coffee | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index b396d37f66..e2f25ad934 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -469,6 +469,10 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? secure: parse(process.env["SHARELATEX_EMAIL_SMTP_SECURE"]) ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"]) + + templates: + customFooter: process.env["SHARELATEX_CUSTOM_EMAIL_FOOTER"] + if process.env["SHARELATEX_EMAIL_SMTP_USER"]? or process.env["SHARELATEX_EMAIL_SMTP_PASS"]? settings.email.parameters.auth = user: process.env["SHARELATEX_EMAIL_SMTP_USER"] @@ -477,6 +481,7 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? if process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]? settings.email.parameters.tls = rejectUnauthorized: parse(process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]) + # Password Settings # ----------- From 5bc0e529d5fd81e199d2e785da3ef61203c87ba9 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 30 Jun 2016 14:52:45 +0100 Subject: [PATCH 233/525] upgrade east and check for null ids --- server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee | 1 + server-ce/migrations/2_doc_lines_delete_from_project.coffee | 1 + server-ce/package.json | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee b/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee index d1f94638b3..8712cf9f54 100644 --- a/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee +++ b/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee @@ -26,6 +26,7 @@ loadProjectIds = (callback)-> console.log "loading project ids from #{all_projects_path}" fs.readFile all_projects_path, "utf-8", (err, data)-> ids = data.split("\n") + ids = _.filter ids, (id)-> id? and id.length == 24 console.log "loaded #{ids.length} project ids from #{all_projects_path}" callback err, ids diff --git a/server-ce/migrations/2_doc_lines_delete_from_project.coffee b/server-ce/migrations/2_doc_lines_delete_from_project.coffee index 1e6a13dbf7..2d5222f63d 100644 --- a/server-ce/migrations/2_doc_lines_delete_from_project.coffee +++ b/server-ce/migrations/2_doc_lines_delete_from_project.coffee @@ -25,6 +25,7 @@ loadProjectIds = (callback)-> console.log "loading project ids from #{all_projects_path}" fs.readFile all_projects_path, "utf-8", (err, data)-> ids = data.split("\n") + ids = _.filter ids, (id)-> id? and id.length == 24 console.log "loaded #{ids.length} project ids from #{all_projects_path}" callback err, ids diff --git a/server-ce/package.json b/server-ce/package.json index cee7ffc776..6b28b15e29 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -4,7 +4,7 @@ "description": "An online collaborative LaTeX editor", "dependencies": { "async": "^0.9.0", - "east": "^0.2.3", + "east": "0.5.1", "east-mongo": "^0.1.2", "grunt-shell": "^1.1.1", "lodash": "^3.0.0", From e5808c29333e16443a614fe1ab1f7b355e0f43b4 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 30 Jun 2016 16:35:23 +0100 Subject: [PATCH 234/525] added example docker compose file --- server-ce/docker-compose.yml | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 server-ce/docker-compose.yml diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml new file mode 100644 index 0000000000..67525765b2 --- /dev/null +++ b/server-ce/docker-compose.yml @@ -0,0 +1,39 @@ +version: '2' +services: + sharelatex: + restart: always + image: sharelatex/sharelatex + container_name: sharelatex + depends_on: + - mongo + - redis + privileged: true + ports: + - 80:80 + links: + - mongo + - redis + volumes: + - ~/sharelatex_data:/var/lib/sharelatex + environment: + SHARELATEX_MONGO_URL: mongodb://mongo/sharelatex + SHARELATEX_REDIS_HOST: redis + SHARELATEX_APP_NAME: 'ShareLaTeX' + + mongo: + restart: always + image: mongo + container_name: mongo + expose: + - 27017 + volumes: + - ~/mongo_data:/data/db + + redis: + restart: always + image: redis + container_name: redis + expose: + - 6379 + volumes: + - ~/redis_data:/data \ No newline at end of file From 60bfe17f2ce6f456b3906ae4c42831a39a12a21b Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 30 Jun 2016 16:47:13 +0100 Subject: [PATCH 235/525] move install latexmk and path higher up --- server-ce/Dockerfile | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 097de9a123..dba9ac2066 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -19,6 +19,14 @@ RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile + +RUN rm -r /install-tl-unx; \ + rm install-tl-unx.tar.gz + +ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2016/bin/x86_64-linux/ +RUN tlmgr install latexmk + + # Install Node.js and Grunt RUN npm install -g grunt-cli @@ -34,7 +42,7 @@ RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharela # Install ShareLaTeX -RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex +RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex #random_change ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js ADD ${baseDir}/package.json /var/www/package.json @@ -85,13 +93,6 @@ RUN rm /etc/nginx/sites-enabled/default ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf -RUN rm -r /install-tl-unx; \ - rm install-tl-unx.tar.gz - -ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2016/bin/x86_64-linux/ -RUN apt-get update -RUN tlmgr install latexmk - # phusion/baseimage init script ADD ${baseDir}/init_scripts/00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh ADD ${baseDir}/init_scripts/00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh From cb459a94b97d85a462da993ec36143967971521c Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 30 Jun 2016 16:47:23 +0100 Subject: [PATCH 236/525] add permissions change for templates dir --- server-ce/init_scripts/00_make_sharelatex_data_dirs.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh index 6269f1b2a9..49e5b7ba6d 100755 --- a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh +++ b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh @@ -11,6 +11,9 @@ chown www-data:www-data /var/lib/sharelatex/data/compiles mkdir -p /var/lib/sharelatex/data/cache chown www-data:www-data /var/lib/sharelatex/data/cache +mkdir -p /var/lib/sharelatex/data/templates +chown www-data:www-data /var/lib/sharelatex/data/templates + mkdir -p /var/lib/sharelatex/tmp chown www-data:www-data /var/lib/sharelatex/tmp From 3d33e5bc985a916879679ca8681fb73fd0216398 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 30 Jun 2016 16:47:35 +0100 Subject: [PATCH 237/525] add echo for finished migrations in --- server-ce/init_scripts/99_migrate.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/init_scripts/99_migrate.sh b/server-ce/init_scripts/99_migrate.sh index 762aae2806..d062496581 100755 --- a/server-ce/init_scripts/99_migrate.sh +++ b/server-ce/init_scripts/99_migrate.sh @@ -3,3 +3,4 @@ which node which grunt ls -al /var/www/sharelatex/migrations cd /var/www/sharelatex && grunt migrate -v +echo "All migrations finished" From 11667b379c38c14081fe6c1e15ac0ec4955f6dc1 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 14 Jul 2016 16:50:11 +0100 Subject: [PATCH 238/525] added dump folder and template files fix to init script --- server-ce/init_scripts/00_make_sharelatex_data_dirs.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh index 49e5b7ba6d..6085a087da 100755 --- a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh +++ b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh @@ -11,8 +11,11 @@ chown www-data:www-data /var/lib/sharelatex/data/compiles mkdir -p /var/lib/sharelatex/data/cache chown www-data:www-data /var/lib/sharelatex/data/cache -mkdir -p /var/lib/sharelatex/data/templates -chown www-data:www-data /var/lib/sharelatex/data/templates +mkdir -p /var/lib/sharelatex/data/template_files +chown www-data:www-data /var/lib/sharelatex/data/template_files + +mkdir -p /var/lib/sharelatex/tmp/dumpFolder +chown www-data:www-data /var/lib/sharelatex/tmp/dumpFolder mkdir -p /var/lib/sharelatex/tmp chown www-data:www-data /var/lib/sharelatex/tmp From e35303decfa3433e7a01f689bde55187e2f381ca Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 18 Jul 2016 16:08:33 +0100 Subject: [PATCH 239/525] Update docker-compose.yml --- server-ce/docker-compose.yml | 51 ++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 67525765b2..ca6dd4f532 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -18,7 +18,54 @@ services: environment: SHARELATEX_MONGO_URL: mongodb://mongo/sharelatex SHARELATEX_REDIS_HOST: redis - SHARELATEX_APP_NAME: 'ShareLaTeX' + SHARELATEX_APP_NAME: 'Our ShareLaTeX' + + # SHARELATEX_SITE_URL: "http://sharelatex.mydomain.com" + # SHARELATEX_NAV_TITLE: "Our ShareLaTeX Instance" + # SHARELATEX_HEADER_IMAGE_URL: "http://somewhere.com/mylogo.png" + # SHARELATEX_ADMIN_EMAIL: "support@it.com" + + # SHARELATEX_LEFT_FOOTER: '[{"text": "Powered by ShareLaTeX 2016"},{"text": "Another page I want to link to can be found here"} ]' + # SHARELATEX_RIGHT_FOOTER: '[{"text": "Hello I am on the Right"} ]' + + # SHARELATEX_EMAIL_FROM_ADDRESS: "team@sharelatex.com" + + # SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID: "" + # SHARELATEX_EMAIL_AWS_SES_SECRET_KEY: "" + + # SHARELATEX_EMAIL_SMTP_HOST: "smtp.mydomain.com" + # SHARELATEX_EMAIL_SMTP_PORT: 587 + # SHARELATEX_EMAIL_SMTP_SECURE: 'false' + # SHARELATEX_EMAIL_SMTP_USER: "" + # SHARELATEX_EMAIL_SMTP_PASS: "" + # SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH: 'true' + # SHARELATEX_EMAIL_SMTP_IGNORE_TLS: 'false' + # SHARELATEX_CUSTOM_EMAIL_FOOTER:"
This system is run by department x
" + + ################ + ## Server Pro ## + ################ + + # SANDBOXED_COMPILES: "true" + + # SHARELATEX_LDAP_HOST: 'ldap://ldap.forumsys.com' + # SHARELATEX_LDAP_DN: 'uid=:userKey,dc=example,dc=com' + # SHARELATEX_LDAP_BASE_SEARCH: 'dc=example,dc=com' + # SHARELATEX_LDAP_FILTER: '(uid=:userKey)' + # SHARELATEX_LDAP_ADMIN_DN: 'cn=read-only-admin,dc=example,dc=com' + # SHARELATEX_LDAP_ADMIN_PW: password' + # SHARELATEX_LDAP_ANONYMOUS: "false" + # SHARELATEX_LDAP_EMAIL_ATT: "mail" + # SHARELATEX_LDAP_NAME_ATT: "name" + # SHARELATEX_LDAP_LAST_NAME_ATT: "secondname" + # SHARELATEX_LDAP_PLACEHOLDER: "Username" + # SHARELATEX_LDAP_TLS: "true" + # SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH: + # SHARELATEX_LDAP_TLS_OPTS_CA_PATH: '["/var/one.pem", "/var/two.pem"]' + + # SHARELATEX_TEMPLATES_USER_ID: "578773160210479700917ee5" + + # SHARELATEX_PROXY_LEARN: "true" mongo: restart: always @@ -36,4 +83,4 @@ services: expose: - 6379 volumes: - - ~/redis_data:/data \ No newline at end of file + - ~/redis_data:/data From 03bfbe8d44ad43f173731a0f9d4af55871910f12 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 18 Jul 2016 16:11:04 +0100 Subject: [PATCH 240/525] Update docker-compose.yml --- server-ce/docker-compose.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index ca6dd4f532..07db7756a9 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -19,6 +19,9 @@ services: SHARELATEX_MONGO_URL: mongodb://mongo/sharelatex SHARELATEX_REDIS_HOST: redis SHARELATEX_APP_NAME: 'Our ShareLaTeX' + + #Set for SSL via nginx-proxy + #VIRTUAL_HOST: 103.112.212.22 # SHARELATEX_SITE_URL: "http://sharelatex.mydomain.com" # SHARELATEX_NAV_TITLE: "Our ShareLaTeX Instance" @@ -84,3 +87,13 @@ services: - 6379 volumes: - ~/redis_data:/data + +# nginx-proxy: +# image: jwilder/nginx-proxy +# container_name: nginx-proxy +# ports: +# #- "80:80" +# - "443:443" +# volumes: +# - /var/run/docker.sock:/tmp/docker.sock:ro +# - /home/sharelatex/tmp:/etc/nginx/certs From c167eec53bb58b5711e414798d3361b41f7232c7 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 22 Jul 2016 15:54:31 +0100 Subject: [PATCH 241/525] added contacts to service list --- server-ce/config/services.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server-ce/config/services.js b/server-ce/config/services.js index be4da8698a..3614b2c020 100644 --- a/server-ce/config/services.js +++ b/server-ce/config/services.js @@ -40,4 +40,8 @@ module.exports = name: "spelling", repo: "https://github.com/sharelatex/spelling-sharelatex.git", version: "master" +}, { + name: "contacts", + repo: "https://github.com/sharelatex/contacts-sharelatex.git", + version: "master" }] From 7818af50ba8fc7299d085e020cb55457ef4699a2 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 3 Aug 2016 16:21:44 +0100 Subject: [PATCH 242/525] add contacts to services.js --- server-ce/services.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server-ce/services.js b/server-ce/services.js index be4da8698a..3614b2c020 100644 --- a/server-ce/services.js +++ b/server-ce/services.js @@ -40,4 +40,8 @@ module.exports = name: "spelling", repo: "https://github.com/sharelatex/spelling-sharelatex.git", version: "master" +}, { + name: "contacts", + repo: "https://github.com/sharelatex/contacts-sharelatex.git", + version: "master" }] From 67cc868c4bec13987418c128aefe9e556e0b4077 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 3 Aug 2016 16:22:10 +0100 Subject: [PATCH 243/525] add template links SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS to config file --- server-ce/settings.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index e2f25ad934..86d49e39ec 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -565,6 +565,8 @@ if process.env["SHARELATEX_TEMPLATES_USER_ID"] settings.templates = mountPointUrl: "/templates" user_id: process.env["SHARELATEX_TEMPLATES_USER_ID"] + + settings.templateLinks: parse(process.env["SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS"]) # /Learn From 81d99e968ffc43f476abeef5b655042b970af9f2 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 3 Aug 2016 16:22:17 +0100 Subject: [PATCH 244/525] add logrotate --- server-ce/Dockerfile | 2 ++ server-ce/logrotate/sharelatex | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 server-ce/logrotate/sharelatex diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index dba9ac2066..41aaa7e20c 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -6,6 +6,8 @@ RUN apt-get update RUN curl -sL https://deb.nodesource.com/setup | sudo bash - RUN apt-get install -y build-essential wget nodejs unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu +ADD logrotate/sharelatex /etc/logrotate.d/sharelatex + WORKDIR /opt RUN wget https://s3.amazonaws.com/sharelatex-random-files/qpdf-6.0.0.tar.gz && tar xzf qpdf-6.0.0.tar.gz WORKDIR /opt/qpdf-6.0.0 diff --git a/server-ce/logrotate/sharelatex b/server-ce/logrotate/sharelatex new file mode 100644 index 0000000000..efc51cc6c9 --- /dev/null +++ b/server-ce/logrotate/sharelatex @@ -0,0 +1,9 @@ +/var/log/sharelatex/*.log { + daily + missingok + rotate 5 + compress + copytruncate + notifempty + create 644 root adm +} \ No newline at end of file From 37142832280cb88b7df0610cc9f5b7cfeb0f391a Mon Sep 17 00:00:00 2001 From: ShareLaTeX Date: Thu, 4 Aug 2016 13:19:33 +0000 Subject: [PATCH 245/525] cleaned up settings file and added refernces option in --- server-ce/settings.coffee | 274 ++++++++++++-------------------------- 1 file changed, 82 insertions(+), 192 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index e2f25ad934..3bbed39856 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -155,270 +155,146 @@ settings = # dictionaries you have installed. These should be set for the `code` for # each language. languages: [{ - "code":"en", - "name":"English (American)" + "code":"en", "name":"English (American)" },{ - "code":"en_GB", - "name":"English (British)" + "code":"en_GB", "name":"English (British)" },{ - "code":"af", - "name":"Africaans" + "code":"af", "name":"Africaans" },{ - "code":"am", - "name":"Amharic" + "code":"am", "name":"Amharic" },{ - "code":"ar", - "name":"Arabic" + "code":"ar", "name":"Arabic" },{ - "code":"hy", - "name":"Armenian" + "code":"hy", "name":"Armenian" },{ - "code":"gl", - "name":"Galician" + "code":"gl", "name":"Galician" },{ - "code":"eu", - "name":"Basque" + "code":"eu", "name":"Basque" },{ - "code":"bn", - "name":"Bengali" + "code":"bn", "name":"Bengali" },{ - "code":"br", - "name":"Breton" + "code":"br", "name":"Breton" },{ - "code":"bg", - "name":"Bulgarian" + "code":"bg", "name":"Bulgarian" },{ - "code":"ca", - "name":"Catalan" + "code":"ca", "name":"Catalan" },{ - "code":"hr", - "name":"Croatian" + "code":"hr", "name":"Croatian" },{ - "code":"cs", - "name":"Czech" + "code":"cs", "name":"Czech" },{ - "code":"da", - "name":"Danish" + "code":"da", "name":"Danish" },{ - "code":"nl", - "name":"Dutch" + "code":"nl", "name":"Dutch" },{ - "code":"eo", - "name":"Esperanto" + "code":"eo", "name":"Esperanto" },{ - "code":"et", - "name":"Estonian" + "code":"et", "name":"Estonian" },{ - "code":"fo", - "name":"Faroese" + "code":"fo", "name":"Faroese" },{ - "code":"fr", - "name":"French" + "code":"fr", "name":"French" },{ - "code":"de", - "name":"German" + "code":"de", "name":"German" },{ - "code":"el", - "name":"Greek" + "code":"el", "name":"Greek" },{ - "code":"gu", - "name":"Gujarati" + "code":"gu", "name":"Gujarati" },{ - "code":"he", - "name":"Hebrew" + "code":"he", "name":"Hebrew" },{ - "code":"hi", - "name":"Hindi" + "code":"hi", "name":"Hindi" },{ - "code":"hu", - "name":"Hungarian" + "code":"hu", "name":"Hungarian" },{ - "code":"is", - "name":"Icelandic" + "code":"is", "name":"Icelandic" },{ - "code":"id", - "name":"Indonesian" + "code":"id", "name":"Indonesian" },{ - "code":"ga", - "name":"Irish" + "code":"ga", "name":"Irish" },{ - "code":"it", - "name":"Italian" + "code":"it", "name":"Italian" },{ - "code":"kn", - "name":"Kannada" + "code":"kn", "name":"Kannada" },{ - "code":"kk", - "name":"Kazakh" + "code":"kk", "name":"Kazakh" },{ - "code":"ku", - "name":"Kurdish" + "code":"ku", "name":"Kurdish" },{ - "code":"lv", - "name":"Latvian" + "code":"lv", "name":"Latvian" },{ - "code":"lt", - "name":"Lithuanian" + "code":"lt", "name":"Lithuanian" },{ - "code":"ml", - "name":"Malayalam" + "code":"ml", "name":"Malayalam" },{ - "code":"mr", - "name":"Marathi" + "code":"mr", "name":"Marathi" },{ - "code":"nr", - "name":"Ndebele" + "code":"nr", "name":"Ndebele" },{ - "code":"ns", - "name":"Northern Sotho" + "code":"ns", "name":"Northern Sotho" },{ - "code":"no", - "name":"Norwegian" + "code":"no", "name":"Norwegian" },{ - "code":"or", - "name":"Oriya" + "code":"or", "name":"Oriya" },{ - "code":"fa", - "name":"Persian" + "code":"fa", "name":"Persian" },{ - "code":"pl", - "name":"Polish" + "code":"pl", "name":"Polish" },{ - "code":"pt_BR", - "name":"Portuguese (Brazilian)" + "code":"pt_BR", "name":"Portuguese (Brazilian)" },{ - "code":"pt_PT", - "name":"Portuguese (European)" + "code":"pt_PT", "name":"Portuguese (European)" },{ - "code":"pa", - "name":"Punjabi" + "code":"pa", "name":"Punjabi" },{ - "code":"ro", - "name":"Romanian" + "code":"ro", "name":"Romanian" },{ - "code":"ru", - "name":"Russian" + "code":"ru", "name":"Russian" },{ - "code":"sk", - "name":"Slovak" + "code":"sk", "name":"Slovak" },{ - "code":"sl", - "name":"Slovenian" + "code":"sl", "name":"Slovenian" },{ - "code":"st", - "name":"Southern Sotho" + "code":"st", "name":"Southern Sotho" },{ - "code":"es", - "name":"Spanish" + "code":"es", "name":"Spanish" },{ - "code":"ss", - "name":"Swazi" + "code":"ss", "name":"Swazi" },{ - "code":"sv", - "name":"Swedish" + "code":"sv", "name":"Swedish" },{ - "code":"tl", - "name":"Tagalog" + "code":"tl", "name":"Tagalog" },{ - "code":"ta", - "name":"Tamil" + "code":"ta", "name":"Tamil" },{ - "code":"te", - "name":"Telugu" + "code":"te", "name":"Telugu" },{ - "code":"ts", - "name":"Tsonga" + "code":"ts", "name":"Tsonga" },{ - "code":"tn", - "name":"Tswana" + "code":"tn", "name":"Tswana" },{ - "code":"uk", - "name":"Ukrainian" + "code":"uk", "name":"Ukrainian" },{ - "code":"hsb", - "name":"Upper Sorbian" + "code":"hsb", "name":"Upper Sorbian" },{ - "code":"uz", - "name":"Uzbek" + "code":"uz", "name":"Uzbek" },{ - "code":"cy", - "name":"Welsh" + "code":"cy", "name":"Welsh" },{ - "code":"xh", - "name":"Xhosa" + "code":"xh", "name":"Xhosa" },{ - "code":"zu", - "name":"Zulu" + "code":"zu", "name":"Zulu" } ] - - # Service locations - # ----------------- - # ShareLaTeX is comprised of many small services, which each expose - # an HTTP API running on a different port. Generally you - # can leave these as they are unless you have some other services - # running which conflict, or want to run the web process on port 80. - # internal: - # web: - # port: webPort = 3000 - # host: "localhost" - # documentupdater: - # port: docUpdaterPort = 3003 - # host: "localhost" - # filestore: - # port: filestorePort = 3009 - # host: "localhost" - # chat: - # port: chatPort = 3010 - # host: "localhost" - # tags: - # port: tagsPort = 3012 - # host: "localhost" - # clsi: - # port: clsiPort = 3013 - # host: "localhost" - # trackchanges: - # port: trackchangesPort = 3015 - # host: "localhost" - # docstore: - # port: docstorePort = 3016 - # host: "localhost" - # spelling: - # port: spellingPort = 3005 - # host: "localhost" - # templates: - # port: templatesPort = 3007 - # host: "localhost" - - # If you change the above config, or run some services on remote servers, - # you need to tell the other services where to find them: apis: web: url: "http://localhost:3000" user: httpAuthUser pass: httpAuthPass - references:undefined + references:{} notifications:undefined - # documentupdater: - # url : "http://localhost:#{docUpdaterPort}" - # clsi: - # url: "http://localhost:#{clsiPort}" - # filestore: - # url: "http://localhost:#{filestorePort}" - # trackchanges: - # url: "http://localhost:#{trackchangesPort}" - # docstore: - # url: "http://localhost:#{docstorePort}" - # tags: - # url: "http://localhost:#{tagsPort}" - # spelling: - # url: "http://localhost:#{spellingPort}" - # chat: - # url: "http://localhost:#{chatPort}" - # templates: - # url: "http://localhost:#{templatesPort}" #### OPTIONAL CONFIGERABLE SETTINGS @@ -440,7 +316,10 @@ if process.env["SHARELATEX_HEADER_IMAGE_URL"]? settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"] if process.env["SHARELATEX_HEADER"]? - settings.nav.header = process.env["SHARELATEX_HEADER"] + settings.nav.header = process.env["SHARELATEX_HEADER_NAV_LINKS"] + +# if process.env["SHARELATEX_PROXY_LEARN"]? +# settings.nav.header.push({text: "help", class: "subdued", dropdown: [{text: "documentation", url: "/learn"}] }) # Sending Email @@ -500,7 +379,9 @@ if process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or process.env["SHARELA # ShareLaTeX Server Pro ####################### - +if parse(process.env["SHARELATEX_IS_SERVER_PRO"]) == true + settings.apis.references = + url: "http://localhost:3040" # LDAP - SERVER PRO ONLY @@ -565,6 +446,8 @@ if process.env["SHARELATEX_TEMPLATES_USER_ID"] settings.templates = mountPointUrl: "/templates" user_id: process.env["SHARELATEX_TEMPLATES_USER_ID"] + + settings.templateLinks = parse(process.env["SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS"]) # /Learn @@ -573,6 +456,12 @@ if process.env["SHARELATEX_PROXY_LEARN"]? settings.proxyLearn = parse(process.env["SHARELATEX_PROXY_LEARN"]) +# /References +# ----------- +if process.env["SHARELATEX_ELASTICSEARCH_URL"]? + settings.references.elasticsearch = + host: process.env["SHARELATEX_ELASTICSEARCH_URL"] + # With lots of incoming and outgoing HTTP connections to different services, # sometimes long running, it is a good idea to increase the default number @@ -583,3 +472,4 @@ https = require('https') https.globalAgent.maxSockets = 300 module.exports = settings + From 2e9561d126c541829ac3bac1c3398fea8cf9fefb Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 5 Aug 2016 11:36:02 +0100 Subject: [PATCH 246/525] Delete CHANGELOG.md --- server-ce/CHANGELOG.md | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 server-ce/CHANGELOG.md diff --git a/server-ce/CHANGELOG.md b/server-ce/CHANGELOG.md deleted file mode 100644 index baac4bcc25..0000000000 --- a/server-ce/CHANGELOG.md +++ /dev/null @@ -1,31 +0,0 @@ -v0.1.4 ------- - -* Move to a private registration scheme where users must be added by an admin. -* Proxy websockets connection through web to real-time service so no websocketsUrl parameter is needed. -* Use worker aspell processes in spelling to prevent excessing forking. -* Properly clean up after long running ImageMagick conversions in the filestore. -* Allow a configurable app name and email contact address. -* Switch to new PDF viewer with partial page loading for immediate preview of visible page. - -v0.1.3 ------- - -* Fix bug with large files being corrupted when downloaded. -* Update Ace editor to lastest release. -* Lots of added null checks in the front-end javascript. -* Don't crash if 'unzip' program isn't present. -* Allow track-changes history to be packed into compressed 'packs'. This must be done manually for now. -* Escape any shell special characters in the CLSI root path. - -v0.1.2 ------- - -* Re-brand open-source ShareLaTeX code as 'ShareLaTeX Community Edition'. -* The Dropbox and template code has been extracted out into a separate module and removed from the ShareLaTeX Community Edition. There should be no broken features due to lack of open source components now. -* Websockets and real-time data now go to a separate light-weight [real-time](https://github.com/sharelatex/real-time) service. -* Updated PDF viewer that loads page-by-page for much quicker loading times on large documents. -* Links are clickable in chat messages. -* Mathjax libraries are now served locally. -* Optimisation of Angular digest loop in editor should reduce CPU usage in certain cases. -* Numerous small bug fixes. From 507c0dc65689ba516cfd64f889e74cfc3a2b3f0d Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 5 Aug 2016 11:59:39 +0100 Subject: [PATCH 247/525] cleaned up dockerfile more, removing undded things --- server-ce/Dockerfile | 51 ++++--------------- .../run.sh} | 0 .../run.sh} | 0 .../run.sh} | 0 .../run.sh} | 0 .../run.sh} | 0 server-ce/runit/{nginx.sh => nginx/run.sh} | 0 .../run.sh} | 0 .../run.sh} | 0 .../run.sh} | 0 .../run.sh} | 0 .../run.sh} | 0 12 files changed, 9 insertions(+), 42 deletions(-) rename server-ce/runit/{chat-sharelatex.sh => chat-sharelatex/run.sh} (100%) rename server-ce/runit/{clsi-sharelatex.sh => clsi-sharelatex/run.sh} (100%) rename server-ce/runit/{docstore-sharelatex.sh => docstore-sharelatex/run.sh} (100%) rename server-ce/runit/{document-updater-sharelatex.sh => document-updater-sharelatex/run.sh} (100%) rename server-ce/runit/{filestore-sharelatex.sh => filestore-sharelatex/run.sh} (100%) rename server-ce/runit/{nginx.sh => nginx/run.sh} (100%) rename server-ce/runit/{real-time-sharelatex.sh => real-time-sharelatex/run.sh} (100%) rename server-ce/runit/{spelling-sharelatex.sh => spelling-sharelatex/run.sh} (100%) rename server-ce/runit/{tags-sharelatex.sh => tags-sharelatex/run.sh} (100%) rename server-ce/runit/{track-changes-sharelatex.sh => track-changes-sharelatex/run.sh} (100%) rename server-ce/runit/{web-sharelatex.sh => web-sharelatex/run.sh} (100%) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 41aaa7e20c..240404ca65 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -21,18 +21,14 @@ RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile - RUN rm -r /install-tl-unx; \ rm install-tl-unx.tar.gz ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2016/bin/x86_64-linux/ RUN tlmgr install latexmk - -# Install Node.js and Grunt RUN npm install -g grunt-cli - # Set up sharelatex user and home directory RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex; \ mkdir -p /var/lib/sharelatex; \ @@ -43,6 +39,15 @@ RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharela chown www-data:www-data /var/lib/sharelatex/data/template_files; +ADD ${baseDir}/runit /etc/service + +RUN rm /etc/nginx/sites-enabled/default +ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf +ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf + +COPY {baseDir}/init_scripts /etc/my_init.d/ + + # Install ShareLaTeX RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex #random_change @@ -64,45 +69,7 @@ RUN cd /var/www/sharelatex/web; \ RUN cd /var/www/sharelatex/clsi; \ grunt compile:bin -RUN mkdir /etc/service/nginx -ADD ${baseDir}/runit/nginx.sh /etc/service/nginx/run - -# Set up ShareLaTeX services to run automatically on boot -RUN mkdir /etc/service/chat-sharelatex; \ - mkdir /etc/service/clsi-sharelatex; \ - mkdir /etc/service/docstore-sharelatex; \ - mkdir /etc/service/document-updater-sharelatex; \ - mkdir /etc/service/filestore-sharelatex; \ - mkdir /etc/service/real-time-sharelatex; \ - mkdir /etc/service/spelling-sharelatex; \ - mkdir /etc/service/tags-sharelatex; \ - mkdir /etc/service/track-changes-sharelatex; \ - mkdir /etc/service/web-sharelatex; - - -ADD ${baseDir}/runit/chat-sharelatex.sh /etc/service/chat-sharelatex/run -ADD ${baseDir}/runit/clsi-sharelatex.sh /etc/service/clsi-sharelatex/run -ADD ${baseDir}/runit/docstore-sharelatex.sh /etc/service/docstore-sharelatex/run -ADD ${baseDir}/runit/document-updater-sharelatex.sh /etc/service/document-updater-sharelatex/run -ADD ${baseDir}/runit/filestore-sharelatex.sh /etc/service/filestore-sharelatex/run -ADD ${baseDir}/runit/real-time-sharelatex.sh /etc/service/real-time-sharelatex/run -ADD ${baseDir}/runit/spelling-sharelatex.sh /etc/service/spelling-sharelatex/run -ADD ${baseDir}/runit/tags-sharelatex.sh /etc/service/tags-sharelatex/run -ADD ${baseDir}/runit/track-changes-sharelatex.sh /etc/service/track-changes-sharelatex/run -ADD ${baseDir}/runit/web-sharelatex.sh /etc/service/web-sharelatex/run - -RUN rm /etc/nginx/sites-enabled/default -ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf -ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf - -# phusion/baseimage init script -ADD ${baseDir}/init_scripts/00_regen_sharelatex_secrets.sh /etc/my_init.d/00_regen_sharelatex_secrets.sh -ADD ${baseDir}/init_scripts/00_make_sharelatex_data_dirs.sh /etc/my_init.d/00_make_sharelatex_data_dirs.sh -ADD ${baseDir}/init_scripts/00_set_docker_host_ipaddress.sh /etc/my_init.d/00_set_docker_host_ipaddress.sh -ADD ${baseDir}/init_scripts/99_migrate.sh /etc/my_init.d/99_migrate.sh - # Install ShareLaTeX settings file -RUN mkdir /etc/sharelatex ADD ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee diff --git a/server-ce/runit/chat-sharelatex.sh b/server-ce/runit/chat-sharelatex/run.sh similarity index 100% rename from server-ce/runit/chat-sharelatex.sh rename to server-ce/runit/chat-sharelatex/run.sh diff --git a/server-ce/runit/clsi-sharelatex.sh b/server-ce/runit/clsi-sharelatex/run.sh similarity index 100% rename from server-ce/runit/clsi-sharelatex.sh rename to server-ce/runit/clsi-sharelatex/run.sh diff --git a/server-ce/runit/docstore-sharelatex.sh b/server-ce/runit/docstore-sharelatex/run.sh similarity index 100% rename from server-ce/runit/docstore-sharelatex.sh rename to server-ce/runit/docstore-sharelatex/run.sh diff --git a/server-ce/runit/document-updater-sharelatex.sh b/server-ce/runit/document-updater-sharelatex/run.sh similarity index 100% rename from server-ce/runit/document-updater-sharelatex.sh rename to server-ce/runit/document-updater-sharelatex/run.sh diff --git a/server-ce/runit/filestore-sharelatex.sh b/server-ce/runit/filestore-sharelatex/run.sh similarity index 100% rename from server-ce/runit/filestore-sharelatex.sh rename to server-ce/runit/filestore-sharelatex/run.sh diff --git a/server-ce/runit/nginx.sh b/server-ce/runit/nginx/run.sh similarity index 100% rename from server-ce/runit/nginx.sh rename to server-ce/runit/nginx/run.sh diff --git a/server-ce/runit/real-time-sharelatex.sh b/server-ce/runit/real-time-sharelatex/run.sh similarity index 100% rename from server-ce/runit/real-time-sharelatex.sh rename to server-ce/runit/real-time-sharelatex/run.sh diff --git a/server-ce/runit/spelling-sharelatex.sh b/server-ce/runit/spelling-sharelatex/run.sh similarity index 100% rename from server-ce/runit/spelling-sharelatex.sh rename to server-ce/runit/spelling-sharelatex/run.sh diff --git a/server-ce/runit/tags-sharelatex.sh b/server-ce/runit/tags-sharelatex/run.sh similarity index 100% rename from server-ce/runit/tags-sharelatex.sh rename to server-ce/runit/tags-sharelatex/run.sh diff --git a/server-ce/runit/track-changes-sharelatex.sh b/server-ce/runit/track-changes-sharelatex/run.sh similarity index 100% rename from server-ce/runit/track-changes-sharelatex.sh rename to server-ce/runit/track-changes-sharelatex/run.sh diff --git a/server-ce/runit/web-sharelatex.sh b/server-ce/runit/web-sharelatex/run.sh similarity index 100% rename from server-ce/runit/web-sharelatex.sh rename to server-ce/runit/web-sharelatex/run.sh From 023289ef290eecd8efdb17450913baa540b78300 Mon Sep 17 00:00:00 2001 From: ShareLaTeX Date: Fri, 5 Aug 2016 11:05:06 +0000 Subject: [PATCH 248/525] added log rotate and locked down docupdater version for moment --- server-ce/Dockerfile | 2 +- server-ce/services.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 41aaa7e20c..c29e55c3d7 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -6,7 +6,7 @@ RUN apt-get update RUN curl -sL https://deb.nodesource.com/setup | sudo bash - RUN apt-get install -y build-essential wget nodejs unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu -ADD logrotate/sharelatex /etc/logrotate.d/sharelatex +ADD ${baseDir}/logrotate/sharelatex /etc/logrotate.d/sharelatex WORKDIR /opt RUN wget https://s3.amazonaws.com/sharelatex-random-files/qpdf-6.0.0.tar.gz && tar xzf qpdf-6.0.0.tar.gz diff --git a/server-ce/services.js b/server-ce/services.js index 3614b2c020..ed590505cc 100644 --- a/server-ce/services.js +++ b/server-ce/services.js @@ -11,7 +11,7 @@ module.exports = }, { name: "document-updater", repo: "https://github.com/sharelatex/document-updater-sharelatex.git", - version: "master" + version: "75c84e2" }, { name: "clsi", repo: "https://github.com/sharelatex/clsi-sharelatex.git", From c85ae093316c471dd6a33dfba0817bb5e85939df Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 5 Aug 2016 12:51:37 +0100 Subject: [PATCH 249/525] deletd undeeded tasks --- server-ce/Gruntfile.coffee | 70 ++------------------------------------ 1 file changed, 2 insertions(+), 68 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 1c8c120ef5..984a6ae287 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -78,17 +78,9 @@ module.exports = (grunt) -> grunt.registerTask "install:#{service.name}", "Download and set up the #{service.name} service", () -> done = @async() Helpers.installService(service, done) - grunt.registerTask "update:#{service.name}", "Checkout and update the #{service.name} service", () -> - done = @async() - Helpers.updateService(service, done) - grunt.registerTask "run:#{service.name}", "Run the ShareLaTeX #{service.name} service", ["bunyan", "execute:#{service.name}"] - grunt.registerTask "release:#{service.name}", "Create a new release version of #{service.name} (specify with --release option)", () -> - done = @async() - Helpers.createNewRelease(service, grunt.option("release"), done) - grunt.registerTask 'install:dirs', "Copy the example config into the real config", () -> - Helpers.createDataDirs @async() + grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", ["check:make"].concat( ("install:#{service.name}" for service in SERVICES) @@ -119,10 +111,9 @@ module.exports = (grunt) -> Helpers.checkAspell @async() grunt.registerTask "check:make", "Check that make is installed", () -> Helpers.checkMake @async() + grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3", "check:fs", "check:aspell"] - grunt.registerTask "build:upstart_scripts", "Create upstart scripts for each service", () -> - Helpers.buildUpstartScripts() grunt.registerTask 'migrate', "compile migrations and run them", ['coffee:migrate', 'shell:migrate'] @@ -140,16 +131,6 @@ module.exports = (grunt) -> return callback(error) if error? callback() - updateService: (service, callback = (error) ->) -> - Helpers.updateGitRepo service, (error) -> - return callback(error) if error? - Helpers.installNpmModules service, (error) -> - return callback(error) if error? - Helpers.rebuildNpmModules service, (error) -> - return callback(error) if error? - Helpers.runGruntInstall service, (error) -> - return callback(error) if error? - callback() cloneGitRepo: (service, callback = (error) ->) -> repo_src = service.repo @@ -172,31 +153,6 @@ module.exports = (grunt) -> proc.on "close", () -> callback() - updateGitRepo: (service, callback = (error) ->) -> - dir = service.name - proc = spawn "git", ["checkout", service.version], cwd: dir, stdio: "inherit" - proc.on "close", () -> - proc = spawn "git", ["pull"], cwd: dir, stdio: "inherit" - proc.on "close", () -> - callback() - - createNewRelease: (service, version, callback = (error) ->) -> - dir = service.name - proc = spawn "sed", [ - "-i", "", - "s/\"version\".*$/\"version\": \"#{version}\",/g", - "package.json" - ], cwd: dir, stdio: "inherit" - proc.on "close", () -> - proc = spawn "git", ["commit", "-a", "-m", "Release version #{version}"], cwd: dir, stdio: "inherit" - proc.on "close", () -> - proc = spawn "git", ["tag", "v#{version}"], cwd: dir, stdio: "inherit" - proc.on "close", () -> - proc = spawn "git", ["push"], cwd: dir, stdio: "inherit" - proc.on "close", () -> - proc = spawn "git", ["push", "--tags"], cwd: dir, stdio: "inherit" - proc.on "close", () -> - callback() installNpmModules: (service, callback = (error) ->) -> dir = service.name @@ -212,24 +168,6 @@ module.exports = (grunt) -> proc.on "close", () -> callback() - createDataDirs: (callback = (error) ->) -> - DIRS = [ - "tmp/dumpFolder" - "tmp/uploads" - "data/user_files" - "data/compiles" - "data/cache" - ] - jobs = [] - for dir in DIRS - do (dir) -> - jobs.push (callback) -> - path = Path.join(__dirname, dir) - grunt.log.writeln "Ensuring '#{path}' exists" - exec "mkdir -p #{path}", callback - async.series jobs, callback - - runGruntInstall: (service, callback = (error) ->) -> dir = service.name proc = spawn "grunt", ["install"], stdio: "inherit", cwd: dir @@ -406,7 +344,3 @@ module.exports = (grunt) -> grunt.log.write "OK." return callback() - buildUpstartScripts: () -> - template = fs.readFileSync("package/upstart/sharelatex-template.conf").toString() - for service in SERVICES - fs.writeFileSync "package/upstart/sharelatex-#{service.name}.conf", template.replace(/__SERVICE__/g, service.name) From 1695a1bf398f6cab3df7fc5b0a444cb681c89fb0 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 5 Aug 2016 13:29:11 +0100 Subject: [PATCH 250/525] move create-admin-user and delete-user to grunt folder --- server-ce/Gruntfile.coffee | 1 + server-ce/grunt/CreateAndDestoryUsers.coffee | 56 ++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 server-ce/grunt/CreateAndDestoryUsers.coffee diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 984a6ae287..a6c0d84c6a 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -19,6 +19,7 @@ module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-concurrent' grunt.loadNpmTasks "grunt-contrib-coffee" grunt.loadNpmTasks "grunt-shell" + require('load-grunt-config')(grunt) execute = {} diff --git a/server-ce/grunt/CreateAndDestoryUsers.coffee b/server-ce/grunt/CreateAndDestoryUsers.coffee new file mode 100644 index 0000000000..a6e73089a4 --- /dev/null +++ b/server-ce/grunt/CreateAndDestoryUsers.coffee @@ -0,0 +1,56 @@ + +module.exports = (grunt) -> + + grunt.registerTask 'create-admin-user', "Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt create-admin-user --email joe@example.com", () -> + done = @async() + email = grunt.option("email") + if !email? + console.error "Usage: grunt create-admin-user --email joe@example.com" + process.exit(1) + + settings = require "settings-sharelatex" + UserRegistrationHandler = require "../web/app/js/Features/User/UserRegistrationHandler" + OneTimeTokenHandler = require "../web/app/js/Features/Security/OneTimeTokenHandler" + UserRegistrationHandler.registerNewUser { + email: email + password: require("crypto").randomBytes(32).toString("hex") + }, (error, user) -> + if error? and error?.message != "EmailAlreadyRegistered" + throw error + user.isAdmin = true + user.save (error) -> + throw error if error? + ONE_WEEK = 7 * 24 * 60 * 60 # seconds + OneTimeTokenHandler.getNewToken user._id, { expiresIn: ONE_WEEK }, (err, token)-> + return next(err) if err? + + console.log "" + console.log """ + Successfully created #{email} as an admin user. + + Please visit the following URL to set a password for #{email} and log in: + + #{settings.siteUrl}/user/password/set?passwordResetToken=#{token} + + """ + done() + + grunt.registerTask 'delete-user', "deletes a user and all their data, Usage: grunt delete-user --email joe@example.com", () -> + done = @async() + email = grunt.option("email") + if !email? + console.error "Usage: grunt delete-user --email joe@example.com" + process.exit(1) + settings = require "settings-sharelatex" + UserGetter = require "../web/app/js/Features/User/UserGetter" + UserDeleter = require "../web/app/js/Features/User/UserDeleter" + UserGetter.getUser email:email, (error, user) -> + if error? + throw error + if !user? + console.log("user #{email} not in database, potentially already deleted") + return done() + UserDeleter.deleteUser user._id, (err)-> + if err? + throw err + done() \ No newline at end of file From 40c4f281c155dac87dcb1a89917959116694f7c1 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 5 Aug 2016 15:18:13 +0100 Subject: [PATCH 251/525] fixed init.d copy --- server-ce/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 09b47ab367..f31c08aabe 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -45,7 +45,7 @@ RUN rm /etc/nginx/sites-enabled/default ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf -COPY {baseDir}/init_scripts /etc/my_init.d/ +COPY {baseDir}/init_scripts/ /etc/my_init.d/ # Install ShareLaTeX From dcdc56cbe2c02649036f38d7e6156dd6d240a1fa Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 5 Aug 2016 15:18:35 +0100 Subject: [PATCH 252/525] added runit --- server-ce/runit/notifications-sharelatex/run.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 server-ce/runit/notifications-sharelatex/run.sh diff --git a/server-ce/runit/notifications-sharelatex/run.sh b/server-ce/runit/notifications-sharelatex/run.sh new file mode 100755 index 0000000000..6d1629152c --- /dev/null +++ b/server-ce/runit/notifications-sharelatex/run.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/notifcations/app.js >> /var/log/sharelatex/notifcations.log 2>&1 \ No newline at end of file From 511054423ef6d4a5bd3a0d6ea702e261696f187e Mon Sep 17 00:00:00 2001 From: ShareLaTeX Date: Fri, 5 Aug 2016 14:22:42 +0000 Subject: [PATCH 253/525] added dollar to base path --- server-ce/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index f31c08aabe..63a584ad6d 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -45,7 +45,7 @@ RUN rm /etc/nginx/sites-enabled/default ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf -COPY {baseDir}/init_scripts/ /etc/my_init.d/ +COPY ${baseDir}/init_scripts/ /etc/my_init.d/ # Install ShareLaTeX From 906a47cecbaf514fee5ca24ea3131667862a32d5 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 5 Aug 2016 15:35:43 +0100 Subject: [PATCH 254/525] added notifications and package for multi config files --- server-ce/config/services.js | 4 ++++ server-ce/package.json | 1 + 2 files changed, 5 insertions(+) diff --git a/server-ce/config/services.js b/server-ce/config/services.js index 3614b2c020..3a85bfb597 100644 --- a/server-ce/config/services.js +++ b/server-ce/config/services.js @@ -44,4 +44,8 @@ module.exports = name: "contacts", repo: "https://github.com/sharelatex/contacts-sharelatex.git", version: "master" +}, { + name: "notifications", + repo: "https://github.com/sharelatex/notifications-sharelatex.git", + version: "master" }] diff --git a/server-ce/package.json b/server-ce/package.json index 6b28b15e29..112c9adcf6 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -7,6 +7,7 @@ "east": "0.5.1", "east-mongo": "^0.1.2", "grunt-shell": "^1.1.1", + "load-grunt-config": "^0.19.2", "lodash": "^3.0.0", "mongojs": "^0.18.1", "rimraf": "~2.2.6", From 21317b68fce61ad6ec3f2d53274e804363044b6a Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 5 Aug 2016 15:36:27 +0100 Subject: [PATCH 255/525] change command to create and delete users --- server-ce/grunt/CreateAndDestoryUsers.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/grunt/CreateAndDestoryUsers.coffee b/server-ce/grunt/CreateAndDestoryUsers.coffee index a6e73089a4..293c1d6ef2 100644 --- a/server-ce/grunt/CreateAndDestoryUsers.coffee +++ b/server-ce/grunt/CreateAndDestoryUsers.coffee @@ -1,7 +1,7 @@ module.exports = (grunt) -> - grunt.registerTask 'create-admin-user', "Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt create-admin-user --email joe@example.com", () -> + grunt.registerTask 'user:create-admin', "Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt create-admin-user --email joe@example.com", () -> done = @async() email = grunt.option("email") if !email? @@ -35,7 +35,7 @@ module.exports = (grunt) -> """ done() - grunt.registerTask 'delete-user', "deletes a user and all their data, Usage: grunt delete-user --email joe@example.com", () -> + grunt.registerTask 'user:delete', "deletes a user and all their data, Usage: grunt delete-user --email joe@example.com", () -> done = @async() email = grunt.option("email") if !email? From c9c43ad628b0c1e4bce0107c09c8c98460b1cace Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 5 Aug 2016 17:35:46 +0100 Subject: [PATCH 256/525] added logging --- server-ce/Gruntfile.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index a6c0d84c6a..5790eacb2a 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -122,6 +122,7 @@ module.exports = (grunt) -> Helpers = installService: (service, callback = (error) ->) -> + console.log "Installing #{service.name}" Helpers.cloneGitRepo service, (error) -> return callback(error) if error? Helpers.installNpmModules service, (error) -> @@ -130,6 +131,7 @@ module.exports = (grunt) -> return callback(error) if error? Helpers.runGruntInstall service, (error) -> return callback(error) if error? + console.log "Finished installing #{service.name}" callback() From 0dfd8f9d88fbe06a9708c7ddf8c17bf06432fd8f Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 15 Aug 2016 13:39:34 +0100 Subject: [PATCH 257/525] remove calls to dirs --- server-ce/Gruntfile.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 5790eacb2a..201f351646 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -70,7 +70,7 @@ module.exports = (grunt) -> "Misc": [ "help" ] - "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install", "install:dirs"]) + "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install"]) "Update tasks": ("update:#{service.name}" for service in SERVICES).concat(["update:all", "update"]) "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make"] @@ -85,7 +85,7 @@ module.exports = (grunt) -> grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", ["check:make"].concat( ("install:#{service.name}" for service in SERVICES) - ).concat([ "install:dirs"]) + ) grunt.registerTask 'install', 'install:all' From 7d4286d3684874baa97db7d121fdece394896f64 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 20 Sep 2016 17:07:52 +0100 Subject: [PATCH 258/525] add checkMongoConnect and checkRedisConnect funcs to grunt --- server-ce/Gruntfile.coffee | 49 +++++++++++++++++++++++++++++++++++++- server-ce/package.json | 1 + 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 201f351646..b30c403709 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -8,6 +8,7 @@ knox = require "knox" crypto = require "crypto" async = require "async" settings = require("settings-sharelatex") +_ = require("underscore") SERVICES = require("./config/services") @@ -101,7 +102,7 @@ module.exports = (grunt) -> grunt.registerTask 'default', 'run' grunt.registerTask "check:redis", "Check that redis is installed and running", () -> - Helpers.checkRedis @async() + Helpers.checkRedisConnect @async() grunt.registerTask "check:latexmk", "Check that latexmk is installed", () -> Helpers.checkLatexmk @async() grunt.registerTask "check:s3", "Check that Amazon S3 credentials are configured", () -> @@ -113,6 +114,9 @@ module.exports = (grunt) -> grunt.registerTask "check:make", "Check that make is installed", () -> Helpers.checkMake @async() + grunt.registerTask "check:mongo", "Check that make is installed", () -> + Helpers.checkMongoConnect @async() + grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3", "check:fs", "check:aspell"] @@ -347,3 +351,46 @@ module.exports = (grunt) -> grunt.log.write "OK." return callback() + + checkMongoConnect: (callback = (error) ->) -> + grunt.log.write "Checking can connect to mongo" + mongojs = require("mongojs") + db = mongojs.connect(settings.mongo.url, ["tags"]) + db.runCommand { ping: 1 }, (err, res) -> + if !err and res.ok + grunt.log.write "OK." + return callback() + db.on 'error', (err)-> + err = "Can not connect to mongodb" + grunt.log.error "FAIL." + grunt.log.errorlns """ + + ShareLaTeX can not talk to the mongdb instance + + Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL + + """ + return callback(err) + + checkRedisConnect: (callback = (error) ->) -> + grunt.log.write "Checking can connect to redis\n" + rclient = require("redis").createClient(settings.redis.web) + + rclient.ping (err, res) -> + if !err? + grunt.log.write "OK." + else + throw new Error("hllll") + return callback() + errorHandler = _.once (err)-> + err = "Can not connect to redis" + grunt.log.error "FAIL." + grunt.log.errorlns """ + + ShareLaTeX can not talk to the redis instance + + Check the redis instance is running and accessible on env var SHARELATEX_REDIS_URL + + """ + return callback(err) + rclient.on 'error', errorHandler diff --git a/server-ce/package.json b/server-ce/package.json index 112c9adcf6..851b4d8af9 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -10,6 +10,7 @@ "load-grunt-config": "^0.19.2", "lodash": "^3.0.0", "mongojs": "^0.18.1", + "redis": "^2.6.2", "rimraf": "~2.2.6", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git", "underscore": "^1.7.0" From c41540fc026cecf131630d991eefa66fc45098e7 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 20 Sep 2016 17:08:38 +0100 Subject: [PATCH 259/525] =?UTF-8?q?remove=20helpers=20we=20don=E2=80=99t?= =?UTF-8?q?=20use?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server-ce/Gruntfile.coffee | 180 ------------------------------------- 1 file changed, 180 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index b30c403709..8bb11e01ee 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -103,16 +103,6 @@ module.exports = (grunt) -> grunt.registerTask "check:redis", "Check that redis is installed and running", () -> Helpers.checkRedisConnect @async() - grunt.registerTask "check:latexmk", "Check that latexmk is installed", () -> - Helpers.checkLatexmk @async() - grunt.registerTask "check:s3", "Check that Amazon S3 credentials are configured", () -> - Helpers.checkS3 @async() - grunt.registerTask "check:fs", "Check that local filesystem options are configured", () -> - Helpers.checkFS @async() - grunt.registerTask "check:aspell", "Check that aspell is installed", () -> - Helpers.checkAspell @async() - grunt.registerTask "check:make", "Check that make is installed", () -> - Helpers.checkMake @async() grunt.registerTask "check:mongo", "Check that make is installed", () -> Helpers.checkMongoConnect @async() @@ -181,176 +171,6 @@ module.exports = (grunt) -> proc.on "close", () -> callback() - checkRedis: (callback = (error) ->) -> - grunt.log.write "Checking Redis is running... " - exec "redis-cli info", (error, stdout, stderr) -> - if error? and error.message.match("Could not connect") - grunt.log.error "FAIL. Redis is not running" - return callback(error) - else if error? - return callback(error) - else - m = stdout.match(/redis_version:(.*)/) - if !m? - grunt.log.error "FAIL." - grunt.log.error "Unknown redis version" - error = new Error("Unknown redis version") - else - version = m[1] - if semver.gte(version, "2.6.12") - grunt.log.writeln "OK." - grunt.log.writeln "Running Redis version #{version}" - else - grunt.log.error "FAIL." - grunt.log.error "Redis version is too old (#{version}). Must be 2.6.12 or greater." - error = new Error("Redis version is too old (#{version}). Must be 2.6.12 or greater.") - callback(error) - - checkLatexmk: (callback = (error) ->) -> - grunt.log.write "Checking latexmk is installed... " - exec "latexmk --version", (error, stdout, stderr) -> - if error? and error.message.match("not found") - grunt.log.error "FAIL." - grunt.log.errorlns """ - Either latexmk is not installed or is not in your PATH. - - latexmk comes with TexLive 2013, and must be a version from 2013 or later. - If you have already have TeXLive installed, then make sure it is - included in your PATH (example for 64-bit linux): - - export PATH=$PATH:/usr/local/texlive/2014/bin/x86_64-linux/ - - This is a not a fatal error, but compiling will not work without latexmk. - """ - return callback(error) - else if error? - return callback(error) - else - m = stdout.match(/Version (.*)/) - if !m? - grunt.log.error "FAIL." - grunt.log.error "Unknown latexmk version" - error = new Error("Unknown latexmk version") - else - version = m[1] - if semver.gte(version + ".0", "4.39.0") - grunt.log.writeln "OK." - grunt.log.writeln "Running latexmk version #{version}" - else - grunt.log.error "FAIL." - grunt.log.errorlns """ - latexmk version is too old (#{version}). Must be 4.39 or greater. - This is a not a fatal error, but compiling will not work without latexmk - """ - error = new Error("latexmk is too old") - callback(error) - - checkAspell: (callback = (error) ->) -> - grunt.log.write "Checking aspell is installed... " - exec "aspell dump dicts", (error, stdout, stderr) -> - if error? and error.message.match("not found") - grunt.log.error "FAIL." - grunt.log.errorlns """ - Either aspell is not installed or is not in your PATH. - - On Ubuntu you can install aspell with: - - sudo apt-get install aspell - - Or on a mac: - - brew install aspell - - This is not a fatal error, but the spell-checker will not work without aspell - """ - return callback(error) - else if error? - return callback(error) - else - grunt.log.writeln "OK." - grunt.log.writeln "The following spell check dictionaries are available:" - grunt.log.write stdout - callback() - callback(error) - - checkS3: (callback = (error) ->) -> - Settings = require "settings-sharelatex" - if Settings.filestore.backend=="" - grunt.log.writeln "No backend specified. Assuming Amazon S3" - Settings.filestore.backend = "s3" - if Settings.filestore.backend=="s3" - grunt.log.write "Checking S3 credentials... " - try - client = knox.createClient({ - key: Settings.filestore.s3.key - secret: Settings.filestore.s3.secret - bucket: Settings.filestore.stores.user_files - }) - catch e - grunt.log.error "FAIL." - grunt.log.errorlns """ - Please configure your Amazon S3 credentials in config/settings.development.coffee - - Amazon S3 (Simple Storage Service) is a cloud storage service provided by - Amazon. ShareLaTeX uses S3 for storing binary files like images. You can - sign up for an account and find out more at: - - http://aws.amazon.com/s3/ - - """ - return callback() - client.getFile "does-not-exist", (error, response) -> - unless response? and response.statusCode == 404 - grunt.log.error "FAIL." - grunt.log.errorlns """ - Could not connect to Amazon S3. Please check your credentials. - """ - else - grunt.log.writeln "OK." - callback() - else - grunt.log.writeln "Filestore other than S3 configured. Not checking S3." - callback() - - checkFS: (callback = (error) ->) -> - Settings = require "settings-sharelatex" - if Settings.filestore.backend=="fs" - grunt.log.write "Checking FS configuration... " - fs = require("fs") - fs.exists Settings.filestore.stores.user_files, (exists) -> - if exists - grunt.log.writeln "OK." - else - grunt.log.error "FAIL." - grunt.log.errorlns """ - Could not find directory "#{Settings.filestore.stores.user_files}". - Please check your configuration. - """ - callback() - else - grunt.log.writeln "Filestore other than FS configured. Not checking FS." - callback() - - checkMake: (callback = (error) ->) -> - grunt.log.write "Checking make is installed... " - exec "make --version", (error, stdout, stderr) -> - if error? and error.message.match("not found") - grunt.log.error "FAIL." - grunt.log.errorlns """ - Either make is not installed or is not in your path. - - On Ubuntu you can install make with: - - sudo apt-get install build-essential - - """ - return callback(error) - else if error? - return callback(error) - else - grunt.log.write "OK." - return callback() - checkMongoConnect: (callback = (error) ->) -> grunt.log.write "Checking can connect to mongo" From 2443aa9e7550c6b5615be44ef8cb6a5c0efa1ea5 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 21 Sep 2016 12:08:11 +0100 Subject: [PATCH 260/525] added check make back in and list of make grunt tasks --- server-ce/Gruntfile.coffee | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 8bb11e01ee..06a009e955 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -73,7 +73,7 @@ module.exports = (grunt) -> ] "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install"]) "Update tasks": ("update:#{service.name}" for service in SERVICES).concat(["update:all", "update"]) - "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make"] + "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make", "check:mongo"] for service in SERVICES do (service) -> @@ -84,7 +84,7 @@ module.exports = (grunt) -> grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", - ["check:make"].concat( + [].concat( ("install:#{service.name}" for service in SERVICES) ) @@ -104,12 +104,13 @@ module.exports = (grunt) -> grunt.registerTask "check:redis", "Check that redis is installed and running", () -> Helpers.checkRedisConnect @async() - grunt.registerTask "check:mongo", "Check that make is installed", () -> + grunt.registerTask "check:mongo", "Check that mongo is installed", () -> Helpers.checkMongoConnect @async() - grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:latexmk", "check:s3", "check:fs", "check:aspell"] - + grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:mongo", "check:make"] + grunt.registerTask "check:make", "Check that make is installed", () -> + Helpers.checkMake @async() grunt.registerTask 'migrate', "compile migrations and run them", ['coffee:migrate', 'shell:migrate'] @@ -171,7 +172,25 @@ module.exports = (grunt) -> proc.on "close", () -> callback() + checkMake: (callback = (error) ->) -> + grunt.log.write "Checking make is installed... " + exec "make --version", (error, stdout, stderr) -> + if error? and error.message.match("not found") + grunt.log.error "FAIL." + grunt.log.errorlns """ + Either make is not installed or is not in your path. + On Ubuntu you can install make with: + + sudo apt-get install build-essential + + """ + return callback(error) + else if error? + return callback(error) + else + grunt.log.write "OK." + return callback() checkMongoConnect: (callback = (error) ->) -> grunt.log.write "Checking can connect to mongo" mongojs = require("mongojs") From 1e81ab7bef62171cdff253927d66e49c2e63e613 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 21 Sep 2016 12:43:58 +0100 Subject: [PATCH 261/525] throw errors in grunt when checking --- server-ce/Gruntfile.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 06a009e955..b11c3163bb 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -209,6 +209,7 @@ module.exports = (grunt) -> Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL """ + throw new Error("Can not connect to Mongodb") return callback(err) checkRedisConnect: (callback = (error) ->) -> @@ -219,7 +220,7 @@ module.exports = (grunt) -> if !err? grunt.log.write "OK." else - throw new Error("hllll") + throw new Error("Can not connect to redis") return callback() errorHandler = _.once (err)-> err = "Can not connect to redis" @@ -231,5 +232,6 @@ module.exports = (grunt) -> Check the redis instance is running and accessible on env var SHARELATEX_REDIS_URL """ + throw new Error("Can not connect to redis") return callback(err) rclient.on 'error', errorHandler From 66dcbb9b96b7bd94ff47beeb525d11c035558d77 Mon Sep 17 00:00:00 2001 From: ShareLaTeX Date: Wed, 21 Sep 2016 12:47:07 +0000 Subject: [PATCH 262/525] move settings file to early on --- server-ce/Dockerfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 63a584ad6d..cd53f43be7 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -13,6 +13,10 @@ RUN wget https://s3.amazonaws.com/sharelatex-random-files/qpdf-6.0.0.tar.gz && t WORKDIR /opt/qpdf-6.0.0 RUN ./configure && make && make install && ldconfig +# Install ShareLaTeX settings file +ADD ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee +ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee + # Install TexLive RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ mkdir /install-tl-unx; \ @@ -69,9 +73,6 @@ RUN cd /var/www/sharelatex/web; \ RUN cd /var/www/sharelatex/clsi; \ grunt compile:bin -# Install ShareLaTeX settings file -ADD ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee -ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee EXPOSE 80 From cb90144ae5d995a986d810982eea053f320fda80 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 21 Sep 2016 15:24:07 +0100 Subject: [PATCH 263/525] moved run.sh to run --- server-ce/runit/chat-sharelatex/{run.sh => run} | 0 server-ce/runit/clsi-sharelatex/{run.sh => run} | 0 server-ce/runit/docstore-sharelatex/{run.sh => run} | 0 server-ce/runit/document-updater-sharelatex/{run.sh => run} | 0 server-ce/runit/filestore-sharelatex/{run.sh => run} | 0 server-ce/runit/nginx/{run.sh => run} | 0 server-ce/runit/notifications-sharelatex/{run.sh => run} | 0 server-ce/runit/real-time-sharelatex/{run.sh => run} | 0 server-ce/runit/spelling-sharelatex/{run.sh => run} | 0 server-ce/runit/tags-sharelatex/{run.sh => run} | 0 server-ce/runit/track-changes-sharelatex/{run.sh => run} | 0 server-ce/runit/web-sharelatex/{run.sh => run} | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename server-ce/runit/chat-sharelatex/{run.sh => run} (100%) rename server-ce/runit/clsi-sharelatex/{run.sh => run} (100%) rename server-ce/runit/docstore-sharelatex/{run.sh => run} (100%) rename server-ce/runit/document-updater-sharelatex/{run.sh => run} (100%) rename server-ce/runit/filestore-sharelatex/{run.sh => run} (100%) rename server-ce/runit/nginx/{run.sh => run} (100%) rename server-ce/runit/notifications-sharelatex/{run.sh => run} (100%) rename server-ce/runit/real-time-sharelatex/{run.sh => run} (100%) rename server-ce/runit/spelling-sharelatex/{run.sh => run} (100%) rename server-ce/runit/tags-sharelatex/{run.sh => run} (100%) rename server-ce/runit/track-changes-sharelatex/{run.sh => run} (100%) rename server-ce/runit/web-sharelatex/{run.sh => run} (100%) diff --git a/server-ce/runit/chat-sharelatex/run.sh b/server-ce/runit/chat-sharelatex/run similarity index 100% rename from server-ce/runit/chat-sharelatex/run.sh rename to server-ce/runit/chat-sharelatex/run diff --git a/server-ce/runit/clsi-sharelatex/run.sh b/server-ce/runit/clsi-sharelatex/run similarity index 100% rename from server-ce/runit/clsi-sharelatex/run.sh rename to server-ce/runit/clsi-sharelatex/run diff --git a/server-ce/runit/docstore-sharelatex/run.sh b/server-ce/runit/docstore-sharelatex/run similarity index 100% rename from server-ce/runit/docstore-sharelatex/run.sh rename to server-ce/runit/docstore-sharelatex/run diff --git a/server-ce/runit/document-updater-sharelatex/run.sh b/server-ce/runit/document-updater-sharelatex/run similarity index 100% rename from server-ce/runit/document-updater-sharelatex/run.sh rename to server-ce/runit/document-updater-sharelatex/run diff --git a/server-ce/runit/filestore-sharelatex/run.sh b/server-ce/runit/filestore-sharelatex/run similarity index 100% rename from server-ce/runit/filestore-sharelatex/run.sh rename to server-ce/runit/filestore-sharelatex/run diff --git a/server-ce/runit/nginx/run.sh b/server-ce/runit/nginx/run similarity index 100% rename from server-ce/runit/nginx/run.sh rename to server-ce/runit/nginx/run diff --git a/server-ce/runit/notifications-sharelatex/run.sh b/server-ce/runit/notifications-sharelatex/run similarity index 100% rename from server-ce/runit/notifications-sharelatex/run.sh rename to server-ce/runit/notifications-sharelatex/run diff --git a/server-ce/runit/real-time-sharelatex/run.sh b/server-ce/runit/real-time-sharelatex/run similarity index 100% rename from server-ce/runit/real-time-sharelatex/run.sh rename to server-ce/runit/real-time-sharelatex/run diff --git a/server-ce/runit/spelling-sharelatex/run.sh b/server-ce/runit/spelling-sharelatex/run similarity index 100% rename from server-ce/runit/spelling-sharelatex/run.sh rename to server-ce/runit/spelling-sharelatex/run diff --git a/server-ce/runit/tags-sharelatex/run.sh b/server-ce/runit/tags-sharelatex/run similarity index 100% rename from server-ce/runit/tags-sharelatex/run.sh rename to server-ce/runit/tags-sharelatex/run diff --git a/server-ce/runit/track-changes-sharelatex/run.sh b/server-ce/runit/track-changes-sharelatex/run similarity index 100% rename from server-ce/runit/track-changes-sharelatex/run.sh rename to server-ce/runit/track-changes-sharelatex/run diff --git a/server-ce/runit/web-sharelatex/run.sh b/server-ce/runit/web-sharelatex/run similarity index 100% rename from server-ce/runit/web-sharelatex/run.sh rename to server-ce/runit/web-sharelatex/run From e98a23759c061a610090d202cf4b3e2f39d8ef2a Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 21 Sep 2016 16:59:37 +0100 Subject: [PATCH 264/525] install texcount on default image --- server-ce/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index cd53f43be7..d9a4b36e49 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -30,6 +30,7 @@ RUN rm -r /install-tl-unx; \ ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2016/bin/x86_64-linux/ RUN tlmgr install latexmk +RUN tlmgr install texcount RUN npm install -g grunt-cli From b32cdab053aff2d1a8287dfa2df8aa2586d06951 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 21 Sep 2016 17:54:46 +0100 Subject: [PATCH 265/525] spell check notifications --- server-ce/runit/notifications-sharelatex/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/runit/notifications-sharelatex/run b/server-ce/runit/notifications-sharelatex/run index 6d1629152c..12b3457f2c 100755 --- a/server-ce/runit/notifications-sharelatex/run +++ b/server-ce/runit/notifications-sharelatex/run @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/notifcations/app.js >> /var/log/sharelatex/notifcations.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/notifications/app.js >> /var/log/sharelatex/notifications.log 2>&1 \ No newline at end of file From ea7f7af88d595686df221f040777a08db5d2d467 Mon Sep 17 00:00:00 2001 From: ShareLaTeX Date: Wed, 21 Sep 2016 17:09:23 +0000 Subject: [PATCH 266/525] added notificaitons service --- server-ce/services.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server-ce/services.js b/server-ce/services.js index ed590505cc..3dcb1df7da 100644 --- a/server-ce/services.js +++ b/server-ce/services.js @@ -44,4 +44,8 @@ module.exports = name: "contacts", repo: "https://github.com/sharelatex/contacts-sharelatex.git", version: "master" +}, { + name: "notifications", + repo: "https://github.com/sharelatex/notifications-sharelatex.git", + version: "master" }] From 046faae5900579824f3a86f26c74b59ff0e8a00d Mon Sep 17 00:00:00 2001 From: ShareLaTeX Date: Wed, 21 Sep 2016 17:09:53 +0000 Subject: [PATCH 267/525] added contacts runit --- server-ce/runit/contacts-sharelatex.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 server-ce/runit/contacts-sharelatex.sh diff --git a/server-ce/runit/contacts-sharelatex.sh b/server-ce/runit/contacts-sharelatex.sh new file mode 100755 index 0000000000..29b513cb97 --- /dev/null +++ b/server-ce/runit/contacts-sharelatex.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/contacts/app.js >> /var/log/sharelatex/contacts 2>&1 From 22a3225e70faf42b38ac7728827358affc9e194d Mon Sep 17 00:00:00 2001 From: ShareLaTeX Date: Wed, 21 Sep 2016 17:10:27 +0000 Subject: [PATCH 268/525] added check db init script --- server-ce/init_scripts/98_check_db_access.sh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100755 server-ce/init_scripts/98_check_db_access.sh diff --git a/server-ce/init_scripts/98_check_db_access.sh b/server-ce/init_scripts/98_check_db_access.sh new file mode 100755 index 0000000000..a90adba84f --- /dev/null +++ b/server-ce/init_scripts/98_check_db_access.sh @@ -0,0 +1,5 @@ +#!/bin/sh +echo "Checking can connect to mongo and redis" +cd /var/www/sharelatex && grunt check:redis +cd /var/www/sharelatex && grunt check:mongo +echo "All checks passed" From 5e1f7d86fd324c2788b56a4c3e5443cb16d58793 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 22 Sep 2016 12:30:43 +0100 Subject: [PATCH 269/525] make errors more clear --- server-ce/Gruntfile.coffee | 10 +++++++--- server-ce/config/services.js | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index b11c3163bb..dd347da2aa 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -203,11 +203,13 @@ module.exports = (grunt) -> err = "Can not connect to mongodb" grunt.log.error "FAIL." grunt.log.errorlns """ - + !!!!!!!!!!!!!! MONGO ERROR !!!!!!!!!!!!!! + ShareLaTeX can not talk to the mongdb instance Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL - + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! """ throw new Error("Can not connect to Mongodb") return callback(err) @@ -226,11 +228,13 @@ module.exports = (grunt) -> err = "Can not connect to redis" grunt.log.error "FAIL." grunt.log.errorlns """ - + !!!!!!!!!!!!!! REDIS ERROR !!!!!!!!!!!!!! + ShareLaTeX can not talk to the redis instance Check the redis instance is running and accessible on env var SHARELATEX_REDIS_URL + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! """ throw new Error("Can not connect to redis") return callback(err) diff --git a/server-ce/config/services.js b/server-ce/config/services.js index 3a85bfb597..2072964383 100644 --- a/server-ce/config/services.js +++ b/server-ce/config/services.js @@ -48,4 +48,5 @@ module.exports = name: "notifications", repo: "https://github.com/sharelatex/notifications-sharelatex.git", version: "master" -}] +} +] From 1c3be11b8ca944b1c61f3419ebd9a0954d312110 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 22 Sep 2016 12:32:25 +0100 Subject: [PATCH 270/525] Update docker-compose.yml --- server-ce/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 07db7756a9..70ae0cdbd6 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -49,7 +49,7 @@ services: ## Server Pro ## ################ - # SANDBOXED_COMPILES: "true" + # SANDBOXED_COMPILES:true # SHARELATEX_LDAP_HOST: 'ldap://ldap.forumsys.com' # SHARELATEX_LDAP_DN: 'uid=:userKey,dc=example,dc=com' From 1fca396be2aade21836f944073ed3db21eae881e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 22 Sep 2016 12:45:45 +0100 Subject: [PATCH 271/525] fix comments for user create --- server-ce/grunt/CreateAndDestoryUsers.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server-ce/grunt/CreateAndDestoryUsers.coffee b/server-ce/grunt/CreateAndDestoryUsers.coffee index 293c1d6ef2..0f0bff2e0f 100644 --- a/server-ce/grunt/CreateAndDestoryUsers.coffee +++ b/server-ce/grunt/CreateAndDestoryUsers.coffee @@ -1,11 +1,11 @@ module.exports = (grunt) -> - grunt.registerTask 'user:create-admin', "Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt create-admin-user --email joe@example.com", () -> + grunt.registerTask 'user:create-admin', "Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt user:create-admin --email joe@example.com", () -> done = @async() email = grunt.option("email") if !email? - console.error "Usage: grunt create-admin-user --email joe@example.com" + console.error "Usage: grunt user:create-admin --email joe@example.com" process.exit(1) settings = require "settings-sharelatex" @@ -35,11 +35,11 @@ module.exports = (grunt) -> """ done() - grunt.registerTask 'user:delete', "deletes a user and all their data, Usage: grunt delete-user --email joe@example.com", () -> + grunt.registerTask 'user:delete', "deletes a user and all their data, Usage: grunt user:delete --email joe@example.com", () -> done = @async() email = grunt.option("email") if !email? - console.error "Usage: grunt delete-user --email joe@example.com" + console.error "Usage: grunt user:delete --email joe@example.com" process.exit(1) settings = require "settings-sharelatex" UserGetter = require "../web/app/js/Features/User/UserGetter" From 1fe4b894d542e597c90a9e88672fc07d36ad045e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 3 Oct 2016 16:54:11 +0100 Subject: [PATCH 272/525] set clsi home to tmp which fixed luatex bug --- server-ce/settings.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 3bbed39856..799cb73121 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -432,6 +432,7 @@ if process.env["SANDBOXED_COMPILES"] == "true" docker: image: process.env["TEX_LIVE_DOCKER_IMAGE"] env: + HOME: "/tmp" PATH: process.env["COMPILER_PATH"] or "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" user: "www-data" From 6db09c2c15f9c7b584d0188fc5092e80a1032a9c Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 13 Oct 2016 14:21:33 +0100 Subject: [PATCH 273/525] added textEncoding for email option --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 799cb73121..c9d99521bd 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -348,7 +348,7 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? secure: parse(process.env["SHARELATEX_EMAIL_SMTP_SECURE"]) ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"]) - + textEncoding: process.env["SHARELATEX_EMAIL_TEXT_ENCODING"] templates: customFooter: process.env["SHARELATEX_CUSTOM_EMAIL_FOOTER"] From 75364f058a3f265e6c1a8420a1d9e4c0bd315179 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 13 Oct 2016 15:46:18 +0100 Subject: [PATCH 274/525] Create ProjectSize.coffee --- server-ce/grunt/ProjectSize.coffee | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 server-ce/grunt/ProjectSize.coffee diff --git a/server-ce/grunt/ProjectSize.coffee b/server-ce/grunt/ProjectSize.coffee new file mode 100644 index 0000000000..1c8745a8e0 --- /dev/null +++ b/server-ce/grunt/ProjectSize.coffee @@ -0,0 +1,24 @@ +require("coffee-script") + +fs = require("fs") +_ = require("underscore") + +if not process.argv[2] + console.log "Usage: coffee project_size.coffee user_files_path" +else + dirPath = process.argv[2] + if not fs.lstatSync(dirPath).isDirectory() + console.log dirPath + " directory not exist" + else + fs.readdir dirPath, (err, files)-> + projects = [] + files.forEach (file)-> + project_id = file.split("_")[0] + if !projects[project_id] + projects[project_id] = 0 + projects[project_id] += fs.lstatSync(dirPath+"/"+file).size + + ids = _.keys projects + console.log "project \t size" + ids.forEach (id)-> + console.log id + "\t" + projects[id] From 3eeeccc0ec9f5abf5164820bc5945e563c14d9a8 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 19 Oct 2016 11:30:10 +0100 Subject: [PATCH 275/525] log out which version is being checked out --- server-ce/Gruntfile.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index dd347da2aa..217e06d2f0 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -147,6 +147,7 @@ module.exports = (grunt) -> checkoutVersion: (service, callback = (error) ->) -> dir = service.name + grunt.log.write "checking out #{service.name} #{service.version}" proc = spawn "git", ["checkout", service.version], stdio: "inherit", cwd: dir proc.on "close", () -> callback() From 3e13565a84a9746f948bcd7434585d1e60d3dbb8 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 19 Oct 2016 11:39:40 +0100 Subject: [PATCH 276/525] added coffeescript and moved admin require to bottom of file --- server-ce/Gruntfile.coffee | 6 +++++- server-ce/config/services.js | 2 +- server-ce/package.json | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 217e06d2f0..aca3b1cbbd 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -1,3 +1,4 @@ +coffee = require("coffee-script") fs = require "fs" spawn = require("child_process").spawn exec = require("child_process").exec @@ -20,7 +21,6 @@ module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-concurrent' grunt.loadNpmTasks "grunt-contrib-coffee" grunt.loadNpmTasks "grunt-shell" - require('load-grunt-config')(grunt) execute = {} @@ -240,3 +240,7 @@ module.exports = (grunt) -> throw new Error("Can not connect to redis") return callback(err) rclient.on 'error', errorHandler + + + require('load-grunt-config')(grunt) + diff --git a/server-ce/config/services.js b/server-ce/config/services.js index 2072964383..e324b129f3 100644 --- a/server-ce/config/services.js +++ b/server-ce/config/services.js @@ -3,7 +3,7 @@ module.exports = [{ name: "web", repo: "https://github.com/sharelatex/web-sharelatex.git", - version: "master" + version: "ha-docker" }, { name: "real-time", repo: "https://github.com/sharelatex/real-time-sharelatex.git", diff --git a/server-ce/package.json b/server-ce/package.json index 851b4d8af9..3d63f4c5fa 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -4,6 +4,7 @@ "description": "An online collaborative LaTeX editor", "dependencies": { "async": "^0.9.0", + "coffee-script": "^1.11.1", "east": "0.5.1", "east-mongo": "^0.1.2", "grunt-shell": "^1.1.1", From 1707ea187d38980dee41b5720568a6c8941cf58e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 19 Oct 2016 12:10:27 +0100 Subject: [PATCH 277/525] Update docker-compose.yml --- server-ce/docker-compose.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 70ae0cdbd6..efba08f4cc 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -18,31 +18,31 @@ services: environment: SHARELATEX_MONGO_URL: mongodb://mongo/sharelatex SHARELATEX_REDIS_HOST: redis - SHARELATEX_APP_NAME: 'Our ShareLaTeX' + SHARELATEX_APP_NAME: Our ShareLaTeX #Set for SSL via nginx-proxy #VIRTUAL_HOST: 103.112.212.22 - # SHARELATEX_SITE_URL: "http://sharelatex.mydomain.com" - # SHARELATEX_NAV_TITLE: "Our ShareLaTeX Instance" - # SHARELATEX_HEADER_IMAGE_URL: "http://somewhere.com/mylogo.png" - # SHARELATEX_ADMIN_EMAIL: "support@it.com" + # SHARELATEX_SITE_URL: http://sharelatex.mydomain.com + # SHARELATEX_NAV_TITLE: Our ShareLaTeX Instance + # SHARELATEX_HEADER_IMAGE_URL: http://somewhere.com/mylogo.png + # SHARELATEX_ADMIN_EMAIL: support@it.com # SHARELATEX_LEFT_FOOTER: '[{"text": "Powered by ShareLaTeX 2016"},{"text": "Another page I want to link to can be found here"} ]' # SHARELATEX_RIGHT_FOOTER: '[{"text": "Hello I am on the Right"} ]' # SHARELATEX_EMAIL_FROM_ADDRESS: "team@sharelatex.com" - # SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID: "" - # SHARELATEX_EMAIL_AWS_SES_SECRET_KEY: "" + # SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID: + # SHARELATEX_EMAIL_AWS_SES_SECRET_KEY: - # SHARELATEX_EMAIL_SMTP_HOST: "smtp.mydomain.com" + # SHARELATEX_EMAIL_SMTP_HOST: smtp.mydomain.com # SHARELATEX_EMAIL_SMTP_PORT: 587 - # SHARELATEX_EMAIL_SMTP_SECURE: 'false' - # SHARELATEX_EMAIL_SMTP_USER: "" - # SHARELATEX_EMAIL_SMTP_PASS: "" - # SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH: 'true' - # SHARELATEX_EMAIL_SMTP_IGNORE_TLS: 'false' + # SHARELATEX_EMAIL_SMTP_SECURE: false + # SHARELATEX_EMAIL_SMTP_USER: + # SHARELATEX_EMAIL_SMTP_PASS: + # SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH: true + # SHARELATEX_EMAIL_SMTP_IGNORE_TLS: false # SHARELATEX_CUSTOM_EMAIL_FOOTER:"
This system is run by department x
" ################ From 227666087c89aeee8abfcb0de97d52e0ba4633b8 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 21 Oct 2016 15:43:58 +0100 Subject: [PATCH 278/525] don't show register when external auth is used --- server-ce/package.json | 3 ++- server-ce/settings.coffee | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/server-ce/package.json b/server-ce/package.json index e1efb9b159..d3c19d112f 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -7,6 +7,7 @@ "grunt-contrib-rename": "0.0.3", "grunt-docker-io": "^0.7.0", "grunt-github-api": "^0.2.3", - "simple-git": "^1.32.1" + "simple-git": "^1.32.1", + "underscore": "^1.8.3" } } diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index c9d99521bd..81395d8b2e 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -1,4 +1,5 @@ Path = require('path') +_ = require("underscore") # These credentials are used for authenticating api requests # between services that may need to go over public channels @@ -391,6 +392,7 @@ if parse(process.env["SHARELATEX_IS_SERVER_PRO"]) == true if process.env["SHARELATEX_LDAP_HOST"] + settings.externalAuth = true settings.ldap = host: process.env["SHARELATEX_LDAP_HOST"] dn: process.env["SHARELATEX_LDAP_DN"] @@ -424,6 +426,9 @@ if process.env["SHARELATEX_LDAP_HOST"] rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true" ca:ca_paths # e.g.'/etc/ldap/ca_certs.pem' +if settings.externalAuth + settings.nav.header = _.filter settings.nav.header, (button)-> button.url != "/register" + # Compiler # -------- if process.env["SANDBOXED_COMPILES"] == "true" From 78008cd2a654bd8bba3a2278a484f5c290045463 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 3 Nov 2016 10:59:17 +0000 Subject: [PATCH 279/525] comment out project size for test --- server-ce/grunt/ProjectSize.coffee | 42 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/server-ce/grunt/ProjectSize.coffee b/server-ce/grunt/ProjectSize.coffee index 1c8745a8e0..1d02d33d26 100644 --- a/server-ce/grunt/ProjectSize.coffee +++ b/server-ce/grunt/ProjectSize.coffee @@ -1,24 +1,24 @@ -require("coffee-script") +# require("coffee-script") -fs = require("fs") -_ = require("underscore") +# fs = require("fs") +# _ = require("underscore") -if not process.argv[2] - console.log "Usage: coffee project_size.coffee user_files_path" -else - dirPath = process.argv[2] - if not fs.lstatSync(dirPath).isDirectory() - console.log dirPath + " directory not exist" - else - fs.readdir dirPath, (err, files)-> - projects = [] - files.forEach (file)-> - project_id = file.split("_")[0] - if !projects[project_id] - projects[project_id] = 0 - projects[project_id] += fs.lstatSync(dirPath+"/"+file).size +# if not process.argv[2] +# console.log "Usage: coffee project_size.coffee user_files_path" +# else +# dirPath = process.argv[2] +# if not fs.lstatSync(dirPath).isDirectory() +# console.log dirPath + " directory not exist" +# else +# fs.readdir dirPath, (err, files)-> +# projects = [] +# files.forEach (file)-> +# project_id = file.split("_")[0] +# if !projects[project_id] +# projects[project_id] = 0 +# projects[project_id] += fs.lstatSync(dirPath+"/"+file).size - ids = _.keys projects - console.log "project \t size" - ids.forEach (id)-> - console.log id + "\t" + projects[id] +# ids = _.keys projects +# console.log "project \t size" +# ids.forEach (id)-> +# console.log id + "\t" + projects[id] From fa55d8017e992405601721d602962af4976f0617 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 3 Nov 2016 11:18:34 +0000 Subject: [PATCH 280/525] remove underscore from settings.coffee --- server-ce/settings.coffee | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 81395d8b2e..2ecd4295f4 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -1,5 +1,4 @@ Path = require('path') -_ = require("underscore") # These credentials are used for authenticating api requests # between services that may need to go over public channels @@ -427,8 +426,13 @@ if process.env["SHARELATEX_LDAP_HOST"] ca:ca_paths # e.g.'/etc/ldap/ca_certs.pem' if settings.externalAuth - settings.nav.header = _.filter settings.nav.header, (button)-> button.url != "/register" + results = [] + for button in settings.nav.header + if button.url != "/register" + results.push(button) + settings.nav.header = results + # Compiler # -------- if process.env["SANDBOXED_COMPILES"] == "true" From 3b2cbfd7434cf87be8591f9ae9e71874d67beb9f Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 3 Nov 2016 15:13:02 +0000 Subject: [PATCH 281/525] should check SHARELATEX_REDIS_HOST not SHARELATEX_REDIS_URL --- server-ce/Gruntfile.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 217e06d2f0..da95f2d46e 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -233,7 +233,7 @@ module.exports = (grunt) -> ShareLaTeX can not talk to the redis instance - Check the redis instance is running and accessible on env var SHARELATEX_REDIS_URL + Check the redis instance is running and accessible on env var SHARELATEX_REDIS_HOST !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! """ From 8be95a5169b590c84f885f62b2528e1ea2dcff22 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 3 Nov 2016 16:28:25 +0000 Subject: [PATCH 282/525] Use the ? operator --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 2ecd4295f4..57d3c22c0d 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -416,7 +416,7 @@ if process.env["SHARELATEX_LDAP_HOST"] if typeof(ca) == 'string' ca_paths = [ca] - else if typeof(ca) == 'object' && ca.length? + else if typeof(ca) == 'object' && ca?.length? ca_paths = ca else console.error "problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH" From f1ce0b406829423567a796e46760341c6d49db96 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 4 Nov 2016 15:14:33 +0000 Subject: [PATCH 283/525] check that nav.header is configured --- server-ce/settings.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 57d3c22c0d..691de1d9f4 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -425,14 +425,14 @@ if process.env["SHARELATEX_LDAP_HOST"] rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true" ca:ca_paths # e.g.'/etc/ldap/ca_certs.pem' -if settings.externalAuth +if settings.externalAuth and settings?.nav?.header? results = [] for button in settings.nav.header if button.url != "/register" results.push(button) settings.nav.header = results - + # Compiler # -------- if process.env["SANDBOXED_COMPILES"] == "true" From 494839591adbb5ca916f09b4a4db9f40555ac848 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 8 Nov 2016 22:37:31 +0000 Subject: [PATCH 284/525] added default features --- server-ce/settings.coffee | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 691de1d9f4..50d12acfdb 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -295,7 +295,14 @@ settings = references:{} notifications:undefined - + defaultFeatures: + collaborators: -1 + dropbox: true + versioning: true + compileTimeout: 180 + compileGroup: "standard" + references: true + templates: true #### OPTIONAL CONFIGERABLE SETTINGS From 2042575b86cb495dab23703360f1ae31f26b9324 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Mon, 14 Nov 2016 15:40:18 +0000 Subject: [PATCH 285/525] Add saml config options --- server-ce/settings.coffee | 59 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 691de1d9f4..85f87677f5 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -425,6 +425,65 @@ if process.env["SHARELATEX_LDAP_HOST"] rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true" ca:ca_paths # e.g.'/etc/ldap/ca_certs.pem' +if process.env["SHARELATEX_SAML_ENTRYPOINT"] + # NOTE: see https://github.com/bergie/passport-saml/blob/master/README.md for docs of `server` options + settings.externalAuth = true + settings.saml = + server: + # strings + entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"] + callbackUrl: process.env["SHARELATEX_SAML_CALLBACK_URL"] + issuer: process.env["SHARELATEX_SAML_ISSUER"] + cert: process.env["SHARELATEX_SAML_CERT"] + privateCert: process.env["SHARELATEX_SAML_PRIVATE_CERT"] + decryptionPvk: process.env["SHARELATEX_SAML_DECRYPTION_PVK"] + signatureAlgorithm: process.env["SHARELATEX_SAML_SIGNATURE_ALGORITHM"] + identifierFormat: process.env["SHARELATEX_SAML_IDENTIFIER_FORMAT"] + attributeConsumingServiceIndex: process.env["SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX"] + authnContext: process.env["SHARELATEX_SAML_AUTHN_CONTEXT"] + authnRequestBinding: process.env["SHARELATEX_SAML_AUTHN_REQUEST_BINDING"] + validateInResponseTo: process.env["SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO"] + cacheProvider: process.env["SHARELATEX_SAML_CACHE_PROVIDER"] + logoutUrl: process.env["SHARELATEX_SAML_LOGOUT_URL"] + additionalLogoutParams: process.env["SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"] + logoutCallbackUrl: process.env["SHARELATEX_SAML_LOGOUT_CALLBACK_URL"] + disableRequestedAuthnContext: process.env["SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT"] == 'true' + forceAuthn: process.env["SHARELATEX_SAML_FORCE_AUTHN"] == 'true' + skipRequestCompression: process.env["SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION"] == 'true' + acceptedClockSkewMs: ( + if _saml_skew = process.env["SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"] + try + parseInt(_saml_skew) + catch e + console.error "Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS" + else + undefined + ) + requestIdExpirationPeriodMs: ( + if _saml_exiration = process.env["SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"] + try + parseInt(_saml_expiration) + catch e + console.error "Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS" + else + undefined + ) + + identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"] + + if _saml_additionalParams = process.env["SHARELATEX_SAML_ADDITIONAL_PARAMS"] + try + settings.saml.server.additionalAuthorizeParams = JSON.parse(_saml_additionalParams) + catch e + console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS" + + if _saml_additionalAuthorizeParams = process.env["SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"] + try + settings.saml.server.additionalAuthorizeParams = JSON.parse(_saml_additionalAuthorizeParams ) + catch e + console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS" + + if settings.externalAuth and settings?.nav?.header? results = [] for button in settings.nav.header From 1c3f8451436ab192d9206727b23aa1fb499e7ba2 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Mon, 14 Nov 2016 15:46:12 +0000 Subject: [PATCH 286/525] Refactor. --- server-ce/settings.coffee | 44 +++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 9d8fcef66b..8ac6e34307 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -436,6 +436,7 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] # NOTE: see https://github.com/bergie/passport-saml/blob/master/README.md for docs of `server` options settings.externalAuth = true settings.saml = + identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"] server: # strings entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"] @@ -452,7 +453,6 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] validateInResponseTo: process.env["SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO"] cacheProvider: process.env["SHARELATEX_SAML_CACHE_PROVIDER"] logoutUrl: process.env["SHARELATEX_SAML_LOGOUT_URL"] - additionalLogoutParams: process.env["SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"] logoutCallbackUrl: process.env["SHARELATEX_SAML_LOGOUT_CALLBACK_URL"] disableRequestedAuthnContext: process.env["SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT"] == 'true' forceAuthn: process.env["SHARELATEX_SAML_FORCE_AUTHN"] == 'true' @@ -475,21 +475,33 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] else undefined ) - - identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"] - - if _saml_additionalParams = process.env["SHARELATEX_SAML_ADDITIONAL_PARAMS"] - try - settings.saml.server.additionalAuthorizeParams = JSON.parse(_saml_additionalParams) - catch e - console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS" - - if _saml_additionalAuthorizeParams = process.env["SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"] - try - settings.saml.server.additionalAuthorizeParams = JSON.parse(_saml_additionalAuthorizeParams ) - catch e - console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS" - + additionalParams: ( + if _saml_additionalParams = process.env["SHARELATEX_SAML_ADDITIONAL_PARAMS"] + try + JSON.parse(_saml_additionalParams) + catch e + console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS" + else + undefined + ) + additionalAuthorizeParams: ( + if _saml_additionalAuthorizeParams = process.env["SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"] + try + JSON.parse(_saml_additionalAuthorizeParams ) + catch e + console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS" + else + undefined + ) + additionalLogoutParams: ( + if _saml_additionalLogoutParams = process.env["SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"] + try + JSON.parse(_saml_additionalLogoutParams ) + catch e + console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS" + else + undefined + ) if settings.externalAuth and settings?.nav?.header? results = [] From 5d69513fe870a30aa6d37d7e85538efd3700dcca Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 15 Nov 2016 10:19:20 +0000 Subject: [PATCH 287/525] Create ISSUE_TEMPLATE --- server-ce/ISSUE_TEMPLATE | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 server-ce/ISSUE_TEMPLATE diff --git a/server-ce/ISSUE_TEMPLATE b/server-ce/ISSUE_TEMPLATE new file mode 100644 index 0000000000..0a49049094 --- /dev/null +++ b/server-ce/ISSUE_TEMPLATE @@ -0,0 +1,4 @@ +Please tell us the following when opening an issue + +- Offical Docker version being run: +- URL to appropriate logs: From d94b622a8e537c04749be831f454c1c1bbf3bda3 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 15 Nov 2016 10:19:58 +0000 Subject: [PATCH 288/525] Update ISSUE_TEMPLATE --- server-ce/ISSUE_TEMPLATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/ISSUE_TEMPLATE b/server-ce/ISSUE_TEMPLATE index 0a49049094..0408054675 100644 --- a/server-ce/ISSUE_TEMPLATE +++ b/server-ce/ISSUE_TEMPLATE @@ -1,4 +1,4 @@ Please tell us the following when opening an issue -- Offical Docker version being run: +- Official Docker version being run: - URL to appropriate logs: From fc868f00258a86c9b0c1c85b1dd4e68e3b8a0abc Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 15 Nov 2016 10:27:21 +0000 Subject: [PATCH 289/525] Update docker-compose.yml --- server-ce/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index efba08f4cc..2cd7434505 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -43,7 +43,7 @@ services: # SHARELATEX_EMAIL_SMTP_PASS: # SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH: true # SHARELATEX_EMAIL_SMTP_IGNORE_TLS: false - # SHARELATEX_CUSTOM_EMAIL_FOOTER:"
This system is run by department x
" + # SHARELATEX_CUSTOM_EMAIL_FOOTER: "
This system is run by department x
" ################ ## Server Pro ## From 6f9891891043ad8d1056572fd4c3623f548fd80f Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 15 Nov 2016 10:29:06 +0000 Subject: [PATCH 290/525] Update README.md --- server-ce/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 70c32d9e76..a94976919b 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -30,48 +30,48 @@ This repository does not contain any code. It acts a wrapper and toolkit for man The different services are: -### [web](https://github.com/sharelatex/web-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/web-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/web-sharelatex) +### [web](https://github.com/sharelatex/web-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/web-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/web-sharelatex) The front facing web server that serves all the HTML pages, CSS and JavaScript to the client. Also contains a lot of logic around creating and editing projects, and account management. -### [document-updater](https://github.com/sharelatex/document-updater-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/document-updater-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/document-updater-sharelatex) +### [document-updater](https://github.com/sharelatex/document-updater-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/document-updater-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/document-updater-sharelatex) Processes updates that come in from the editor when users modify documents. Ensures that the updates are applied in the right order, and that only one operation is modifying the document at a time. Also caches the documents in redis for very fast but persistent modifications. -### [CLSI](https://github.com/sharelatex/clsi-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/clsi-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/clsi-sharelatex) +### [CLSI](https://github.com/sharelatex/clsi-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/clsi-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/clsi-sharelatex) The Common LaTeX Service Interface (CLSI) which provides an API for compiling LaTeX documents. -### [docstore](https://github.com/sharelatex/docstore-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/docstore-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/docstore-sharelatex) +### [docstore](https://github.com/sharelatex/docstore-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/docstore-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/docstore-sharelatex) An API for performing CRUD (Create, Read, Update and Delete) operations on text files stored in ShareLaTeX. -### [realtime](https://github.com/sharelatex/real-time-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/real-time-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/real-time-sharelatex) +### [realtime](https://github.com/sharelatex/real-time-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/real-time-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/real-time-sharelatex) The websocket process clients connect to -### [filestore](https://github.com/sharelatex/filestore-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/filestore-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/filestore-sharelatex) +### [filestore](https://github.com/sharelatex/filestore-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/filestore-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/filestore-sharelatex) An API for performing CRUD (Create, Read, Update and Delete) operations on binary files (like images) stored in ShareLaTeX. -### [track-changes](https://github.com/sharelatex/track-changes-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/track-changes-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/track-changes-sharelatex) +### [track-changes](https://github.com/sharelatex/track-changes-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/track-changes-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/track-changes-sharelatex) An API for compressing and storing the updates applied to a document, and then rendering a diff of the changes between any two time points. -### [chat](https://github.com/sharelatex/chat-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/chat-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/chat-sharelatex) +### [chat](https://github.com/sharelatex/chat-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/chat-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/chat-sharelatex) The backend API for storing and fetching chat messages. -### [tags](https://github.com/sharelatex/tags-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/tags-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/tags-sharelatex) +### [tags](https://github.com/sharelatex/tags-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/tags-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/tags-sharelatex) The backend API for managing project tags (folders). From 62849c79eedac2a267736a22ebd7b3cc768bd6a7 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 17 Nov 2016 15:42:51 +0000 Subject: [PATCH 291/525] Update README.md --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index a94976919b..19d5567717 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -14,7 +14,7 @@ Installation We have detailed installation instructions in our wiki: -* [Installing ShareLaTeX in Production using docker](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) +* [ShareLaTeX Quick Start Guide](https://github.com/sharelatex/sharelatex/wiki/Quick-Start-Guide) Upgrading From 3aecf9abe4d27c46f6fca2b79a8cb541378d89c9 Mon Sep 17 00:00:00 2001 From: Ethan Date: Sat, 19 Nov 2016 19:02:27 -0800 Subject: [PATCH 292/525] =?UTF-8?q?Update=20+1=20to=20=F0=9F=91=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change comment with a +1 to modern github reaction (👍) --- server-ce/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index a40bc8814f..3b32dee34e 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -14,7 +14,7 @@ If you'd like a report a bug or open an issue then please: 1. **Find the correct repository.** ShareLaTeX is split across multiple different repositories, each containing a different service (you can find a list of [all repositories here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories)). If you know the bug only applies to one service, then please open an issue in that repository. For general bugs and issues that span more than one service, please open an issue in the [sharelatex/sharelatex](https://github.com/sharelatex/sharelatex) repository. 2. **Check if there is an existing issue.** If there is then please add - any more information that you have, or give it a "+1" in the comments. + any more information that you have, or give it a 👍. When submitting an issue please describe the issue as clearly as possible, including how to reproduce the bug, which situations it appears in, what you expected to happen, and what actually happens. From 4de0d3538446cab7d46788ee89cffcd69f939361 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 23 Nov 2016 10:37:35 +0000 Subject: [PATCH 293/525] Add saml emailFieldName option --- server-ce/settings.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 8ac6e34307..b2113c1d91 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -437,6 +437,7 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] settings.externalAuth = true settings.saml = identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"] + emailFieldName: process.env["SHARELATEX_SAML_EMAIL_FIELD_NAME"] server: # strings entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"] From 8a8ac600d1d879cb2626b60ada46a5a0424a3952 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 23 Nov 2016 14:13:37 +0000 Subject: [PATCH 294/525] Add options for saml firstName and lastName fields. --- server-ce/settings.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index b2113c1d91..2bb169d8dc 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -437,7 +437,9 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] settings.externalAuth = true settings.saml = identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"] - emailFieldName: process.env["SHARELATEX_SAML_EMAIL_FIELD_NAME"] + emailField: process.env["SHARELATEX_SAML_EMAIL_FIELD"] || process.env["SHARELATEX_SAML_EMAIL_FIELD_NAME"] + firstNameField: process.env["SHARELATEX_SAML_FIRST_NAME_FIELD"] + lastNameField: process.env["SHARELATEX_SAML_LAST_NAME_FIELD"] server: # strings entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"] From b1a3be45109307476ece0ec6659f3631cd0608ad Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 23 Nov 2016 15:32:44 +0000 Subject: [PATCH 295/525] change how grunt splits tasks up which fix broken migrate call --- server-ce/Gruntfile.coffee | 4 ++-- server-ce/{grunt => tasks}/CreateAndDestoryUsers.coffee | 0 server-ce/{grunt => tasks}/ProjectSize.coffee | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename server-ce/{grunt => tasks}/CreateAndDestoryUsers.coffee (100%) rename server-ce/{grunt => tasks}/ProjectSize.coffee (100%) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index c2af03cf45..fc2c654427 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -22,6 +22,7 @@ module.exports = (grunt) -> grunt.loadNpmTasks "grunt-contrib-coffee" grunt.loadNpmTasks "grunt-shell" + grunt.task.loadTasks "./tasks" execute = {} for service in SERVICES @@ -112,7 +113,7 @@ module.exports = (grunt) -> grunt.registerTask "check:make", "Check that make is installed", () -> Helpers.checkMake @async() - grunt.registerTask 'migrate', "compile migrations and run them", ['coffee:migrate', 'shell:migrate'] + grunt.registerTask 'migrate', "compile migrations and run them", ["coffee:migrate", 'shell:migrate'] Helpers = @@ -242,5 +243,4 @@ module.exports = (grunt) -> rclient.on 'error', errorHandler - require('load-grunt-config')(grunt) diff --git a/server-ce/grunt/CreateAndDestoryUsers.coffee b/server-ce/tasks/CreateAndDestoryUsers.coffee similarity index 100% rename from server-ce/grunt/CreateAndDestoryUsers.coffee rename to server-ce/tasks/CreateAndDestoryUsers.coffee diff --git a/server-ce/grunt/ProjectSize.coffee b/server-ce/tasks/ProjectSize.coffee similarity index 100% rename from server-ce/grunt/ProjectSize.coffee rename to server-ce/tasks/ProjectSize.coffee From cc878e4caf2af5b7010df2478c71d16703da4483 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 2 Dec 2016 14:01:19 +0000 Subject: [PATCH 296/525] Add an `update_user_features` migration. --- .../migrations/4_update_user_features.coffee | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 server-ce/migrations/4_update_user_features.coffee diff --git a/server-ce/migrations/4_update_user_features.coffee b/server-ce/migrations/4_update_user_features.coffee new file mode 100644 index 0000000000..0a13416e5c --- /dev/null +++ b/server-ce/migrations/4_update_user_features.coffee @@ -0,0 +1,32 @@ +Settings = require "settings-sharelatex" +fs = require("fs") +mongojs = require("mongojs") +ObjectId = mongojs.ObjectId +db = mongojs(Settings.mongo.url, ['users']) +_ = require("underscore") +BSON = db.bson.BSON + +handleExit = () -> + console.log('Got signal. Shutting down.') + +process.on 'SIGINT', handleExit +process.on 'SIGHUP', handleExit + +module.exports.migrate = (client, done=()->) -> + patch = { + $set: { + features: { + collaborators: -1 + dropbox: true + versioning: true + references: true + templates: true + compileTimeout: 180 + compileGroup: "standard" + } + } + } + console.log ">> updating all user features: ", patch + db.users.update {}, patch, {multi: true}, (err) -> + console.log "finished updating all user features" + return done(err) From afcd6b9f53e921c4d967e6a8951dad0af87c5262 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 2 Dec 2016 14:12:52 +0000 Subject: [PATCH 297/525] Add a dummy rollback, clean up. --- server-ce/migrations/4_update_user_features.coffee | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/server-ce/migrations/4_update_user_features.coffee b/server-ce/migrations/4_update_user_features.coffee index 0a13416e5c..8704c23ec4 100644 --- a/server-ce/migrations/4_update_user_features.coffee +++ b/server-ce/migrations/4_update_user_features.coffee @@ -6,13 +6,16 @@ db = mongojs(Settings.mongo.url, ['users']) _ = require("underscore") BSON = db.bson.BSON + handleExit = () -> console.log('Got signal. Shutting down.') + process.on 'SIGINT', handleExit process.on 'SIGHUP', handleExit -module.exports.migrate = (client, done=()->) -> + +exports.migrate = (client, done=()->) -> patch = { $set: { features: { @@ -30,3 +33,7 @@ module.exports.migrate = (client, done=()->) -> db.users.update {}, patch, {multi: true}, (err) -> console.log "finished updating all user features" return done(err) + + +exports.rollback = (client, done) -> + done() From 06c9ebdd7262e63512d47df7f7fedd59766d4a91 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 2 Dec 2016 15:12:57 +0000 Subject: [PATCH 298/525] Add `updateUserDetailsOnLogin` options to ldap and saml. --- server-ce/settings.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 2bb169d8dc..1397930cfc 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -414,6 +414,7 @@ if process.env["SHARELATEX_LDAP_HOST"] starttls: parse(process.env["SHARELATEX_LDAP_TLS"]) nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"] lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"] + updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] try @@ -436,6 +437,7 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] # NOTE: see https://github.com/bergie/passport-saml/blob/master/README.md for docs of `server` options settings.externalAuth = true settings.saml = + updateUserDetailsOnLogin: process.env["SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"] emailField: process.env["SHARELATEX_SAML_EMAIL_FIELD"] || process.env["SHARELATEX_SAML_EMAIL_FIELD_NAME"] firstNameField: process.env["SHARELATEX_SAML_FIRST_NAME_FIELD"] From 799cca1d6d970dbfd17507ab093055207b03ec84 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 9 Dec 2016 09:22:31 +0000 Subject: [PATCH 299/525] Update to new ldap config --- server-ce/settings.coffee | 126 +++++++++++++++++++++++++++++++++----- 1 file changed, 111 insertions(+), 15 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 1397930cfc..683b674036 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -397,24 +397,116 @@ if parse(process.env["SHARELATEX_IS_SERVER_PRO"]) == true # When testing with forumsys.com use username = einstein and password = password +# if process.env["SHARELATEX_LDAP_HOST"] +# settings.externalAuth = true +# settings.ldap = +# host: process.env["SHARELATEX_LDAP_HOST"] +# dn: process.env["SHARELATEX_LDAP_DN"] +# baseSearch: process.env["SHARELATEX_LDAP_BASE_SEARCH"] +# filter: process.env["SHARELATEX_LDAP_FILTER"] +# failMessage: process.env["SHARELATEX_LDAP_FAIL_MESSAGE"] or 'LDAP User Fail' +# fieldName: process.env["SHARELATEX_LDAP_FIELD_NAME"] or 'LDAP User' +# placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"] or 'LDAP User ID' +# emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"] or 'mail' +# anonymous: parse(process.env["SHARELATEX_LDAP_ANONYMOUS"]) +# adminDN: process.env["SHARELATEX_LDAP_ADMIN_DN"] +# adminPW: process.env["SHARELATEX_LDAP_ADMIN_PW"] +# starttls: parse(process.env["SHARELATEX_LDAP_TLS"]) +# nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"] +# lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"] +# updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' + +# if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] +# try +# ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]) +# catch e +# console.error "could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON" + +# if typeof(ca) == 'string' +# ca_paths = [ca] +# else if typeof(ca) == 'object' && ca?.length? +# ca_paths = ca +# else +# console.error "problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH" + +# settings.ldap.tlsOptions = +# rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true" +# ca:ca_paths # e.g.'/etc/ldap/ca_certs.pem' + + + + +# LDAP - SERVER PRO ONLY +# ---------- + if process.env["SHARELATEX_LDAP_HOST"] + console.error """ +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# WARNING: The LDAP configuration format has changed in version 0.5.1 +# See https://github.com/sharelatex/sharelatex/wiki/Server-Pro:-LDAP-Config +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +""" + +if process.env["SHARELATEX_LDAP_URL"] settings.externalAuth = true settings.ldap = - host: process.env["SHARELATEX_LDAP_HOST"] - dn: process.env["SHARELATEX_LDAP_DN"] - baseSearch: process.env["SHARELATEX_LDAP_BASE_SEARCH"] - filter: process.env["SHARELATEX_LDAP_FILTER"] - failMessage: process.env["SHARELATEX_LDAP_FAIL_MESSAGE"] or 'LDAP User Fail' - fieldName: process.env["SHARELATEX_LDAP_FIELD_NAME"] or 'LDAP User' - placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"] or 'LDAP User ID' - emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"] or 'mail' - anonymous: parse(process.env["SHARELATEX_LDAP_ANONYMOUS"]) - adminDN: process.env["SHARELATEX_LDAP_ADMIN_DN"] - adminPW: process.env["SHARELATEX_LDAP_ADMIN_PW"] - starttls: parse(process.env["SHARELATEX_LDAP_TLS"]) - nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"] - lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"] + server: + url: process.env["SHARELATEX_LDAP_URL"] + bindDn: process.env["SHARELATEX_LDAP_BIND_DN"] + bindCredentials: process.env["SHARELATEX_LDAP_BIND_CREDENTIALS"] + bindProperty: process.env["SHARELATEX_LDAP_BIND_PROPERTY"] + searchBase: process.env["SHARELATEX_LDAP_SEARCHBASE"] + searchScope: process.env["SHARELATEX_LDAP_SEARCH_SCOPE"] + searchFilter: process.env["SHARELATEX_LDAP_SEARCH_FILTER"] + searchAttributes: ( + if _ldap_search_attribs = process.env["SHARELATEX_LDAP_SEARCH_ATTRIBUTES"] + try + JSON.parse(_ldap_search_attribs) + catch + console.error "could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES" + else + undefined + ) + groupDnProperty: process.env["SHARELATEX_LDAP_GROUP_DN_PROPERTY"] + groupSearchBase: process.env["SHARELATEX_LDAP_GROUP_SEARCH_BASE"] + groupSearchScope: process.env["SHARELATEX_LDAP_GROUP_SEARCH_SCOPE"] + groupSearchFilter: process.env["SHARELATEX_LDAP_GROUP_SEARCH_FILTER"] # + groupSearchAttributes: ( + if _ldap_group_search_attribs = process.env["SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"] + try + JSON.parse(_ldap_group_search_attribs) + catch + console.error "could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES" + else + undefined + ) + cache: process.env["SHARELATEX_LDAP_CACHE"] == 'true' + timeout: ( + if _ldap_timeout = process.env["SHARELATEX_LDAP_TIMEOUT"] + try + parseInt(_ldap_timeout) + catch e + console.error "Cannot parse SHARELATEX_LDAP_TIMEOUT" + else + undefined + ) + connectTimeout: ( + if _ldap_connect_timeout = process.env["SHARELATEX_LDAP_CONNECT_TIMEOUT"] + try + parseInt(_ldap_connect_timeout) + catch e + console.error "Cannot parse SHARELATEX_CONNECTLDAP_TIMEOUT" + else + undefined + ) + emailAtt: process.env["SHARELATEX_LDAP_"] + nameAtt: process.env["SHARELATEX_LDAP_"] + lastNameAtt: process.env["SHARELATEX_LDAP_"] updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' + placeholder: process.env["SHARELATEX_LDAP_"] + starttls: process.env["SHARELATEX_LDAP_TLS"] == 'true' if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] try @@ -429,10 +521,14 @@ if process.env["SHARELATEX_LDAP_HOST"] else console.error "problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH" - settings.ldap.tlsOptions = + settings.ldap.server.tlsOptions = rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true" ca:ca_paths # e.g.'/etc/ldap/ca_certs.pem' + + + + if process.env["SHARELATEX_SAML_ENTRYPOINT"] # NOTE: see https://github.com/bergie/passport-saml/blob/master/README.md for docs of `server` options settings.externalAuth = true From 779bbfa2613deb37f58620156cfa4ee8c8086fbb Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 9 Dec 2016 10:40:43 +0000 Subject: [PATCH 300/525] Remove the starttls option --- server-ce/settings.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 683b674036..db943f45bb 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -506,7 +506,6 @@ if process.env["SHARELATEX_LDAP_URL"] lastNameAtt: process.env["SHARELATEX_LDAP_"] updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' placeholder: process.env["SHARELATEX_LDAP_"] - starttls: process.env["SHARELATEX_LDAP_TLS"] == 'true' if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] try From 6e99800298e7a321b1fd9df7b11c64b9203903c5 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 9 Dec 2016 11:01:01 +0000 Subject: [PATCH 301/525] Fix ldap settings --- server-ce/settings.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index db943f45bb..06778973e5 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -452,6 +452,11 @@ if process.env["SHARELATEX_LDAP_HOST"] if process.env["SHARELATEX_LDAP_URL"] settings.externalAuth = true settings.ldap = + emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"] + nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"] + lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"] + updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' + placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"] server: url: process.env["SHARELATEX_LDAP_URL"] bindDn: process.env["SHARELATEX_LDAP_BIND_DN"] @@ -472,7 +477,7 @@ if process.env["SHARELATEX_LDAP_URL"] groupDnProperty: process.env["SHARELATEX_LDAP_GROUP_DN_PROPERTY"] groupSearchBase: process.env["SHARELATEX_LDAP_GROUP_SEARCH_BASE"] groupSearchScope: process.env["SHARELATEX_LDAP_GROUP_SEARCH_SCOPE"] - groupSearchFilter: process.env["SHARELATEX_LDAP_GROUP_SEARCH_FILTER"] # + groupSearchFilter: process.env["SHARELATEX_LDAP_GROUP_SEARCH_FILTER"] groupSearchAttributes: ( if _ldap_group_search_attribs = process.env["SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"] try @@ -501,11 +506,6 @@ if process.env["SHARELATEX_LDAP_URL"] else undefined ) - emailAtt: process.env["SHARELATEX_LDAP_"] - nameAtt: process.env["SHARELATEX_LDAP_"] - lastNameAtt: process.env["SHARELATEX_LDAP_"] - updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' - placeholder: process.env["SHARELATEX_LDAP_"] if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] try From bef595eced87ca5ed1046eff9265d48cbcd12ea9 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 9 Dec 2016 11:13:20 +0000 Subject: [PATCH 302/525] Add error var --- server-ce/settings.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 06778973e5..6c41616556 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -469,7 +469,7 @@ if process.env["SHARELATEX_LDAP_URL"] if _ldap_search_attribs = process.env["SHARELATEX_LDAP_SEARCH_ATTRIBUTES"] try JSON.parse(_ldap_search_attribs) - catch + catch e console.error "could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES" else undefined @@ -482,7 +482,7 @@ if process.env["SHARELATEX_LDAP_URL"] if _ldap_group_search_attribs = process.env["SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"] try JSON.parse(_ldap_group_search_attribs) - catch + catch e console.error "could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES" else undefined From 17d2d4561ddfe59e5c2272924afb400ba358ce22 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 9 Dec 2016 12:34:08 +0000 Subject: [PATCH 303/525] Fix daft typos --- server-ce/settings.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 6c41616556..14a5c0d49f 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -462,7 +462,7 @@ if process.env["SHARELATEX_LDAP_URL"] bindDn: process.env["SHARELATEX_LDAP_BIND_DN"] bindCredentials: process.env["SHARELATEX_LDAP_BIND_CREDENTIALS"] bindProperty: process.env["SHARELATEX_LDAP_BIND_PROPERTY"] - searchBase: process.env["SHARELATEX_LDAP_SEARCHBASE"] + searchBase: process.env["SHARELATEX_LDAP_SEARCH_BASE"] searchScope: process.env["SHARELATEX_LDAP_SEARCH_SCOPE"] searchFilter: process.env["SHARELATEX_LDAP_SEARCH_FILTER"] searchAttributes: ( @@ -502,7 +502,7 @@ if process.env["SHARELATEX_LDAP_URL"] try parseInt(_ldap_connect_timeout) catch e - console.error "Cannot parse SHARELATEX_CONNECTLDAP_TIMEOUT" + console.error "Cannot parse SHARELATEX_LDAP_CONNECT_TIMEOUT" else undefined ) From eadfb316b499a2b0930ff0cffcc493f05d3a3739 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 19 Dec 2016 14:17:39 +0000 Subject: [PATCH 304/525] chown /var/www/ to www-data --- server-ce/init_scripts/00_make_sharelatex_data_dirs.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh index 6085a087da..7857b984fb 100755 --- a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh +++ b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh @@ -26,6 +26,8 @@ chown www-data:www-data /var/lib/sharelatex/tmp/uploads mkdir -p /var/lib/sharelatex/tmp/dumpFolder chown www-data:www-data /var/lib/sharelatex/tmp/dumpFolder +chown www-data:www-data /var/www/ + if [ ! -e "/var/lib/sharelatex/data/db.sqlite" ]; then touch /var/lib/sharelatex/data/db.sqlite fi From b585560dd0b3416b42458c8796950891984162fc Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 20 Dec 2016 10:28:37 +0000 Subject: [PATCH 305/525] Remove cruft. --- server-ce/settings.coffee | 45 --------------------------------------- 1 file changed, 45 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 14a5c0d49f..5c795e17dc 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -391,51 +391,6 @@ if parse(process.env["SHARELATEX_IS_SERVER_PRO"]) == true url: "http://localhost:3040" -# LDAP - SERVER PRO ONLY -# ---------- -# Settings below use a working LDAP test server kindly provided by forumsys.com -# When testing with forumsys.com use username = einstein and password = password - - -# if process.env["SHARELATEX_LDAP_HOST"] -# settings.externalAuth = true -# settings.ldap = -# host: process.env["SHARELATEX_LDAP_HOST"] -# dn: process.env["SHARELATEX_LDAP_DN"] -# baseSearch: process.env["SHARELATEX_LDAP_BASE_SEARCH"] -# filter: process.env["SHARELATEX_LDAP_FILTER"] -# failMessage: process.env["SHARELATEX_LDAP_FAIL_MESSAGE"] or 'LDAP User Fail' -# fieldName: process.env["SHARELATEX_LDAP_FIELD_NAME"] or 'LDAP User' -# placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"] or 'LDAP User ID' -# emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"] or 'mail' -# anonymous: parse(process.env["SHARELATEX_LDAP_ANONYMOUS"]) -# adminDN: process.env["SHARELATEX_LDAP_ADMIN_DN"] -# adminPW: process.env["SHARELATEX_LDAP_ADMIN_PW"] -# starttls: parse(process.env["SHARELATEX_LDAP_TLS"]) -# nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"] -# lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"] -# updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' - -# if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] -# try -# ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]) -# catch e -# console.error "could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON" - -# if typeof(ca) == 'string' -# ca_paths = [ca] -# else if typeof(ca) == 'object' && ca?.length? -# ca_paths = ca -# else -# console.error "problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH" - -# settings.ldap.tlsOptions = -# rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true" -# ca:ca_paths # e.g.'/etc/ldap/ca_certs.pem' - - - - # LDAP - SERVER PRO ONLY # ---------- From 8f37d7dd2ce72410bc7b637cf829b6f639d7c175 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 20 Dec 2016 10:28:54 +0000 Subject: [PATCH 306/525] add `restrictInvitesToExistingAccounts` option --- server-ce/settings.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 5c795e17dc..b5d74c701d 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -109,6 +109,7 @@ settings = # The name this is used to describe your ShareLaTeX Installation appName: process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX (Community Edition)" + restrictInvitesToExistingAccounts: process.env["SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS"] == 'true' nav: title: process.env["SHARELATEX_NAV_TITLE"] or process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX Community Edition" From 453311136f0ad60417897c12511b6ea01dd6af88 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 21 Dec 2016 13:51:05 +0000 Subject: [PATCH 307/525] Move the filtering-out of `/register` links to web --- server-ce/settings.coffee | 7 ------- 1 file changed, 7 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index b5d74c701d..58f83c5def 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -559,13 +559,6 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] undefined ) -if settings.externalAuth and settings?.nav?.header? - results = [] - for button in settings.nav.header - if button.url != "/register" - results.push(button) - settings.nav.header = results - # Compiler # -------- From fa29f0f19d4c907aaf79dad1c88a7cc6dcee2ea3 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 21 Dec 2016 14:57:47 +0000 Subject: [PATCH 308/525] Fix the header-nav links option --- server-ce/settings.coffee | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 58f83c5def..a132c4eb99 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -305,7 +305,7 @@ settings = references: true templates: true -#### OPTIONAL CONFIGERABLE SETTINGS +## OPTIONAL CONFIGERABLE SETTINGS if process.env["SHARELATEX_LEFT_FOOTER"]? try @@ -322,9 +322,12 @@ if process.env["SHARELATEX_RIGHT_FOOTER"]? if process.env["SHARELATEX_HEADER_IMAGE_URL"]? settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"] - -if process.env["SHARELATEX_HEADER"]? - settings.nav.header = process.env["SHARELATEX_HEADER_NAV_LINKS"] + +if process.env["SHARELATEX_HEADER_NAV_LINKS"]? + try + settings.nav.header = JSON.parse(process.env["SHARELATEX_HEADER_NAV_LINKS"]) + catch e + console.error("could not parse SHARELATEX_HEADER_NAV_LINKS, not valid JSON") # if process.env["SHARELATEX_PROXY_LEARN"]? # settings.nav.header.push({text: "help", class: "subdued", dropdown: [{text: "documentation", url: "/learn"}] }) From c6153c5b44f3458b15c562014c5fb17234a9f803 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 4 Jan 2017 11:41:38 +0000 Subject: [PATCH 309/525] - added option to set lang code - removed commeted out learn header code - increased max pass length to 150 --- server-ce/settings.coffee | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index a132c4eb99..c410305a59 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -148,6 +148,12 @@ settings = behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] or false + # Site Languages + i18n: + subdomainLang: + www: {lngCode:process.env["SHARELATEX_SITE_LANGUAGE"] or "en", url: siteUrl} + defaultLng: process.env["SHARELATEX_SITE_LANGUAGE"] or "en" + # Spell Check Languages # --------------------- # @@ -329,9 +335,6 @@ if process.env["SHARELATEX_HEADER_NAV_LINKS"]? catch e console.error("could not parse SHARELATEX_HEADER_NAV_LINKS, not valid JSON") -# if process.env["SHARELATEX_PROXY_LEARN"]? -# settings.nav.header.push({text: "help", class: "subdued", dropdown: [{text: "documentation", url: "/learn"}] }) - # Sending Email # ------------- @@ -381,7 +384,7 @@ if process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or process.env["SHARELA settings.passwordStrengthOptions = pattern: process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or "aA$3" - length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] or 50} + length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] or 150} From b1e6b8a5e9241aa3a540a90cbe5e267dedf54422 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 6 Jan 2017 11:28:32 +0000 Subject: [PATCH 310/525] add option to set lang per domain --- server-ce/settings.coffee | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index c410305a59..25dfe1e548 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -148,7 +148,6 @@ settings = behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] or false - # Site Languages i18n: subdomainLang: www: {lngCode:process.env["SHARELATEX_SITE_LANGUAGE"] or "en", url: siteUrl} @@ -374,7 +373,12 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? if process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]? settings.email.parameters.tls = rejectUnauthorized: parse(process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]) - + + +# i18n +if process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]? + + settings.i18n.subdomainLang = parse(process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]) # Password Settings # ----------- From af4703a2e27114219e953568bd485c2164a0adc2 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 6 Jan 2017 16:02:27 +0000 Subject: [PATCH 311/525] remove proxy_set_header X-Forwarded-Proto $scheme for https --- server-ce/nginx/sharelatex.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/server-ce/nginx/sharelatex.conf b/server-ce/nginx/sharelatex.conf index 0111797967..cf63f4c5c4 100644 --- a/server-ce/nginx/sharelatex.conf +++ b/server-ce/nginx/sharelatex.conf @@ -10,7 +10,6 @@ server { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Host $host; - proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 3m; proxy_send_timeout 3m; From 581ec86fb178029371578755a28d811f4c0609f1 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 12 Jan 2017 13:51:10 +0000 Subject: [PATCH 312/525] Add new SHARELATEX_HEADER_EXTRAS option --- server-ce/settings.coffee | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index a132c4eb99..77e4085642 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -324,10 +324,21 @@ if process.env["SHARELATEX_HEADER_IMAGE_URL"]? settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"] if process.env["SHARELATEX_HEADER_NAV_LINKS"]? + console.error """ +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# WARNING: SHARELATEX_HEADER_NAV_LINKS is no longer supported +# See https://github.com/sharelatex/sharelatex/wiki/Configuring-Headers,-Footers-&-Logo +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +""" + +if process.env["SHARELATEX_HEADER_EXTRAS"]? try - settings.nav.header = JSON.parse(process.env["SHARELATEX_HEADER_NAV_LINKS"]) + settings.nav.header_extras = JSON.parse(process.env["SHARELATEX_HEADER_EXTRAS"]) catch e - console.error("could not parse SHARELATEX_HEADER_NAV_LINKS, not valid JSON") + console.error("could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON") + # if process.env["SHARELATEX_PROXY_LEARN"]? # settings.nav.header.push({text: "help", class: "subdued", dropdown: [{text: "documentation", url: "/learn"}] }) From 8478935071fc3d8aafaf82fb826cee9db34e4815 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 13 Jan 2017 11:39:34 -0500 Subject: [PATCH 313/525] add /var/log/sharlatex-errors.log --- server-ce/runit/errorlogs/run | 2 ++ 1 file changed, 2 insertions(+) create mode 100755 server-ce/runit/errorlogs/run diff --git a/server-ce/runit/errorlogs/run b/server-ce/runit/errorlogs/run new file mode 100755 index 0000000000..e4053dab9e --- /dev/null +++ b/server-ce/runit/errorlogs/run @@ -0,0 +1,2 @@ +#!/bin/bash +tail -F /var/log/sharelatex/*.log | grep '"level":50' >> /var/log/sharlatex-errors.log From 13c2fd794bae0cf09532b0ff574a743e6a6dabd0 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 24 Jan 2017 10:35:05 +0000 Subject: [PATCH 314/525] Move `web-sharelatex` back to `master` branch. --- server-ce/config/services.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/config/services.js b/server-ce/config/services.js index e324b129f3..2072964383 100644 --- a/server-ce/config/services.js +++ b/server-ce/config/services.js @@ -3,7 +3,7 @@ module.exports = [{ name: "web", repo: "https://github.com/sharelatex/web-sharelatex.git", - version: "ha-docker" + version: "master" }, { name: "real-time", repo: "https://github.com/sharelatex/real-time-sharelatex.git", From d18b1b08050afd4bf88fd457e699852c72739b89 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 25 Jan 2017 15:22:32 +0000 Subject: [PATCH 315/525] Un-pin doc-updater --- server-ce/services.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/services.js b/server-ce/services.js index 3dcb1df7da..b79ab9a4b7 100644 --- a/server-ce/services.js +++ b/server-ce/services.js @@ -11,7 +11,7 @@ module.exports = }, { name: "document-updater", repo: "https://github.com/sharelatex/document-updater-sharelatex.git", - version: "75c84e2" + version: "master" }, { name: "clsi", repo: "https://github.com/sharelatex/clsi-sharelatex.git", From c172455cd7d8abd55a49e434f89e0b2ee51799dd Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 26 Jan 2017 10:27:17 +0000 Subject: [PATCH 316/525] Add documentupdater config --- server-ce/settings.coffee | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index f1e32e87bc..7b6fc315d3 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -44,6 +44,19 @@ settings = port: process.env["SHARELATEX_REDIS_PORT"] or "6379" password: process.env["SHARELATEX_REDIS_PASS"] or "" fairy: redisConfig + documentupdater: + port: process.env["SHARELATEX_REDIS_PORT"] or "6379" + host: process.env["SHARELATEX_REDIS_HOST"] or "dockerhost" + password: process.env["SHARELATEX_REDIS_PASS"] or "" + key_schema: + blockingKey: ({doc_id}) -> "Blocking:#{doc_id}" + docLines: ({doc_id}) -> "doclines:#{doc_id}" + docOps: ({doc_id}) -> "DocOps:#{doc_id}" + docVersion: ({doc_id}) -> "DocVersion:#{doc_id}" + projectKey: ({doc_id}) -> "ProjectId:#{doc_id}" + docsInProject: ({project_id}) -> "DocsIn:#{project_id}" + ranges: ({doc_id}) -> "Ranges:#{doc_id}" + # The compile server (the clsi) uses a SQL database to cache files and # meta-data. sqllite is the default, and the load is low enough that this will From f0dc32f8791d6ac90655b27d0b313ec8cbca650e Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 26 Jan 2017 13:43:07 +0000 Subject: [PATCH 317/525] Add array wrapper --- server-ce/settings.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 7b6fc315d3..f60ff9f106 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -44,7 +44,7 @@ settings = port: process.env["SHARELATEX_REDIS_PORT"] or "6379" password: process.env["SHARELATEX_REDIS_PASS"] or "" fairy: redisConfig - documentupdater: + documentupdater: [{ port: process.env["SHARELATEX_REDIS_PORT"] or "6379" host: process.env["SHARELATEX_REDIS_HOST"] or "dockerhost" password: process.env["SHARELATEX_REDIS_PASS"] or "" @@ -56,6 +56,7 @@ settings = projectKey: ({doc_id}) -> "ProjectId:#{doc_id}" docsInProject: ({project_id}) -> "DocsIn:#{project_id}" ranges: ({doc_id}) -> "Ranges:#{doc_id}" + }] # The compile server (the clsi) uses a SQL database to cache files and From d4f00fca5a5eb024533626e6139711ca672cab22 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 27 Jan 2017 09:52:55 +0000 Subject: [PATCH 318/525] replace spaces with tabs --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index f60ff9f106..53cf424853 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -56,7 +56,7 @@ settings = projectKey: ({doc_id}) -> "ProjectId:#{doc_id}" docsInProject: ({project_id}) -> "DocsIn:#{project_id}" ranges: ({doc_id}) -> "Ranges:#{doc_id}" - }] + }] # The compile server (the clsi) uses a SQL database to cache files and From 634881529429c21debaf967bc96c99b56be76ea3 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 27 Jan 2017 13:28:14 +0000 Subject: [PATCH 319/525] Add primary=true --- server-ce/settings.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 53cf424853..394a1d09f9 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -45,6 +45,7 @@ settings = password: process.env["SHARELATEX_REDIS_PASS"] or "" fairy: redisConfig documentupdater: [{ + primary: true port: process.env["SHARELATEX_REDIS_PORT"] or "6379" host: process.env["SHARELATEX_REDIS_HOST"] or "dockerhost" password: process.env["SHARELATEX_REDIS_PASS"] or "" From 92da38bb6b28533a11a7992081e745d46a4b51f7 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 30 Jan 2017 14:36:06 +0100 Subject: [PATCH 320/525] Add migration to remove holding accounts --- .../5_remove_holding_accounts.coffee | 53 +++++++++++++++++++ server-ce/migrations/about_migrations.md | 11 +++- 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 server-ce/migrations/5_remove_holding_accounts.coffee diff --git a/server-ce/migrations/5_remove_holding_accounts.coffee b/server-ce/migrations/5_remove_holding_accounts.coffee new file mode 100644 index 0000000000..c9ab2a041b --- /dev/null +++ b/server-ce/migrations/5_remove_holding_accounts.coffee @@ -0,0 +1,53 @@ +Settings = require "settings-sharelatex" +mongojs = require("mongojs") +ObjectId = mongojs.ObjectId +db = mongojs(Settings.mongo.url, ['users', 'projects']) +async = require "async" + +findHoldingAccounts = (callback = (error, users) ->) -> + db.users.find({holdingAccount: true}, {holdingAccount: 1, email: 1}, callback) + +deleteUserProjects = (user_id, callback = (error) ->) -> + # Holding accounts can't own projects, so only remove from + # collaberator_refs and readOnly_refs + console.log "[Removing user from projects]", user_id + db.projects.update { + $or: [ + {collaberator_refs: user_id}, + {readOnly_refs: user_id} + ] + }, { + $pull: { + collaberator_refs: user_id, + readOnly_refs: user_id + } + }, { + multi: true + }, (error, result) -> + console.log "[Removed user from projects]", user_id, result + callback(error) + +deleteUser = (user_id, callback = (error) ->) -> + if !user_id? + throw new Error("must have user_id") + console.log "[Removing user]", user_id + db.users.remove {_id: user_id}, (error, result) -> + console.log "[Removed user]", user_id, result + callback(error) + +exports.migrate = (client, done=()->) -> + findHoldingAccounts (error, users) -> + throw error if error? + console.log "[Got list of holding accounts]", users.map (u) -> u._id + jobs = users.map (u) -> + (cb) -> + deleteUserProjects u._id, (error) -> + return cb(error) if error? + deleteUser u._id, cb + async.series jobs, (error) -> + throw error if error? + console.log "[Removed holding accounts]" + done() + +exports.rollback = (client, done) -> + done() diff --git a/server-ce/migrations/about_migrations.md b/server-ce/migrations/about_migrations.md index 146cb9c047..97f91442b1 100644 --- a/server-ce/migrations/about_migrations.md +++ b/server-ce/migrations/about_migrations.md @@ -1,2 +1,9 @@ -* if migration is stopped mid way it will start at the beginging next time -* to see the run migrations do db.getCollection('_migrations').find() you can't do db._migrations.find() \ No newline at end of file +If migration is stopped mid way it will start at the beginging next time + +To see the run migrations do db.getCollection('_migrations').find() you can't do db._migrations.find() + +When testing, to roll back a migration run: + +``` +./node_modules/east/bin/east rollback 5 --adapter east-mongo --url mongodb://localhost:27017/sharelatex +``` From a53939827592b8b4dc9a5169e9601638774d4b4c Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 30 Jan 2017 15:40:31 +0100 Subject: [PATCH 321/525] Add in dry run option for holding account migration and log out removed users --- .../5_remove_holding_accounts.coffee | 116 +++++++++++------- 1 file changed, 73 insertions(+), 43 deletions(-) diff --git a/server-ce/migrations/5_remove_holding_accounts.coffee b/server-ce/migrations/5_remove_holding_accounts.coffee index c9ab2a041b..a4afe59582 100644 --- a/server-ce/migrations/5_remove_holding_accounts.coffee +++ b/server-ce/migrations/5_remove_holding_accounts.coffee @@ -4,50 +4,80 @@ ObjectId = mongojs.ObjectId db = mongojs(Settings.mongo.url, ['users', 'projects']) async = require "async" -findHoldingAccounts = (callback = (error, users) ->) -> - db.users.find({holdingAccount: true}, {holdingAccount: 1, email: 1}, callback) +module.exports = HoldingAccountMigration = + DRY_RUN: true -deleteUserProjects = (user_id, callback = (error) ->) -> - # Holding accounts can't own projects, so only remove from - # collaberator_refs and readOnly_refs - console.log "[Removing user from projects]", user_id - db.projects.update { - $or: [ - {collaberator_refs: user_id}, - {readOnly_refs: user_id} - ] - }, { - $pull: { - collaberator_refs: user_id, - readOnly_refs: user_id - } - }, { - multi: true - }, (error, result) -> - console.log "[Removed user from projects]", user_id, result - callback(error) + findHoldingAccounts: (callback = (error, users) ->) -> + db.users.find({holdingAccount: true}, {holdingAccount: 1, email: 1}, callback) -deleteUser = (user_id, callback = (error) ->) -> - if !user_id? - throw new Error("must have user_id") - console.log "[Removing user]", user_id - db.users.remove {_id: user_id}, (error, result) -> - console.log "[Removed user]", user_id, result - callback(error) + deleteUserProjects: (user_id, callback = (error) ->) -> + # Holding accounts can't own projects, so only remove from + # collaberator_refs and readOnly_refs + console.log "[Removing user from projects]", user_id + db.projects.find { + $or: [ + {collaberator_refs: user_id}, + {readOnly_refs: user_id} + ] + }, { collaberator_refs: 1, readOnly_refs: 1 }, (error, projects = []) -> + return callback(error) if error? + jobs = projects.map (project) -> + (cb) -> + console.log "[Removing user from project]", user_id, JSON.stringify(project) + if !project._id? + throw new Error("no project id") + + if !HoldingAccountMigration.DRY_RUN + db.projects.update { + _id: project._id + }, { + $pull: { + collaberator_refs: user_id, + readOnly_refs: user_id + } + }, (error, result) -> + return cb(error) if error? + console.log "[Removed user from project]", user_id, project._id, result + cb() + else + console.log "[Would have removed user from project]", user_id, project._id + cb() + + async.series jobs, callback -exports.migrate = (client, done=()->) -> - findHoldingAccounts (error, users) -> - throw error if error? - console.log "[Got list of holding accounts]", users.map (u) -> u._id - jobs = users.map (u) -> - (cb) -> - deleteUserProjects u._id, (error) -> - return cb(error) if error? - deleteUser u._id, cb - async.series jobs, (error) -> + deleteUser: (user_id, callback = (error) ->) -> + if !user_id? + throw new Error("must have user_id") + db.users.find {_id: user_id}, (error, user) -> + return callback(error) if error? + if !user? + throw new Error("expected user") + console.log "[Removing user]", user_id, JSON.stringify(user) + if !HoldingAccountMigration.DRY_RUN + db.users.remove {_id: user_id}, (error, result) -> + console.log "[Removed user]", user_id, result + callback(error) + else + console.log "[Would have removed user]", user_id + callback() + + run: (done) -> + HoldingAccountMigration.findHoldingAccounts (error, users) -> throw error if error? - console.log "[Removed holding accounts]" - done() - -exports.rollback = (client, done) -> - done() + console.log "[Got list of holding accounts]", users.map (u) -> u._id + jobs = users.map (u) -> + (cb) -> + HoldingAccountMigration.deleteUserProjects u._id, (error) -> + return cb(error) if error? + HoldingAccountMigration.deleteUser u._id, cb + async.series jobs, (error) -> + throw error if error? + console.log "[Removed holding accounts]" + done() + + migrate: (client, done=()->) -> + HoldingAccountMigration.DRY_RUN = false + HoldingAccountMigration.run(done) + + rollback: (client, done) -> + done() From ee0c7293e97f4992a0a0ab1e2a42e6bdf7a2c812 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 2 Feb 2017 14:09:55 +0000 Subject: [PATCH 322/525] Add launchpad to docker build --- server-ce/Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index d9a4b36e49..4e721dc5ef 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -63,7 +63,10 @@ RUN cd /var/www && npm install RUN cd /var/www/sharelatex; \ npm install; \ - grunt install; + grunt install; \ + cd web/modules; \ + git clone https://bitbucket.org/sharelatex/launchpad-webmodule.git launchpad; \ + grunt compile; RUN cd /var/www && node git-revision > revisions.txt From 1e843c52dacb64d61f72853d10237f0a7780ee1e Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 3 Feb 2017 14:10:42 +0000 Subject: [PATCH 323/525] add sandboxed compiles sibling containers --- server-ce/settings.coffee | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 394a1d09f9..7891c4a1a5 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -611,6 +611,12 @@ if process.env["SANDBOXED_COMPILES"] == "true" if !settings.path? settings.path = {} settings.path.synctexBaseDir = () -> "/compile" + if process.env['SANDBOXED_COMPILES_SIBLING_CONTAINERS'] == 'true' + console.log("Using sibling containers for sandoxed compiles") + if process.env['SANDBOXED_COMPILES_HOST_DIR'] + settings.path.sandboxedCompilesHostDir = process.env['SANDBOXED_COMPILES_HOST_DIR'] + else + console.error('Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set') # Templates From 29b2648606d0984d253499ef321e15d6c526a693 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 21 Feb 2017 11:01:52 +0000 Subject: [PATCH 324/525] Remove texlive docks --- server-ce/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 4e721dc5ef..b8ca0a0360 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -23,7 +23,8 @@ RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ - /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile + /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile; \ + rm -rf /usr/local/texlive/2016/texmf-dist/doc/ RUN rm -r /install-tl-unx; \ rm install-tl-unx.tar.gz From 3c431008ddf4837c403d102a23116cdb33b7f80c Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 21 Feb 2017 11:22:25 +0000 Subject: [PATCH 325/525] split base image from main image --- server-ce/Dockerfile | 50 ++++----------------------------------- server-ce/Dockerfile-base | 41 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 46 deletions(-) create mode 100644 server-ce/Dockerfile-base diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index b8ca0a0360..2e688a0c55 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -1,58 +1,18 @@ -FROM phusion/baseimage:0.9.16 +FROM sharelatex-base-image -ENV baseDir . - -RUN apt-get update -RUN curl -sL https://deb.nodesource.com/setup | sudo bash - -RUN apt-get install -y build-essential wget nodejs unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu - -ADD ${baseDir}/logrotate/sharelatex /etc/logrotate.d/sharelatex - -WORKDIR /opt -RUN wget https://s3.amazonaws.com/sharelatex-random-files/qpdf-6.0.0.tar.gz && tar xzf qpdf-6.0.0.tar.gz -WORKDIR /opt/qpdf-6.0.0 -RUN ./configure && make && make install && ldconfig - -# Install ShareLaTeX settings file +# Install sharelatex settings file ADD ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee -# Install TexLive -RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ - mkdir /install-tl-unx; \ - tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 - -RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ - /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile; \ - rm -rf /usr/local/texlive/2016/texmf-dist/doc/ - -RUN rm -r /install-tl-unx; \ - rm install-tl-unx.tar.gz - -ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2016/bin/x86_64-linux/ -RUN tlmgr install latexmk -RUN tlmgr install texcount - -RUN npm install -g grunt-cli - -# Set up sharelatex user and home directory -RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex; \ - mkdir -p /var/lib/sharelatex; \ - chown www-data:www-data /var/lib/sharelatex; \ - mkdir -p /var/log/sharelatex; \ - chown www-data:www-data /var/log/sharelatex; \ - mkdir -p /var/lib/sharelatex/data/template_files; \ - chown www-data:www-data /var/lib/sharelatex/data/template_files; - - ADD ${baseDir}/runit /etc/service RUN rm /etc/nginx/sites-enabled/default ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf -COPY ${baseDir}/init_scripts/ /etc/my_init.d/ +ADD ${baseDir}/logrotate/sharelatex /etc/logrotate.d/sharelatex +COPY ${baseDir}/init_scripts/ /etc/my_init.d/ # Install ShareLaTeX RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex #random_change @@ -78,8 +38,6 @@ RUN cd /var/www/sharelatex/web; \ RUN cd /var/www/sharelatex/clsi; \ grunt compile:bin - - EXPOSE 80 WORKDIR / diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base new file mode 100644 index 0000000000..55c69e0aa5 --- /dev/null +++ b/server-ce/Dockerfile-base @@ -0,0 +1,41 @@ +# Sharelatex Base Image + +FROM phusion/baseimage:0.9.16 + +ENV baseDir . + +RUN apt-get update +RUN curl -sL https://deb.nodesource.com/setup | sudo bash - +RUN apt-get install -y build-essential wget nodejs unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu + +WORKDIR /opt +RUN wget https://s3.amazonaws.com/sharelatex-random-files/qpdf-6.0.0.tar.gz && tar xzf qpdf-6.0.0.tar.gz +WORKDIR /opt/qpdf-6.0.0 +RUN ./configure && make && make install && ldconfig + +# Install TexLive +RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ + mkdir /install-tl-unx; \ + tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 + +RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ + /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile + +RUN rm -r /install-tl-unx; \ + rm install-tl-unx.tar.gz + +ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2016/bin/x86_64-linux/ +RUN tlmgr install latexmk +RUN tlmgr install texcount + +RUN npm install -g grunt-cli + +# Set up sharelatex user and home directory +RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex; \ + mkdir -p /var/lib/sharelatex; \ + chown www-data:www-data /var/lib/sharelatex; \ + mkdir -p /var/log/sharelatex; \ + chown www-data:www-data /var/log/sharelatex; \ + mkdir -p /var/lib/sharelatex/data/template_files; \ + chown www-data:www-data /var/lib/sharelatex/data/template_files; + From 4c78f400b2d728faf4fdfdf85d6aa0d531edc4ac Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 22 Feb 2017 09:20:07 +0000 Subject: [PATCH 326/525] Update image names --- server-ce/Dockerfile | 4 +++- server-ce/Dockerfile-base | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 2e688a0c55..0efcdefa30 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -1,4 +1,6 @@ -FROM sharelatex-base-image +# Sharelatex Community Edition (sharelatex/sharelatex) + +FROM sharelatex/sharelatex-base # Install sharelatex settings file ADD ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index 55c69e0aa5..4142c48b0c 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -1,4 +1,4 @@ -# Sharelatex Base Image +# Sharelatex Base Image (sharelatex/sharelatex-base) FROM phusion/baseimage:0.9.16 From 618c2710393c0cff82e7d6a2214098001d52eba6 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 22 Feb 2017 09:23:01 +0000 Subject: [PATCH 327/525] Add a makefil --- server-ce/Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 server-ce/Makefile diff --git a/server-ce/Makefile b/server-ce/Makefile new file mode 100644 index 0000000000..75e967936a --- /dev/null +++ b/server-ce/Makefile @@ -0,0 +1,12 @@ +# Makefile + + +build-base: + docker build -f Dockerfile-base -t sharelatex/sharelatex-base . + + +build-community: + docker build -f Dockerfile -t sharelatex/sharelatex . + + +PHONY: build-base build-community From f31b9d3a7df1b8cb8b90b82c244464fae6239927 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 22 Feb 2017 09:48:34 +0000 Subject: [PATCH 328/525] Set baseDir var --- server-ce/Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 0efcdefa30..a520960c4f 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -2,6 +2,8 @@ FROM sharelatex/sharelatex-base +ENV baseDir . + # Install sharelatex settings file ADD ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee @@ -17,7 +19,7 @@ ADD ${baseDir}/logrotate/sharelatex /etc/logrotate.d/sharelatex COPY ${baseDir}/init_scripts/ /etc/my_init.d/ # Install ShareLaTeX -RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex #random_change +RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js ADD ${baseDir}/package.json /var/www/package.json From d1a73c5600bc104e03ff64af9ac3e88963bf866e Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 23 Feb 2017 09:47:11 +0000 Subject: [PATCH 329/525] Add docHash to key_schema --- server-ce/settings.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 7891c4a1a5..9eec76da71 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -54,6 +54,7 @@ settings = docLines: ({doc_id}) -> "doclines:#{doc_id}" docOps: ({doc_id}) -> "DocOps:#{doc_id}" docVersion: ({doc_id}) -> "DocVersion:#{doc_id}" + docHash: ({doc_id}) -> "DocHash:#{doc_id}" projectKey: ({doc_id}) -> "ProjectId:#{doc_id}" docsInProject: ({project_id}) -> "DocsIn:#{project_id}" ranges: ({doc_id}) -> "Ranges:#{doc_id}" From b30b100dca71585509e9c0e144c29ca434750158 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Mon, 27 Feb 2017 15:46:28 +0000 Subject: [PATCH 330/525] Pin to sharelatex-base:v1.0.0 --- server-ce/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index a520960c4f..11f0d2ef39 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -1,6 +1,6 @@ # Sharelatex Community Edition (sharelatex/sharelatex) -FROM sharelatex/sharelatex-base +FROM sharelatex/sharelatex-base:v1.0.0 ENV baseDir . From 303dcba51b3ff8f7d376a7b3721274d5c2efa518 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 23 Mar 2017 11:34:45 +0000 Subject: [PATCH 331/525] Address Henry's comments about robustness --- .../5_remove_holding_accounts.coffee | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/server-ce/migrations/5_remove_holding_accounts.coffee b/server-ce/migrations/5_remove_holding_accounts.coffee index a4afe59582..1b503656c6 100644 --- a/server-ce/migrations/5_remove_holding_accounts.coffee +++ b/server-ce/migrations/5_remove_holding_accounts.coffee @@ -24,7 +24,7 @@ module.exports = HoldingAccountMigration = jobs = projects.map (project) -> (cb) -> console.log "[Removing user from project]", user_id, JSON.stringify(project) - if !project._id? + if !project?._id? throw new Error("no project id") if !HoldingAccountMigration.DRY_RUN @@ -48,31 +48,31 @@ module.exports = HoldingAccountMigration = deleteUser: (user_id, callback = (error) ->) -> if !user_id? throw new Error("must have user_id") - db.users.find {_id: user_id}, (error, user) -> - return callback(error) if error? - if !user? - throw new Error("expected user") - console.log "[Removing user]", user_id, JSON.stringify(user) - if !HoldingAccountMigration.DRY_RUN - db.users.remove {_id: user_id}, (error, result) -> - console.log "[Removed user]", user_id, result - callback(error) - else - console.log "[Would have removed user]", user_id + if !HoldingAccountMigration.DRY_RUN + db.users.remove {_id: user_id, holdingAccount: true}, (error, result) -> + return callback(error) if error? + console.log "[Removed user]", user_id, result + if result.n != 1 + return callback(new Error("failed to remove user as expected")) callback() + else + console.log "[Would have removed user]", user_id + callback() - run: (done) -> + run: (done = () ->) -> HoldingAccountMigration.findHoldingAccounts (error, users) -> throw error if error? console.log "[Got list of holding accounts]", users.map (u) -> u._id jobs = users.map (u) -> (cb) -> - HoldingAccountMigration.deleteUserProjects u._id, (error) -> + HoldingAccountMigration.deleteUser u._id, (error) -> return cb(error) if error? - HoldingAccountMigration.deleteUser u._id, cb + HoldingAccountMigration.deleteUserProjects u._id, (error) -> + return cb(error) if error? + setTimeout cb, 200 # Small delay to not hammer DB async.series jobs, (error) -> throw error if error? - console.log "[Removed holding accounts]" + console.log "[FINISHED]" done() migrate: (client, done=()->) -> From 51dd24574a4f7bb73bf6c7b33ea569c7afe44a81 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 23 Mar 2017 11:50:46 +0000 Subject: [PATCH 332/525] Improve logging --- server-ce/migrations/5_remove_holding_accounts.coffee | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server-ce/migrations/5_remove_holding_accounts.coffee b/server-ce/migrations/5_remove_holding_accounts.coffee index 1b503656c6..687b1ee3b7 100644 --- a/server-ce/migrations/5_remove_holding_accounts.coffee +++ b/server-ce/migrations/5_remove_holding_accounts.coffee @@ -60,16 +60,17 @@ module.exports = HoldingAccountMigration = callback() run: (done = () ->) -> + console.log "[Getting list of holding accounts]" HoldingAccountMigration.findHoldingAccounts (error, users) -> throw error if error? - console.log "[Got list of holding accounts]", users.map (u) -> u._id + console.log "[Got #{users.length} holding accounts]" jobs = users.map (u) -> (cb) -> HoldingAccountMigration.deleteUser u._id, (error) -> return cb(error) if error? HoldingAccountMigration.deleteUserProjects u._id, (error) -> return cb(error) if error? - setTimeout cb, 200 # Small delay to not hammer DB + setTimeout cb, 50 # Small delay to not hammer DB async.series jobs, (error) -> throw error if error? console.log "[FINISHED]" From ba3333303cde4c94bc748a6db8abaccdd98a0f95 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 23 Mar 2017 11:56:46 +0000 Subject: [PATCH 333/525] More loggin --- server-ce/migrations/5_remove_holding_accounts.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/migrations/5_remove_holding_accounts.coffee b/server-ce/migrations/5_remove_holding_accounts.coffee index 687b1ee3b7..3e45d41605 100644 --- a/server-ce/migrations/5_remove_holding_accounts.coffee +++ b/server-ce/migrations/5_remove_holding_accounts.coffee @@ -64,8 +64,10 @@ module.exports = HoldingAccountMigration = HoldingAccountMigration.findHoldingAccounts (error, users) -> throw error if error? console.log "[Got #{users.length} holding accounts]" + i = 0 jobs = users.map (u) -> (cb) -> + console.log "[Removing user #{i++}/#{users.length}]" HoldingAccountMigration.deleteUser u._id, (error) -> return cb(error) if error? HoldingAccountMigration.deleteUserProjects u._id, (error) -> From 930aa9c5724ddc9ae45a62e0d99f9a37bb31a5a9 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 24 Mar 2017 13:46:31 +0000 Subject: [PATCH 334/525] Don't find holding accounts with a hashed password --- server-ce/migrations/5_remove_holding_accounts.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/migrations/5_remove_holding_accounts.coffee b/server-ce/migrations/5_remove_holding_accounts.coffee index 3e45d41605..494669859d 100644 --- a/server-ce/migrations/5_remove_holding_accounts.coffee +++ b/server-ce/migrations/5_remove_holding_accounts.coffee @@ -8,7 +8,7 @@ module.exports = HoldingAccountMigration = DRY_RUN: true findHoldingAccounts: (callback = (error, users) ->) -> - db.users.find({holdingAccount: true}, {holdingAccount: 1, email: 1}, callback) + db.users.find({holdingAccount: true, hashedPassword: { $exists: false }}, {holdingAccount: 1, email: 1}, callback) deleteUserProjects: (user_id, callback = (error) ->) -> # Holding accounts can't own projects, so only remove from From 25d21cbf2951bc96994e89e37c7317f169cd436c Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 5 Apr 2017 14:48:36 +0100 Subject: [PATCH 335/525] Add `trackchanges.continueOnError` as default --- server-ce/settings.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 9eec76da71..99c8b9d280 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -101,6 +101,9 @@ settings = # secret: "AWS_SECRET" # + trackchanges: + continueOnError: true + # Local disk caching # ------------------ path: From 48e4f32745d1b10240ae2e09ae46238fbb43cd52 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 17 May 2017 14:23:55 +0100 Subject: [PATCH 336/525] Add migration to enable trackChanges for all users --- .../6_add_track_changes_feature.coffee | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 server-ce/migrations/6_add_track_changes_feature.coffee diff --git a/server-ce/migrations/6_add_track_changes_feature.coffee b/server-ce/migrations/6_add_track_changes_feature.coffee new file mode 100644 index 0000000000..90ce03ffd7 --- /dev/null +++ b/server-ce/migrations/6_add_track_changes_feature.coffee @@ -0,0 +1,31 @@ +Settings = require "settings-sharelatex" +fs = require("fs") +mongojs = require("mongojs") +ObjectId = mongojs.ObjectId +db = mongojs(Settings.mongo.url, ['users']) +_ = require("underscore") +BSON = db.bson.BSON + + +handleExit = () -> + console.log('Got signal. Shutting down.') + + +process.on 'SIGINT', handleExit +process.on 'SIGHUP', handleExit + + +exports.migrate = (client, done=()->) -> + patch = { + $set: { + 'features.trackChanges': true + } + } + console.log ">> enabling trackChanges feature: ", patch + db.users.update {}, patch, {multi: true}, (err) -> + console.log "finished enabling trackChanges feature" + return done(err) + + +exports.rollback = (client, done) -> + done() From f7a2d60c440f4f7ce58cdc21a2e0ec90412c8b41 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 17 May 2017 15:29:01 +0100 Subject: [PATCH 337/525] Update redis configs to accomodate recent changes --- server-ce/settings.coffee | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 99c8b9d280..adf5bb5867 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -43,13 +43,8 @@ settings = host: process.env["SHARELATEX_REDIS_HOST"] or "dockerhost" port: process.env["SHARELATEX_REDIS_PORT"] or "6379" password: process.env["SHARELATEX_REDIS_PASS"] or "" - fairy: redisConfig - documentupdater: [{ - primary: true - port: process.env["SHARELATEX_REDIS_PORT"] or "6379" - host: process.env["SHARELATEX_REDIS_HOST"] or "dockerhost" - password: process.env["SHARELATEX_REDIS_PASS"] or "" key_schema: + # document-updater blockingKey: ({doc_id}) -> "Blocking:#{doc_id}" docLines: ({doc_id}) -> "doclines:#{doc_id}" docOps: ({doc_id}) -> "DocOps:#{doc_id}" @@ -58,8 +53,25 @@ settings = projectKey: ({doc_id}) -> "ProjectId:#{doc_id}" docsInProject: ({project_id}) -> "DocsIn:#{project_id}" ranges: ({doc_id}) -> "Ranges:#{doc_id}" - }] - + # document-updater:realtime + pendingUpdates: ({doc_id}) -> "PendingUpdates:#{doc_id}" + # document-updater:history + uncompressedHistoryOps: ({doc_id}) -> "UncompressedHistoryOps:#{doc_id}" + docsWithHistoryOps: ({project_id}) -> "DocsWithHistoryOps:#{project_id}" + # document-updater:lock + blockingKey: ({doc_id}) -> "Blocking:#{doc_id}" + # track-changes:lock + historyLock: ({doc_id}) -> "HistoryLock:#{doc_id}" + historyIndexLock: ({project_id}) -> "HistoryIndexLock:#{project_id}" + # track-chanegs:history + uncompressedHistoryOps: ({doc_id}) -> "UncompressedHistoryOps:#{doc_id}" + docsWithHistoryOps: ({project_id}) -> "DocsWithHistoryOps:#{project_id}" + fairy: redisConfig + # track-changes and document-updater + realtime: redisConfig + documentupdater: redisConfig + lock: redisConfig + history: redisConfig # The compile server (the clsi) uses a SQL database to cache files and # meta-data. sqllite is the default, and the load is low enough that this will From b52028c7bbbed498d323d539a4e231c0857a12a4 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 18 May 2017 10:55:41 +0100 Subject: [PATCH 338/525] Add realtime config and websessions to redis --- server-ce/settings.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index adf5bb5867..a68eb483dd 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -66,12 +66,16 @@ settings = # track-chanegs:history uncompressedHistoryOps: ({doc_id}) -> "UncompressedHistoryOps:#{doc_id}" docsWithHistoryOps: ({project_id}) -> "DocsWithHistoryOps:#{project_id}" + # realtime + clientsInProject: ({project_id}) -> "clients_in_project:#{project_id}" + connectedUser: ({project_id, client_id})-> "connected_user:#{project_id}:#{client_id}" fairy: redisConfig # track-changes and document-updater realtime: redisConfig documentupdater: redisConfig lock: redisConfig history: redisConfig + websessions: redisConfig # The compile server (the clsi) uses a SQL database to cache files and # meta-data. sqllite is the default, and the load is low enough that this will From d5fa1401a1a22b1c313a5ae57d17ede7973bfb20 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 18 May 2017 13:08:55 +0100 Subject: [PATCH 339/525] Ensure bcrypt gets installed --- server-ce/Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 11f0d2ef39..9f6cd1032a 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -29,7 +29,9 @@ RUN cd /var/www && npm install RUN cd /var/www/sharelatex; \ npm install; \ grunt install; \ - cd web/modules; \ + cd web; \ + npm install && npm install bcrypt; \ + cd modules; \ git clone https://bitbucket.org/sharelatex/launchpad-webmodule.git launchpad; \ grunt compile; From 4b46a4e655ed1e735e77dfe4c9190eba878b23db Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 19 May 2017 08:32:34 +0100 Subject: [PATCH 340/525] Refactor --- server-ce/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 9f6cd1032a..10db29293c 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -30,7 +30,8 @@ RUN cd /var/www/sharelatex; \ npm install; \ grunt install; \ cd web; \ - npm install && npm install bcrypt; \ + npm install; \ + npm install bcrypt; \ cd modules; \ git clone https://bitbucket.org/sharelatex/launchpad-webmodule.git launchpad; \ grunt compile; From 8090e5fca149f51508e6a227b0c246772478a848 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 14 Jun 2017 17:03:05 +0100 Subject: [PATCH 341/525] Update migration script for holding accounts to migrate group invites --- .../5_remove_holding_accounts.coffee | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/server-ce/migrations/5_remove_holding_accounts.coffee b/server-ce/migrations/5_remove_holding_accounts.coffee index 494669859d..ee796b3023 100644 --- a/server-ce/migrations/5_remove_holding_accounts.coffee +++ b/server-ce/migrations/5_remove_holding_accounts.coffee @@ -1,7 +1,7 @@ Settings = require "settings-sharelatex" mongojs = require("mongojs") ObjectId = mongojs.ObjectId -db = mongojs(Settings.mongo.url, ['users', 'projects']) +db = mongojs(Settings.mongo.url, ['users', 'projects', 'subscriptions']) async = require "async" module.exports = HoldingAccountMigration = @@ -58,6 +58,21 @@ module.exports = HoldingAccountMigration = else console.log "[Would have removed user]", user_id callback() + + migrateGroupInvites: (user_id, email, callback = (error) ->) -> + if !user_id? + throw new Error("must have user_id") + if !HoldingAccountMigration.DRY_RUN + db.subscriptions.update {member_ids: user_id}, { + $pull: { member_ids: user_id }, + $addToSet : { invited_emails: email } + }, { multi : true }, (error, result) -> + return callback(error) if error? + console.log "[Migrated user in group accounts]", user_id, email, result + callback() + else + console.log "[Would have migrated user in group accounts]", user_id, email + callback() run: (done = () ->) -> console.log "[Getting list of holding accounts]" @@ -68,11 +83,13 @@ module.exports = HoldingAccountMigration = jobs = users.map (u) -> (cb) -> console.log "[Removing user #{i++}/#{users.length}]" - HoldingAccountMigration.deleteUser u._id, (error) -> + HoldingAccountMigration.migrateGroupInvites u._id, u.email, (error) -> return cb(error) if error? - HoldingAccountMigration.deleteUserProjects u._id, (error) -> + HoldingAccountMigration.deleteUser u._id, (error) -> return cb(error) if error? - setTimeout cb, 50 # Small delay to not hammer DB + HoldingAccountMigration.deleteUserProjects u._id, (error) -> + return cb(error) if error? + setTimeout cb, 50 # Small delay to not hammer DB async.series jobs, (error) -> throw error if error? console.log "[FINISHED]" From 0c65c4d963e9683a9d4a3b193f44882e78b562dd Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 21 Jun 2017 10:59:19 +0100 Subject: [PATCH 342/525] add the driver field to email config --- server-ce/settings.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index a68eb483dd..9b7fe58c40 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -396,6 +396,7 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? settings.email = fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] replyTo: process.env["SHARELATEX_EMAIL_REPLY_TO"] or "" + driver: process.env["SHARELATEX_EMAIL_DRIVER"] parameters: #AWS Creds AWSAccessKeyID: process.env["SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID"] From 5f509a9413082a5135d749cea661867656e3df86 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 25 Jul 2017 14:25:56 +0100 Subject: [PATCH 343/525] Create ISSUE_TEMPLATE.md --- server-ce/ISSUE_TEMPLATE.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 server-ce/ISSUE_TEMPLATE.md diff --git a/server-ce/ISSUE_TEMPLATE.md b/server-ce/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..58e3b3f067 --- /dev/null +++ b/server-ce/ISSUE_TEMPLATE.md @@ -0,0 +1,22 @@ +(If you have a feature request, or bug with ShareLaTeX, please file an issue at https://github.com/sharelatex/web-sharelatex. This repository should **only be used for installation and maintenance problems** of ShareLaTeX Community Edition) + +## Problem + +Please describe the problem you are facing + +## Install type + +Are you using the Docker image (as described at https://github.com/sharelatex/sharelatex/wiki/Quick-Start-Guide), or some other method of installing ShareLaTeX Community Edition? + +## Version + +Which version of the docker image are you using? + +## Logs and errors + +Please include any logs and error messages. + +## Screenshots + +Please provide any screenshots of errors in ShareLaTeX Community Edition. + From 230fe00c489324cc1f35ede9393aea239c855406 Mon Sep 17 00:00:00 2001 From: Hayden Faulds Date: Thu, 27 Jul 2017 15:39:22 +0100 Subject: [PATCH 344/525] replace grunt service initialisation with bash script --- server-ce/Gruntfile.coffee | 35 ++++------------------------------ server-ce/bin/install-services | 12 ++++++++++++ 2 files changed, 16 insertions(+), 31 deletions(-) create mode 100644 server-ce/bin/install-services diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index fc2c654427..cab7824da4 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -120,16 +120,10 @@ module.exports = (grunt) -> installService: (service, callback = (error) ->) -> console.log "Installing #{service.name}" Helpers.cloneGitRepo service, (error) -> - return callback(error) if error? - Helpers.installNpmModules service, (error) -> - return callback(error) if error? - Helpers.rebuildNpmModules service, (error) -> - return callback(error) if error? - Helpers.runGruntInstall service, (error) -> - return callback(error) if error? - console.log "Finished installing #{service.name}" - callback() - + if error? + callback(error) + else + callback() cloneGitRepo: (service, callback = (error) ->) -> repo_src = service.repo @@ -153,27 +147,6 @@ module.exports = (grunt) -> proc.on "close", () -> callback() - - installNpmModules: (service, callback = (error) ->) -> - dir = service.name - proc = spawn "npm", ["install"], stdio: "inherit", cwd: dir - proc.on "close", () -> - callback() - - # work around for https://github.com/npm/npm/issues/5400 - # where binary modules are not built due to bug in npm - rebuildNpmModules: (service, callback = (error) ->) -> - dir = service.name - proc = spawn "npm", ["rebuild"], stdio: "inherit", cwd: dir - proc.on "close", () -> - callback() - - runGruntInstall: (service, callback = (error) ->) -> - dir = service.name - proc = spawn "grunt", ["install"], stdio: "inherit", cwd: dir - proc.on "close", () -> - callback() - checkMake: (callback = (error) ->) -> grunt.log.write "Checking make is installed... " exec "make --version", (error, stdout, stderr) -> diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services new file mode 100644 index 0000000000..528bb0bd9c --- /dev/null +++ b/server-ce/bin/install-services @@ -0,0 +1,12 @@ +#! env bash + +grep 'name:' config/services.js | \ + sed 's/.*name: "\(.*\)",/\1/' | \ + while read service + do + pushd $service && + nvm install && + nvm use && + npm install + popd + done From 2405b80e45c43c48ad0e5cbff17d18a5d498b2fc Mon Sep 17 00:00:00 2001 From: Hayden Faulds Date: Mon, 31 Jul 2017 13:36:18 +0100 Subject: [PATCH 345/525] add postinstall message explaining how to use bin/install-services --- server-ce/Gruntfile.coffee | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index cab7824da4..7a3e8d3ca3 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -87,9 +87,11 @@ module.exports = (grunt) -> grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", [].concat( ("install:#{service.name}" for service in SERVICES) - ) + ).concat(['postinstall']) grunt.registerTask 'install', 'install:all' + grunt.registerTask 'postinstall', 'Explain postinstall steps', () -> + Helpers.postinstallMessage @async() grunt.registerTask 'update:all', "Checkout and update all ShareLaTeX services", ["check:make"].concat( @@ -147,6 +149,17 @@ module.exports = (grunt) -> proc.on "close", () -> callback() + postinstallMessage: (callback = (error) ->) -> + grunt.log.write """ + Services cloned: + #{service.name for service in SERVICES} + To install services run: + $ source bin/install-services + This will install the required node versions and run `npm install` for each service. + See https://github.com/sharelatex/sharelatex/pull/549 for more info. + """ + callback() + checkMake: (callback = (error) ->) -> grunt.log.write "Checking make is installed... " exec "make --version", (error, stdout, stderr) -> From 71927c97f1945585e353963a8f5c8d8bc610db97 Mon Sep 17 00:00:00 2001 From: Hayden Faulds Date: Mon, 31 Jul 2017 13:36:37 +0100 Subject: [PATCH 346/525] add logging to install-services script --- server-ce/bin/install-services | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services index 528bb0bd9c..760f0a7edf 100644 --- a/server-ce/bin/install-services +++ b/server-ce/bin/install-services @@ -5,8 +5,11 @@ grep 'name:' config/services.js | \ while read service do pushd $service && + echo "Installing Service $service" && + echo ' installing Node' && nvm install && nvm use && + echo ' installing Dependencies' && npm install popd done From bcd1c7c4d6951149bf350f5b266fc6e2c9146908 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 2 Aug 2017 08:42:30 +0100 Subject: [PATCH 347/525] Update the node distro --- server-ce/Dockerfile-base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index 4142c48b0c..6ea4fd93d6 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -5,7 +5,7 @@ FROM phusion/baseimage:0.9.16 ENV baseDir . RUN apt-get update -RUN curl -sL https://deb.nodesource.com/setup | sudo bash - +RUN curl -sL https://deb.nodesource.com/setup_6.x | sudo bash - RUN apt-get install -y build-essential wget nodejs unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu WORKDIR /opt From ff99e226bc7f7fb5bd6f0c909255e45296543d6c Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 2 Aug 2017 09:45:08 +0100 Subject: [PATCH 348/525] Update texlive path --- server-ce/Dockerfile-base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index 6ea4fd93d6..a59431fc9d 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -24,7 +24,7 @@ RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ RUN rm -r /install-tl-unx; \ rm install-tl-unx.tar.gz -ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2016/bin/x86_64-linux/ +ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2017/bin/x86_64-linux/ RUN tlmgr install latexmk RUN tlmgr install texcount From 65247bd8ab5513e211b876f0e1444ab43688a557 Mon Sep 17 00:00:00 2001 From: tomcoombs87 Date: Sat, 5 Aug 2017 20:09:55 +0100 Subject: [PATCH 349/525] fixed a typo --- server-ce/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index 3b32dee34e..cb5bc7a867 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -10,7 +10,7 @@ of ShareLaTeX, then here are some notes on how to do that. Reporting bugs and opening issues --------------------------------- -If you'd like a report a bug or open an issue then please: +If you'd like to report a bug or open an issue then please: 1. **Find the correct repository.** ShareLaTeX is split across multiple different repositories, each containing a different service (you can find a list of [all repositories here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories)). If you know the bug only applies to one service, then please open an issue in that repository. For general bugs and issues that span more than one service, please open an issue in the [sharelatex/sharelatex](https://github.com/sharelatex/sharelatex) repository. 2. **Check if there is an existing issue.** If there is then please add From 79b54adfd88d020b0d2a3fb5aaf0378c6153ec81 Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 5 Aug 2017 22:00:33 +0100 Subject: [PATCH 350/525] removed a space to fix broken wiki link --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 19d5567717..658211805a 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -20,7 +20,7 @@ We have detailed installation instructions in our wiki: Upgrading --------- -If you are upgrading from a previous version of ShareLaTeX, please see the [Release Notes section on the Wiki] (https://github.com/sharelatex/sharelatex/wiki/Home) for all of the versions between your current version and the version you are upgrading to. +If you are upgrading from a previous version of ShareLaTeX, please see the [Release Notes section on the Wiki](https://github.com/sharelatex/sharelatex/wiki/Home) for all of the versions between your current version and the version you are upgrading to. Other repositories From b0dce93a249a782b02f91aa38afa77683c06e5c9 Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 5 Aug 2017 22:33:16 +0100 Subject: [PATCH 351/525] tiny typo --- server-ce/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index cb5bc7a867..50c94baaf0 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -56,7 +56,7 @@ contact us at team@sharelatex.com first. Contributor License Agreement ----------------------------- -Before we can accept and contributions of code, we need you to agree to our +Before we can accept any contributions of code, we need you to agree to our [Contributor License Agreement](https://sharelatex.wufoo.com/forms/sharelatex-contributor-license-agreement/). This is to ensure that you own the copyright of your contribution, and that you agree to give us a license to use it in both the open source version, and the version From e591df91f597beb9a5b1f82b40485b8e03b970b4 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Mon, 4 Sep 2017 15:40:27 +0100 Subject: [PATCH 352/525] check for nvm presence before using, survive abscence --- server-ce/bin/install-services | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services index 760f0a7edf..38cc89c60c 100644 --- a/server-ce/bin/install-services +++ b/server-ce/bin/install-services @@ -4,12 +4,12 @@ grep 'name:' config/services.js | \ sed 's/.*name: "\(.*\)",/\1/' | \ while read service do - pushd $service && - echo "Installing Service $service" && - echo ' installing Node' && - nvm install && - nvm use && - echo ' installing Dependencies' && + pushd $service + echo "Installing Service $service" + echo ' installing Node' + type nvm && nvm install + type nvm && nvm use + echo ' installing Dependencies' npm install popd done From 2ca8dc903b02a05ae44cbf0bd2a930dc125aa152 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Mon, 4 Sep 2017 15:57:13 +0100 Subject: [PATCH 353/525] Suppress verbose output from `type` command. --- server-ce/bin/install-services | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services index 38cc89c60c..10ddfe0e43 100644 --- a/server-ce/bin/install-services +++ b/server-ce/bin/install-services @@ -7,8 +7,8 @@ grep 'name:' config/services.js | \ pushd $service echo "Installing Service $service" echo ' installing Node' - type nvm && nvm install - type nvm && nvm use + type -t nvm && nvm install + type -t nvm && nvm use echo ' installing Dependencies' npm install popd From c63753f9f023d19886694cf5811fcdcdf0bc50f4 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 5 Sep 2017 15:26:40 +0100 Subject: [PATCH 354/525] Add warning when NVM is not present --- server-ce/bin/install-services | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services index 10ddfe0e43..662255db06 100644 --- a/server-ce/bin/install-services +++ b/server-ce/bin/install-services @@ -1,5 +1,14 @@ #! env bash +[ -z "`type -t nvm`" ] && cat < Date: Tue, 5 Sep 2017 15:33:32 +0100 Subject: [PATCH 355/525] Update to node6. - update nvmrc file - update mongojs dependency (for migrations) --- server-ce/.nvmrc | 2 +- server-ce/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/.nvmrc b/server-ce/.nvmrc index 61012ac6c8..e18a34b9d6 100644 --- a/server-ce/.nvmrc +++ b/server-ce/.nvmrc @@ -1 +1 @@ -0.10.26 +6.11.2 diff --git a/server-ce/package.json b/server-ce/package.json index 3d63f4c5fa..5825b147f8 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -10,7 +10,7 @@ "grunt-shell": "^1.1.1", "load-grunt-config": "^0.19.2", "lodash": "^3.0.0", - "mongojs": "^0.18.1", + "mongojs": "2.4.0", "redis": "^2.6.2", "rimraf": "~2.2.6", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git", From 93b8a9b13d502eae99573ffeccfd06a8e6b8314c Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 6 Sep 2017 09:56:44 +0100 Subject: [PATCH 356/525] Fix the doc lines migration. - The bson module changed at some point, update to new api --- .../migrations/1_move_doc_lines_to_doc_collection.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee b/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee index 8712cf9f54..e4433de7bd 100644 --- a/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee +++ b/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee @@ -1,4 +1,6 @@ Settings = require "settings-sharelatex" +bson = require('bson') +BSON = new bson() fs = require("fs") mongojs = require("mongojs") ObjectId = mongojs.ObjectId @@ -61,7 +63,7 @@ getAllDocs = (project_id, callback = (error, docs) ->) -> if !project? console.log "no such project #{project_id}" return callback() - size = require("../node_modules/mongojs/node_modules/mongodb/node_modules/bson/").BSONPure.BSON.calculateObjectSize(project) + size = BSON.calculateObjectSize(project) if size > 12000000 #12mb return markProjectAsToLargeAndFinished project_id, callback findAllDocsInProject project, (error, docs) -> From fd71cd3c0a331e9a80ca0dca8ed9d5b07160eb21 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 6 Sep 2017 11:16:12 +0100 Subject: [PATCH 357/525] Add call to install-services --- server-ce/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 10db29293c..6e94aa3ab8 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -29,6 +29,7 @@ RUN cd /var/www && npm install RUN cd /var/www/sharelatex; \ npm install; \ grunt install; \ + bash -c 'source ./bin/install-services'; \ cd web; \ npm install; \ npm install bcrypt; \ From 575869142c786fa1ad2acf20ca64ef529adec5a5 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 6 Sep 2017 13:37:34 +0100 Subject: [PATCH 358/525] Add `grunt install` command to install-services --- server-ce/bin/install-services | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services index 662255db06..3f1e5dd44b 100644 --- a/server-ce/bin/install-services +++ b/server-ce/bin/install-services @@ -20,5 +20,6 @@ grep 'name:' config/services.js | \ type -t nvm && nvm use echo ' installing Dependencies' npm install + grunt install popd done From 34158a00dd7a0ffe412f12588aee992a31322247 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 7 Sep 2017 13:23:18 +0100 Subject: [PATCH 359/525] depend on bson explicitely --- server-ce/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/package.json b/server-ce/package.json index 5825b147f8..0fe5f7b26b 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -4,6 +4,7 @@ "description": "An online collaborative LaTeX editor", "dependencies": { "async": "^0.9.0", + "bson": "^1.0.4", "coffee-script": "^1.11.1", "east": "0.5.1", "east-mongo": "^0.1.2", From d11b11222b916f17a42dc15441812715d81aaf35 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 7 Sep 2017 15:27:28 +0100 Subject: [PATCH 360/525] update bson api in migration 3 --- server-ce/migrations/3_pack_docHistory_collection.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server-ce/migrations/3_pack_docHistory_collection.coffee b/server-ce/migrations/3_pack_docHistory_collection.coffee index c5febea0c2..c652dd7816 100644 --- a/server-ce/migrations/3_pack_docHistory_collection.coffee +++ b/server-ce/migrations/3_pack_docHistory_collection.coffee @@ -6,7 +6,8 @@ db = mongojs(Settings.mongo.url, ['docs','docHistory', 'docHistoryStats']) _ = require("underscore") async = require("async") exec = require("child_process").exec -BSON = db.bson.BSON +bson = require('bson') +BSON = new bson() logger = { log: -> From d14d5002abc5f48b30fb11c9edfbed1ace2d7711 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 8 Sep 2017 09:06:48 +0100 Subject: [PATCH 361/525] Remove un-used package import --- server-ce/migrations/4_update_user_features.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/server-ce/migrations/4_update_user_features.coffee b/server-ce/migrations/4_update_user_features.coffee index 8704c23ec4..680df3c459 100644 --- a/server-ce/migrations/4_update_user_features.coffee +++ b/server-ce/migrations/4_update_user_features.coffee @@ -4,7 +4,6 @@ mongojs = require("mongojs") ObjectId = mongojs.ObjectId db = mongojs(Settings.mongo.url, ['users']) _ = require("underscore") -BSON = db.bson.BSON handleExit = () -> From d13fbe4c4861a746154063471a72d24d1a578161 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 8 Sep 2017 09:09:42 +0100 Subject: [PATCH 362/525] Pin to latest base image --- server-ce/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 6e94aa3ab8..7593c726f7 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -1,6 +1,6 @@ # Sharelatex Community Edition (sharelatex/sharelatex) -FROM sharelatex/sharelatex-base:v1.0.0 +FROM sharelatex/sharelatex-base:latest ENV baseDir . From 1b76a0e7c3478b697860c90facf22b816fdc0bda Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 18 Oct 2017 13:28:13 +0100 Subject: [PATCH 363/525] Add setting to enable anonymous read-write sharing --- server-ce/settings.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 9b7fe58c40..01614eae00 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -22,6 +22,9 @@ TMP_DIR = '/var/lib/sharelatex/tmp' settings = + allowAnonymousReadAndWriteSharing: + process.env['SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING'] == 'true' + # Databases # --------- From 8dd61c9d53c3da02b238d84e0db769887b4a1585 Mon Sep 17 00:00:00 2001 From: Rico Date: Mon, 23 Oct 2017 14:46:37 +0200 Subject: [PATCH 364/525] Fix typo in error log filename --- server-ce/runit/errorlogs/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/runit/errorlogs/run b/server-ce/runit/errorlogs/run index e4053dab9e..45ab0ed313 100755 --- a/server-ce/runit/errorlogs/run +++ b/server-ce/runit/errorlogs/run @@ -1,2 +1,2 @@ #!/bin/bash -tail -F /var/log/sharelatex/*.log | grep '"level":50' >> /var/log/sharlatex-errors.log +tail -F /var/log/sharelatex/*.log | grep '"level":50' >> /var/log/sharelatex-errors.log From 008d0528621ee9fcc18792b1ecdf66aabbfc6060 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 8 Nov 2017 09:59:08 +0000 Subject: [PATCH 365/525] add migration for token-based access indexes --- .../migrations/7_add_token_indexes.coffee | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 server-ce/migrations/7_add_token_indexes.coffee diff --git a/server-ce/migrations/7_add_token_indexes.coffee b/server-ce/migrations/7_add_token_indexes.coffee new file mode 100644 index 0000000000..6563b08a13 --- /dev/null +++ b/server-ce/migrations/7_add_token_indexes.coffee @@ -0,0 +1,43 @@ +Settings = require "settings-sharelatex" +fs = require("fs") +mongojs = require("mongojs") +ObjectId = mongojs.ObjectId +db = mongojs(Settings.mongo.url, ['docs','docHistory', 'docHistoryStats']) +_ = require("underscore") +async = require("async") +exec = require("child_process").exec +bson = require('bson') +BSON = new bson() + + +handleExit = () -> + console.log('Got signal. Shutting down.') + + +exports.migrate = (client, done=()->) -> + console.log ">> Adding indexes for token-based project access: " + db.projects.ensureIndex {'tokens.readAndWrite': 1}, { + partialFilterExpression: { 'tokens.readAndWrite': { $exists: true } }, + unique: true, + background: true + }, (err) -> + if err? + return done(err) + db.projects.ensureIndex {'tokens.readOnly': 1}, { + partialFilterExpression: { 'tokens.readOnly': { $exists: true } }, + unique: true, + background: true + }, (err) -> + if err? + return done(err) + console.log ">> done adding indexes for token-based project access" + done() + + +exports.rollback = (client, done) -> + done() + + +process.on 'SIGINT', handleExit +process.on 'SIGHUP', handleExit + From efe09aa8859a47850501bdb29d125df0dc890cbd Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 8 Nov 2017 11:55:08 +0000 Subject: [PATCH 366/525] Add token-access-refs indexes --- server-ce/migrations/7_add_token_indexes.coffee | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/server-ce/migrations/7_add_token_indexes.coffee b/server-ce/migrations/7_add_token_indexes.coffee index 6563b08a13..2155363978 100644 --- a/server-ce/migrations/7_add_token_indexes.coffee +++ b/server-ce/migrations/7_add_token_indexes.coffee @@ -30,8 +30,16 @@ exports.migrate = (client, done=()->) -> }, (err) -> if err? return done(err) - console.log ">> done adding indexes for token-based project access" - done() + db.projects.ensureIndex {tokenAccessReadAndWrite_refs: 1}, { + background: true + }, (err) -> + if err? + return done(err) + db.projects.ensureIndex {tokenAccessOnly_refs: 1}, { + background: true + }, (err) -> + console.log ">> done adding indexes for token-based project access" + done() exports.rollback = (client, done) -> From e8078424edf212780585489f390e5b1107549d15 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 10 Nov 2017 14:15:22 +0000 Subject: [PATCH 367/525] add option to bypass percentage-based rollouts --- server-ce/settings.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 01614eae00..37bb88a18a 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -448,6 +448,7 @@ if process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or process.env["SHARELA ####################### if parse(process.env["SHARELATEX_IS_SERVER_PRO"]) == true + settings.bypassPercentageRollouts = true settings.apis.references = url: "http://localhost:3040" From 8cae3f66c22800148b4bc8030bd0bc6e50d56a2b Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 5 Dec 2017 09:48:05 +0000 Subject: [PATCH 368/525] move contacts run file --- .../runit/{contacts-sharelatex.sh => contacts-sharelatex/run} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename server-ce/runit/{contacts-sharelatex.sh => contacts-sharelatex/run} (100%) diff --git a/server-ce/runit/contacts-sharelatex.sh b/server-ce/runit/contacts-sharelatex/run similarity index 100% rename from server-ce/runit/contacts-sharelatex.sh rename to server-ce/runit/contacts-sharelatex/run From 04579ce5037809b422bbd7aff8fe22f397b27b7f Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 6 Dec 2017 11:21:54 +0000 Subject: [PATCH 369/525] Pin contacts to branch 'sk-update-mongojs' --- server-ce/services.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/services.js b/server-ce/services.js index b79ab9a4b7..941dd23a0e 100644 --- a/server-ce/services.js +++ b/server-ce/services.js @@ -43,7 +43,7 @@ module.exports = }, { name: "contacts", repo: "https://github.com/sharelatex/contacts-sharelatex.git", - version: "master" + version: "sk-update-mongojs" }, { name: "notifications", repo: "https://github.com/sharelatex/notifications-sharelatex.git", From 9091749448c734f53d26de55854369a9a54f902f Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Mon, 8 Jan 2018 16:21:18 +0000 Subject: [PATCH 370/525] Chown the sharelatex directory to www-data --- server-ce/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 7593c726f7..36ad4e19c2 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -44,7 +44,8 @@ RUN cd /var/www/sharelatex/web; \ grunt compile:minify; RUN cd /var/www/sharelatex/clsi; \ - grunt compile:bin + grunt compile:bin; \ + chown -R www-data:www-data /var/www/sharelatex; EXPOSE 80 From ad30a56f0a9fb9831462cb8138b2808196ec6dfe Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Mon, 22 Jan 2018 14:47:00 +0000 Subject: [PATCH 371/525] Pin version of simple-git --- server-ce/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/package.json b/server-ce/package.json index d3c19d112f..9a8f125940 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -7,7 +7,7 @@ "grunt-contrib-rename": "0.0.3", "grunt-docker-io": "^0.7.0", "grunt-github-api": "^0.2.3", - "simple-git": "^1.32.1", + "simple-git": "1.85.0", "underscore": "^1.8.3" } } From 3b878001c270d734d079955b9a7959a4d329f9c9 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 25 Jan 2018 11:34:29 +0000 Subject: [PATCH 372/525] Update docker-compose.yml --- server-ce/docker-compose.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 2cd7434505..8039e108d7 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -15,6 +15,7 @@ services: - redis volumes: - ~/sharelatex_data:/var/lib/sharelatex + - /var/run/docker.sock:/var/run/docker.sock environment: SHARELATEX_MONGO_URL: mongodb://mongo/sharelatex SHARELATEX_REDIS_HOST: redis @@ -49,7 +50,10 @@ services: ## Server Pro ## ################ - # SANDBOXED_COMPILES:true + # SANDBOXED_COMPILES: 'true' + + # SANDBOXED_COMPILES_SIBLING_CONTAINERS: 'true' + # SANDBOXED_COMPILES_HOST_DIR: '/var/clsi/compiles' # SHARELATEX_LDAP_HOST: 'ldap://ldap.forumsys.com' # SHARELATEX_LDAP_DN: 'uid=:userKey,dc=example,dc=com' From 3970b5b4be75136dc9cddf6929a0e19cfb6dd47a Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 26 Jan 2018 09:43:43 +0000 Subject: [PATCH 373/525] added trackChanges into features --- server-ce/settings.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 37bb88a18a..7f4f18067f 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -345,8 +345,9 @@ settings = versioning: true compileTimeout: 180 compileGroup: "standard" - references: true + trackChanges: true templates: true + references: true ## OPTIONAL CONFIGERABLE SETTINGS From a08a74b95c10f95427213d33db2bd0c36f5cbc29 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 26 Jan 2018 09:46:35 +0000 Subject: [PATCH 374/525] added track changes migration in again, we didn't add the setting as a default before so needs 2nd migration --- .../7_add_track_changes_feature_again.coffee | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 server-ce/migrations/7_add_track_changes_feature_again.coffee diff --git a/server-ce/migrations/7_add_track_changes_feature_again.coffee b/server-ce/migrations/7_add_track_changes_feature_again.coffee new file mode 100644 index 0000000000..88de3f57b2 --- /dev/null +++ b/server-ce/migrations/7_add_track_changes_feature_again.coffee @@ -0,0 +1,32 @@ +#This is needed because we forgot to add track changes into the default settings +Settings = require "settings-sharelatex" +fs = require("fs") +mongojs = require("mongojs") +ObjectId = mongojs.ObjectId +db = mongojs(Settings.mongo.url, ['users']) +_ = require("underscore") +BSON = db.bson.BSON + + +handleExit = () -> + console.log('Got signal. Shutting down.') + + +process.on 'SIGINT', handleExit +process.on 'SIGHUP', handleExit + + +exports.migrate = (client, done=()->) -> + patch = { + $set: { + 'features.trackChanges': true + } + } + console.log ">> enabling trackChanges feature: ", patch + db.users.update {}, patch, {multi: true}, (err) -> + console.log "finished enabling trackChanges feature" + return done(err) + + +exports.rollback = (client, done) -> + done() From 9771a1dac1182eb0de5d0e27ee08869006396083 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 31 Jan 2018 11:04:58 +0000 Subject: [PATCH 375/525] fix mongo connect issue, .connect no longer exists on mongojs --- server-ce/Gruntfile.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 7a3e8d3ca3..7fb8881930 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -182,7 +182,7 @@ module.exports = (grunt) -> checkMongoConnect: (callback = (error) ->) -> grunt.log.write "Checking can connect to mongo" mongojs = require("mongojs") - db = mongojs.connect(settings.mongo.url, ["tags"]) + db = mongojs(settings.mongo.url, ["tags"]) db.runCommand { ping: 1 }, (err, res) -> if !err and res.ok grunt.log.write "OK." From 59410906298407f4ff1d92137f8aff71a3f6c517 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 31 Jan 2018 11:19:05 +0000 Subject: [PATCH 376/525] added npm shrinkwrap to fix mongodb native version change --- .../6_add_track_changes_feature.coffee | 1 - .../7_add_track_changes_feature_again.coffee | 1 - server-ce/npm-shrinkwrap.json | 688 ++++++++++++++++++ server-ce/package.json | 5 +- 4 files changed, 691 insertions(+), 4 deletions(-) create mode 100644 server-ce/npm-shrinkwrap.json diff --git a/server-ce/migrations/6_add_track_changes_feature.coffee b/server-ce/migrations/6_add_track_changes_feature.coffee index 90ce03ffd7..e807102faa 100644 --- a/server-ce/migrations/6_add_track_changes_feature.coffee +++ b/server-ce/migrations/6_add_track_changes_feature.coffee @@ -4,7 +4,6 @@ mongojs = require("mongojs") ObjectId = mongojs.ObjectId db = mongojs(Settings.mongo.url, ['users']) _ = require("underscore") -BSON = db.bson.BSON handleExit = () -> diff --git a/server-ce/migrations/7_add_track_changes_feature_again.coffee b/server-ce/migrations/7_add_track_changes_feature_again.coffee index 88de3f57b2..b942e61f3f 100644 --- a/server-ce/migrations/7_add_track_changes_feature_again.coffee +++ b/server-ce/migrations/7_add_track_changes_feature_again.coffee @@ -5,7 +5,6 @@ mongojs = require("mongojs") ObjectId = mongojs.ObjectId db = mongojs(Settings.mongo.url, ['users']) _ = require("underscore") -BSON = db.bson.BSON handleExit = () -> diff --git a/server-ce/npm-shrinkwrap.json b/server-ce/npm-shrinkwrap.json new file mode 100644 index 0000000000..f376912404 --- /dev/null +++ b/server-ce/npm-shrinkwrap.json @@ -0,0 +1,688 @@ +{ + "name": "sharelatex", + "version": "0.0.1", + "dependencies": { + "async": { + "version": "0.9.2", + "from": "async@>=0.9.0 <0.10.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz" + }, + "bson": { + "version": "1.0.4", + "from": "bson@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz" + }, + "coffee-script": { + "version": "1.12.7", + "from": "coffee-script@>=1.11.1 <2.0.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz" + }, + "east": { + "version": "0.5.7", + "from": "east@0.5.7", + "resolved": "http://registry.npmjs.org/east/-/east-0.5.7.tgz", + "dependencies": { + "commander": { + "version": "2.9.0", + "from": "commander@2.9.0", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "dependencies": { + "graceful-readlink": { + "version": "1.0.1", + "from": "graceful-readlink@>=1.0.0", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" + } + } + }, + "expressionify": { + "version": "0.9.3", + "from": "expressionify@0.9.3", + "resolved": "http://registry.npmjs.org/expressionify/-/expressionify-0.9.3.tgz" + }, + "progress": { + "version": "1.1.8", + "from": "progress@1.1.8", + "resolved": "http://registry.npmjs.org/progress/-/progress-1.1.8.tgz" + }, + "twostep": { + "version": "0.4.2", + "from": "twostep@0.4.2", + "resolved": "http://registry.npmjs.org/twostep/-/twostep-0.4.2.tgz" + } + } + }, + "east-mongo": { + "version": "0.3.3", + "from": "east-mongo@0.3.3", + "resolved": "http://registry.npmjs.org/east-mongo/-/east-mongo-0.3.3.tgz" + }, + "grunt-shell": { + "version": "1.3.1", + "from": "grunt-shell@>=1.1.1 <2.0.0", + "resolved": "http://registry.npmjs.org/grunt-shell/-/grunt-shell-1.3.1.tgz", + "dependencies": { + "chalk": { + "version": "1.1.3", + "from": "chalk@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "from": "ansi-styles@>=2.2.1 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" + }, + "escape-string-regexp": { + "version": "1.0.5", + "from": "escape-string-regexp@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + }, + "has-ansi": { + "version": "2.0.0", + "from": "has-ansi@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "from": "strip-ansi@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + } + } + }, + "supports-color": { + "version": "2.0.0", + "from": "supports-color@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" + } + } + }, + "npm-run-path": { + "version": "1.0.0", + "from": "npm-run-path@>=1.0.0 <2.0.0", + "resolved": "http://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", + "dependencies": { + "path-key": { + "version": "1.0.0", + "from": "path-key@>=1.0.0 <2.0.0", + "resolved": "http://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz" + } + } + }, + "object-assign": { + "version": "4.1.1", + "from": "object-assign@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + } + } + }, + "load-grunt-config": { + "version": "0.19.2", + "from": "load-grunt-config@>=0.19.2 <0.20.0", + "resolved": "http://registry.npmjs.org/load-grunt-config/-/load-grunt-config-0.19.2.tgz", + "dependencies": { + "cson": { + "version": "3.0.2", + "from": "cson@>=3.0.2 <3.1.0", + "resolved": "http://registry.npmjs.org/cson/-/cson-3.0.2.tgz", + "dependencies": { + "cson-parser": { + "version": "1.3.5", + "from": "cson-parser@>=1.0.6 <2.0.0", + "resolved": "http://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz" + }, + "extract-opts": { + "version": "3.3.1", + "from": "extract-opts@>=3.0.1 <4.0.0", + "resolved": "http://registry.npmjs.org/extract-opts/-/extract-opts-3.3.1.tgz", + "dependencies": { + "eachr": { + "version": "3.2.0", + "from": "eachr@>=3.2.0 <4.0.0", + "resolved": "http://registry.npmjs.org/eachr/-/eachr-3.2.0.tgz" + }, + "editions": { + "version": "1.3.4", + "from": "editions@>=1.1.1 <2.0.0", + "resolved": "http://registry.npmjs.org/editions/-/editions-1.3.4.tgz" + }, + "typechecker": { + "version": "4.4.1", + "from": "typechecker@>=4.3.0 <5.0.0", + "resolved": "http://registry.npmjs.org/typechecker/-/typechecker-4.4.1.tgz" + } + } + }, + "requirefresh": { + "version": "2.1.0", + "from": "requirefresh@>=2.0.0 <3.0.0", + "resolved": "http://registry.npmjs.org/requirefresh/-/requirefresh-2.1.0.tgz", + "dependencies": { + "editions": { + "version": "1.3.4", + "from": "editions@>=1.1.1 <2.0.0", + "resolved": "http://registry.npmjs.org/editions/-/editions-1.3.4.tgz" + } + } + }, + "safefs": { + "version": "4.1.0", + "from": "safefs@>=4.0.0 <5.0.0", + "resolved": "http://registry.npmjs.org/safefs/-/safefs-4.1.0.tgz", + "dependencies": { + "editions": { + "version": "1.3.4", + "from": "editions@>=1.1.1 <2.0.0", + "resolved": "http://registry.npmjs.org/editions/-/editions-1.3.4.tgz" + }, + "graceful-fs": { + "version": "4.1.11", + "from": "graceful-fs@>=4.1.4 <5.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz" + } + } + } + } + }, + "glob": { + "version": "5.0.15", + "from": "glob@>=5.0.15 <5.1.0", + "resolved": "http://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "dependencies": { + "inflight": { + "version": "1.0.6", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.2", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + } + } + }, + "inherits": { + "version": "2.0.3", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + }, + "minimatch": { + "version": "3.0.4", + "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "from": "brace-expansion@>=1.1.7 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "from": "balanced-match@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + }, + "once": { + "version": "1.4.0", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.2", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + } + } + }, + "path-is-absolute": { + "version": "1.0.1", + "from": "path-is-absolute@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + } + } + }, + "jit-grunt": { + "version": "0.10.0", + "from": "jit-grunt@>=0.10.0 <0.11.0", + "resolved": "http://registry.npmjs.org/jit-grunt/-/jit-grunt-0.10.0.tgz" + }, + "js-yaml": { + "version": "3.4.6", + "from": "js-yaml@>=3.4.3 <3.5.0", + "resolved": "http://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz", + "dependencies": { + "argparse": { + "version": "1.0.9", + "from": "argparse@>=1.0.2 <2.0.0", + "resolved": "http://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "from": "sprintf-js@>=1.0.2 <1.1.0", + "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + } + } + }, + "esprima": { + "version": "2.7.3", + "from": "esprima@>=2.6.0 <3.0.0", + "resolved": "http://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz" + }, + "inherit": { + "version": "2.2.6", + "from": "inherit@>=2.2.2 <3.0.0", + "resolved": "http://registry.npmjs.org/inherit/-/inherit-2.2.6.tgz" + } + } + }, + "load-grunt-tasks": { + "version": "3.3.0", + "from": "load-grunt-tasks@>=3.3.0 <3.4.0", + "resolved": "http://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.3.0.tgz", + "dependencies": { + "arrify": { + "version": "1.0.1", + "from": "arrify@>=1.0.0 <2.0.0", + "resolved": "http://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + }, + "multimatch": { + "version": "2.1.0", + "from": "multimatch@>=2.0.0 <3.0.0", + "resolved": "http://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "dependencies": { + "array-differ": { + "version": "1.0.0", + "from": "array-differ@>=1.0.0 <2.0.0", + "resolved": "http://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz" + }, + "array-union": { + "version": "1.0.2", + "from": "array-union@>=1.0.1 <2.0.0", + "resolved": "http://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "dependencies": { + "array-uniq": { + "version": "1.0.3", + "from": "array-uniq@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" + } + } + }, + "minimatch": { + "version": "3.0.4", + "from": "minimatch@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "from": "brace-expansion@>=1.1.7 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "from": "balanced-match@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + } + } + }, + "pkg-up": { + "version": "1.0.0", + "from": "pkg-up@>=1.0.0 <2.0.0", + "resolved": "http://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "dependencies": { + "find-up": { + "version": "1.1.2", + "from": "find-up@>=1.0.0 <2.0.0", + "resolved": "http://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "dependencies": { + "path-exists": { + "version": "2.1.0", + "from": "path-exists@>=2.0.0 <3.0.0", + "resolved": "http://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz" + }, + "pinkie-promise": { + "version": "2.0.1", + "from": "pinkie-promise@>=2.0.0 <3.0.0", + "resolved": "http://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "dependencies": { + "pinkie": { + "version": "2.0.4", + "from": "pinkie@>=2.0.0 <3.0.0", + "resolved": "http://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" + } + } + } + } + } + } + } + } + } + } + }, + "lodash": { + "version": "3.10.1", + "from": "lodash@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" + }, + "mongodb": { + "version": "2.2.22", + "from": "mongodb@2.2.22", + "resolved": "http://registry.npmjs.org/mongodb/-/mongodb-2.2.22.tgz", + "dependencies": { + "es6-promise": { + "version": "3.2.1", + "from": "es6-promise@3.2.1", + "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz" + }, + "mongodb-core": { + "version": "2.1.7", + "from": "mongodb-core@2.1.7", + "resolved": "http://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.7.tgz", + "dependencies": { + "require_optional": { + "version": "1.0.1", + "from": "require_optional@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "dependencies": { + "semver": { + "version": "5.5.0", + "from": "semver@>=5.1.0 <6.0.0", + "resolved": "http://registry.npmjs.org/semver/-/semver-5.5.0.tgz" + }, + "resolve-from": { + "version": "2.0.0", + "from": "resolve-from@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz" + } + } + } + } + }, + "readable-stream": { + "version": "2.1.5", + "from": "readable-stream@2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "from": "buffer-shims@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" + }, + "core-util-is": { + "version": "1.0.2", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "inherits": { + "version": "2.0.3", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + }, + "isarray": { + "version": "1.0.0", + "from": "isarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "process-nextick-args": { + "version": "1.0.7", + "from": "process-nextick-args@>=1.0.6 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "util-deprecate": { + "version": "1.0.2", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + } + } + } + } + }, + "mongojs": { + "version": "2.4.0", + "from": "mongojs@2.4.0", + "resolved": "http://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", + "dependencies": { + "each-series": { + "version": "1.0.0", + "from": "each-series@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz" + }, + "mongodb": { + "version": "2.2.34", + "from": "mongodb@>=2.0.45 <3.0.0", + "resolved": "http://registry.npmjs.org/mongodb/-/mongodb-2.2.34.tgz", + "dependencies": { + "es6-promise": { + "version": "3.2.1", + "from": "es6-promise@3.2.1", + "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz" + }, + "mongodb-core": { + "version": "2.1.18", + "from": "mongodb-core@2.1.18", + "resolved": "http://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", + "dependencies": { + "require_optional": { + "version": "1.0.1", + "from": "require_optional@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "dependencies": { + "semver": { + "version": "5.5.0", + "from": "semver@>=5.1.0 <6.0.0", + "resolved": "http://registry.npmjs.org/semver/-/semver-5.5.0.tgz" + }, + "resolve-from": { + "version": "2.0.0", + "from": "resolve-from@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz" + } + } + } + } + }, + "readable-stream": { + "version": "2.2.7", + "from": "readable-stream@2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "from": "buffer-shims@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" + }, + "core-util-is": { + "version": "1.0.2", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "isarray": { + "version": "1.0.0", + "from": "isarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "inherits": { + "version": "2.0.3", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + }, + "process-nextick-args": { + "version": "1.0.7", + "from": "process-nextick-args@>=1.0.6 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" + }, + "string_decoder": { + "version": "1.0.3", + "from": "string_decoder@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "dependencies": { + "safe-buffer": { + "version": "5.1.1", + "from": "safe-buffer@>=5.1.0 <5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + } + } + } + } + }, + "once": { + "version": "1.4.0", + "from": "once@>=1.3.2 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.2", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + } + } + }, + "parse-mongo-url": { + "version": "1.1.1", + "from": "parse-mongo-url@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz" + }, + "readable-stream": { + "version": "2.3.3", + "from": "readable-stream@>=2.0.2 <3.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "inherits": { + "version": "2.0.3", + "from": "inherits@>=2.0.3 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + }, + "isarray": { + "version": "1.0.0", + "from": "isarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "process-nextick-args": { + "version": "1.0.7", + "from": "process-nextick-args@>=1.0.6 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" + }, + "safe-buffer": { + "version": "5.1.1", + "from": "safe-buffer@>=5.1.1 <5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + }, + "string_decoder": { + "version": "1.0.3", + "from": "string_decoder@>=1.0.3 <1.1.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz" + }, + "util-deprecate": { + "version": "1.0.2", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + } + } + }, + "thunky": { + "version": "0.1.0", + "from": "thunky@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz" + }, + "to-mongodb-core": { + "version": "2.0.0", + "from": "to-mongodb-core@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz" + }, + "xtend": { + "version": "4.0.1", + "from": "xtend@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + } + }, + "redis": { + "version": "2.8.0", + "from": "redis@>=2.6.2 <3.0.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", + "dependencies": { + "double-ended-queue": { + "version": "2.1.0-0", + "from": "double-ended-queue@>=2.1.0-0 <3.0.0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz" + }, + "redis-commands": { + "version": "1.3.1", + "from": "redis-commands@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz" + }, + "redis-parser": { + "version": "2.6.0", + "from": "redis-parser@>=2.6.0 <3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz" + } + } + }, + "rimraf": { + "version": "2.2.8", + "from": "rimraf@>=2.2.6 <2.3.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz" + }, + "settings-sharelatex": { + "version": "1.0.0", + "from": "git+https://github.com/sharelatex/settings-sharelatex.git", + "resolved": "git+https://github.com/sharelatex/settings-sharelatex.git#b4fb8404c5de571d029bf4c29e96a60b21206f94", + "dependencies": { + "coffee-script": { + "version": "1.6.0", + "from": "coffee-script@1.6.0", + "resolved": "http://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz" + } + } + }, + "underscore": { + "version": "1.8.3", + "from": "underscore@>=1.7.0 <2.0.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz" + } + } +} diff --git a/server-ce/package.json b/server-ce/package.json index 0fe5f7b26b..9b870694df 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -6,11 +6,12 @@ "async": "^0.9.0", "bson": "^1.0.4", "coffee-script": "^1.11.1", - "east": "0.5.1", - "east-mongo": "^0.1.2", + "east": "0.5.7", + "east-mongo": "0.3.3", "grunt-shell": "^1.1.1", "load-grunt-config": "^0.19.2", "lodash": "^3.0.0", + "mongodb": "^2.2.22", "mongojs": "2.4.0", "redis": "^2.6.2", "rimraf": "~2.2.6", From 4c891486f7cbdc78e997424729eaa3afdd937f52 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 31 Jan 2018 11:28:50 +0000 Subject: [PATCH 377/525] lockk down to latest versions of mongodb --- server-ce/npm-shrinkwrap.json | 128 +++++++--------------------------- server-ce/package.json | 2 +- 2 files changed, 26 insertions(+), 104 deletions(-) diff --git a/server-ce/npm-shrinkwrap.json b/server-ce/npm-shrinkwrap.json index f376912404..f5fd1370e1 100644 --- a/server-ce/npm-shrinkwrap.json +++ b/server-ce/npm-shrinkwrap.json @@ -392,9 +392,9 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" }, "mongodb": { - "version": "2.2.22", - "from": "mongodb@2.2.22", - "resolved": "http://registry.npmjs.org/mongodb/-/mongodb-2.2.22.tgz", + "version": "2.2.34", + "from": "mongodb@>=2.2.34 <3.0.0", + "resolved": "http://registry.npmjs.org/mongodb/-/mongodb-2.2.34.tgz", "dependencies": { "es6-promise": { "version": "3.2.1", @@ -402,9 +402,9 @@ "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz" }, "mongodb-core": { - "version": "2.1.7", - "from": "mongodb-core@2.1.7", - "resolved": "http://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.7.tgz", + "version": "2.1.18", + "from": "mongodb-core@2.1.18", + "resolved": "http://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", "dependencies": { "require_optional": { "version": "1.0.1", @@ -426,13 +426,13 @@ } }, "readable-stream": { - "version": "2.1.5", - "from": "readable-stream@2.1.5", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "version": "2.2.7", + "from": "readable-stream@2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", "dependencies": { "buffer-shims": { "version": "1.0.0", - "from": "buffer-shims@>=1.0.0 <2.0.0", + "from": "buffer-shims@>=1.0.0 <1.1.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" }, "core-util-is": { @@ -440,25 +440,32 @@ "from": "core-util-is@>=1.0.0 <1.1.0", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" }, - "inherits": { - "version": "2.0.3", - "from": "inherits@>=2.0.1 <2.1.0", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - }, "isarray": { "version": "1.0.0", "from": "isarray@>=1.0.0 <1.1.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" }, + "inherits": { + "version": "2.0.3", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + }, "process-nextick-args": { "version": "1.0.7", "from": "process-nextick-args@>=1.0.6 <1.1.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" }, "string_decoder": { - "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + "version": "1.0.3", + "from": "string_decoder@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "dependencies": { + "safe-buffer": { + "version": "5.1.1", + "from": "safe-buffer@>=5.1.0 <5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } + } }, "util-deprecate": { "version": "1.0.2", @@ -479,91 +486,6 @@ "from": "each-series@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz" }, - "mongodb": { - "version": "2.2.34", - "from": "mongodb@>=2.0.45 <3.0.0", - "resolved": "http://registry.npmjs.org/mongodb/-/mongodb-2.2.34.tgz", - "dependencies": { - "es6-promise": { - "version": "3.2.1", - "from": "es6-promise@3.2.1", - "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz" - }, - "mongodb-core": { - "version": "2.1.18", - "from": "mongodb-core@2.1.18", - "resolved": "http://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", - "dependencies": { - "require_optional": { - "version": "1.0.1", - "from": "require_optional@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "dependencies": { - "semver": { - "version": "5.5.0", - "from": "semver@>=5.1.0 <6.0.0", - "resolved": "http://registry.npmjs.org/semver/-/semver-5.5.0.tgz" - }, - "resolve-from": { - "version": "2.0.0", - "from": "resolve-from@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz" - } - } - } - } - }, - "readable-stream": { - "version": "2.2.7", - "from": "readable-stream@2.2.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", - "dependencies": { - "buffer-shims": { - "version": "1.0.0", - "from": "buffer-shims@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" - }, - "core-util-is": { - "version": "1.0.2", - "from": "core-util-is@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - }, - "isarray": { - "version": "1.0.0", - "from": "isarray@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - }, - "inherits": { - "version": "2.0.3", - "from": "inherits@>=2.0.1 <2.1.0", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - }, - "process-nextick-args": { - "version": "1.0.7", - "from": "process-nextick-args@>=1.0.6 <1.1.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" - }, - "string_decoder": { - "version": "1.0.3", - "from": "string_decoder@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "dependencies": { - "safe-buffer": { - "version": "5.1.1", - "from": "safe-buffer@>=5.1.0 <5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "from": "util-deprecate@>=1.0.1 <1.1.0", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - } - } - } - } - }, "once": { "version": "1.4.0", "from": "once@>=1.3.2 <2.0.0", diff --git a/server-ce/package.json b/server-ce/package.json index 9b870694df..4b32165fcd 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -11,7 +11,7 @@ "grunt-shell": "^1.1.1", "load-grunt-config": "^0.19.2", "lodash": "^3.0.0", - "mongodb": "^2.2.22", + "mongodb": "^2.2.34", "mongojs": "2.4.0", "redis": "^2.6.2", "rimraf": "~2.2.6", From 56b2f641d2ba386b450cd166be215e60611eb624 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 6 Feb 2018 10:26:29 +0000 Subject: [PATCH 378/525] Change launchpad location to github --- server-ce/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 36ad4e19c2..881d48cfe6 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -34,7 +34,7 @@ RUN cd /var/www/sharelatex; \ npm install; \ npm install bcrypt; \ cd modules; \ - git clone https://bitbucket.org/sharelatex/launchpad-webmodule.git launchpad; \ + git clone https://github.com/sharelatex/launchpad-web-module.git launchpad; \ grunt compile; RUN cd /var/www && node git-revision > revisions.txt From 5a2662e2685079c2ac22f7c23b3bc76335fb7bcc Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 27 Feb 2018 10:15:42 +0000 Subject: [PATCH 379/525] updated the docker compose file with working ldap example --- server-ce/docker-compose.yml | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 8039e108d7..d6c232e990 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -21,7 +21,7 @@ services: SHARELATEX_REDIS_HOST: redis SHARELATEX_APP_NAME: Our ShareLaTeX - #Set for SSL via nginx-proxy + ## Set for SSL via nginx-proxy #VIRTUAL_HOST: 103.112.212.22 # SHARELATEX_SITE_URL: http://sharelatex.mydomain.com @@ -55,20 +55,16 @@ services: # SANDBOXED_COMPILES_SIBLING_CONTAINERS: 'true' # SANDBOXED_COMPILES_HOST_DIR: '/var/clsi/compiles' - # SHARELATEX_LDAP_HOST: 'ldap://ldap.forumsys.com' - # SHARELATEX_LDAP_DN: 'uid=:userKey,dc=example,dc=com' - # SHARELATEX_LDAP_BASE_SEARCH: 'dc=example,dc=com' - # SHARELATEX_LDAP_FILTER: '(uid=:userKey)' - # SHARELATEX_LDAP_ADMIN_DN: 'cn=read-only-admin,dc=example,dc=com' - # SHARELATEX_LDAP_ADMIN_PW: password' - # SHARELATEX_LDAP_ANONYMOUS: "false" - # SHARELATEX_LDAP_EMAIL_ATT: "mail" - # SHARELATEX_LDAP_NAME_ATT: "name" - # SHARELATEX_LDAP_LAST_NAME_ATT: "secondname" - # SHARELATEX_LDAP_PLACEHOLDER: "Username" - # SHARELATEX_LDAP_TLS: "true" - # SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH: - # SHARELATEX_LDAP_TLS_OPTS_CA_PATH: '["/var/one.pem", "/var/two.pem"]' + ## Works with test LDAP server shown at bottom of docker compose + # SHARELATEX_LDAP_URL: 'ldap://ldap:389' + # SHARELATEX_LDAP_SEARCH_BASE: 'ou=people,dc=planetexpress,dc=com' + # SHARELATEX_LDAP_SEARCH_FILTER: '(uid={{username}})' + # SHARELATEX_LDAP_BIND_DN: 'cn=admin,dc=planetexpress,dc=com' + # SHARELATEX_LDAP_BIND_CREDENTIALS: 'GoodNewsEveryone' + # SHARELATEX_LDAP_EMAIL_ATT: 'mail' + # SHARELATEX_LDAP_NAME_ATT: 'cn' + # SHARELATEX_LDAP_LAST_NAME_ATT: 'sn' + # SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN: 'true' # SHARELATEX_TEMPLATES_USER_ID: "578773160210479700917ee5" @@ -91,7 +87,13 @@ services: - 6379 volumes: - ~/redis_data:/data - + + # ldap: + # restart: always + # image: rroemhild/test-openldap + # container_name: ldap + # expose: + # - 389 # nginx-proxy: # image: jwilder/nginx-proxy # container_name: nginx-proxy From 79c1370640e6b7ce54b192eb99a025b5164c9e96 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 26 Apr 2018 09:43:07 +0100 Subject: [PATCH 380/525] Update CONTRIBUTING.md --- server-ce/CONTRIBUTING.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index 50c94baaf0..50bf2e1cc0 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -30,10 +30,6 @@ We love pull requests, so be bold with them! Don't be afraid of going ahead and changing something, or adding a new feature. We're very happy to work with you to get your changes merged into ShareLaTeX. -If you've got an idea for a change then please discuss it in the open first, -either by opening an issue, or by joining us in our -[development chat room](http://www.hipchat.com/g1nJMcj7b). - If you're looking for something to work on, then take a look at our [development roadmap](https://github.com/sharelatex/sharelatex/wiki/Development-Roadmap), or have a look at the open issues in any of the repositories listed [here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories). Developer Chat Room From f888b90663bea227b574e57760127fe60b0ab39d Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 2 May 2018 16:07:23 +0100 Subject: [PATCH 381/525] added example sandbox compiles mount --- server-ce/docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index d6c232e990..f13b455093 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -16,6 +16,7 @@ services: volumes: - ~/sharelatex_data:/var/lib/sharelatex - /var/run/docker.sock:/var/run/docker.sock + #- /var/clsi/compiles:/var/www/sharelatex/clsi/compiles environment: SHARELATEX_MONGO_URL: mongodb://mongo/sharelatex SHARELATEX_REDIS_HOST: redis From 1d1bf4a541de41fa24f096cf185bb8325433a5e3 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 2 Aug 2018 10:10:19 +0100 Subject: [PATCH 382/525] Fix whitespace --- server-ce/migrations/7_add_token_indexes.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server-ce/migrations/7_add_token_indexes.coffee b/server-ce/migrations/7_add_token_indexes.coffee index 2155363978..867c209753 100644 --- a/server-ce/migrations/7_add_token_indexes.coffee +++ b/server-ce/migrations/7_add_token_indexes.coffee @@ -17,10 +17,10 @@ handleExit = () -> exports.migrate = (client, done=()->) -> console.log ">> Adding indexes for token-based project access: " db.projects.ensureIndex {'tokens.readAndWrite': 1}, { - partialFilterExpression: { 'tokens.readAndWrite': { $exists: true } }, - unique: true, - background: true - }, (err) -> + partialFilterExpression: { 'tokens.readAndWrite': { $exists: true } }, + unique: true, + background: true + }, (err) -> if err? return done(err) db.projects.ensureIndex {'tokens.readOnly': 1}, { From 9727c374b7d5e0d83aa8afbda1ba98696e92d425 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 19 Feb 2019 10:20:17 +0000 Subject: [PATCH 383/525] Update the readme with a short explanation of how this code works --- server-ce/README.md | 49 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 8e5cd84b8e..53a770d328 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,2 +1,47 @@ -## Install -Please see the [offical wiki for install guides](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) \ No newline at end of file +# ShareLaTeX Docker Image + +This is the source for building the sharelatex community-edition docker image. + + +## End-User Install +Please see the [offical wiki for install +guides](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) + + +## Development + +This repo contains two dockerfiles, `Dockerfile-base`, which builds the +`sharelatex/sharelatex-base` image, and `Dockerfile` which builds the +`sharelatex/sharelatex` (or "community") image. + +The Base image generally contains the basic dependencies like `wget` and +`aspell`, plus `texlive`. We split this out because it's a pretty heavy set of +dependencies, and it's nice to not have to rebuild all of that every time. + +The Sharelatex image extends the base image and adds the actual sharelatex code +and services. + +Use `make build-base` and `make build-community` to build these images. + + +### How the Sharelatex code gets here + +This repo uses [the public Sharelatex +repository](https://github.com/sharelatex/sharelatex), which used to be the main +public source for the sharelatex system. + +That repo is cloned down into the docker image, and a script then installs all +the services. This way of doing things predates the new dev-env, and isn't +currently tested. + + +### How services run inside the container + +We use the [Phusion base-image](https://github.com/phusion/baseimage-docker) +(which is extended by our `base` image) to provide us with a VM-like container +in which to run the sharelatex services. Baseimage uses the `runit` service +manager to manage services, and we add our init-scripts from the `./runit` +folder. + +Overall, this is very like how the services would run in production, it just +happens to be all inside one docker container instead of being on one VM. From f8b3741292049e9fa7935c1ed816c5f8e72f7996 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 1 Mar 2019 11:16:12 +0000 Subject: [PATCH 384/525] remove bit from readme --- server-ce/README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 53a770d328..ed5cd3a91f 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -42,6 +42,3 @@ We use the [Phusion base-image](https://github.com/phusion/baseimage-docker) in which to run the sharelatex services. Baseimage uses the `runit` service manager to manage services, and we add our init-scripts from the `./runit` folder. - -Overall, this is very like how the services would run in production, it just -happens to be all inside one docker container instead of being on one VM. From 32546b048440f6c73f69f286b8937be2231cd6a0 Mon Sep 17 00:00:00 2001 From: John Lees-Miller Date: Mon, 1 Apr 2019 08:25:50 +0100 Subject: [PATCH 385/525] Remove travis build status icons --- server-ce/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 658211805a..07f465fbc5 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -30,48 +30,48 @@ This repository does not contain any code. It acts a wrapper and toolkit for man The different services are: -### [web](https://github.com/sharelatex/web-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/web-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/web-sharelatex) +### [web](https://github.com/sharelatex/web-sharelatex) The front facing web server that serves all the HTML pages, CSS and JavaScript to the client. Also contains a lot of logic around creating and editing projects, and account management. -### [document-updater](https://github.com/sharelatex/document-updater-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/document-updater-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/document-updater-sharelatex) +### [document-updater](https://github.com/sharelatex/document-updater-sharelatex) Processes updates that come in from the editor when users modify documents. Ensures that the updates are applied in the right order, and that only one operation is modifying the document at a time. Also caches the documents in redis for very fast but persistent modifications. -### [CLSI](https://github.com/sharelatex/clsi-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/clsi-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/clsi-sharelatex) +### [CLSI](https://github.com/sharelatex/clsi-sharelatex) The Common LaTeX Service Interface (CLSI) which provides an API for compiling LaTeX documents. -### [docstore](https://github.com/sharelatex/docstore-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/docstore-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/docstore-sharelatex) +### [docstore](https://github.com/sharelatex/docstore-sharelatex) An API for performing CRUD (Create, Read, Update and Delete) operations on text files stored in ShareLaTeX. -### [realtime](https://github.com/sharelatex/real-time-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/real-time-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/real-time-sharelatex) +### [realtime](https://github.com/sharelatex/real-time-sharelatex) The websocket process clients connect to -### [filestore](https://github.com/sharelatex/filestore-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/filestore-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/filestore-sharelatex) +### [filestore](https://github.com/sharelatex/filestore-sharelatex) An API for performing CRUD (Create, Read, Update and Delete) operations on binary files (like images) stored in ShareLaTeX. -### [track-changes](https://github.com/sharelatex/track-changes-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/track-changes-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/track-changes-sharelatex) +### [track-changes](https://github.com/sharelatex/track-changes-sharelatex) An API for compressing and storing the updates applied to a document, and then rendering a diff of the changes between any two time points. -### [chat](https://github.com/sharelatex/chat-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/chat-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/chat-sharelatex) +### [chat](https://github.com/sharelatex/chat-sharelatex) The backend API for storing and fetching chat messages. -### [tags](https://github.com/sharelatex/tags-sharelatex) [![Build Status](https://travis-ci.org/sharelatex/tags-sharelatex.svg?branch=master)](https://travis-ci.org/sharelatex/tags-sharelatex) +### [tags](https://github.com/sharelatex/tags-sharelatex) The backend API for managing project tags (folders). From 98bc755b9f7b2abbb5ff23f59bac4eb11a853d42 Mon Sep 17 00:00:00 2001 From: John Lees-Miller Date: Wed, 10 Apr 2019 16:15:41 +0100 Subject: [PATCH 386/525] Update CLA and other links --- server-ce/CONTRIBUTING.md | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index 50bf2e1cc0..5d9f82d9fc 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -23,37 +23,29 @@ If you can include a screenshot for front end issues that is very helpful. Pull Requests ------------- -See [our wiki](https://github.com/sharelatex/sharelatex/wiki/Developer-Guidelines) +See [our wiki](https://github.com/sharelatex/sharelatex/wiki) for how to manage the ShareLaTeX development environment and for our developer guidelines. We love pull requests, so be bold with them! Don't be afraid of going ahead and changing something, or adding a new feature. We're very happy to work with you to get your changes merged into ShareLaTeX. -If you're looking for something to work on, then take a look at our [development roadmap](https://github.com/sharelatex/sharelatex/wiki/Development-Roadmap), or have a look at the open issues in any of the repositories listed [here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories). - -Developer Chat Room -------------------- - -If you want to ask any questions in real-time, or get a feel for what's going on -then please drop into our [development chat room](http://www.hipchat.com/g1nJMcj7b). -If no one is online then you can still leave a message that will hopefully get a reply -when we return. +If you're looking for something to work on, have a look at the open issues in any of the repositories listed [here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories). Security -------- Please do not publish security vulnerabilities publicly until we've had a chance to address them. All security related issues/patches should be sent directly to -team@sharelatex.com where we will attempt to address them quickly. If you're +security@overleaf.com where we will attempt to address them quickly. If you're unsure whether something is a security issue or not, then please be cautious and -contact us at team@sharelatex.com first. +contact us at security@overleaf.com first. Contributor License Agreement ----------------------------- Before we can accept any contributions of code, we need you to agree to our -[Contributor License Agreement](https://sharelatex.wufoo.com/forms/sharelatex-contributor-license-agreement/). +[Contributor License Agreement](https://docs.google.com/forms/d/e/1FAIpQLSef79XH3mb7yIiMzZw-yALEegS-wyFetvjTiNBfZvf_IHD2KA/viewform?usp=sf_link). This is to ensure that you own the copyright of your contribution, and that you agree to give us a license to use it in both the open source version, and the version -of ShareLaTeX running at www.sharelatex.com, which may have additional changes. +of Overleaf running at www.overleaf.com, which may have additional changes. From cae2dcfa5f15ae7d3c25cecf2b164b26804ec229 Mon Sep 17 00:00:00 2001 From: Tim Alby Date: Tue, 7 May 2019 19:28:15 +0200 Subject: [PATCH 387/525] update README - change app name - update copyright notice - update links - change authors --- server-ce/README.md | 51 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 07f465fbc5..91ca4dcf25 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,98 +1,97 @@ -ShareLaTeX -========== +Overleaf +======== -[ShareLaTeX](https://www.sharelatex.com) is an open-source online real-time collaborative LaTeX editor. We run a hosted version at http://www.sharelatex.com, but you can also run your own local version, and contribute to the development of ShareLaTeX. +[Overleaf](https://www.overleaf.com) is an open-source online real-time collaborative LaTeX editor. We run a hosted version at http://www.overleaf.com, but you can also run your own local version, and contribute to the development of Overleaf. -*[If you want help installing and maintaining ShareLaTeX at your university or workplace, we offer an officially supported version called ShareLaTeX Server Pro. It also comes with extra security and admin features. Click here to find out more!](https://www.sharelatex.com/university/onsite.html)* +*[If you want help installing and maintaining Overleaf at your university or workplace, we offer an officially supported version called Overleaf Server Pro. It also comes with extra security and admin features. Click here to find out more!](https://www.overleaf.com/university/onsite.html)* Keeping up to date ------------ -Sign up to the [mailing list](http://eepurl.com/bPWeiH) to get updates on ShareLaTeX Releases and development +Sign up to the [mailing list](http://eepurl.com/bPWeiH) to get updates on Overleaf Releases and development Installation ------------ We have detailed installation instructions in our wiki: -* [ShareLaTeX Quick Start Guide](https://github.com/sharelatex/sharelatex/wiki/Quick-Start-Guide) +* [Overleaf Quick Start Guide](https://github.com/overleaf/overleaf/wiki/Quick-Start-Guide) Upgrading --------- -If you are upgrading from a previous version of ShareLaTeX, please see the [Release Notes section on the Wiki](https://github.com/sharelatex/sharelatex/wiki/Home) for all of the versions between your current version and the version you are upgrading to. +If you are upgrading from a previous version of Overleaf, please see the [Release Notes section on the Wiki](https://github.com/overleaf/overleaf/wiki/Home) for all of the versions between your current version and the version you are upgrading to. Other repositories ------------------ -This repository does not contain any code. It acts a wrapper and toolkit for managing the many different ShareLaTeX services. These each run as their own Node.js process and have their own Github repository. These are all downloaded and set up when you run `grunt install` +This repository does not contain any code. It acts a wrapper and toolkit for managing the many different Overleaf services. These each run as their own Node.js process and have their own Github repository. These are all downloaded and set up when you run `grunt install` The different services are: -### [web](https://github.com/sharelatex/web-sharelatex) +### [web](https://github.com/overleaf/web) The front facing web server that serves all the HTML pages, CSS and JavaScript to the client. Also contains a lot of logic around creating and editing projects, and account management. -### [document-updater](https://github.com/sharelatex/document-updater-sharelatex) +### [document-updater](https://github.com/overleaf/document-updater) Processes updates that come in from the editor when users modify documents. Ensures that the updates are applied in the right order, and that only one operation is modifying the document at a time. Also caches the documents in redis for very fast but persistent modifications. -### [CLSI](https://github.com/sharelatex/clsi-sharelatex) +### [CLSI](https://github.com/overleaf/clsi) -The Common LaTeX Service Interface (CLSI) which provides an API for compiling LaTeX +The Common LaTeX Service Interface (CLSI) which provides an API for compiling LaTeX documents. -### [docstore](https://github.com/sharelatex/docstore-sharelatex) +### [docstore](https://github.com/overleaf/docstore) An API for performing CRUD (Create, Read, Update and Delete) operations on text files -stored in ShareLaTeX. +stored in Overleaf. -### [realtime](https://github.com/sharelatex/real-time-sharelatex) +### [realtime](https://github.com/overleaf/real-time) The websocket process clients connect to -### [filestore](https://github.com/sharelatex/filestore-sharelatex) +### [filestore](https://github.com/overleaf/filestore) An API for performing CRUD (Create, Read, Update and Delete) operations on binary files -(like images) stored in ShareLaTeX. +(like images) stored in Overleaf. -### [track-changes](https://github.com/sharelatex/track-changes-sharelatex) +### [track-changes](https://github.com/overleaf/track-changes) An API for compressing and storing the updates applied to a document, and then rendering a diff of the changes between any two time points. -### [chat](https://github.com/sharelatex/chat-sharelatex) +### [chat](https://github.com/overleaf/chat) The backend API for storing and fetching chat messages. -### [tags](https://github.com/sharelatex/tags-sharelatex) +### [tags](https://github.com/overleaf/tags) The backend API for managing project tags (folders). -### [spelling](https://github.com/sharelatex/spelling-sharelatex) +### [spelling](https://github.com/overleaf/spelling) -An API for running server-side spelling checking on ShareLaTeX documents. +An API for running server-side spelling checking on Overleaf documents. Contributing ------------ -Please see the [CONTRIBUTING](https://github.com/sharelatex/sharelatex/blob/master/CONTRIBUTING.md) file for information on contributing to the development of ShareLaTeX. See [our wiki](https://github.com/sharelatex/sharelatex/wiki/Developer-Guidelines) for information on setting up a development environment and how to recompile and run ShareLaTeX after modifications. +Please see the [CONTRIBUTING](https://github.com/overleaf/overleaf/blob/master/CONTRIBUTING.md) file for information on contributing to the development of Overleaf. See [our wiki](https://github.com/overleaf/overleaf/wiki/Developer-Guidelines) for information on setting up a development environment and how to recompile and run Overleaf after modifications. Authors --- -- [Henry Oswald](http://twitter.com/henryoswald) -- [James Allen](http://twitter.com/thejpallen) +[The Overleaf Team](https://www.overleaf.com/about) License ---- The code in this repository is released under the GNU AFFERO GENERAL PUBLIC LICENSE, version 3. A copy can be found in the `LICENSE` file. -Copyright (c) ShareLaTeX, 2014. +Copyright (c) Overleaf, 2014-2019. From 6ed76fdceb5c243cab81c640b9f509559d9c2ff1 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 31 May 2019 10:27:15 +0100 Subject: [PATCH 388/525] Update docker-compose.yml --- server-ce/docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index f13b455093..d6c232e990 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -16,7 +16,6 @@ services: volumes: - ~/sharelatex_data:/var/lib/sharelatex - /var/run/docker.sock:/var/run/docker.sock - #- /var/clsi/compiles:/var/www/sharelatex/clsi/compiles environment: SHARELATEX_MONGO_URL: mongodb://mongo/sharelatex SHARELATEX_REDIS_HOST: redis From 3c791751c1f0ff052b4581a4a4b81a8fa0b74825 Mon Sep 17 00:00:00 2001 From: mserranom Date: Tue, 23 Jul 2019 12:56:25 +0000 Subject: [PATCH 389/525] updated node version --- server-ce/.nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/.nvmrc b/server-ce/.nvmrc index e18a34b9d6..5007551bf8 100644 --- a/server-ce/.nvmrc +++ b/server-ce/.nvmrc @@ -1 +1 @@ -6.11.2 +10.16.0 From 3dbced021dffd4761a52b93d011d59dc4c13767b Mon Sep 17 00:00:00 2001 From: mserranom Date: Tue, 23 Jul 2019 12:56:49 +0000 Subject: [PATCH 390/525] fixed install-services and split install and compilation --- server-ce/bin/compile-services | 23 +++++++++++++++++++++++ server-ce/bin/install-services | 21 ++++++--------------- 2 files changed, 29 insertions(+), 15 deletions(-) create mode 100755 server-ce/bin/compile-services mode change 100644 => 100755 server-ce/bin/install-services diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services new file mode 100755 index 0000000000..3114df405d --- /dev/null +++ b/server-ce/bin/compile-services @@ -0,0 +1,23 @@ +#! env bash + +set -ex + +grep 'name:' config/services.js | \ + sed 's/.*name: "\(.*\)",/\1/' | \ + while read service + do + pushd $service + echo "Compiling Service $service" + case $service in + web) + make compile_full + ;; + chat) + echo "$service doesn't require a compilation" + ;; + *) + npm run compile:all + ;; + esac + popd + done diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services old mode 100644 new mode 100755 index 3f1e5dd44b..b5a1711102 --- a/server-ce/bin/install-services +++ b/server-ce/bin/install-services @@ -1,25 +1,16 @@ #! env bash -[ -z "`type -t nvm`" ] && cat < Date: Tue, 6 Aug 2019 12:00:43 +0000 Subject: [PATCH 391/525] removed -x option in bash command --- server-ce/bin/compile-services | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index 3114df405d..471a2b7130 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -1,6 +1,6 @@ #! env bash -set -ex +set -e grep 'name:' config/services.js | \ sed 's/.*name: "\(.*\)",/\1/' | \ From 1973fbddf13bbef8005376b5cf743cad117a35ff Mon Sep 17 00:00:00 2001 From: mserranom Date: Tue, 6 Aug 2019 12:00:55 +0000 Subject: [PATCH 392/525] removed nvm --- server-ce/bin/install-services | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services index b5a1711102..b688a4b4f8 100755 --- a/server-ce/bin/install-services +++ b/server-ce/bin/install-services @@ -1,14 +1,12 @@ #! env bash -set -ex +set -e grep 'name:' config/services.js | \ sed 's/.*name: "\(.*\)",/\1/' | \ while read service do pushd $service - echo "Installing Node from .nvmrc" - nvm install && nvm use echo "Installing service $service" npm install --quiet popd From 2bf86d8ea7c84768cb5a7d48693fa0a860c57d0d Mon Sep 17 00:00:00 2001 From: mserranom Date: Wed, 7 Aug 2019 08:47:05 +0000 Subject: [PATCH 393/525] Revive overleaf community --- server-ce/Dockerfile | 89 ++++++++++++++++-------- server-ce/Dockerfile-base | 48 +++++++++---- server-ce/runit/real-time-sharelatex/run | 2 +- server-ce/settings.coffee | 4 +- 4 files changed, 98 insertions(+), 45 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 881d48cfe6..c527411457 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -1,51 +1,80 @@ -# Sharelatex Community Edition (sharelatex/sharelatex) +# --------------------------------------------- +# Overleaf Community Edition (overleaf/overleaf) +# --------------------------------------------- FROM sharelatex/sharelatex-base:latest ENV baseDir . -# Install sharelatex settings file + +# Install app settings files +# -------------------------- ADD ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee -ADD ${baseDir}/runit /etc/service -RUN rm /etc/nginx/sites-enabled/default -ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf -ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf +# Checkout Overleaf Community Edition repo +# ---------------------------------------- +RUN git clone https://github.com/overleaf/overleaf.git \ + --depth 1 /var/www/sharelatex -ADD ${baseDir}/logrotate/sharelatex /etc/logrotate.d/sharelatex -COPY ${baseDir}/init_scripts/ /etc/my_init.d/ - -# Install ShareLaTeX -RUN git clone https://github.com/sharelatex/sharelatex.git /var/www/sharelatex - -ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js +# Install dependencies needed to run configuration scripts +# -------------------------------------------------------- ADD ${baseDir}/package.json /var/www/package.json ADD ${baseDir}/git-revision.js /var/www/git-revision.js RUN cd /var/www && npm install -RUN cd /var/www/sharelatex; \ - npm install; \ - grunt install; \ - bash -c 'source ./bin/install-services'; \ - cd web; \ - npm install; \ - npm install bcrypt; \ - cd modules; \ - git clone https://github.com/sharelatex/launchpad-web-module.git launchpad; \ - grunt compile; +# Replace overleaf/config/services.js with the list of available +# services in Overleaf Community Edition +# -------------------------------------------------------------- +ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js + + +# Checkout services +# ----------------- +RUN cd /var/www/sharelatex && \ + npm install && grunt install; + + +# install and compile services +# ---------------------------- +RUN bash -c 'cd /var/www/sharelatex && source ./bin/install-services' +RUN bash -c 'cd /var/www/sharelatex && source ./bin/compile-services' + + +# Change application ownership to www-data +# ---------------------------------------- +RUN chown -R www-data:www-data /var/www/sharelatex; + + +# Copy runit service startup scripts to its location +# -------------------------------------------------- +ADD ${baseDir}/runit /etc/service + + +# Configure nginx +# --------------- +RUN rm /etc/nginx/sites-enabled/default +ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf +ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf + + +# Configure log rotation +# ---------------------- +ADD ${baseDir}/logrotate/sharelatex /etc/logrotate.d/sharelatex + + +# Copy Phusion Image startup scripts to its location +# -------------------------------------------------- +COPY ${baseDir}/init_scripts/ /etc/my_init.d/ + + +# Stores the version installed for each service +# --------------------------------------------- RUN cd /var/www && node git-revision > revisions.txt - -# Minify js assets -RUN cd /var/www/sharelatex/web; \ - grunt compile:minify; -RUN cd /var/www/sharelatex/clsi; \ - grunt compile:bin; \ - chown -R www-data:www-data /var/www/sharelatex; EXPOSE 80 diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index a59431fc9d..f1a7e22531 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -1,41 +1,63 @@ +# -------------------------------------------------- # Sharelatex Base Image (sharelatex/sharelatex-base) +# -------------------------------------------------- -FROM phusion/baseimage:0.9.16 +FROM phusion/baseimage:0.11 ENV baseDir . -RUN apt-get update -RUN curl -sL https://deb.nodesource.com/setup_6.x | sudo bash - -RUN apt-get install -y build-essential wget nodejs unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-alt aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-or aspell-pa aspell-pl aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-ta aspell-te aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu +# Install dependencies +# -------------------- +RUN apt-get update +RUN apt-get install -y sudo +RUN apt-get install -y build-essential wget net-tools unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev aspell aspell-en + + +# Install qpdf +# ------------ WORKDIR /opt RUN wget https://s3.amazonaws.com/sharelatex-random-files/qpdf-6.0.0.tar.gz && tar xzf qpdf-6.0.0.tar.gz WORKDIR /opt/qpdf-6.0.0 RUN ./configure && make && make install && ldconfig + +# Install Node +# ------------ +RUN curl -sL https://deb.nodesource.com/setup_10.x | sudo bash - +RUN apt-get install -y nodejs +RUN npm install -g grunt-cli + + +# Install Node6 (required by some services) +# ----------------------------------------- +RUN wget https://nodejs.org/dist/v6.17.1/node-v6.17.1-linux-x64.tar.gz && \ + mkdir -p /opt/nodejs && tar -xzf node-v6.17.1-linux-x64.tar.gz -C /opt/nodejs/ && \ + cd /opt/nodejs && mv node-v6.17.1-linux-x64 6.17.1 && \ + ln -s /opt/nodejs/6.17.1/bin/node /usr/bin/node6 + + # Install TexLive -RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz; \ +# --------------- +RUN wget https://ctan.crest.fr/tex-archive/systems/texlive/tlnet/install-tl-unx.tar.gz; \ mkdir /install-tl-unx; \ tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 - RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ - /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile - + /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile \ + -repository http://tug.ctan.org/systems/texlive/tlnet/ RUN rm -r /install-tl-unx; \ rm install-tl-unx.tar.gz - -ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2017/bin/x86_64-linux/ +ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2019/bin/x86_64-linux/ RUN tlmgr install latexmk RUN tlmgr install texcount -RUN npm install -g grunt-cli # Set up sharelatex user and home directory +# ----------------------------------------- RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex; \ mkdir -p /var/lib/sharelatex; \ chown www-data:www-data /var/lib/sharelatex; \ mkdir -p /var/log/sharelatex; \ chown www-data:www-data /var/log/sharelatex; \ mkdir -p /var/lib/sharelatex/data/template_files; \ - chown www-data:www-data /var/lib/sharelatex/data/template_files; - + chown www-data:www-data /var/lib/sharelatex/data/template_files; \ No newline at end of file diff --git a/server-ce/runit/real-time-sharelatex/run b/server-ce/runit/real-time-sharelatex/run index c57d1d489e..7168368c38 100755 --- a/server-ce/runit/real-time-sharelatex/run +++ b/server-ce/runit/real-time-sharelatex/run @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/real-time/app.js >> /var/log/sharelatex/real-time.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node6 /var/www/sharelatex/real-time/app.js >> /var/log/sharelatex/real-time.log 2>&1 \ No newline at end of file diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 7f4f18067f..92a545eac7 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -22,6 +22,8 @@ TMP_DIR = '/var/lib/sharelatex/tmp' settings = + brandPrefix: "" + allowAnonymousReadAndWriteSharing: process.env['SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING'] == 'true' @@ -169,7 +171,7 @@ settings = # Should javascript assets be served minified or not. Note that you will # need to run `grunt compile:minify` within the web-sharelatex directory # to generate these. - useMinifiedJs: true + useMinifiedJs: false # Should static assets be sent with a header to tell the browser to cache # them. This should be false in development where changes are being made, From 28772d6d2518cdef2f1c8ca78ad4a303ddcb5387 Mon Sep 17 00:00:00 2001 From: mserranom Date: Wed, 7 Aug 2019 08:52:55 +0000 Subject: [PATCH 394/525] added missing aspell languages --- server-ce/Dockerfile-base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index f1a7e22531..2f88946bdd 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -11,7 +11,7 @@ ENV baseDir . # -------------------- RUN apt-get update RUN apt-get install -y sudo -RUN apt-get install -y build-essential wget net-tools unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev aspell aspell-en +RUN apt-get install -y build-essential wget net-tools unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-nr aspell-ns aspell-pa aspell-pl aspell-pt aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu # Install qpdf From 803f920b550c51c87f52fee1bf250e306430621f Mon Sep 17 00:00:00 2001 From: mserranom Date: Thu, 8 Aug 2019 10:44:14 +0000 Subject: [PATCH 395/525] addressed PR comments --- server-ce/.editorconfig | 9 +++++++++ server-ce/Dockerfile-base | 23 +++++++++++------------ 2 files changed, 20 insertions(+), 12 deletions(-) create mode 100644 server-ce/.editorconfig diff --git a/server-ce/.editorconfig b/server-ce/.editorconfig new file mode 100644 index 0000000000..9d08a1a828 --- /dev/null +++ b/server-ce/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index 2f88946bdd..aed92b21b8 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -39,12 +39,11 @@ RUN wget https://nodejs.org/dist/v6.17.1/node-v6.17.1-linux-x64.tar.gz && \ # Install TexLive # --------------- -RUN wget https://ctan.crest.fr/tex-archive/systems/texlive/tlnet/install-tl-unx.tar.gz; \ - mkdir /install-tl-unx; \ +RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz && \ + mkdir /install-tl-unx && \ tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 -RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile; \ - /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile \ - -repository http://tug.ctan.org/systems/texlive/tlnet/ +RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile && \ + /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile RUN rm -r /install-tl-unx; \ rm install-tl-unx.tar.gz ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2019/bin/x86_64-linux/ @@ -54,10 +53,10 @@ RUN tlmgr install texcount # Set up sharelatex user and home directory # ----------------------------------------- -RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex; \ - mkdir -p /var/lib/sharelatex; \ - chown www-data:www-data /var/lib/sharelatex; \ - mkdir -p /var/log/sharelatex; \ - chown www-data:www-data /var/log/sharelatex; \ - mkdir -p /var/lib/sharelatex/data/template_files; \ - chown www-data:www-data /var/lib/sharelatex/data/template_files; \ No newline at end of file +RUN adduser --system --group --home /var/www/sharelatex --no-create-home sharelatex && \ + mkdir -p /var/lib/sharelatex && \ + chown www-data:www-data /var/lib/sharelatex && \ + mkdir -p /var/log/sharelatex && \ + chown www-data:www-data /var/log/sharelatex && \ + mkdir -p /var/lib/sharelatex/data/template_files && \ + chown www-data:www-data /var/lib/sharelatex/data/template_files From 22477bc187f08641731147fa783dd9a0d44ccd1c Mon Sep 17 00:00:00 2001 From: mserranom Date: Thu, 8 Aug 2019 16:11:43 +0000 Subject: [PATCH 396/525] added minification for web --- server-ce/bin/compile-services | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index 471a2b7130..31f9873ced 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -11,6 +11,7 @@ grep 'name:' config/services.js | \ case $service in web) make compile_full + make minify ;; chat) echo "$service doesn't require a compilation" From 1c931c347ea5c0b8a3f663096e39d754706bb16f Mon Sep 17 00:00:00 2001 From: mserranom Date: Mon, 12 Aug 2019 09:32:54 +0000 Subject: [PATCH 397/525] reverted minification for web --- server-ce/bin/compile-services | 1 - 1 file changed, 1 deletion(-) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index 31f9873ced..471a2b7130 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -11,7 +11,6 @@ grep 'name:' config/services.js | \ case $service in web) make compile_full - make minify ;; chat) echo "$service doesn't require a compilation" From 9dc65ebc82d9fee427ca439e42afddeba5296e7d Mon Sep 17 00:00:00 2001 From: John Lees-Miller Date: Thu, 15 Aug 2019 10:55:25 +0100 Subject: [PATCH 398/525] Update mailing list link --- server-ce/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/README.md b/server-ce/README.md index 91ca4dcf25..e8068baef4 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -7,7 +7,7 @@ Overleaf Keeping up to date ------------ -Sign up to the [mailing list](http://eepurl.com/bPWeiH) to get updates on Overleaf Releases and development +Sign up to the [mailing list](https://mailchi.mp/overleaf.com/community-edition-and-server-pro) to get updates on Overleaf Releases and development Installation ------------ From 1df1f17fc60c412dd2670a02f3cb579cf23d77b0 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 20 Aug 2019 10:50:23 +0200 Subject: [PATCH 399/525] Run filestore with node6 (#108) --- server-ce/runit/filestore-sharelatex/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/runit/filestore-sharelatex/run b/server-ce/runit/filestore-sharelatex/run index e0858c01ce..1ba126dda0 100755 --- a/server-ce/runit/filestore-sharelatex/run +++ b/server-ce/runit/filestore-sharelatex/run @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/filestore/app.js >> /var/log/sharelatex/filestore.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node6 /var/www/sharelatex/filestore/app.js >> /var/log/sharelatex/filestore.log 2>&1 From f100877eb76cd5e7c3e722e6239c6533db2df971 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 22 Aug 2019 16:57:26 +0200 Subject: [PATCH 400/525] Server Pro fixes (#109) --- server-ce/.dockerignore | 3 + server-ce/.gitignore | 1 + server-ce/Dockerfile-base | 12 +++- server-ce/README.md | 21 +++--- server-ce/settings.coffee | 144 +------------------------------------- 5 files changed, 27 insertions(+), 154 deletions(-) create mode 100644 server-ce/.dockerignore diff --git a/server-ce/.dockerignore b/server-ce/.dockerignore new file mode 100644 index 0000000000..fd3df9c73e --- /dev/null +++ b/server-ce/.dockerignore @@ -0,0 +1,3 @@ +.DS_Store +.git/ +node_modules/ \ No newline at end of file diff --git a/server-ce/.gitignore b/server-ce/.gitignore index 023b43469e..877b99b865 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -1,3 +1,4 @@ +.DS_Store node_modules/ api-data versions/ diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index aed92b21b8..f56136fd87 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -1,5 +1,5 @@ # -------------------------------------------------- -# Sharelatex Base Image (sharelatex/sharelatex-base) +# Overleaf Base Image (sharelatex/sharelatex-base) # -------------------------------------------------- FROM phusion/baseimage:0.11 @@ -44,6 +44,16 @@ RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz && \ tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile && \ /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile + +# CTAN mirrors occasionally fail, in that case install TexLive against an +# specific server, for example http://ctan.crest.fr +# RUN wget http://ctan.crest.fr/tex-archive/systems/texlive/tlnet/install-tl-unx.tar.gz && \ +# mkdir /install-tl-unx && \ +# tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 +# RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile && \ +# /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile \ +# -repository http://ctan.crest.fr/tex-archive/systems/texlive/tlnet/ + RUN rm -r /install-tl-unx; \ rm install-tl-unx.tar.gz ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2019/bin/x86_64-linux/ diff --git a/server-ce/README.md b/server-ce/README.md index ed5cd3a91f..c1894afce0 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,11 +1,11 @@ -# ShareLaTeX Docker Image +# Overleaf Docker Image -This is the source for building the sharelatex community-edition docker image. +This is the source for building the Overleaf community-edition docker image. ## End-User Install Please see the [offical wiki for install -guides](https://github.com/sharelatex/sharelatex/wiki/Production-Installation-Instructions) +guides](https://github.com/overleaf/overleaf/wiki) ## Development @@ -18,27 +18,26 @@ The Base image generally contains the basic dependencies like `wget` and `aspell`, plus `texlive`. We split this out because it's a pretty heavy set of dependencies, and it's nice to not have to rebuild all of that every time. -The Sharelatex image extends the base image and adds the actual sharelatex code +The `sharelatex/sharelatex` image extends the base image and adds the actual Overleaf code and services. Use `make build-base` and `make build-community` to build these images. -### How the Sharelatex code gets here +### How the Overleaf code gets here -This repo uses [the public Sharelatex -repository](https://github.com/sharelatex/sharelatex), which used to be the main -public source for the sharelatex system. +This repo uses [the public Overleaf +repository](https://github.com/overleaf/overleaf), which used to be the main +public source for the Overleaf system. That repo is cloned down into the docker image, and a script then installs all -the services. This way of doing things predates the new dev-env, and isn't -currently tested. +the services. ### How services run inside the container We use the [Phusion base-image](https://github.com/phusion/baseimage-docker) (which is extended by our `base` image) to provide us with a VM-like container -in which to run the sharelatex services. Baseimage uses the `runit` service +in which to run the Overleaf services. Baseimage uses the `runit` service manager to manage services, and we add our init-scripts from the `./runit` folder. diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 92a545eac7..b8259b96ed 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -193,146 +193,6 @@ settings = www: {lngCode:process.env["SHARELATEX_SITE_LANGUAGE"] or "en", url: siteUrl} defaultLng: process.env["SHARELATEX_SITE_LANGUAGE"] or "en" - # Spell Check Languages - # --------------------- - # - # You must have the corresponding aspell dictionary installed to - # be able to use a language. Run `grunt check:aspell` to check which - # dictionaries you have installed. These should be set for the `code` for - # each language. - languages: [{ - "code":"en", "name":"English (American)" - },{ - "code":"en_GB", "name":"English (British)" - },{ - "code":"af", "name":"Africaans" - },{ - "code":"am", "name":"Amharic" - },{ - "code":"ar", "name":"Arabic" - },{ - "code":"hy", "name":"Armenian" - },{ - "code":"gl", "name":"Galician" - },{ - "code":"eu", "name":"Basque" - },{ - "code":"bn", "name":"Bengali" - },{ - "code":"br", "name":"Breton" - },{ - "code":"bg", "name":"Bulgarian" - },{ - "code":"ca", "name":"Catalan" - },{ - "code":"hr", "name":"Croatian" - },{ - "code":"cs", "name":"Czech" - },{ - "code":"da", "name":"Danish" - },{ - "code":"nl", "name":"Dutch" - },{ - "code":"eo", "name":"Esperanto" - },{ - "code":"et", "name":"Estonian" - },{ - "code":"fo", "name":"Faroese" - },{ - "code":"fr", "name":"French" - },{ - "code":"de", "name":"German" - },{ - "code":"el", "name":"Greek" - },{ - "code":"gu", "name":"Gujarati" - },{ - "code":"he", "name":"Hebrew" - },{ - "code":"hi", "name":"Hindi" - },{ - "code":"hu", "name":"Hungarian" - },{ - "code":"is", "name":"Icelandic" - },{ - "code":"id", "name":"Indonesian" - },{ - "code":"ga", "name":"Irish" - },{ - "code":"it", "name":"Italian" - },{ - "code":"kn", "name":"Kannada" - },{ - "code":"kk", "name":"Kazakh" - },{ - "code":"ku", "name":"Kurdish" - },{ - "code":"lv", "name":"Latvian" - },{ - "code":"lt", "name":"Lithuanian" - },{ - "code":"ml", "name":"Malayalam" - },{ - "code":"mr", "name":"Marathi" - },{ - "code":"nr", "name":"Ndebele" - },{ - "code":"ns", "name":"Northern Sotho" - },{ - "code":"no", "name":"Norwegian" - },{ - "code":"or", "name":"Oriya" - },{ - "code":"fa", "name":"Persian" - },{ - "code":"pl", "name":"Polish" - },{ - "code":"pt_BR", "name":"Portuguese (Brazilian)" - },{ - "code":"pt_PT", "name":"Portuguese (European)" - },{ - "code":"pa", "name":"Punjabi" - },{ - "code":"ro", "name":"Romanian" - },{ - "code":"ru", "name":"Russian" - },{ - "code":"sk", "name":"Slovak" - },{ - "code":"sl", "name":"Slovenian" - },{ - "code":"st", "name":"Southern Sotho" - },{ - "code":"es", "name":"Spanish" - },{ - "code":"ss", "name":"Swazi" - },{ - "code":"sv", "name":"Swedish" - },{ - "code":"tl", "name":"Tagalog" - },{ - "code":"ta", "name":"Tamil" - },{ - "code":"te", "name":"Telugu" - },{ - "code":"ts", "name":"Tsonga" - },{ - "code":"tn", "name":"Tswana" - },{ - "code":"uk", "name":"Ukrainian" - },{ - "code":"hsb", "name":"Upper Sorbian" - },{ - "code":"uz", "name":"Uzbek" - },{ - "code":"cy", "name":"Welsh" - },{ - "code":"xh", "name":"Xhosa" - },{ - "code":"zu", "name":"Zulu" - } - ] - apis: web: url: "http://localhost:3000" @@ -628,7 +488,7 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] # -------- if process.env["SANDBOXED_COMPILES"] == "true" settings.clsi = - commandRunner: "docker-runner-sharelatex" + dockerRunner: true docker: image: process.env["TEX_LIVE_DOCKER_IMAGE"] env: @@ -640,7 +500,7 @@ if process.env["SANDBOXED_COMPILES"] == "true" settings.path = {} settings.path.synctexBaseDir = () -> "/compile" if process.env['SANDBOXED_COMPILES_SIBLING_CONTAINERS'] == 'true' - console.log("Using sibling containers for sandoxed compiles") + console.log("Using sibling containers for sandboxed compiles") if process.env['SANDBOXED_COMPILES_HOST_DIR'] settings.path.sandboxedCompilesHostDir = process.env['SANDBOXED_COMPILES_HOST_DIR'] else From 34b01f94e4dacae0d92b8695d400e5fef85ba8e7 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 3 Sep 2019 11:36:10 +0200 Subject: [PATCH 401/525] Added minification to web compile script (#631) --- server-ce/bin/compile-services | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index 471a2b7130..1c508ae693 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -11,6 +11,7 @@ grep 'name:' config/services.js | \ case $service in web) make compile_full + WEBPACK_ENV=production make minify ;; chat) echo "$service doesn't require a compilation" From a818b1d427dac43c677377982c20bc3cfcbb00ea Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 3 Sep 2019 11:36:39 +0200 Subject: [PATCH 402/525] Updated settings to serve minified assets (#110) --- server-ce/settings.coffee | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index b8259b96ed..89fc442d64 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -169,9 +169,8 @@ settings = httpAuthUsers: httpAuthUsers # Should javascript assets be served minified or not. Note that you will - # need to run `grunt compile:minify` within the web-sharelatex directory - # to generate these. - useMinifiedJs: false + # need to run `make minify` within the web directory to generate these. + useMinifiedJs: true # Should static assets be sent with a header to tell the browser to cache # them. This should be false in development where changes are being made, From d126eb711239d1c85ad71483cd4ef14c31ff7e06 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 4 Sep 2019 16:39:47 +0200 Subject: [PATCH 403/525] Updated settings with several fixes (#111) --- server-ce/settings.coffee | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 89fc442d64..96970b8bb1 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -168,8 +168,7 @@ settings = # between services that may need to go over public channels httpAuthUsers: httpAuthUsers - # Should javascript assets be served minified or not. Note that you will - # need to run `make minify` within the web directory to generate these. + # Should javascript assets be served minified or not. useMinifiedJs: true # Should static assets be sent with a header to tell the browser to cache @@ -197,6 +196,10 @@ settings = url: "http://localhost:3000" user: httpAuthUser pass: httpAuthPass + # overrides v1.url to indicate via Feature Flags that Overleaf V1 + # is not available + v1: + url: null references:{} notifications:undefined @@ -421,8 +424,6 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"] callbackUrl: process.env["SHARELATEX_SAML_CALLBACK_URL"] issuer: process.env["SHARELATEX_SAML_ISSUER"] - cert: process.env["SHARELATEX_SAML_CERT"] - privateCert: process.env["SHARELATEX_SAML_PRIVATE_CERT"] decryptionPvk: process.env["SHARELATEX_SAML_DECRYPTION_PVK"] signatureAlgorithm: process.env["SHARELATEX_SAML_SIGNATURE_ALGORITHM"] identifierFormat: process.env["SHARELATEX_SAML_IDENTIFIER_FORMAT"] @@ -482,6 +483,11 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] undefined ) + # SHARELATEX_SAML_CERT cannot be empty + # https://github.com/bergie/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 + if process.env["SHARELATEX_SAML_CERT"] + settings.saml.server.cert = process.env["SHARELATEX_SAML_CERT"] + settings.saml.server.privateCert = process.env["SHARELATEX_SAML_PRIVATE_CERT"] # Compiler # -------- From 47eb3e4186b74dc5280d2b3e3b12d759f8266493 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 6 Sep 2019 10:37:03 +0200 Subject: [PATCH 404/525] Override v1.url setting with "" instead of null (#112) --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 96970b8bb1..fb930628a1 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -199,7 +199,7 @@ settings = # overrides v1.url to indicate via Feature Flags that Overleaf V1 # is not available v1: - url: null + url: "" references:{} notifications:undefined From e5dacbdc74f83f05963d0d19c555ba4554d183c5 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 6 Sep 2019 10:47:14 +0200 Subject: [PATCH 405/525] Updated docker-compose.yml with new and missing properties for ServerPro 2.0 (#632) --- server-ce/docker-compose.yml | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index d6c232e990..48a6692e8e 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -17,10 +17,18 @@ services: - ~/sharelatex_data:/var/lib/sharelatex - /var/run/docker.sock:/var/run/docker.sock environment: + + SHARELATEX_APP_NAME: Overleaf Community Edition + SHARELATEX_MONGO_URL: mongodb://mongo/sharelatex + + # Same property, unfortunately with different names in + # different locations SHARELATEX_REDIS_HOST: redis - SHARELATEX_APP_NAME: Our ShareLaTeX - + REDIS_HOST: redis + + ENABLED_LINKED_FILE_TYPES: 'url,project_file' + ## Set for SSL via nginx-proxy #VIRTUAL_HOST: 103.112.212.22 @@ -34,14 +42,14 @@ services: # SHARELATEX_EMAIL_FROM_ADDRESS: "team@sharelatex.com" - # SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID: - # SHARELATEX_EMAIL_AWS_SES_SECRET_KEY: + # SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID: + # SHARELATEX_EMAIL_AWS_SES_SECRET_KEY: # SHARELATEX_EMAIL_SMTP_HOST: smtp.mydomain.com # SHARELATEX_EMAIL_SMTP_PORT: 587 # SHARELATEX_EMAIL_SMTP_SECURE: false - # SHARELATEX_EMAIL_SMTP_USER: - # SHARELATEX_EMAIL_SMTP_PASS: + # SHARELATEX_EMAIL_SMTP_USER: + # SHARELATEX_EMAIL_SMTP_PASS: # SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH: true # SHARELATEX_EMAIL_SMTP_IGNORE_TLS: false # SHARELATEX_CUSTOM_EMAIL_FOOTER: "
This system is run by department x
" @@ -51,10 +59,12 @@ services: ################ # SANDBOXED_COMPILES: 'true' - + # SANDBOXED_COMPILES_SIBLING_CONTAINERS: 'true' # SANDBOXED_COMPILES_HOST_DIR: '/var/clsi/compiles' + # DOCKER_RUNNER: 'false' + ## Works with test LDAP server shown at bottom of docker compose # SHARELATEX_LDAP_URL: 'ldap://ldap:389' # SHARELATEX_LDAP_SEARCH_BASE: 'ou=people,dc=planetexpress,dc=com' @@ -67,6 +77,8 @@ services: # SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN: 'true' # SHARELATEX_TEMPLATES_USER_ID: "578773160210479700917ee5" + # SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS: '[ {"name":"All Templates","url":"/templates/all"}]' + # SHARELATEX_PROXY_LEARN: "true" From fad5639f5581fcc64472a1670e64ce252e73cedd Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 10 Sep 2019 17:13:17 +0200 Subject: [PATCH 406/525] Added debugging support to services (#113) --- server-ce/.dockerignore | 2 +- server-ce/Dockerfile-base | 2 +- server-ce/runit/chat-sharelatex/run | 9 +++++- server-ce/runit/clsi-sharelatex/run | 9 +++++- server-ce/runit/contacts-sharelatex/run | 9 +++++- server-ce/runit/docstore-sharelatex/run | 9 +++++- .../runit/document-updater-sharelatex/run | 9 +++++- server-ce/runit/notifications-sharelatex/run | 9 +++++- server-ce/runit/real-time-sharelatex/run | 2 +- server-ce/runit/spelling-sharelatex/run | 9 +++++- server-ce/runit/tags-sharelatex/run | 9 +++++- server-ce/runit/track-changes-sharelatex/run | 9 +++++- server-ce/runit/web-sharelatex/run | 9 +++++- server-ce/settings.coffee | 28 +++++++++---------- 14 files changed, 97 insertions(+), 27 deletions(-) diff --git a/server-ce/.dockerignore b/server-ce/.dockerignore index fd3df9c73e..2a5c59398a 100644 --- a/server-ce/.dockerignore +++ b/server-ce/.dockerignore @@ -1,3 +1,3 @@ .DS_Store .git/ -node_modules/ \ No newline at end of file +node_modules/ diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index f56136fd87..2cff8a830f 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -43,7 +43,7 @@ RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz && \ mkdir /install-tl-unx && \ tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile && \ - /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile + /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile # CTAN mirrors occasionally fail, in that case install TexLive against an # specific server, for example http://ctan.crest.fr diff --git a/server-ce/runit/chat-sharelatex/run b/server-ce/runit/chat-sharelatex/run index 1b8533bb86..cc5f75057f 100755 --- a/server-ce/runit/chat-sharelatex/run +++ b/server-ce/runit/chat-sharelatex/run @@ -1,3 +1,10 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/chat/app.js >> /var/log/sharelatex/chat.log 2>&1 \ No newline at end of file + +NODE_PARAMS="" +if [ "$DEBUG_NODE" == "true" ]; then + echo "running debug - chat" + NODE_PARAMS="--inspect=0.0.0.0:30100" +fi + +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/chat/app.js >> /var/log/sharelatex/chat.log 2>&1 diff --git a/server-ce/runit/clsi-sharelatex/run b/server-ce/runit/clsi-sharelatex/run index 1c6974cd2a..7492acf6d1 100755 --- a/server-ce/runit/clsi-sharelatex/run +++ b/server-ce/runit/clsi-sharelatex/run @@ -1,3 +1,10 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/clsi/app.js >> /var/log/sharelatex/clsi.log 2>&1 \ No newline at end of file + +NODE_PARAMS="" +if [ "$DEBUG_NODE" == "true" ]; then + echo "running debug - clsi" + NODE_PARAMS="--inspect=0.0.0.0:30130" +fi + +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/clsi/app.js >> /var/log/sharelatex/clsi.log 2>&1 diff --git a/server-ce/runit/contacts-sharelatex/run b/server-ce/runit/contacts-sharelatex/run index 29b513cb97..e220d9ac1d 100755 --- a/server-ce/runit/contacts-sharelatex/run +++ b/server-ce/runit/contacts-sharelatex/run @@ -1,3 +1,10 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/contacts/app.js >> /var/log/sharelatex/contacts 2>&1 + +NODE_PARAMS="" +if [ "$DEBUG_NODE" == "true" ]; then + echo "running debug - contacts" + NODE_PARAMS="--inspect=0.0.0.0:30360" +fi + +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/contacts/app.js >> /var/log/sharelatex/contacts 2>&1 diff --git a/server-ce/runit/docstore-sharelatex/run b/server-ce/runit/docstore-sharelatex/run index 0de82ccf20..2a171f0968 100755 --- a/server-ce/runit/docstore-sharelatex/run +++ b/server-ce/runit/docstore-sharelatex/run @@ -1,3 +1,10 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/docstore/app.js >> /var/log/sharelatex/docstore.log 2>&1 \ No newline at end of file + +NODE_PARAMS="" +if [ "$DEBUG_NODE" == "true" ]; then + echo "running debug - docstore" + NODE_PARAMS="--inspect=0.0.0.0:30160" +fi + +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/docstore/app.js >> /var/log/sharelatex/docstore.log 2>&1 diff --git a/server-ce/runit/document-updater-sharelatex/run b/server-ce/runit/document-updater-sharelatex/run index 274b7f9998..51472b3d48 100755 --- a/server-ce/runit/document-updater-sharelatex/run +++ b/server-ce/runit/document-updater-sharelatex/run @@ -1,3 +1,10 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/document-updater/app.js >> /var/log/sharelatex/document-updater.log 2>&1 \ No newline at end of file + +NODE_PARAMS="" +if [ "$DEBUG_NODE" == "true" ]; then + echo "running debug - document updater" + NODE_PARAMS="--inspect=0.0.0.0:30030" +fi + +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/document-updater/app.js >> /var/log/sharelatex/document-updater.log 2>&1 diff --git a/server-ce/runit/notifications-sharelatex/run b/server-ce/runit/notifications-sharelatex/run index 12b3457f2c..89f8ad54f9 100755 --- a/server-ce/runit/notifications-sharelatex/run +++ b/server-ce/runit/notifications-sharelatex/run @@ -1,3 +1,10 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/notifications/app.js >> /var/log/sharelatex/notifications.log 2>&1 \ No newline at end of file + +NODE_PARAMS="" +if [ "$DEBUG_NODE" == "true" ]; then + echo "running debug - notifications" + NODE_PARAMS="--inspect=0.0.0.0:30420" +fi + +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/notifications/app.js >> /var/log/sharelatex/notifications.log 2>&1 diff --git a/server-ce/runit/real-time-sharelatex/run b/server-ce/runit/real-time-sharelatex/run index 7168368c38..1d00837def 100755 --- a/server-ce/runit/real-time-sharelatex/run +++ b/server-ce/runit/real-time-sharelatex/run @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node6 /var/www/sharelatex/real-time/app.js >> /var/log/sharelatex/real-time.log 2>&1 \ No newline at end of file +exec /sbin/setuser www-data /usr/bin/node6 /var/www/sharelatex/real-time/app.js >> /var/log/sharelatex/real-time.log 2>&1 diff --git a/server-ce/runit/spelling-sharelatex/run b/server-ce/runit/spelling-sharelatex/run index 4466bcfcf5..a9a73f8ae0 100755 --- a/server-ce/runit/spelling-sharelatex/run +++ b/server-ce/runit/spelling-sharelatex/run @@ -1,3 +1,10 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/spelling/app.js >> /var/log/sharelatex/spelling.log 2>&1 \ No newline at end of file + +NODE_PARAMS="" +if [ "$DEBUG_NODE" == "true" ]; then + echo "running debug - spelling" + NODE_PARAMS="--inspect=0.0.0.0:30050" +fi + +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/spelling/app.js >> /var/log/sharelatex/spelling.log 2>&1 diff --git a/server-ce/runit/tags-sharelatex/run b/server-ce/runit/tags-sharelatex/run index a5630ed4ff..62fe058ad9 100755 --- a/server-ce/runit/tags-sharelatex/run +++ b/server-ce/runit/tags-sharelatex/run @@ -1,3 +1,10 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/tags/app.js >> /var/log/sharelatex/tags.log 2>&1 \ No newline at end of file + +NODE_PARAMS="" +if [ "$DEBUG_NODE" == "true" ]; then + echo "running debug - tags" + NODE_PARAMS="--inspect=0.0.0.0:30120" +fi + +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/tags/app.js >> /var/log/sharelatex/tags.log 2>&1 diff --git a/server-ce/runit/track-changes-sharelatex/run b/server-ce/runit/track-changes-sharelatex/run index aeb812ef38..45b3b77ebc 100755 --- a/server-ce/runit/track-changes-sharelatex/run +++ b/server-ce/runit/track-changes-sharelatex/run @@ -1,3 +1,10 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/track-changes/app.js >> /var/log/sharelatex/track-changes.log 2>&1 \ No newline at end of file + +NODE_PARAMS="" +if [ "$DEBUG_NODE" == "true" ]; then + echo "running debug - track-changes" + NODE_PARAMS="--inspect=0.0.0.0:30150" +fi + +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/track-changes/app.js >> /var/log/sharelatex/track-changes.log 2>&1 diff --git a/server-ce/runit/web-sharelatex/run b/server-ce/runit/web-sharelatex/run index 053a55a326..c1371de0f4 100755 --- a/server-ce/runit/web-sharelatex/run +++ b/server-ce/runit/web-sharelatex/run @@ -1,3 +1,10 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/web/app.js >> /var/log/sharelatex/web.log 2>&1 \ No newline at end of file + +NODE_PARAMS="" +if [ "$DEBUG_NODE" == "true" ]; then + echo "running debug - web" + NODE_PARAMS="--inspect=0.0.0.0:40000" +fi + +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/web/app.js >> /var/log/sharelatex/web.log 2>&1 diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index fb930628a1..3cb6a510b9 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -34,7 +34,7 @@ settings = # Documentation about the URL connection string format can be found at: # # http://docs.mongodb.org/manual/reference/connection-string/ - # + # # The following works out of the box with Mongo's default settings: mongo: url : process.env["SHARELATEX_MONGO_URL"] or 'mongodb://dockerhost/sharelatex' @@ -105,11 +105,11 @@ settings = # ShareLaTeX can store binary files like images either locally or in Amazon # S3. The default is locally: filestore: - backend: "fs" + backend: "fs" stores: user_files: Path.join(DATA_DIR, "user_files") template_files: Path.join(DATA_DIR, "template_files") - + # To use Amazon S3 as a storage backend, comment out the above config, and # uncomment the following, filling in your key, secret, and bucket name: # @@ -120,7 +120,7 @@ settings = # s3: # key: "AWS_KEY" # secret: "AWS_SECRET" - # + # trackchanges: continueOnError: true @@ -158,7 +158,7 @@ settings = # The email address which users will be directed to as the main point of # contact for this installation of ShareLaTeX. adminEmail: process.env["SHARELATEX_ADMIN_EMAIL"] or "placeholder@example.com" - + # If provided, a sessionSecret is used to sign cookies so that they cannot be # spoofed. This is recommended. security: @@ -167,7 +167,7 @@ settings = # These credentials are used for authenticating api requests # between services that may need to go over public channels httpAuthUsers: httpAuthUsers - + # Should javascript assets be served minified or not. useMinifiedJs: true @@ -179,7 +179,7 @@ settings = # If you are running ShareLaTeX over https, set this to true to send the # cookie with a secure flag (recommended). secureCookie: process.env["SHARELATEX_SECURE_COOKIE"]? - + # If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) # then set this to true to allow it to correctly detect the forwarded IP # address and http/https protocol information. @@ -197,9 +197,9 @@ settings = user: httpAuthUser pass: httpAuthPass # overrides v1.url to indicate via Feature Flags that Overleaf V1 - # is not available + # is not available v1: - url: "" + url: "" references:{} notifications:undefined @@ -260,7 +260,7 @@ if process.env["SHARELATEX_HEADER_EXTRAS"]? if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? - + settings.email = fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] replyTo: process.env["SHARELATEX_EMAIL_REPLY_TO"] or "" @@ -291,7 +291,7 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? # i18n -if process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]? +if process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]? settings.i18n.subdomainLang = parse(process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]) @@ -484,7 +484,7 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] ) # SHARELATEX_SAML_CERT cannot be empty - # https://github.com/bergie/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 + # https://github.com/bergie/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 if process.env["SHARELATEX_SAML_CERT"] settings.saml.server.cert = process.env["SHARELATEX_SAML_CERT"] settings.saml.server.privateCert = process.env["SHARELATEX_SAML_PRIVATE_CERT"] @@ -518,7 +518,7 @@ if process.env["SHARELATEX_TEMPLATES_USER_ID"] settings.templates = mountPointUrl: "/templates" user_id: process.env["SHARELATEX_TEMPLATES_USER_ID"] - + settings.templateLinks = parse(process.env["SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS"]) @@ -533,7 +533,7 @@ if process.env["SHARELATEX_PROXY_LEARN"]? if process.env["SHARELATEX_ELASTICSEARCH_URL"]? settings.references.elasticsearch = host: process.env["SHARELATEX_ELASTICSEARCH_URL"] - + # With lots of incoming and outgoing HTTP connections to different services, # sometimes long running, it is a good idea to increase the default number From 4889e528ec6b614a534614b18f261aef9c215c8a Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 10 Sep 2019 17:13:25 +0200 Subject: [PATCH 407/525] Added docker compose override file for debugging (#634) --- server-ce/docker-compose.debug.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 server-ce/docker-compose.debug.yml diff --git a/server-ce/docker-compose.debug.yml b/server-ce/docker-compose.debug.yml new file mode 100644 index 0000000000..9bcc623047 --- /dev/null +++ b/server-ce/docker-compose.debug.yml @@ -0,0 +1,20 @@ +version: '2' +services: + sharelatex: + ports: + - 40000:40000 + - 30150:30150 + - 30120:30120 + - 30050:30050 + - 30420:30420 + - 30030:30030 + - 30160:30160 + - 30360:30360 + - 30130:30130 + - 30100:30100 + + # Server Pro + - 30070:30070 + - 30400:30400 + environment: + DEBUG_NODE: 'true' From 74ff4139ef2fa10a27aa2d82be839fee4bef5042 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 11 Sep 2019 13:08:02 +0200 Subject: [PATCH 408/525] Added ENABLE_CONVERSIONS environment variable (#635) --- server-ce/docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 48a6692e8e..623bdf29ea 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -29,6 +29,9 @@ services: ENABLED_LINKED_FILE_TYPES: 'url,project_file' + # Enables Thumbnail generation using ImageMagick + ENABLE_CONVERSIONS: 'true' + ## Set for SSL via nginx-proxy #VIRTUAL_HOST: 103.112.212.22 From bff8cf75e5463ff1db36b866843e2951dab164c5 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 11 Sep 2019 14:07:26 +0200 Subject: [PATCH 409/525] Added mongo healthcheck to docker-compose (#636) --- server-ce/docker-compose.debug.yml | 2 +- server-ce/docker-compose.yml | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/server-ce/docker-compose.debug.yml b/server-ce/docker-compose.debug.yml index 9bcc623047..f6f5657c19 100644 --- a/server-ce/docker-compose.debug.yml +++ b/server-ce/docker-compose.debug.yml @@ -1,4 +1,4 @@ -version: '2' +version: '2.2' services: sharelatex: ports: diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 623bdf29ea..725c241318 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -1,12 +1,14 @@ -version: '2' +version: '2.2' services: sharelatex: restart: always image: sharelatex/sharelatex container_name: sharelatex depends_on: - - mongo - - redis + mongo: + condition: service_healthy + redis: + condition: service_started privileged: true ports: - 80:80 @@ -93,6 +95,11 @@ services: - 27017 volumes: - ~/mongo_data:/data/db + healthcheck: + test: echo 'db.stats().ok' | mongo localhost:27017/test --quiet + interval: 10s + timeout: 10s + retries: 5 redis: restart: always From 0da28dd924017b0f87ad0870504e112e8270f8ec Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 13 Sep 2019 13:57:37 +0200 Subject: [PATCH 410/525] Added migration script for User.emails (#639) --- .../migrations/9_create_user_emails_array.js | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 server-ce/migrations/9_create_user_emails_array.js diff --git a/server-ce/migrations/9_create_user_emails_array.js b/server-ce/migrations/9_create_user_emails_array.js new file mode 100644 index 0000000000..08e9fb06f6 --- /dev/null +++ b/server-ce/migrations/9_create_user_emails_array.js @@ -0,0 +1,49 @@ +const Settings = require('settings-sharelatex') +const mongojs = require('mongojs') +const db = mongojs(Settings.mongo.url, ['users']) +const async = require('async') + +const handleExit = () => console.log('Got signal. Shutting down.') +process.on('SIGINT', handleExit) +process.on('SIGHUP', handleExit) + +const initUserEmailsAttribute = (user, callback) => { + const update = { + $set: { + emails: [ + { + email: user.email, + createdAt: new Date() + } + ] + } + } + db.users.update({ _id: user._id }, update, callback) +} + +const updateAllUsersEmailsAttribute = (users, callback) => { + console.log(`updating ${user.length} users`) + async.eachSeries(users, initUserEmailsAttribute, callback) +} + +exports.migrate = (client, done) => + db.users.find( + { emails: { $exists: false } }, + { email: 1 }, + (error, users) => { + if (error) { + callback(error) + } else { + updateAllUsersEmailsAttribute(users, done) + } + } + ) + +exports.rollback = (client, done) => { + const update = { + $unset: { + emails: 1 + } + } + db.users.update({ emails: { $exists: true } }, update, done) +} From 436ba9cfb83c0a54070f8bade95310327980699d Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 13 Sep 2019 16:21:59 +0200 Subject: [PATCH 411/525] README beautification (#640) --- server-ce/README.md | 108 +++++++++++++---------------------- server-ce/doc/logo.png | Bin 0 -> 72621 bytes server-ce/doc/screenshot.png | Bin 0 -> 756645 bytes 3 files changed, 40 insertions(+), 68 deletions(-) create mode 100644 server-ce/doc/logo.png create mode 100644 server-ce/doc/screenshot.png diff --git a/server-ce/README.md b/server-ce/README.md index e8068baef4..f6500481b8 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -1,96 +1,68 @@ -Overleaf -======== +

+
+ Overleaf +

+ +

An open-source online real-time collaborative LaTeX editor.

+ +

+ Key Features • + Wiki • + Server Pro • + Contributing • + Mailing List • + Authors • + License +

+ +Overleaf + +## Key Features [Overleaf](https://www.overleaf.com) is an open-source online real-time collaborative LaTeX editor. We run a hosted version at http://www.overleaf.com, but you can also run your own local version, and contribute to the development of Overleaf. *[If you want help installing and maintaining Overleaf at your university or workplace, we offer an officially supported version called Overleaf Server Pro. It also comes with extra security and admin features. Click here to find out more!](https://www.overleaf.com/university/onsite.html)* -Keeping up to date ------------- +## Keeping up to date + Sign up to the [mailing list](https://mailchi.mp/overleaf.com/community-edition-and-server-pro) to get updates on Overleaf Releases and development -Installation ------------- +## Installation We have detailed installation instructions in our wiki: * [Overleaf Quick Start Guide](https://github.com/overleaf/overleaf/wiki/Quick-Start-Guide) - -Upgrading ---------- +## Upgrading If you are upgrading from a previous version of Overleaf, please see the [Release Notes section on the Wiki](https://github.com/overleaf/overleaf/wiki/Home) for all of the versions between your current version and the version you are upgrading to. - -Other repositories ------------------- +## Other repositories This repository does not contain any code. It acts a wrapper and toolkit for managing the many different Overleaf services. These each run as their own Node.js process and have their own Github repository. These are all downloaded and set up when you run `grunt install` -The different services are: +| Service | Description | +| ------- | ----------- | +| **[web](https://github.com/overleaf/web)** | The front facing web server that serves all the HTML pages, CSS and JavaScript to the client. Also contains a lot of logic around creating and editing projects, and account management. | +| **[document-updater](https://github.com/overleaf/document-updater)** | Processes updates that come in from the editor when users modify documents. Ensures that the updates are applied in the right order, and that only one operation is modifying the document at a time. Also caches the documents in redis for very fast but persistent modifications. | +| **[CLSI](https://github.com/overleaf/clsi)** | The Common LaTeX Service Interface (CLSI) which provides an API for compiling LaTeX documents. | +| **[docstore](https://github.com/overleaf/docstore)** | An API for performing CRUD (Create, Read, Update and Delete) operations on text files stored in Overleaf. | +| **[real-time](https://github.com/overleaf/real-time)** | The websocket process clients connect to. | +| **[filestore](https://github.com/overleaf/filestore)** | An API for performing CRUD (Create, Read, Update and Delete) operations on binary files (like images) stored in Overleaf. | +| **[track-changes](https://github.com/overleaf/track-changes)** | An API for compressing and storing the updates applied to a document, and then rendering a diff of the changes between any two time points. | +| **[chat](https://github.com/overleaf/chat)** | The backend API for storing and fetching chat messages. | +| **[tags](https://github.com/overleaf/tags)** | The backend API for managing project tags (folders). | +| **[spelling](https://github.com/overleaf/spelling)** | An API for running server-side spelling checking on Overleaf documents. | -### [web](https://github.com/overleaf/web) - -The front facing web server that serves all the HTML pages, CSS and JavaScript -to the client. Also contains a lot of logic around creating and editing -projects, and account management. - -### [document-updater](https://github.com/overleaf/document-updater) - -Processes updates that come in from the editor when users modify documents. Ensures that -the updates are applied in the right order, and that only one operation is modifying -the document at a time. Also caches the documents in redis for very fast but persistent -modifications. - -### [CLSI](https://github.com/overleaf/clsi) - -The Common LaTeX Service Interface (CLSI) which provides an API for compiling LaTeX -documents. - -### [docstore](https://github.com/overleaf/docstore) - -An API for performing CRUD (Create, Read, Update and Delete) operations on text files -stored in Overleaf. - -### [realtime](https://github.com/overleaf/real-time) - -The websocket process clients connect to - -### [filestore](https://github.com/overleaf/filestore) - -An API for performing CRUD (Create, Read, Update and Delete) operations on binary files -(like images) stored in Overleaf. - -### [track-changes](https://github.com/overleaf/track-changes) - -An API for compressing and storing the updates applied to a document, and then rendering a diff of the changes -between any two time points. - -### [chat](https://github.com/overleaf/chat) - -The backend API for storing and fetching chat messages. - -### [tags](https://github.com/overleaf/tags) - -The backend API for managing project tags (folders). - -### [spelling](https://github.com/overleaf/spelling) - -An API for running server-side spelling checking on Overleaf documents. - -Contributing ------------- +## Contributing Please see the [CONTRIBUTING](https://github.com/overleaf/overleaf/blob/master/CONTRIBUTING.md) file for information on contributing to the development of Overleaf. See [our wiki](https://github.com/overleaf/overleaf/wiki/Developer-Guidelines) for information on setting up a development environment and how to recompile and run Overleaf after modifications. -Authors ---- +## Authors [The Overleaf Team](https://www.overleaf.com/about) -License ----- +## License The code in this repository is released under the GNU AFFERO GENERAL PUBLIC LICENSE, version 3. A copy can be found in the `LICENSE` file. diff --git a/server-ce/doc/logo.png b/server-ce/doc/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..106926b0950802d42414a1d94952e73f703d5c25 GIT binary patch literal 72621 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 z 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 z�c3P${W0i+88p=+^=OWuh*4zY+1^1ND7oMz;*i?qIotLmK-{32Yh2|Il&m8d%3W zI}6QXw;nX5x1#jT~Stq+5J#FGkk3bU zq1=a(s9Pt6I)BuSQ3{s&@BQyQ^9>tno*dDaZq~Q>vQg}{Z{uBL)&6iY zuMTl<>ka18Yx-1ES4V5>wcXw9KsTi+9X)_Dq@;|GpB%e~QITMPXAhK*R6kix)>*($ z7RoaiYJ)%?(BWurV#47YYX!X+vgfg}CD7Mn%Lji(T^Cp>vA(|pVjl%v7EjtAo&#vS z9v6BotWf{nk;h^vt+r~C^_Rrv*tvNYXThD|BybZ2gf4VtfQT!wJ zuDcgxgT?D$l48|qTD!^WnQOy0@>Hh|cK!Meunu}LzCZRARgW|6A{`Ns+Qn$cl zZL5IfX$nmrMCBgh|=wWJ_2ORAUh6Vofrc* zd_+hs92@|Ko)5$X6@vj#ld>RtKP$NX8p?6S9`s^@e;C1;02>>d)i)9Jxkf559wAIi zxPulf{`9y20H+NB9EysbIOxdGJVT1Q0-_I&ep_F@zm>&m9I72Vn`%FX_;T=gjT##C z%`9SkapoWCen)B49J3wbv*ABbWd8usr`7L_F9>-C>j8FwcpVG#dW|2P_ILG&ySM*3 z<;8Z*u+(b)JB}0$?_(pMxw3LHxmo!1q0rG&wIkCStmi%VNWX^noQ&77X)M0Pvr=9x z!16WJ*BO)L(wARn$&-;GVryhzD+N<4O#J@#@`_!9arGnkVN^bKFR z_kO!s8`)8jnaM9(sRf_5|6-X(W6_qdXsmq)`; zU!F86^L4e)(abC**Zr-Sujs$n zm5NeooW}$W)0nHcm#jU_BE%6mlay=2(^ku;*6^~@(##>y0B-9gFhKw|UTPGy@Q|As zflfK?S3luKd;QNKy}yNDMfMPC2SB~dr;}i)FO#iB0pJhU=*KDKq|;i{(8q@>x93RP zevg+WK(@lq&ksgW=!L}`hUW*6LWM-n0t`;m|Bg9@X#WZuZimN6<2SgoiXnd+cS0No zP^7Q_FP9U55v4*q@8g@n`Ds4p{yVs&cE}DOp1#+*CPBg=fA>-1a8~tRqr0T~e@9Z! zD+MEVaLwrENd0~zFH1h)F(5Z)e};X{<{R+b+L}aJ6COkJ$=VJ@yaa;`0ywy2+@3f4s@2+f76HJ^&;RJS9!4hx<1Uz`tYHegnkgwbKFR2{%x0 z`_<3%o&4`NaQ7eIfWR4^8q;D$XPndmuY6j|ztNcf1FD%WXn|Ae8yoTg7O%7P{EGXX zNn3f36;qZ020!!ocTxXxsa6IxqrSZQ>$qz~G6z3PaQ^7V1%KrQrNfck!Y2_XwHL(1 zlEbTQCMbWsqbl0p0r;6ZhW8;Vi>}L}cdWe|jv4Rx4JoOirlwg?@-a5{MEnFABqVw!1!f8Wg`{bBWnCG@ z2Ki|aE+Zr+2Cjy~ojX}H!;gSu0>}kmiG%*-edrp0v#1n&<#NOQnudl3aFM{nEz}ve zK^sU^%Negrakpk*rU~dz(4#g9UmOD<(Ai=*osQ$KLDO47;ZfWb%zmt(Vo)>K+uyg< zD^ozTAf0swteDLxq@Lm=h|x zl9DYL0denxBfGJSr>=>K=l4z~0DJ%*IJ2U{DBMyiddL1T)LYBT%YY08hvr=#+_<+JMs041VuiMxj5nl#3 z3g88Wbc6VHs`7nDfCN7ia>I9WcK*bjYRSg~1sh~GK%!@ma^<$HTQE+r|3%zFKb~%N z*DA%jpPDCYD&kA%<)O8kSuoY>G#*ZJw?TEKGT?{tGJ}3H&B<_IO0?A38RHv@Cd{U0 zcK@`Yp8q3%_Cn#@&ti9vf>3TgzG_fCts?L`$ItK35NplA&C5FiC9k%2q}#|t-6e1p zch9ZlOFerXP*5e%U)u4m-yT&kIeX?zy6UG5<5>IDVDD1@cN*T_viw3T6ZT`Xg9gL0 zVncU6Z<+DG**w}EuRZYpaD&A^&NA;iJZq*hr;y3|?ryZbX~o-5Y=ri-!G55o4n9Q> zJUqJCG=4%6HprIR0DReyhzM}QtB0bNJ8Lx247f!Q!VtPdJ+t1<_^eVJA6FA5&UC<3 z#i10&xM-~~$c9}9j8R7@fYU=8rLGTRJ7a#uIu;hD_w+z@---F@teX!em zaHtQMQZzjLS6n$>LqBI|d*U9`(Vkwvr{}!s8Z||UIyZ*MWI&^0Ry6Ey9KB9)th6Uo z!lC`JXTN(&=d0Jd*VSqNdwfMIw_g3l)-t)8duRKEAgkd6Pd|(7c6YDgh5IlWXJr3o zIW5G-*kohl=&z!H_3{GFX)ckoU+<3FoX77~c&&SZZxHkOmG?V%Nv5mL5(hSqXtslb zf>cUM5BjF9y<3&2b;ed-TAJD z{(eJghf^TsXzF{k4cJjOY@8M7MZmBtdTwe;-*C52=X0e2@Xg}l&h%pj0tlkIJx|nj zbnfGDB-D1W)SyM|b`51~3X`lH)j`)eW0~axz@zZJS<<_9Z2^iu03-vnLs`A5y*PV* zM(m+oPXfj#UNG5&;ncG;mljDh)0+8)FIm%Cf1XJrf< z{$vcBucX8kI`=CBw##I!KySDa0}CjUQSw_$OLk_aQuuiuPiWMFc$|xi%gq|EP{ko* z==S}!Oa@??_?2y(&nL^alFPn7*g3>dmqmin+k2ss^wo`-DR+szscnKwwnX5yNvN?046M3gK;C8F(IqthJ z#_3}<>7feX7UGn_sMo_Lyy(mwD~!)Ji$uFz6o8$9h9UzOQ$aJsXEOi@pKA9HE$;IdX zSlFfYo;}zP>QSZ6XIAg)By!H2*Ys#*Lnw?5UYr~Zw_=d%Vo{mqH4zuDbnS37!HviLk^^bYijX0X@#Dz~;;j|{=*r0O@lR{E@;TaI1 z+3-Q^`2ZvUjtHBU6>Pq)OCV2BbqIFz^VRS|e-zz@5>^!5(6DW}LEw+Wccl1?DRf(; zA3g=p+VeN^y_J}~ulNj<-+g>l!gZeP<17>crQA&RH*JM$>^3(y**rj7x1fN=@`C+M z--|v;y^%{!H)y=u&qsxx6n>&(CMWNDYbfwUevg=dAosoFCtt&~ygXuG(sg<&s!US} zCDs2$*?Y%h-T#08_THQ9Y}tDs_R1Dn6(J)Tp_08WaZ=RLWDJgIWf12lvA`2=sJ)@ zoL}NVw8CJ;n|LZseuNCoEt{CpqgPMr$>a*gdP=p-N6lu4ouyuKWWnkI`hCN;mHDvPE-)vL4j$K)KO*@|<9w&`VAlG^oMxUR4LWK6Jx(ScG| z;NpaPoDFG~OpuM-o3=l@Cm5c^Zeke{Y}R`y6g;rRipn8ZQl-K&#z6+XVV+J7(sTE{ zG{snR=VA05Rn6DU^|QyzL0O?XIWDG&%w9qW)x1K#D72^8Ix6EqPrGWmw_YpMPrdt& z9U2+goyYdNm#8lm6jJqev*i5E1dugo(G~RK`a%OQ%I)qAThAY@)LwX3TV72^yxYLR zG2~*sMB&=7H4R~EZHm;|og-YNALD=0BKSCu$c|m2RM`tuS99|O% zjp+R8F*;TLy0IRb{E16?{Gnw%}sZAQhd8FWH!AYKRyH^Aq-s3V{ITaHT*YO=eMt4 z^)p1fK70^TR1AbfdX}K$*Y)-BR zMOJhcq#VAZHa9g5e|ZBGrT~+s7k5Gdaz9blc_jbXf6!pYn91SQwPsmJAT1UL&3RiJ zf{p+|!lysyOioS?2h4dw$qGY7dAR}vIe>*BF)E%{6nSnr*Sv6YvK2I6>q<-2ac_)4 zBkXeNKCH02WF4TaO$HZKq+~>U4l_yL;46q1CNQDcz;{rKs_QlrRZ&>N5~dPIcbebc z-iDpj&-F>t*c>Oep0Zhp&u|B1JfQ!*^P&38HF+-W8H&Rm#)VK%6bHvkbZ%@L#<{tI zAOkepSz!IY-RS>oxAkj};@ACmuxDs%5lpu4pKu$* zj(-QuE%XD$e`Vu}YN`8>xtF9qs#xFK^IjfN{i$&`dhX@c%arQ;{7f^mOvX=5Y4 zFrQ19j`$KfafMAIj)YmoH9dia@87S1?HomE`7)L0y%+E;>Ck5#A(;Xaf_C@!yJ+#0 z-Ajs#+pa1rFxDP!RDVDb8r!%3z^L4%Y95r)ggp%F8_Mx!I|B@ZpD!nHwISVk)b7 z>z+fz$FFTRfwx>-9{Ju5++OLkn{;%?+?-OIcyjFEN{Soa_2r?hC;if~$97p&-C4$u zNza8@@y*&n&zO5o*F&o2`AMNPdd7a*ZzKMs3Z<`;D|i&y_=EN1gF!Y^##*@`UUg5r z;#Uyg^iW5Hu>Qra6SRc|vIIPY80oKMyw8Ryi%X@kke@(<(S|Yen$3|3qu2+DqxL0{ z5rYKV2Bx2APb62a&7HxxWaxX8$~(#%HNNl_-JPr%0!QI?4SxQuS~oL0yguv2RhaG-lywYYo}o@^EcKX16U!G<-QA}$^i9o;L^{F`ML z65~%!P8_iJisbzdD?z)u``f~34}`y6#+1RuMF!cC5fQMJfRLSdb|c!Q>Bf6PimCYb zR7&K+krR$AB(6L3(#5f=JUIB3cgt5pgqQln-EQ9KJJeFSz=ls>T!lsTeOM<7jZKGF z-RYXG-wR`TC0yb`#YV?tEp`I+;r{m$rP{gn7Z>GZUtHxTi+-;IBFyLUyd*i2wQ&X2 zNDhT3QJKcLW-svaiI$g_4bk=~T#cf8EOhcNlD5%yvQiTutwB{bqKtQ2@e6UZT0n_+ z^{fMop3boBf=M0W&0%1`s#yWev0VyRA^WWFCB7Lk$3$b2|m zfy4;-;JljT*!Gf*cfYRUA~+p>Bb=5 z>7Hxts#Qq4j^JO>SnJCpxD;%96-UN491hL6c7ojE4y&8|3i(Rn?X*szg`J6)P|}un=Y{kI2&~MwU2SHlo6ha6!@m%aL?dYN`6JQB7icT~0qd^KC z?kdP~;={>?y&5hq?pq`K_zP6@9^8+K&S7{|XmFx6fbedY5XeD9(I#*KhpCz}j+2s* zM2a)M%dhv}eqxL2@1B(C0>YNfsWWnj*RP_b!Y)68!7zRUA%q|5fYM0Qz|=*u7biHG zFsj(PySp#G2v%LM&Ar3hCWM!X`E3ZetL5>w=n*5!yzlk%c!<=M*y~f(hwUEoAG;vU zqsPSk#LbKdUvR%J<_=?!tWDqOsG%u<;k@Qg==q z9jF-?7)~&TDrU&GW=JMk_Gg39BI#qo^lnKhbvlmIZ7l*w9!tOu?ry)HN3`eQ$93glt3O0p83k z`Yfh|%3CmWR(c?&IK6%LilK*je@Bv4Yk>bZ%g0>C%R+d?W#wmUPCs<9x;Gy4m$6Z%5=Kh!bChNl{? zzk+@qI&XCU(4lMolC{{6_j*ogYB@eRxU4{FtV9W***#i_3RE#4O zqt(}IM<^Y|A5WuDWOQ^|q^9Z`8VO8t6B}5|P#$;?h&uJ8^$iSIL0KgG5iV`deh5Tc zSX|5@^+wo3x-hJ9v^YiHmML+Hi9O*$;u6upU?dz2odt#Gi6hh{H8^N6lVe>2z9$G# zp%>1*NAsz{#}x`Rkg&mu6wVH9?O#0~t@eCyNd@H1Cl|y#yl{3Vm$<>K^_ zoAq`mGUPa`*&PYBqu;*?w>VP>Wl*D&lTsHis*2~XPy_Ysily1vQ)xaYRLYjz%3N_7 zQA2E+BfX{kkG;KoPC<-Eaib*}uu%)q*S#nfk`OxvhV>8NGbm%c$o#cyCBz^ev!1=Q zRQ%`l8rDqG*_ei0e+TrpK?`IND$=n?Q_vtr7<;^iWF({#!b+rYc(-YK;L%dF=T%;8 z1g?|H^HDg5nNkH+-}ny{xG9b0mv06Y%z_Hmym04+ z?|9CBX+ZFmM=q#@*~`xASoQH7J(=xnkZy~(NaT833NPv7Og(;as;6yiU^I#9O$?o; zpfkn5$7-$=RsPi)!pnYfvd81%4rn#6E|=q^kYL*XqKjKxH$Jg17{0pbeV0)>LbhTo0NH;an6>^brdi1<{w@o%&(-m_FZ*XVDg zx%QEQWWjYO72WSfU-aEc55dhPcV9LZ)Eg{ECK5x}lT2BKM$$en-C4Z><#J-PcKl{l zwDPKp*W?0KAE@s~KF`5B++}a=gyEk9;^KxiUBY%J!%=a|M1}`MX2xXkmKWHxTBR7 zTNX#><`luOEhi_(#+DOwc6#`Ibu|OcE^whj1RwykzdvuK(oV`+)#bVLw=>& z-k%YaTund;D6|Yo2 z+D4VetZnM}%1AsVhxfPm=uKp?shbQ+sHkD`i?b-gH0GmxxFvQ>RDC zR$gFAM%c4D7>4gu7gfF~C?ZX=Ke?H=GPQEx6c8O601S#8QX>9a8U_e~mGj}1>U%CtGKOSvAOJ{z1b%o|x`zzWa zy1rp#4Rm_nYEf7mW+}Rf{zTGyhb@(CYy(oRSp8gKge)q^Z%q$=2nQ}iS)~-aW3ZjU zcBU9vCc{d|ub_-f$59JgXiN@?zxa&Mki0(ZT>|&-v>Z zv}qzmg~^H4bm9j3Q3iDS+<^PxdegMV1tkY9MqW3hasJ$zKLhHtK)>i;jG6N_57P>) z1YgB3kfDLFaoK17(>HZk9#DT6&4vOEwRifvTf;3fPW0*zgi`Za;Lb;(eRCeZ(*QWM zYVbo~#F-)U0A#3JpDrlR;XuJu-0#TpUFr4^TX0%OdOcJ8i465T|I2GOx`Fj}C*)rq z+z1Bhq9G1n%t)#k;*syK=OD<=FIE$agKyv?mvu9&Kz@|VJtmC3mP?h5nS>JF))cck z!R%r~mNtB?>-hlVXYwM1RAzI^73zVrL45byDg=oN0??!r(x!Outb|&WN56|T?+6f* zEhFBl{&h+5Tex*z(b@HJiOX^agmx{mnOAL!^d=SwH`#@Um2z?mUjUz!?w>n{xW3qB z*JdhrGy;Bk-@muO!MieIdEmrX$H z_DoHT=;X7B$9iv1Lz*lL)iW@so0^&mpS{rnKqe$`xS!jD*3YFQ0i+Ue4ARdR_M;n2hSOfW3{%|o7cAhb z?n_Y?(T(e_C@FFF|B;DiovcOiTaZVF+VB+*p$ZZ60!NqqARA?}Gdf*whNsptgM4za zDdSPxFF(s(TDKf3x0A){-I$u_1*fiyVWvV)jpQT+&;iPEJ`NGjA$>mFtnMiw=@-^V zi!Q5rmxHafuC8vo0nLlQ=5V8=eKe{(;I^qV#v*P|ZLt*HPi;)j)CnvB2J1+guSq(t z$A{+&U0|=YSpDKDDi%WK?knJap1J4iOCyWa0MS@fK<_WKlA6aD4mdg$tV@xYRWZT) zq{%Hs`A}SDimw7_6S5iQ1F6&+=@48LAG9f}=5Zu4DswRIs6#l3Q#!eQNAKC^cFd<^ z8=T0kSVW9zCJ{=O@u-_{^tW`%s6bBdFs;Bn{YBaS&)#@OE}9M&)8F>#gIgxh9<0CcAssU@p=OvtanAbMmZcV#dF=%p`F!=~8Q} z=l=ZAwKh5D?y{N57*e&G3*(S|z6xWyol40#i@a2JF}-~NUm9kJIE z?mBf8nu2uPCn08eW0q@J5Y*zLW?Op;VcdW5%NpBDowWyk5hvH?nvfA%;-dji>Fh+Z zL;r3GknODeB~!#(6)V235!EceE>_B9wrmn=&cQT(rStdEY;b634*D*ji@^7XOU%I0 zZya0bRsO)=OlG)W6DQRV-HVItw?VH4rfIBl-eTg!%{c%_=!i^e#L(C@ja5P|kB3JOL2aHHA4_?M1*6&iZI=LV#*-&`;sj2^p9yNlu>`so z@4~}V$=C7(BUcs+ziyAGsKqG*7zFtXl$bN2*n}weVK)D3pnx?R3uY;+vDF>wy1O_sP(j;q~8HaR#p;T_-@D`drmC z{<^5e>FXg^01)xQbH+ok#yvfH*)?w%0{3&xCmDfpBT{{HK~6t_*PbTYN1ZLWwm)6$p(;DkO zAT=y!E<`N9V9iVC0<%CW(L(MM&A?rmHaDChb>(+mdI&CwkNu`{Ve1SlR^fb{w{xH3 zA#Ak}QAL(`mmcA~lXjBclRDBz5Z9DUQE1%wM7cfdSH6dOTV?0{$_Y@RDo4fe4?hf)Jz_$;dx(BO^zS2KYohlOT2m^zuWBec6(of{THn^qymZstMEh~ZRH z-__;3i-U(3S6vg+yp2=uxn7rc+EARfml#3ulmlP7 zR|XyW*bspZ!LZkd&2ZW)nQ#;P>Y5cYv`eYjy=-k;SH)e_&}&CW=8#zlN4XQ^-(C$r zWa%6r^mrAbinsu(PCM$LYg0Z(u7D?#R^xa}^1pjGoyKXpsDm*Uc*Fh<9zpR%1*_5u zTuXL?uK^ZlIHt}Cq<8#YHiNm;&rg;Uze!IhW1>PL6b#9zytTbH6MOso`xq~H#LDO6 zrmd3nPG4muKY1eN@fp#tic;Mazi1$*OL*eIiksQl*$E7=z76(*;>Ml3K6WINBkWkH zTWH=p6GG}gEVQ9);~BDyr1lbb*7Wt4UGVmkla*ccViQ>$+o zygqBPPV>@Qwk%DGzjmueJ?=3P-#!M1<|TZ1>jWfaN%-})B#>A7JSbBhC1M+|dI?1+ zFWoXovM_qg%4xMfRs0Dn_{F3t5x>$Qf1bEhqSdG5WW+oVT!taO7@$AZSgUdv=**=G zjAzv}jS>z_F}YqtM7^}I5PB!38g&Kb(ffF!JqG6yk0HAQC3-$X%A7*`{RGKc@Z~~G zQp?Q^1}*o1KqMF=X`zQeL^6*ptW$p+N}taGKw!&QtXPpotr&V^0hu#Sh56OSqNO(6%=*$8@a80GrfT4L1Lleoem?K$VP zwc=LB6;VdX+jN0$yr98a{_#PHcFt(8Q4;!#rY3njXp)%a?+c5QD>WX)VI;n(4<~_i~w@RP4GgJ9z8>QKqF}F1ZzN}6dm;rt`+=Z626E~l+18D+2Z?>vjHhJ1i%#Y&cX|qU(bBcI> zThU1s_p;JP(NVEobHhXmzf$vRm%sa!D7M2r%L(tDF@N2C8_ZoyO3A3Db6ivr-Xvwf z^$2^S;m@EWp~CFzJ%EzAIuHE_lYzGN_jy?NYJ?(&i%AMeSMd+BZUywH30L)B4lCAg z$5B{bsyyH2OluBPi_8$?z5D3m@Ubbzby zI-w!QtzQ!)wB~-(6T;q}qG9wA`8C&(wNZq9=NZO4l)olT=xxt&r+KJqQ3>N7T6I}cVA1D51Y8Z;{HHjUM9B?B(EXUTv`0yXHlg28AcToam*E(vE>`c z?J!LPaC!laq_QT~01Q!1J(xYYvy!;X1P!d_{m`)I?v5uYe5rc3D@c+?_VSQW|9Fv? zjC>XDcpnpLmMcx-L__afhjUjC++7O5>{?$lO%iAuPYHV(Z=_Rdwxv zw+`+~$vg&mqi@F+q)q#cN!X@`8lc6dv_1Cd(8R&kX-3?+^Boo*T}L6e#Zh*7CPag? zTT`zwGvE?lm(->yu3!>yj3&x|ak{F?_~ziX(OY~p0p*x+TC|LX^9I`RNni3ZO55pJX$CK+3m-cSWp_L zXiclNwdu^#Tg!p8zUvAK#3LXXM57cQ1Appvb?8LT7NI2;J+M+~16_Z*B|vT|F`15?gjqiN zc%`G*%g$~gnNv40)~oLJG&{{yvSI&3~06>vsPA%T6BZ-M*#-x4= zm;AeXdKT~Yr|{a7VOkC2@GTT6qe(b*T-g0M(BE%t8MVubiSq+8d5ExaeB~Y&0A=(tB81!7(X0 z_;lht4GIk8w6wBL1+r36wM%(bEGQj6+9$vjV1ydwvRB#MT z&~C6FX;YlAOlWMW@FQ8h!>|cytegF)M?7enU)u1OGy;v*2E)4_*eIjLrRud<|7P2I z<4&=mp=9?2Tg4=5eWde?zCDiYjK!@_U7nke#X=0l^j?o|M%TG+cKg>C`;SfNFP3Ot zO*7{I#6kOG&J2>iZ^rxc{jYV<(|pnss}^&KBSD850uSNW(g_6vcbew69t)E5Cg%(H zjDtB^Yl8<^{5CpG)u&Sdv?{WD%>I}*xZMBG~pz)w<3YdY|?oE2e#O1 z`g;b&#UNq6sQKj z|4}zjM(Pwh{d-W?b~SOLVcTZz;TbHifdeq2bZq_yt^&iyprD}4D(>Pk;zA!e3SH90 ziLo(2GmUhN9#WC6=dn^r0k{@c+)UCQtcr?r8@%Uu8%QiQR!~rIo}=l9z+QP^V!>Gi zI7y(S=SNIIH0#vV6sV4{c#ew{Fj%FZ`}4D zBb*Nl4Mkpcbo>fF@d#1&B5Bj$q~$0sV&;W0evN^QVkV}Mkrcz^eu?`WNoLoJQ*Cj@ zSrocsx$;tRjA*D8AW`(wC+n3T3tfc#EZM0(-S>1K6B)+`uR#kVXc^faV@MGYxrXh5 zH&|j$22)3rEEY!x35d$BWRm2mMf7tdOj$0ISDEZa-pJ+r8%9sbxzECJi9fq>8!~9o5;>!F30A6Q> zQhGMfe58;jv=f2+Q>@*s6to8(eMmXBFbg;QUgbxip{rR;6SmUC#>+RNO)m}c=)8Ev zol@6OlbDD|?U6_B^oT7%)tg-Av2NZ}39ER?`H!tEP68lz;^;w1M*A;3^h!S}Zh_{H(U?1+u5i>Uq(+I`0S3|>BOE&i5Wll`B}Uwip`%DwQ;wVSf^ ztsb@6XFG8fE}2XudjRtIzDoTD78gR3EKg5JL3HCjF^*>cM^Wl^VpLtx7gd9b&Ib21 zbRkj#YlE>ZoIkN|Mxhlq00Bh5hebx9lymPZ#*qS!R@FIc!Pw2F9XWwzn(B&f@=Z}F zSpie4@cw$M%11^F-2Iy62t0vfl(P z;tc%LpZvQzk&T2CE5D#1hC2iJO3n)}3ZKGiGXRvsaHz*|zlR7@@V5VK$7KQF0w?6H zT)K1{{!rU}uIQzqiOJ&D);!=^;e>Rbs$>%u_5fi7Srv%YKh`~Csz%j10%XYk>UtSlHVf3OewwVbY{&TQ!rl?ap$Jn@GFRl|fE=H-^06ZuB$Rh!e*xVOezA0&Ih zjRMm1yl+f!r8zC$bE>uLiUm;a>bFkxj8K|cqqO$BK4|Ij1-Cv!I55wPU@Fpbh6^kc z-4<|da}566{0R8nsB_B!+;Rg3r)))mIYxm_6v;*o)sKHF1f4QYtix(FZ1q7uz$Ufw zG^bazO;#*!TV{qP?}f8F;~83&7@2Edv4mQmtWvr^QG-9MnBzoZa=XSqM+1pGKqavPEDF3z;C+Fz|EJ?*cV z;2xz zi1P|#n!NpXh49C!-J1(F><%TodZF}%*iK{W-(Gtqjp(dc7G4*(dh-1FqnC3d7y_e$ z-u7X>4#J{~>4dGyM=TOwALByFs|ZC+m);jR&!OVWQMW+{>(zpe}{1TYOF?+@r#TUd{S_s@1C?BAY{lg`fM}5R!uTQ^Sv^ zb14RMXmQpg=j+4%j}MrS52z?$=jOI|O3tY`WG0ot?T&Wqr>aQ$&h>Q`ZgzY7W~9X+ zcs)ULW~ezvwR7v{oidov-TGqvB;L`mzhlo@*7Mt3G)P=wpdPga1c+=M154W9;VQuiImB{UHL-tW_+w*Z(9uI~_%j=|^b#qBFDZ@~*HeyR z+*!P5noMqe3cSz9rype&CSQ$K|}u0+tU+bqMqfxR_@#(#xMapwOIl80TFZd6@+9p^!lhHZxt1c z*y{Yp7V#ID5a@W~D_Wvsf@w2UmKJ_TWV=SOsggZ!doSHnPc94Et|O-7;T@F>+X7I- z#!=b|ofBbo`Q=E76*SRAoW)+g)ti>smrKQ8rkdH&DXi#jHLA9im=twh6N-Pd(u=d% zFYmY4`{6@HfDldL0MuE}KR`(eB81kz@&GY}v8w39Nrw z^s@8{ISPNikcqF@pro1H!c#AWPYdM7=2s>eiDTTtRMDC*v3R}5v2;v$d;F3@2qP6E z1JwHA9b*qOILye%Xt=+nhaIP!z07PdQL^!wzE8AMJp7tvQD;s*!XWW_10gPeK z~ zBP1YDpgB}?GjcWU7@ZMv4}veGte#_`zg0s)1$vX~^&ZM{Z_tR8U!LNyK2B?V{!g!y zRaEfLxY+)+X3ZgLnja@(9o{m39@`t44=VBh)6>a>2~Vw1&tn$zH=*Zo7q62g>EyY% zx&h~#%?Hp#`kToL`B|Ni+8a{m91o^!cBq;33d6a8xw^6#XNf7ux?oB7MQuC^~4fwJC?%;4`S zg)GjW8mWO5bUvWb+?u>_6?ymCwQJtqdvM}IN@QM_FYEJH!RR)cbwJjGg9=7z0xmit>q{jd-@G{hCn5aF+0qk(*todbsR@(6 z>`h~!V}#Sk)#y3c=}urM?;j8V%+!iWHtrx5`kk)#sg1{(hj(OWr<&`*HOL|Gymya9#%t-} zOemm-yC{n9H|}jF0Zit?lroyu+aAMY zjx6hAV3$Kmst#h+bnj!za^T!LPQS#@ z-|@7hE3?f4)Z1F`5H5WcctxMpmO{u1-0QB2BkUnP0VuSh~uf8ZIUZ$9>#rO>$}42o?GQcCv_}7=m{?I7)ZZ z7*wub#6DK(E3xaEO;$wP%^^xAl8v#b9rTrP;o5BTW-l``G09_k7K|l23oeZaRkTtK z0^}nkhrXJm8avJo&Ko;AFdY2H<9M8b)lZN{LG^dG)_({SU)$g0MTutcPCr|M8 z*{}S|&yR$2A=qqqA-wS&h`3u17tVPlEhkjiZT`RIi;qq zTl6{Aj~|oDl9t>4qoOJR1P3AZ|o6*n;Rl6U`mlR2E)ov_YDKB z?LZ9*7EK>-@0#rF>u{ocd!JDa!8P#6gIR0|;+3<5PG#(KG2ep<{h~I+3O?u2($nkW z{ezg%RIW!P_GIRw2a8nq=|V)D+!? z3vxbdW4*n-kVAmibL-qIECrBIbMr~?i$j<6xeWR#TMn=_6@r(A&cLt&Qa50w5<{_k zonYnb<|c7!q29AM&ZAtWl}IE)C{4dc4VNy82Xan%p+k(yG3)_jw>%gN81B6b$1mo+ z9G-wKjAc>M27e0lXl^AKN{dc3R^ zEZ8u~xZMcb=yMV(h~wL(Js^7tgljo_uvmq80yzbeV+mk(&l#z}8;VrYQ6`sWqV8eU z5OqM2^+xvRegt3X;`yM|ehSxyM?}OELbZ#rq%F7ne zJwkB3V%Vc68msIEOB3o=ue7M+xLLy|a4H7`1e9c;#5`#-NI3iNnXDKkhTVxYF^m9> zE7=k1b4)fq zS~?mZKTX?AWVuj*;K*}PQBg2hpS?I((?7Q$1sv^>PsqXES9TM2>x6n+uC1V^&jfDZ z>Yj&W!yfF@yaC_k56q*frUzo8TQFzi?sRQt#ri*}E9yr9Kb^PabHfrR5>9Tt8gG?&i(GSPA6K z_$S%fN+7!4-uCFvdiE?XGHl3eF%(vDL`5)KR2lb}%EbU*7O+zMeq>Z!KRa5lfTucQ zHdr2u{@ET>y)Yzfy8DfU^NVl#LWzVCV=dEp^7nZwYow<`Oh6Dy225xFqSK9)m8V%* z@v6mAw}!Hy3Q)P^SJv3r7#BylX<&He3ij*#r&^QqpIy8e7dTv$D{r#;-WX zo(%5+D!M~GHuf`FHdyFa92a&!^!JCB=31c3a%3i7ex#G5WH?~V*MaxHR<3aA{W}@% z51-^eNCP4@>8c3WA6Qt>>mkgaA%8h^8dB)(8uPg|#0gPd3bEx8q6Z|HPI@XAzYWPlFSA$!kr`GRj6+F?;)>JuVcI?LQ@0rA7 zyuy3%!M60GPMtj#{Yh@&)m-63wAvgBDoKXl&tk z_2zljDI{)2Cc}eT3I4q3YPpXRS*VL#*po{y)8jeJJKu1)XDq0JXvmPTxxiP@GZI(B zHh8rD@?)+zy8zFEei(@@`&&Y`XP*QvUc8u;F;SU>J`Is@;EfDXtzo)!`9!Vo)hm7L zG4BxYR}SYW57%%Vbu@!Vs~g8)X|?~^X? zl^JeFOr%%GR4-*!X=~r2(ku~9@8!BDZx0qQ$~5#9uX8f}=f~@rN7YeLQ7aGgWrisF zKbLCq1;6Nz4u{O(5AZtNoEpx(9Jj!el(rN>R+<#5IL;8D=2#V(MNd~;?(PuV&dtOw zmLJ28Lc)vFnW$BQczay(5HARO?-88OF&ek%F#qdm3^{v(uxK|9UBG1xl!2CfPAKzQRZq5vx2#a(Wo)BXAu+9FCITo>Nwp*K+^6 zcPg32Qi*^{kae4>f%_Gnf0eTMhIb*R5w+O%* zTe>jlW+KMnp33Nc@UOhzJ?S7rC0jX}XVNn@I1=C(S@nU^&4 zHq;Q&j1cd>00nHynd7|U6r5Z#Aed#ZZ9U%A&B?Fw&IyiXk-tw?tIE75^>i5u)RiYZ zcmdP_&>#~9kkS%*KY2I=4~4B%G5TOq)TLlLG~yhAXef(FNw**o#w9#UIJ8o%VHu{8 zU4ruqt9@WfF0*N*5vj=*8+$XRy@%pNys0fT|Km=^CRV%Pl$R;}`j7YI3fXUSP$Xoy zoD*_k`g~OT@?&&A+7|aFmwpfsbdQA9 za(=T>C?pDAX&_ow(T?UZGD67Ia7+Y~2prGn0+?dZDTU;3&4sGR?5;UD~!Jt#i=H~s3LqeiCd^eFq8m3o-* z+bMm7t{Dd8vSpHP1^gf0fLsr3=|BjIH(M9F*2H7LqM8|1Ln*|>eg;EiXlKHx3@DZ8CO8leeNmH>=_C%jdU9g8xVWRGbW3@mdrei!@IGNz zC#8uiJ5t5wI;S#4K|Q>Ea3E=AA#08>;2GHse*I!>N9`N>pBN9aUxRCx2aKYL2nbYG zVU7eZWn}Hi+=e(ItcG*AM4=f4O$jbU%gRgXi;?6#Gzd^yB`RpN*t57oiXpPJ?9E{{~{SSS+br>E&< zc9?v~8~r<^p|OBRBvEMV+o!T{YQ&}YJRc{J=6RQZ5oqhncxR>tpF0h5N{Wj3f18{9 zR?#-)hT8U=z*)pM5LvL zP(3b>>TMkz74f$ETpuG(5&viFUj(@>{mm*k>D}Op57m7pAGn=|c_oSR*RqM$U$0HY zV+)Y*CO~KDVD^R*t$xL0l~)d{H=qN7-XEDnwm&{Hhmg#_y?|=Vr&EXLhp=x+Ae@D2 z#zWBvY0z0gWlj5CujmGlm7v3cUtnXB z5trmSbulJ?5~H-Y|9`E^LQv=XvY*95zlj;jI|u$nc=JZn)2lGYz2**d8w6#&oq{4i zzbm{L;xPt~eVOEZ->1B$&zvpf{^n7ftw=MvvS4`0*E09bn~CXZi`()Sm|;nE=&_?k zZ@k)W&7rKiB4gKy_e8?bXqF*Y zVEJN2lB(1mqwW!ZR9dGoQ6LX`0Jm(nbj_!i_Bb4BZ|GQ=oDgD$!M+<(u2v3sqLR*j zetxE=R9%auO82*sD3d#S45~|>&pMOS!$z{v$1$>nrSF*U?(XuOo)2%xrKF_ZUKn)` z7gbEWe8g$|=Rxba-LWcSczz~d7I|l-GNEaz=R2w#*x9>=P8FqP-2_d2ZHwN^(o*|4 zk@KkJ|2mdGZ@<7yO5%Aw)Q@wmS9^het{2kg*|$(=m{e5_J5Ql7#2<`E6GVh?Mz=b}dQT^vjLi>)4~ zZKUlWzjEToL-!*Oha9|xJpjwmi#hfRI9PiFE&us*rdSwgoF@E4W-f;|8E>0BT%Qo&aBy@4uLwGYnqvVb;Hz#lscah3 zLELHj47bFru@KqZPEhCE`u@#r*@NE(OG@Xtlz4C&r9zf0(Ng0o7)j?zBrb&|Dmwx=ec;n%cTt8FZbpV9`p#%><+A?aV|9ESXfblpriME ztr9+=_XorER3CE6rJIUEWGgB9LR5Qj|EUoI<4|CjM#a46wue&64ejamYUK3>ngelw>T)oU5D9|i}RpmL}yykb>-cbzJRGU)J2 z6sh7NQau~3z*u0ysC~r0*#aL$Im1Wrtc&$l+`pb>MUM4l%APU-U6Nm^E zVjfiyKO>akP%ujb$T^)<;#SUQ)mNNvyM-uHU@PMhP|pues08Jf-HJ;O`pBoQEeg-? z@SF9Q4>7_nSyXin4c&pkA$Xflc6wN#6(&^$6(eyPw`+&>;ag81A3a^&htM#AlOsvl z5e99beA>fPWLSsUgY;xy-zv1k{ZBeqD6R+o;?!^dfE(CqXJ@y~BvWy{HNhl4?o~y_ ze4RT>AUTR2hnOKee`@OLQjZ0@(hm4QU@ogl58-K)C3M#y05D8z50Rw^VH;W+j!H^O zdr{EEKq!PNzp1kPqemk7AjaV-fJlz&TOSglqub8WjCqfrD+c(%-_1uD8XD^95et}J z#9^?@3L$aqqM@dK#311U#r(>gDZ#KvH+nB48Cmdq7)*KIy=(Q_4*S=34gttR!ry~H zWPzJGQ|NjNqve-98tS&?jn!4&+j0HiV}@ayDpfpM`Hcsbt#$UsQ`<1j>WyjWu;XEJ zP=GP5vtC0ul%kIVrM;H4v>>04q??kC@j0>jC95|?GPYQIx3c2iiz^}+WH}Viw{m>Q zbO3yyHaoQeqZW7 zH?Da*+Y;DA_ovb%s-<#wtZTy^z2pDst;+ae_B$%e9Bj*uLe{GPv$zXBP9M*9i=`n! z|8Y!leY{yhZXSmZy5vBx>H?4)UaWTdS2z%?OD!a9fchMjzjf8~KCDPpul2QVKpnxJF-3m%~gVG3s zgh(kVp@b;iQqrB$aPIZKd++bt`+WNx2md(6`#Kiuna`Z}yzlG!UBt>lgUbMnAL{3n z76C{>rz9VjV7$@GL}fG$n_;thJy}I_BMcF_#|L?2GBy~$SQX8$_SHU2F6`X>HYI+y z*ru3fH5*SBWnXkOm`SkuoVkwbbUmQRzA0O#0^aYdrk+ z34Ho1d{;xGf_TC#^>PxgK=yC=xDj#q>>M;EWN*-Rx#T(Z8rnz}J{L^fi}#JWvHn29 zg*$)%Q@`9whlY_@0l1xWBW<^zZKFl*>onAd&sX9poxO%CdcCn{24jcX7{!b32I73=m`JkymwXtfAD#t zG69XKMxWp(p3c zy{>o;ThEu)Ly?gs={DrOB*$G7k5-&MK+7f!Yvjt6E0U+{x1npA#`$)`3K}*hMn+>W zZy+Os+b@r2`;U`+K9G5`&dkrFYYXRfT3XW*^bR;z;`6nGp>fjV&{Txj?i*|?oglH6 z^!aFAipqr*X02dMpm&$5{aQJl@!&lm*MejKP++S3NzwvoEE_wxxNr*^aHkqi^@QQ3 z4Fy-1JZ$CFWczU6W8>m_!*5GWD(N(bjzhZ4QGB!hIbRm1kAwD|@fTvOtk}V<*B;4S z_e3!(yB!xJ(t*7BN8g~5Cw)(?D;^dGm7@bFx`!77{I zPifdCg0)n$brqF)T9SX}1ow5K!mSOUUP%}_KcI;PW7#i~tfczSTwLm*ziwTQPR4GY zg6T_~x`3bG*)phj;}K9T!3w5@xGV6u6{xGwafzn74H?*kk8U=NIncahtkVCba_imB z!gRH&b_5<7JNr=eTDWa2z&Vle$~|0VOgi&$DKl^I%2&9R^o710oNsCpkh_6e`?8h( z-4UNmN-~eSibzm4W6YJ zYl`Oo8cpA4+LU0Us$P7*j&)z~?DXq$3t#S|LA)%M-Gk^2kaI-CegTt~sIV|Ez>om{ zUQSlF?L@;mzxoXT?&RQJhlYxZJWN`Fu(bLKdKcFI`lhr3!4DFadNbr#XnPy&#r#wqjvB48F9!!0E>? zAkdkJPe3rtqbfs{V*I}3nmbDybQ`hzdy}*1KKHU@`n=czUxDAzcDC80LFBZA7rQw* zA_9;21+lHt!uRh`06v-{RZ>y{slxoc)s1ZH-*a=sBqV*V+12%j6?l9Di{FLYCnm(8 ztcZoa1e~p}&b7~>ox3SGKl5 zp!6zB=;Zj=0=qwo>h0QdvoLQp>v{>lGhs{P?`OlaU1Syywwaz{3^uQvZj&rr@d+GIL3e!&2TbGT4zL6-5ui;ph(`|;ws zzdG)8LjkRsip}E|rv5DUmPo5yca&ZlRQ;E7=D*joS3Z{E zN#p&Gqc0$`@UabNagjiVu>F%K>?QAQ_Xtpciwf&k$sZVzt7~hv?qeV*JfibyuRK z3=Rz?y2WKtp5fU8G6}+Wyv*?dpwHtdk}2xC3i5?%pFIt@u#tE34*%l;-BKDXF=-tx z5hJ25rlszur9pMa{<8w;1w`;6zZTYAMiIy5 zqkm&@0{6+Gclkh!fSmv(L`M8y(hLuOpsk%;oNjqiK^{&ALx9=N4_-VbT~pHr|I3S= z-{0y!ee(430&v$Fw5992QCrVYI^Yr@>QV?}Y?!Tw6IkKpg0kSvcPMR6Odf)u26~pp z!xa_qTKfB60whXIRFu&bM#gXlgR!G=1%B`6P?4^pqQ#SA-`RzO_W&cVPS0*H$luo z2F2PKSRY_k2gUn)g;W~UByQ7d#Kdv2u{-_ppaFx21dVGc(0;*t!DU{T<4S^S*rXy2 zUvCyI>UbYRfZJ7RppX^S$r7N{{{>VVkN~vMe>=6h5?;#uGe^Kxu3GUhK45c(DCRHQEpirDnfzM{BDeoBUx&N5;Q$L#RJcfpDTeOoaR<%y z{>?bF;3&fXtv~wj`6^l6+VB~H+Y0LV@88vdMlvUX3TWkje1Zf$z3-zRmx{0Zb$B1^ zg!2Wj6UCSs)^hSX1{ExoAFMS=c<>5{nRMUSDJta#vU+Eo8@@>m0gLAT?v=CSC3f5& z=y$@yO=V^2W1Q#OCg1gio~U&9Edxv+S~? z&ngu;xk}6`Zx|;iqudH9z~h^}YOAVwlhsu|RC}qPf+sRVR08!KF8LcN-$jPX{nQ5nkMr~4@w)ymS z(c8_rpN9!I2%PC3L$|l|@`O@?D5=v|JLiT|x%Pi_el3XpX^r@++3|rE5a)kKHcUVh zsn}rEzfe%uURG>5sT||tJ}{$8p-u(WBfJ8}2_ozq9Px2+pm?ly-!kJ`jaJsx)%}-< zG7`VV1q0S#w-b4`-!$V@fPem zKh@l~?2gsvlM{P(_Tu-n41MO6Uv8SsPYo1=Ne6|Bx%*Yv4uB%?y_gdtE2v&h4tCiv zO9`QH;^yXt!YT<GhS% zZ_XDP4V@Z2@$rH#*sR>8&aUCQeDqI7kDlr4ze!S2va+&*7Y%??ATdVn?V2u+f&+SQ zk7SB-X#VVyqB;2(7vy+sXY6M&R^lz9T2B)sC#~;lZ{Z{&>tw5-QR2pNQ1q6YVI|vH zH9R}($X!%oPbE8Ue{)vV*-K9D_pizV)w5H|4pr6p>ug6fVV*G;^?;-Dq_H3WY@BYioe5!k!l`&c)pb|~olpB>G_=P9}sX7h>JaW`{|I7G3Pp4kNz<*I;v+r?US65ba4;4LSW&6OdTH? z0`#vj=--HmC#p_PJ5agzM-iZaX^>idCLEaE%XZ|2u;B3V--x=hj~j>Eacr=5DZ;Af zyjRP6V+5{m+Os4q<$DQMq z+jlOV^F22Wx0kj1-j^{g`FRU+sO|N8{3gm;$de1&4&kTKF-l50GXY4Rwszgr-lNw! z;)j_jDYsp{+K88Mk1-rlS^3xLtgH9u5YG8+KOd>9tNS(_iz5%-J*9kaQS^=}M9?}3 zeLV^`S|&mbGQBIGdCNWcU6p`$^BswtqMKwTfIGP9fH^g{u%-XJpp;c4aho^y_zV4h z=OfSjqZgV}#{LPKIE4mAo&x{xr~38*GI$2|--4&;M^YD17Bx3FgO=mr!-sYs?gpUf zK4I}*{7%I+93&HW%U&`TL@EQfC~d`(-Q2P7f4;Uq{Gf8Tu57L*mzCNHgt~MRUhoX> z!2^fRkx~Suh3)f9!I({u$ANC$lpM)H1lyd(YhfqYGob1j%;5}dGCQ(&b8*4L$FE|( zgkj1EbTlCW@Ab`Q2FB@M3;}{TG1vDEvM`Q3g9-E-8j;A1>U;f>ilTd{D9$6Rpa15A;MidF@mJo$sU zZAf8md_sr@A#|JjpI>=gwl>*mJCrN>+1afE$G2lJz~2;h&Xi5LLl6tPS z?bHFR+$CB!w1Ax;?7kw{xuR3NRjK(Md=w%n2bc(OEz%G+sXpaS6~PD{xjvK|E+lAr zdGH~w1ozeUo=|boV@Q~>|Boy(+Q6nJsSB6ix?)L%Wo7=m^P#Xl#mDUNDQ~N(shyvl z(Ho^E3n}xx(iC@FH++1@3Qit*UN;4K`Tf-)+y@kr(0wpISl5NXRS-n``8E2GH$ubs zH%Ttzg~(k!JuPu-Zca`;aYATYu@Yx?(C?zbr+~PLetKOITK%jWR(Ip**;!avgoF%| zR91&lm}g;re)DbX1f2boj4|NQ6jwo|$$_(|jT9QG=Jqm?f&e!33^LZ~B zio{Ufa8k&Pd@>L{8@D@$t9X~?G>j(esYCvijG4_p3*%i|AqX&9dOiT3-ux>Rj$et*Fu ztW8CPw`wCO#cRWyf2k!NChe*fR2b!m-OP4U+TubBJ5+JNb5}q*lCWs1tEmmZLhg0| zAr>;Lr=_Lk{SGDq2+g8^_J@WDx#|p2?AB2iqQxT~p@zE+E+#{3o|5;kH`l`D)GXGA zOPVD7HJ8ZGFHWr-9OUU5eNrvaH|B`4IL`vPmx*Tlj|{MHVaGnIYFe&bZuI_%f2>u{ zl+{3kYSvJ6X>sUkNQ9XWgj()P^VMe>h~N zAvph3J{nPAJGQ0oT90KqJch8f^vAK-<3RWo*psZTIkqe@mKZBxUBe5nJea@ zuX{LC^XL@qw>+lv-Cmxki`V#?UVhdNM+$~k{7dIUOidK#HS#N$Mw$TkcIe8V7 z7aS~0tZF7W&9y|4#5TstdQRkvDWNo_*__3r9Z)3X@JRpeP)zl*Y3n$b7RAu#Hf4Qw{;xG^N)!VOE}<6+Np z>+-gT1umv8S179h7@Ec+r13wg6BQNx5HJD!i;k_iIX;`-EM$CVK>?@}Rbj0L zn;KvyF;XGz6b2aJ#LvpjWl}Y&u)@*&pCkt&D3LN?j>|x{#CVw|@Ytq%!ZKbCk;l*q zEMypluxPRf=;-Rg{PXwXq9AA=MBaV=JU%cm0D(QAKqA{0C2J80 zLw`sVEBkZJH@sU2v=EDFLJoBExwhBxuqeoIE4{s+$Hfto zt^&NoTXxa>Vwb`Sh^bc#%M9pNfVeT|;#Ku2 zAkzEXSP9lAYJO%p*$z=r5s5&$#UScA`J?u>HgQOqp(RG8;Jz1Pk_;jgalbQ4GMOgX z!@&0Ysb^=4=f|Y?iLB&GvZo@bZcAPqJ*Xs54K{-E10X}ulrD6XC6$$9>6y}4ib8<| zAVmDLy=@3nxs%%>=#@ov>}$)Q*Q#B$pz08T#`*yfE2i~68tN{@0;iPZ=AR{{bw0U- zQQ~=U`nU`63d|)=aDEb9GUF*h3TMO33ncodoy6@ zy=MTEgOB~x0nLb@FBnpIl!1sw*k6n*L@J+JVth?UM@EYeA8}!LMw(l_atyobk|&3F zp8ZkRjH(>=4o?l!>&uadEHoO_)ivtF(_iwM4MGSa{c2J?yRI@kBv|P4?Oy{7h%a$> z0%U#Ven*<$PJE^SM_273E5+r*$7|OtNw&h3Kb%XO`pT_zcO^F&^fCI%>}<`w#DHWP zc(vgei+S}L;OSwiT^z;fBU;qd=~`D7WI`H!3W`3D70{_Hkd=k0acGGWT%~edaWg*I zTO6rOA9jxo+rk$4q`dYw3qZaBplJ^M%^aH2cc0c4<*>-WjYWd3HVwEP8bV~tZbe}&+)L2WF_|g1hU+iZ@~Vq zjfnw;zZ`Wbf*(Ei9!41RQR-FkcLSmK2SBsM!%U5hML~QIPK;Sxu30f*VR;1w*e(|r z7W%pXD~|P}sH_Y~z-_aTH=#mmpCbv^;b6k+b3~{BBM(Xe(WekUKWjhO1F|xFMDtAf zJb7cRyuD9>Lr25t3__Nl)8ZZO>!Y_Keje%Q>kB;kK{LjHPDhS{dCTC_w zn+(s)%)r!SAR3pTp}s!rE0}!PJ|gT6R|c?HnBnZ6#z{_=ljPE86ad>NQZ0;6X-z;# zSo85??nu{6-My=#F7ECH2i}IxFpRz-4>(WePXvgH?JSu4z#j@ z*-ud0Q8y;cgaJE)v(-O46Gyu<{5JDi0GGl70s{1+1oTwT&?Kauy_K_qjL#H85&d$4gd$~_y z>fwZ49j!Dans4P44*CvBKG_(MChTPM&PjU{N=b&-K{H5KAjC~WVPSI>J0dFT)fiwA zdM8^RpnZMb^G@5Ue_)_5jYu=Nmwc$86nmj>t@r$%si_Kmg!&lb$qV+@Yvn46ikN)# zQkGgff-VMBud(&DW8qU5ynQQsy)tp3J%5fpX{9nliW{VUV}fLa+S} z>bW@efEfYG=^r7U=5SYEv?m)xTISOpGxxg&SFVO9z5e36unT2ixwbwk-QQO+( zbP=dW3SVeL&p5jO>T(7>g#?7&oI3#@gb*)`{(6;bHXjbWc>HI8@v6V*$z6R{u1z7j zJShr}FW*|rWU=JK@_ifRARpTZx<~>7uE~C$(zmdWq9}uKae97Q<#Oj+_xOM8<}g!` zFVLb(c=1ek)2fdFx*B_u&(FF7eq0%}%M;P^K^b)7Jx?v(d1nYwAVPQZ7i?>B`iCi*?jTC28dl6j(lCr9dDzi%Q$ zDlt%mI2Z%y4j|dogW!h%yh;Z@Sa|oUfT*cAucmR{J z9c2Zl8~0wZWA~7dknD_1jWS4cE30{+58hwsprBxGFMw{!4_ah&#DM_|8&V&E&J zSy>6lA-C*0pG?&oseQ!z3gB75R^}~G}M-q(L7H?^3j`xL<=cOp5k*~Edm%6M`MzQYZe1~2P zYt*pn&a=?hl{(=b^KC2O4NBa?$Bq+u_?^;FCERQ8DXnooGgFokn@V&J8Ev(JHv<`M zU|K-dw^i1}u4_Oc@*}F6ubI9ga|>VyG4_4rE`@^%JgS(2{s)V$-(46}V}F1n?M0Dt z%NC!yObJ_Bzl+Z8K|5ZGr$O^M&uu0FO$0sxElJ!r=u$gJjJTv-zv}RvlnEwPLIHTC z&+cU+bH=-2SRlG<)_ArWeEs42m~PJL#6w#Y$(q_DXimktte&{i%xPNe#4-uHKt5lx z+sLhOk0yi&Nyk}QqJZ=7uLN$`&390ZmFUv&ZQ$D3@iCg->Z0YDr)N83p^3AhSHUqRsm){KH?_UmS-`@{@iD>BOa`O=F_nj zTW&qz-Nv!$qejRGBO?W531nBgRX^aL4lLb_;o%z~nZQtJ>VDjez5n^Jzk=PX+{6hx zt6_Ra$(VCLEGAVK@tp9s*^HPyg}K29y%_#7Sj}B5u|?kKnPvC9!VbFATn9P_tw&ma z&^(ex#D{jhJ*&>R5v##5KB6Z{AqjHfzAILG&epDx^*MJ?$Yc(`e(J1AKgYC5y&epk zNcUJ4p5642w%g@RUJ09CD%MZuAJsZO#BUtF@y}1T3Xr_U9*#_0? z$^PNqpHbT??Iwm)aVKi7*qMxTr`Y99E0bSI|219v_AN6z`<2w}W|(n>hlLS6gX~mF zD<~?P024cUPWdhmO&%n3VEb+cD!ldiL7D$K6p;+@ML{oG_81PuTymlpvh8iRBGwlc zFan$F1F;CJYifeMWGlWW3gNPMOv1FJ65D08)`_X4hu?TgDNU1XmIHiLtn%!-A+H`+aRW4E;87$v$NzW$LSbl8v zPUE?mWF;AD&o!mDSy_n1c6%}}&Zo}H@{L$n=~#06qX40m?%zOtIGS`PS?$KfaTJiAmF{Ne5}n zPf>b2AJJZniC&uz=10a~`MNrisC5lwM>zfC#Xg=lkMk?AKy1SotkhyuaU{!AlH$DVX8 zL5TEeK9l6xnTC}v4XR(5M#;O9;O|hOv$6EA?tZM-vFi34_o3#jzru+DSBtiQw`{CW zr-sZKSZbEPIBd=1OLOcC-#kT zKh5XKcAs^ynlaMLYChd-!`EbagpC|#D>w34|IajN9OL(=ahPEe(g6e@@fbBq?;D?ro4(Q(KSMG4VEqa7hi?jfBiz*W%H5}6MJ5Z=#~oP zX}2?o3k!Qdc;uZ7@$5k;6QT2Ti$f#Y<0&-qFG>dDeL#It{O;Xz3`{&q$BQ%1Yf@K{ zISdR&C|8(pmSpkgp=Bha(9w}6=Z|};JP>+=M6{WiH@DmZ6tZ@zCowPEu^de zj&oyn*FM?Hb$=TeGdbP)_vU>fvl3iJn3eI*;&z?QuJ98g-SDTVPhYq&1!TZ$S?jyD z)dcX5;fV?AL#<=T;GD|15{6-8z`dfi8a_OlY=DiB&59F{xl4Q{WrR(zJY0DkgNPfQ zJ%@CAo!@PJ6f^^8T-y9H)XniYMS-vR-supP{fw$;ex@cThb9<=PE}~NANJOaesu?W z8XoJ}M$eYBXv;0!{gk-hHXe5_<4YzivNNqFxV^iVlSaC4&9CC1qj54918!29@x*L7 zMU9tK66JEu9nZj<2-1Y#rO&peB)Gchj*0`D{FkHsPF7gBx{hsn+V})|dOpU*AB3a# zqKmiq1D)8caq<|{zZrB-)Gz07<(V(HF2j^EPlksv%>5%fYJgc1pFDCjV(wD7(U&{j z)zv8OSO2{_1<&bXxWsmCglXr|<(^at;q{z}&-x~H!U6&_;XFi_FuYioyiREW(A|ax z4sOZow!_S4_lyp*Y7XDgey;O&+Wh@(d_d>U&w-aGu@C)h{w#7Wv2$FHF_AVfxTCMX z7Mm-yyPH|+h5i~U+AbOL@Rr6Jz8)xaS`&*kW%Nelt`l7TJXl;*(%Yb=y>oGtdoj_F ztgUV$OXl2`4mtMp<2R5)`}*bjIRccq2di$eQX39JteJRO2bUiv#*XLrrOGblRL%d@W&HrSTGw6)RUV`j#*<~LF@PEu*z+?|`CttKQJ2#+gwbav*m z{|)euDQMisU@$siw*b2)C?36)_j}Zi>n9xx zTF*6;6iqqu3pPhe3mK_N@8BW;3jr*Wc&}ZF%JTBwo*pi!(@go@v~$441}){uLC4c9 z>v;`&-{n$`m}^J*WB0}e)KJc)Hc@MzbDKB5cK+6LRpUcj_0(m^qU&`_xe9g$ z#f;w%56`_2h|7Hyc^SQL(clvSB%9qSrj@ldL+VxD_@t+XeQBN2qrQs~KR>&E`pNxF ziDVnPulvstBJx`kBU6{bsfC4QESU&jt;M6v{rx9hKkoLQ9U7Rw`Q$~$mibW*apC-hpD1kSn%*6!Vqi8(=#BQD?5m{` zu>2+q4ygYKv-uS#VFT4D>~$jElR&b}02EKOUfJ{UR7@9%6_ICuM2T^~k&*->g6%`k z2-{p5wRxSeS<8GrZ&HY%WmvP^X`G9 z+UaS3xNHck;&7I(*!hm>UlS29Zq$GEH7eF@q9(F1Y~jU+Vmy-gmab*_*vf4>jd<@d z$=8!3Bf*mkp^hSAzQfW#2qu(y0q-6ybwTM2!6sT^&{qCc@2OiBXlfgDLDb-ag5!U- zgH`eDwxQB^b~Us{W#?g|{1AygAB0kJUwRbXE$bMGc?>^hfT>j<=2LE@cIi$^X67B; zraRN&b*{x=ksqpl`}u6he?Pv$o9ZC4<#(9d$a^EX^V>JF4#}s#^i9jyD8`?4Zr=}l z7F!G8hl&bkkZRr3{}3Mf_`Xb#FFQpt~ExZ1mo;SmPMI zcaNCZbLLZB(`*$rWNt0LPEB2zy8OZ%@a=|;CR=tnIJiqr!e84MT+`3a)yIDAF- z3L{y#DQ7`UOUje=ljyg+vb1lu#uc##6kTfu-m(_f!DIo$vX40}Os3DQmUr-QV%DLW z?{I+^36ofvbK{yTHl+WRn<(b)E8o}CP|kIbQjSjI>AspGL}vI9l&=o;JDA>PQNpm; zb|Hrh|8kC|@$fQ77`>MfW!BcV zQz=gzBEECFwY4#&!R9+$a%$qdyQCDIq<2@+^UtNA8w0sgEM6!>{l%BS{?*kLbDvvc zH}h9`PUReafRt?Np5J}GFFA734i3{iOPfAtov8{I)8R&YRX9@9#oiB5FkPB15B(2y zt0@|;@9giPBs@8PNi)bo0{n6Vd$nW-zWSN}{0cVoD1?`{OkdU*KOTpQUs_+Ck&GPSZGp3f$?CWSlbtMG%b1SnZ` zb*IpOAI;}E1n%)vEtp2Wl9g0NHp1%zDRV1NP~qN5`Zt4h$`vty(Dns>#HkrWjjUnZBM z?|}<2gx6&Aaz^l#8dnuTTvb5MfNE-CJehy~?Zcr8F-D{TiHv7_IB z&{M`p^R@8vB_ff>lglc?0pljsPZ(0QFf}@!zPb1_;lN7U_0qJ0OS5gI@LCG0e&A;< zc{V|D=Xq>))K9@dLCCOoP&%>-jCWq1PhVzt*f7*SmgC$N_1b3@A?f9!jsTLxP1#0J z9^b&9!RaY<2C+f}^K-e7pjTSyNg6HsfzC4Ye!!6k|3=Ijs2(eT*Z6En({PmebXqzd znshQ7DJhiv7jUVSd!~aXcn0wNgvA2sO{R{kkKiB0|L_U*H4=Mmi02$rSBPCli%LwL z*!R>cgzp`5-3C_lquMYPf>QI>iShA)>)+E=fpAwbPI6lZX?}V&td1G-O93^5W$Ecu z5NfuVTcxoCq_OCl`pa*K*CBnPuXedcPFw zyuEmm^m<+1wfq`?B-z9L!W53fwVDh+;)@l|iv@rGx`z1^T6syI!GrV8ZbqH!a9r+O zxNDe(ubX9|pBRgWIsU0J>0%Ip>YEiu5njv#OzFZxyXH`vpO@ZmghZAn$`ZN4+U1V{Pj(;joAwli>$UqXx!{z4>J(1CIe~C-Rh525JZ8u@{7o2w#6;sS6uQz=$wD|{d)#gy!u>fh zwU>mGa;SVnV!iUM4w^8_z-Con2C%H`0$#v|@-91RyOL87f39fN3r1CxYJ~^AHTrF! zAFhLwjEw7g{!$PC&!`^BFp~}tC{yZlQ=#xN7$t?;E9V-w3aX>a&AN1Cqq}9_)B3IT zAnT!wnVXt@kaj4IWsMv!TkfxYL?>n*Z>J1-q2#mMSGId!vhW*Yy`VBe!fE6lGo!U_ zGNSy%-%mGjc7Drz4tNdswe&DiRF;-c06FE)Mp`D2=Q# z>u>bWBz%5#_d^Q`2sDSK0%&M@zF#EHnYRVJK-}ELxZ;%=0Qxp*YU&a2? zwl-p1!bgi5MUddKzz-t(Kz&1)8$X2K1=hEESD73tXWL^^)EP}%;{*k(ILmx z#fk^z9|aUz&Q4Cq(JyyAlqP`Vu@C|>P94l`bMaL@0enX^k=D#FYv1^`xO25u_(XY$ z=zhh;?VCisRsns^U%>8*SX`qfS*do|#Kgktjt!{DWplH-N=AmEt&FGL;RRM90A@3a zomrZg6;Rj$QE_|ejSF~u9iBdYg$k${farzAyq8XW`s;II7@?SwqGHR1@YNhGYvC|+ z3z`p6m1ZU>$g4_{>Yn!~tgJ#^V+q5AYb_vX38$P*ea_bC?ul+{!R!yb5tL>JkbPFsc~^y#Phw$7>IFRVtOh8?bj)X z-S~Ogwtj`d5EB1G`O_SMpF4rl)o7~@?1Djo>bN2vc`Z@(o4t;Kf`4Yv|Fcj5m5D}% zIF-NPw8!sAnEEWv&(|Len^dMf22bS0^S60qULL zB`$i>@hH+w_saWZE8bwPQBTa<(oc1FgbFY+?_D4e z@Tb%z%~;93PZfiI+UMX_fkVRFE84&t1!}YR!5$X;3D;P10)Usq&?$Qd#SXS7RrcRd zTXgIO{c_C%H*wiW_1m|YN*1ed_~qtE9nZ&uSDML;#L8sVtv^p?Hx3h27t)P6IvvFb zy98lR`EV$Fzyz@zdxONoVw6uv%LWKCHkB(;zPX9drXoJZFUMgcxiPTnT^2e)MrK{r)I|_1z zF3Mij6PdM1TkA0b37Y?qvF9ye3-!!|+{+%qj1!V994g4Utb?_+DEfx|<+ z`xF8!G^-w?p85Nwlaw^oH~DSv377aw+>i<=kfn2-;w&Sx1pz|jMt|Z&)d67#86wol z`VD6-`@EL)j;#@DhpoN${!hk_JmwMA|9z)nf<7siAZgQH0atxhRbJja93UXQ@9I+` zA9hhlJ4G{h8}d1Sl!iyyw)>-Zz{>Xl`+Eg_+jEm#*SKsQYwMf)@5{;z1_OOw7YbFO zuD?oH41Fg|FcQlgpM#mG5Qszb(no~uR?L%MMet4Y@Oub@p@t&Fpr{d;h0x@|`>pqn zQzJK#MMB~jCIxh&{Ll6tI%8l1NmL(;(5!B6Ux9|}D)Kq;eh>f7u|_04TX#KtCDF!r z)Rk9iX>jYO|B5pcm{wG?Fu`d_DFH*7EESGmvx@)vYu8uQ>o{N`HwVp};^H+h(12yT zwqS;0!mEt!;r_PjkO3$qz=ze)(4ajE0tqPqK!Py5%h;r))i6DEcp(c*Zp zI1sJqF1{}AeD=aQB#@>M1q=_0cR=28g?}Lhyf$AlE0|p>uMapE5 zKMzCxQIh@r_rKdBDo1~`W;etlVT)1b(AJ-Re3#f!3snHDF0IS3qNSg|qOSaa#Uj0% z$bcJ9Pgup8%ezjr4G6?G_)h=&s_zQsfPbr|X2^n)-5>t*;~FCQzj!67$man+OhM4@ zxSalTiR3J2eGhY**%n7beo(aFrRxa^vRA%GA7hlqs4IVhsQB=GH1R#g?*gxm9Gm<)!XL(40z%`ai# z`e?743v2&+PIAD0heG$3`6UPo;oM74KLyEnjxY?#O5eXv=$Yv44OooKWo5Se_AVof z_ldr~zMGpHWE4QCxi>3cm*Qk}tvAS^+3duGLR75kAlt1&7Ss!omUEWu}|_&BJ|@0N!Zz z+3UcLrAM8DocwEh`x^;wH|QNee(BWI6!dMNqvr!KD%f2E;(*BoTDVc#+Yj+HfqKEl z!vp_H(_dFeC0W@P(2_MlqHtbb9%yD}+n@<^0}OjIY+BH-)X}KK=Vzh$RpXEea9O|Z zCn?Isg@qoM=Z8>NL{OIB|AJcC3SFcD?m4G@Xo=kT0<1AUhD;h%P=6-?!w+tI$TP%N zi=6c%(g}NXe4Kp`HY#NzQqmxQA_#LVKZ8pl=pTxUi&Z8puoe{*Azz2J9Tai!9GLvF zsZclomxPQ^DXE!)AnqjcZbP`UQ{Jw8_zzBd1QA5hSHIRoy7O5{9?%Gj|CGiz44rSD z6$xG^N&f#?xtyT3_*hW^8C`5s3lg9@>MfuQR_Mrru<&6MhlT^_;|JW{1^Zv$DP$`^ zWg3Qyk1qkY#~wRE9vF>)2(nAB5-INF<|e>NNFG5+P|?tkaGXJG$a<2>uwhgK`?9k$ zKs{IxdR~U+=67(=l||e)@7=0yxTHbTuXPRek%$X6QNL!Uq^W^{QY?QW_c+5G_~3_!hVqpIVxi*>VynHqJ+^#x zAYAF_=m1C_NO4*e%I|5*xp2WNv^H3ViC_m_d_CiTzKl6?&0}jL`;!0hyJpOO=gC(! zct`kO_b$)Am9@3*A3xmO-TgPJMz#Sz&2YRoOW?V`tPQ(@t810G5;l(i#W9QD#KgqT z&mB;Wcp0GOeKQg^$as1qOXu-p4$UWacKsX=oEgiDqw$C-MbPPam^yo}uK>yQXH)t7AHM*gzgFOIgPX5Fk<8gdnF>elv&K0{C@dZ(*5-7pxuQ~ z5MB6^!cs}?SdSSgXk<|r(2m_)1AJ6DU8Exl>2v=C@`LGSJj%W%CkM5FsUh~JbxeQ9 zB5aZHbRfp|5Ae8vm-lfnC*t{!>f=Lyq1&V=RXpoH0IPy`tA!Ngz#X^P*i?qmAEk<+ zv-YDyQ!A6l;07`#ZfHn9b=@FKckyQ?p^2?_6w%0Aodec1xSi88*+l~8Td`_pTNaHO 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
V^= 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ὧ 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

{}EZf~Wg^#W9?S5{bA$mn5~d+(-rV^{B{< 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 literal 0 HcmV?d00001 From e5fb7c1ad21915e8ab5804080f4fcb8dafa9b6bb Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 18 Sep 2019 14:11:34 +0200 Subject: [PATCH 412/525] Fixed misspelling in migration script (#641) --- server-ce/migrations/9_create_user_emails_array.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/migrations/9_create_user_emails_array.js b/server-ce/migrations/9_create_user_emails_array.js index 08e9fb06f6..b9216c2a4c 100644 --- a/server-ce/migrations/9_create_user_emails_array.js +++ b/server-ce/migrations/9_create_user_emails_array.js @@ -22,7 +22,7 @@ const initUserEmailsAttribute = (user, callback) => { } const updateAllUsersEmailsAttribute = (users, callback) => { - console.log(`updating ${user.length} users`) + console.log(`updating ${users.length} users`) async.eachSeries(users, initUserEmailsAttribute, callback) } From f52a5aba99ec78d742665b59c43e1be74c2c4e16 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 20 Sep 2019 10:56:25 +0100 Subject: [PATCH 413/525] Add migration for token prefix --- .../migrations/10_update_project_tokens.js | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 server-ce/migrations/10_update_project_tokens.js diff --git a/server-ce/migrations/10_update_project_tokens.js b/server-ce/migrations/10_update_project_tokens.js new file mode 100644 index 0000000000..57095308f8 --- /dev/null +++ b/server-ce/migrations/10_update_project_tokens.js @@ -0,0 +1,109 @@ +const Settings = require('settings-sharelatex') +const Async = require('async') +const mongojs = require('mongojs') +const db = mongojs(Settings.mongo.url, ['users']) + +const indexKeys = { 'tokens.readAndWritePrefix': 1 } +const indexOpts = { + unique: true, + partialFilterExpression: { + 'tokens.readAndWritePrefix': { $exists: true } + }, + background: true +} + +// Index on Prefix +const addReadAndWritePrefixIndex = (db, callback) => { + db.projects.ensureIndex(indexKeys, indexOpts, callback) +} + +const removeReadAndWritePrefixIndex = (db, callback) => { + db.projects.dropIndex(indexKeys, callback) +} + +// Extract prefix data +const extractPrefix = (db, callback) => { + db.projects.find( + { + 'tokens.readAndWrite': { $exists: true }, + 'tokens.readAndWritePrefix': { $exists: false } + }, + { tokens: 1 }, + (err, projects) => { + if (err) { + return callback(err) + } + console.log(`>> Updating ${projects.length} projects`) + Async.eachLimit( + projects, + 5, + (project, cb) => { + const rwToken = project.tokens.readAndWrite + const prefixMatch = rwToken.match(/^(\d+).*$/) + if (!prefixMatch) { + const err = new Error( + `no prefix on token: ${project._id}, ${rwToken}` + ) + console.log(`>> Error, ${err.message}`) + return cb(err) + } + db.projects.update( + { _id: project._id }, + { $set: { 'tokens.readAndWritePrefix': prefixMatch[1] } }, + cb + ) + }, + err => { + if (err) { + return callback(err) + } + console.log('>> done') + callback() + } + ) + } + ) +} + +const erasePrefix = (db, callback) => { + db.projects.update({$unset: 'tokens.readAndWritePrefix'}, callback) +} + + +// Migrations + +exports.migrate = (client, done) => { + console.log(`>> Adding index to projects: ${JSON.stringify(indexKeys)}, with options: ${JSON.stringify(indexOpts)}`) + addReadAndWritePrefixIndex(db, (err) => { + if(err) { + console.log(">> Error while adding index") + return done(err) + } + console.log(">> Extracting tokens.readAndWritePrefix field for existing projects") + extractPrefix(db, (err) => { + if(err) { + console.log(">> Error while extracting prefix data") + return done(err) + } + done() + }) + }) +} + +exports.rollback = (client, done) => { + console.log(`>> Dropping index on projects: ${JSON.stringify(indexKeys)}`) + removeReadAndWritePrefixIndex(db, (err) => { + if(err) { + console.log(">> Error while dropping index") + return done(err) + } + console.log(">> Erasing tokens.readAndWritePrefix field for existing projects") + erasePrefix(db, (err) => { + if(err) { + console.log(">> Error while erasing prefix data") + return done(err) + } + done() + }) + }) +} From 460d334d21c3222729ccfa2d4cff1c26d5f6b2b1 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 24 Sep 2019 11:52:38 +0100 Subject: [PATCH 414/525] Copy logic from clsi entrypoint, to set permissions on docker.sock --- server-ce/runit/clsi-sharelatex/run | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server-ce/runit/clsi-sharelatex/run b/server-ce/runit/clsi-sharelatex/run index 7492acf6d1..539e5f2239 100755 --- a/server-ce/runit/clsi-sharelatex/run +++ b/server-ce/runit/clsi-sharelatex/run @@ -7,4 +7,13 @@ if [ "$DEBUG_NODE" == "true" ]; then NODE_PARAMS="--inspect=0.0.0.0:30130" fi +# Set permissions on docker.sock if present, +# To enable sibling-containers (see entrypoint.sh in clsi project) +if [ -e '/var/run/docker.sock' ]; then + echo ">> Setting permissions on docker socket" + DOCKER_GROUP=$(stat -c '%g' /var/run/docker.sock) + groupadd --non-unique --gid ${DOCKER_GROUP} dockeronhost + usermod -aG dockeronhost www-data +fi + exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/clsi/app.js >> /var/log/sharelatex/clsi.log 2>&1 From fbd5e2a826dc55539ff03acc17ea289763a67bd3 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 8 Oct 2019 11:54:49 +0200 Subject: [PATCH 415/525] Delete aggregated error log (#117) --- server-ce/runit/errorlogs/run | 2 -- 1 file changed, 2 deletions(-) delete mode 100755 server-ce/runit/errorlogs/run diff --git a/server-ce/runit/errorlogs/run b/server-ce/runit/errorlogs/run deleted file mode 100755 index 45ab0ed313..0000000000 --- a/server-ce/runit/errorlogs/run +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -tail -F /var/log/sharelatex/*.log | grep '"level":50' >> /var/log/sharelatex-errors.log From de33a6a7b6e12bfab3cfb7ddc9c8ecac951b8fe5 Mon Sep 17 00:00:00 2001 From: Matthieu Simonin Date: Tue, 8 Oct 2019 12:46:53 +0200 Subject: [PATCH 416/525] Fix the paths in grunt tasks (#643) --- server-ce/tasks/CreateAndDestoryUsers.coffee | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/server-ce/tasks/CreateAndDestoryUsers.coffee b/server-ce/tasks/CreateAndDestoryUsers.coffee index 0f0bff2e0f..9602fe462b 100644 --- a/server-ce/tasks/CreateAndDestoryUsers.coffee +++ b/server-ce/tasks/CreateAndDestoryUsers.coffee @@ -5,12 +5,12 @@ module.exports = (grunt) -> done = @async() email = grunt.option("email") if !email? - console.error "Usage: grunt user:create-admin --email joe@example.com" + console.error "Usage: grunt user:create-admin --email=joe@example.com" process.exit(1) settings = require "settings-sharelatex" - UserRegistrationHandler = require "../web/app/js/Features/User/UserRegistrationHandler" - OneTimeTokenHandler = require "../web/app/js/Features/Security/OneTimeTokenHandler" + UserRegistrationHandler = require "../web/app/src/Features/User/UserRegistrationHandler" + OneTimeTokenHandler = require "../web/app/src/Features/Security/OneTimeTokenHandler" UserRegistrationHandler.registerNewUser { email: email password: require("crypto").randomBytes(32).toString("hex") @@ -39,11 +39,11 @@ module.exports = (grunt) -> done = @async() email = grunt.option("email") if !email? - console.error "Usage: grunt user:delete --email joe@example.com" + console.error "Usage: grunt user:delete --email=joe@example.com" process.exit(1) settings = require "settings-sharelatex" - UserGetter = require "../web/app/js/Features/User/UserGetter" - UserDeleter = require "../web/app/js/Features/User/UserDeleter" + UserGetter = require "../web/app/src/Features/User/UserGetter" + UserDeleter = require "../web/app/src/Features/User/UserDeleter" UserGetter.getUser email:email, (error, user) -> if error? throw error @@ -53,4 +53,4 @@ module.exports = (grunt) -> UserDeleter.deleteUser user._id, (err)-> if err? throw err - done() \ No newline at end of file + done() From 325c31d602c63da7fa02347f6c40a4f78ead70e2 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 8 Oct 2019 12:47:08 +0200 Subject: [PATCH 417/525] Linked CLSI synctext to /opts/synctex (#118) --- server-ce/Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index c527411457..d3a6e69e29 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -44,6 +44,11 @@ RUN bash -c 'cd /var/www/sharelatex && source ./bin/install-services' RUN bash -c 'cd /var/www/sharelatex && source ./bin/compile-services' +# Links CLSI sycntex to its default location +# ------------------------------------------ +RUN ln -s /var/www/sharelatex/clsi/bin/synctex /opt/synctex + + # Change application ownership to www-data # ---------------------------------------- RUN chown -R www-data:www-data /var/www/sharelatex; From 5159c9cc8bbbfb5f60bc3b7788c979ebb1a7a391 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 15 Oct 2019 11:00:38 +0200 Subject: [PATCH 418/525] Disable project-history via settings (#125) --- server-ce/settings.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 3cb6a510b9..8a3cd1af1c 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -200,6 +200,8 @@ settings = # is not available v1: url: "" + project_history: + enabled: false references:{} notifications:undefined From 78d179c4597ac056ef1326241bcc52e71a627c29 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 18 Oct 2019 10:03:05 +0200 Subject: [PATCH 419/525] Fix token creation on admin registration (#648) --- server-ce/tasks/CreateAndDestoryUsers.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/tasks/CreateAndDestoryUsers.coffee b/server-ce/tasks/CreateAndDestoryUsers.coffee index 9602fe462b..14ed4ca360 100644 --- a/server-ce/tasks/CreateAndDestoryUsers.coffee +++ b/server-ce/tasks/CreateAndDestoryUsers.coffee @@ -21,7 +21,7 @@ module.exports = (grunt) -> user.save (error) -> throw error if error? ONE_WEEK = 7 * 24 * 60 * 60 # seconds - OneTimeTokenHandler.getNewToken user._id, { expiresIn: ONE_WEEK }, (err, token)-> + OneTimeTokenHandler.getNewToken "password", { expiresIn: ONE_WEEK, email:user.email, user_id: user._id.toString() }, (err, token)-> return next(err) if err? console.log "" From 936f9f8142a7f560682f4737db92595ffbe651e2 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 18 Oct 2019 15:41:28 +0200 Subject: [PATCH 420/525] Added explicit reference to Server Pro image in docker-compose (#649) --- server-ce/docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 725c241318..23f9aaf1c2 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -2,6 +2,8 @@ version: '2.2' services: sharelatex: restart: always + # Server Pro users: + # image: quay.io/sharelatex/sharelatex-pro image: sharelatex/sharelatex container_name: sharelatex depends_on: From d29b3fa1f7a93647c3306d40a1c9b33184d331a1 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Mon, 21 Oct 2019 11:48:01 +0200 Subject: [PATCH 421/525] Overleaf CE Hotfix 2.0.1 (#126) --- server-ce/hotfix/2.0.1/Dockerfile | 13 +++++++++++++ .../hotfix/2.0.1/create_and_destroy_users.patch | 11 +++++++++++ .../hotfix/2.0.1/disable_project_history.patch | 11 +++++++++++ 3 files changed, 35 insertions(+) create mode 100644 server-ce/hotfix/2.0.1/Dockerfile create mode 100644 server-ce/hotfix/2.0.1/create_and_destroy_users.patch create mode 100644 server-ce/hotfix/2.0.1/disable_project_history.patch diff --git a/server-ce/hotfix/2.0.1/Dockerfile b/server-ce/hotfix/2.0.1/Dockerfile new file mode 100644 index 0000000000..12a85378b4 --- /dev/null +++ b/server-ce/hotfix/2.0.1/Dockerfile @@ -0,0 +1,13 @@ +FROM sharelatex/sharelatex:2.0.0 + + +# Patch 1: Fixes project deletion (https://github.com/overleaf/overleaf/issues/644) +ADD disable_project_history.patch /etc/sharelatex/disable_project_history.patch +RUN cd /etc/sharelatex && \ + patch < disable_project_history.patch + + +# Patch 2: Fixes admin creation via CLI (https://github.com/overleaf/overleaf/issues/647) +ADD create_and_destroy_users.patch /var/www/sharelatex/tasks/create_and_destroy_users.patch +RUN cd /var/www/sharelatex/tasks/ && \ + patch < create_and_destroy_users.patch diff --git a/server-ce/hotfix/2.0.1/create_and_destroy_users.patch b/server-ce/hotfix/2.0.1/create_and_destroy_users.patch new file mode 100644 index 0000000000..bb2dc16898 --- /dev/null +++ b/server-ce/hotfix/2.0.1/create_and_destroy_users.patch @@ -0,0 +1,11 @@ +--- CreateAndDestoryUsers.coffee ++++ CreateAndDestoryUsers.coffee +@@ -21,7 +21,7 @@ module.exports = (grunt) -> + user.save (error) -> + throw error if error? + ONE_WEEK = 7 * 24 * 60 * 60 # seconds +- OneTimeTokenHandler.getNewToken user._id, { expiresIn: ONE_WEEK }, (err, token)-> ++ OneTimeTokenHandler.getNewToken "password", { expiresIn: ONE_WEEK, email:user.email, user_id: user._id.toString() }, (err, token)-> + return next(err) if err? + + console.log "" diff --git a/server-ce/hotfix/2.0.1/disable_project_history.patch b/server-ce/hotfix/2.0.1/disable_project_history.patch new file mode 100644 index 0000000000..830570abbe --- /dev/null +++ b/server-ce/hotfix/2.0.1/disable_project_history.patch @@ -0,0 +1,11 @@ +--- settings.coffee ++++ settings.coffee +@@ -200,6 +200,8 @@ settings = + # is not available + v1: + url: "" ++ project_history: ++ enabled: false + references:{} + notifications:undefined + From 472581d714c6226a055331c813a4bab82483d51f Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 23 Oct 2019 10:20:39 +0200 Subject: [PATCH 422/525] Added webpack compilation scripts (#651) --- server-ce/bin/compile-services | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index 1c508ae693..ba490c5bea 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -11,7 +11,8 @@ grep 'name:' config/services.js | \ case $service in web) make compile_full - WEBPACK_ENV=production make minify + make minify + npm run webpack:production ;; chat) echo "$service doesn't require a compilation" From 853c658499f8d70824937603fc327fa34333de57 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 7 Nov 2019 09:30:55 +0000 Subject: [PATCH 423/525] Create ISSUE_TEMPLATE.md --- server-ce/.github/ISSUE_TEMPLATE.md | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 server-ce/.github/ISSUE_TEMPLATE.md diff --git a/server-ce/.github/ISSUE_TEMPLATE.md b/server-ce/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..865bb70801 --- /dev/null +++ b/server-ce/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,31 @@ + + +## Steps to Reproduce + + + +1. +2. +3. + +## Expected Behaviour + + +## Observed Behaviour + + + +## Context + + +## Technical Info + + +* URL: +* Browser Name and version: +* Operating System and version (desktop or mobile): +* Signed in as: +* Project and/or file: + +## Analysis + From c8ee9f2d4f332ef0faa71011c3b78c9eef459250 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 7 Nov 2019 15:17:39 +0000 Subject: [PATCH 424/525] Update ISSUE_TEMPLATE.md --- server-ce/.github/ISSUE_TEMPLATE.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/server-ce/.github/ISSUE_TEMPLATE.md b/server-ce/.github/ISSUE_TEMPLATE.md index 865bb70801..3a375bcbe9 100644 --- a/server-ce/.github/ISSUE_TEMPLATE.md +++ b/server-ce/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,16 @@ + + + + ## Steps to Reproduce From bfcba2a9432db468b8c1203a19694341a3c3489f Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 21 Nov 2019 11:52:02 +0100 Subject: [PATCH 425/525] Remove overriden v1 settings (#128) --- server-ce/settings.coffee | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 8a3cd1af1c..922fb32c04 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -196,10 +196,6 @@ settings = url: "http://localhost:3000" user: httpAuthUser pass: httpAuthPass - # overrides v1.url to indicate via Feature Flags that Overleaf V1 - # is not available - v1: - url: "" project_history: enabled: false references:{} From 66fec536f51d7555631e6bd95e8559111c5be84c Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 21 Nov 2019 12:16:29 +0100 Subject: [PATCH 426/525] Add SYNCTEX_BIN_HOST_PATH environment variable (#664) --- server-ce/docker-compose.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 23f9aaf1c2..cfb2ef3a4e 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -2,7 +2,7 @@ version: '2.2' services: sharelatex: restart: always - # Server Pro users: + # Server Pro users: # image: quay.io/sharelatex/sharelatex-pro image: sharelatex/sharelatex container_name: sharelatex @@ -68,7 +68,8 @@ services: # SANDBOXED_COMPILES: 'true' # SANDBOXED_COMPILES_SIBLING_CONTAINERS: 'true' - # SANDBOXED_COMPILES_HOST_DIR: '/var/clsi/compiles' + # SANDBOXED_COMPILES_HOST_DIR: '/var/sharelatex_data/data/compiles' + # SYNCTEX_BIN_HOST_PATH: '/var/sharelatex_data/synctex' # DOCKER_RUNNER: 'false' From fc0c464216ba2ddccbe2e4b547f1c1c7feb70aa0 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 22 Nov 2019 10:12:33 +0100 Subject: [PATCH 427/525] Copy synctex executable to docker host (#129) --- server-ce/runit/clsi-sharelatex/run | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/server-ce/runit/clsi-sharelatex/run b/server-ce/runit/clsi-sharelatex/run index 539e5f2239..c1469b6cfe 100755 --- a/server-ce/runit/clsi-sharelatex/run +++ b/server-ce/runit/clsi-sharelatex/run @@ -16,4 +16,17 @@ if [ -e '/var/run/docker.sock' ]; then usermod -aG dockeronhost www-data fi +# Copies over CSLI synctex to the host mounted volume, so it +# can be subsequently mounted in TexLive containers on Sandbox Compilation +SYNCTEX=/var/lib/sharelatex/bin/synctex +if [ ! -f "$SYNCTEX" ]; then + if [ "$DISABLE_SYNCTEX_BINARY_COPY" == "true" ]; then + echo ">> Copy of synctex executable disabled by DISABLE_SYNCTEX_BINARY_COPY flag, feature may not work" + else + echo ">> Copying synctex executable to the host" + mkdir -p $(dirname $SYNCTEX ) + cp /var/www/sharelatex/clsi/bin/synctex $SYNCTEX + fi +fi + exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/clsi/app.js >> /var/log/sharelatex/clsi.log 2>&1 From 5e448fadda2324a86b461bcc33b8c470c9a2fc75 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 22 Nov 2019 13:03:59 +0000 Subject: [PATCH 428/525] Update docker-compose.yml --- server-ce/docker-compose.yml | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index cfb2ef3a4e..6bc502d52b 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -119,12 +119,18 @@ services: # container_name: ldap # expose: # - 389 -# nginx-proxy: -# image: jwilder/nginx-proxy -# container_name: nginx-proxy -# ports: -# #- "80:80" -# - "443:443" -# volumes: -# - /var/run/docker.sock:/tmp/docker.sock:ro -# - /home/sharelatex/tmp:/etc/nginx/certs + + # See https://github.com/jwilder/nginx-proxy for documentation on how to configure the nginx-proxy container, + # and https://github.com/overleaf/overleaf/wiki/HTTPS-reverse-proxy-using-Nginx for an example of some recommended + # settings. We recommend using a properly managed nginx instance outside of the Overleaf Server Pro setup, + # but the example here can be used if you'd prefer to run everything with docker-compose + + # nginx-proxy: + # image: jwilder/nginx-proxy + # container_name: nginx-proxy + # ports: + # #- "80:80" + # - "443:443" + # volumes: + # - /var/run/docker.sock:/tmp/docker.sock:ro + # - /home/sharelatex/tmp:/etc/nginx/certs From feda446983b688b6ea6a1d4892247ffb536f2b98 Mon Sep 17 00:00:00 2001 From: theunbound Date: Mon, 9 Dec 2019 18:02:52 +0100 Subject: [PATCH 429/525] Remove make targets in web (#670) --- server-ce/bin/compile-services | 2 -- 1 file changed, 2 deletions(-) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index ba490c5bea..f8c20ba4c6 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -10,8 +10,6 @@ grep 'name:' config/services.js | \ echo "Compiling Service $service" case $service in web) - make compile_full - make minify npm run webpack:production ;; chat) From c4104806c3e46b07c6d78cbe63741ee8c13a6dd0 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 10 Dec 2019 15:06:40 +0100 Subject: [PATCH 430/525] Hotfix 2.0.2 (#130) --- server-ce/hotfix/2.0.2/1-anon-upload.patch | 60 +++++++++++++++++++ .../hotfix/2.0.2/2-read-only-access.patch | 11 ++++ server-ce/hotfix/2.0.2/3-url-linking-1.patch | 11 ++++ server-ce/hotfix/2.0.2/4-url-linking-2.patch | 20 +++++++ .../hotfix/2.0.2/5-disable-analytics-1.patch | 26 ++++++++ .../hotfix/2.0.2/6-disable-analytics-2.patch | 10 ++++ server-ce/hotfix/2.0.2/Dockerfile | 31 ++++++++++ 7 files changed, 169 insertions(+) create mode 100644 server-ce/hotfix/2.0.2/1-anon-upload.patch create mode 100644 server-ce/hotfix/2.0.2/2-read-only-access.patch create mode 100644 server-ce/hotfix/2.0.2/3-url-linking-1.patch create mode 100644 server-ce/hotfix/2.0.2/4-url-linking-2.patch create mode 100644 server-ce/hotfix/2.0.2/5-disable-analytics-1.patch create mode 100644 server-ce/hotfix/2.0.2/6-disable-analytics-2.patch create mode 100644 server-ce/hotfix/2.0.2/Dockerfile diff --git a/server-ce/hotfix/2.0.2/1-anon-upload.patch b/server-ce/hotfix/2.0.2/1-anon-upload.patch new file mode 100644 index 0000000000..75037901e0 --- /dev/null +++ b/server-ce/hotfix/2.0.2/1-anon-upload.patch @@ -0,0 +1,60 @@ +--- UploadsRouter.js ++++ UploadsRouter.js +@@ -1,13 +1,3 @@ +-/* eslint-disable +- no-unused-vars, +-*/ +-// TODO: This file was created by bulk-decaffeinate. +-// Fix any style issues and re-enable lint. +-/* +- * decaffeinate suggestions: +- * DS102: Remove unnecessary code created because of implicit returns +- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md +- */ + const AuthorizationMiddleware = require('../Authorization/AuthorizationMiddleware') + const AuthenticationController = require('../Authentication/AuthenticationController') + const ProjectUploadController = require('./ProjectUploadController') +@@ -28,18 +18,30 @@ module.exports = { + ProjectUploadController.uploadProject + ) + +- return webRouter.post( +- '/Project/:Project_id/upload', +- RateLimiterMiddleware.rateLimit({ +- endpointName: 'file-upload', +- params: ['Project_id'], +- maxRequests: 200, +- timeInterval: 60 * 30 +- }), +- AuthenticationController.requireLogin(), +- AuthorizationMiddleware.ensureUserCanWriteProjectContent, +- ProjectUploadController.multerMiddleware, +- ProjectUploadController.uploadFile +- ) ++ const fileUploadEndpoint = '/Project/:Project_id/upload' ++ const fileUploadRateLimit = RateLimiterMiddleware.rateLimit({ ++ endpointName: 'file-upload', ++ params: ['Project_id'], ++ maxRequests: 200, ++ timeInterval: 60 * 30 ++ }) ++ if (Settings.allowAnonymousReadAndWriteSharing) { ++ webRouter.post( ++ fileUploadEndpoint, ++ fileUploadRateLimit, ++ AuthorizationMiddleware.ensureUserCanWriteProjectContent, ++ ProjectUploadController.multerMiddleware, ++ ProjectUploadController.uploadFile ++ ) ++ } else { ++ webRouter.post( ++ fileUploadEndpoint, ++ fileUploadRateLimit, ++ AuthenticationController.requireLogin(), ++ AuthorizationMiddleware.ensureUserCanWriteProjectContent, ++ ProjectUploadController.multerMiddleware, ++ ProjectUploadController.uploadFile ++ ) ++ } + } + } diff --git a/server-ce/hotfix/2.0.2/2-read-only-access.patch b/server-ce/hotfix/2.0.2/2-read-only-access.patch new file mode 100644 index 0000000000..246cc3e04d --- /dev/null +++ b/server-ce/hotfix/2.0.2/2-read-only-access.patch @@ -0,0 +1,11 @@ +--- TokenAccessHandler.js ++++ TokenAccessHandler.js +@@ -255,7 +255,7 @@ const TokenAccessHandler = { + + getV1DocPublishedInfo(token, callback) { + // default to allowing access +- if (!Settings.apis || !Settings.apis.v1) { ++ if (!Settings.apis.v1 || !Settings.apis.v1.url) { + return callback(null, { allow: true }) + } + V1Api.request( diff --git a/server-ce/hotfix/2.0.2/3-url-linking-1.patch b/server-ce/hotfix/2.0.2/3-url-linking-1.patch new file mode 100644 index 0000000000..173809842f --- /dev/null +++ b/server-ce/hotfix/2.0.2/3-url-linking-1.patch @@ -0,0 +1,11 @@ +--- Features.js ++++ Features.js +@@ -53,6 +53,8 @@ module.exports = Features = { + return Settings.apis.references.url != null + case 'saml': + return Settings.enableSaml ++ case 'link-url': ++ return Settings.apis.linkedUrlProxy && Settings.apis.linkedUrlProxy.url + default: + throw new Error(`unknown feature: ${feature}`) + } diff --git a/server-ce/hotfix/2.0.2/4-url-linking-2.patch b/server-ce/hotfix/2.0.2/4-url-linking-2.patch new file mode 100644 index 0000000000..587a8e6e0f --- /dev/null +++ b/server-ce/hotfix/2.0.2/4-url-linking-2.patch @@ -0,0 +1,20 @@ +--- new-file-modal.pug ++++ new-file-modal.pug +@@ -21,11 +21,12 @@ script(type='text/ng-template', id='newFileModalTemplate') + i.fa.fa-fw.fa-folder-open + | + | From Another Project +- li(ng-class="type == 'url' ? 'active' : null") +- a(href, ng-click="type = 'url'") +- i.fa.fa-fw.fa-globe +- | +- | From External URL ++ if hasFeature('link-url') ++ li(ng-class="type == 'url' ? 'active' : null") ++ a(href, ng-click="type = 'url'") ++ i.fa.fa-fw.fa-globe ++ | ++ | From External URL + != moduleIncludes("newFileModal:selector", locals) + + td(class="modal-new-file--body modal-new-file--body-{{type}}") diff --git a/server-ce/hotfix/2.0.2/5-disable-analytics-1.patch b/server-ce/hotfix/2.0.2/5-disable-analytics-1.patch new file mode 100644 index 0000000000..198ee03935 --- /dev/null +++ b/server-ce/hotfix/2.0.2/5-disable-analytics-1.patch @@ -0,0 +1,26 @@ +--- AnalyticsController.js ++++ AnalyticsController.js +@@ -3,9 +3,13 @@ const Errors = require('../Errors/Errors') + const AuthenticationController = require('../Authentication/AuthenticationController') + const InstitutionsAPI = require('../Institutions/InstitutionsAPI') + const GeoIpLookup = require('../../infrastructure/GeoIpLookup') ++const Features = require('../../infrastructure/Features') + + module.exports = { + updateEditingSession(req, res, next) { ++ if (!Features.hasFeature('analytics')) { ++ return res.send(204) ++ } + const userId = AuthenticationController.getLoggedInUserId(req) + const { projectId } = req.params + let countryCode = null +@@ -28,6 +32,9 @@ module.exports = { + }, + + recordEvent(req, res, next) { ++ if (!Features.hasFeature('analytics')) { ++ return res.send(204) ++ } + const userId = + AuthenticationController.getLoggedInUserId(req) || req.sessionID + AnalyticsManager.recordEvent(userId, req.params.event, req.body, error => diff --git a/server-ce/hotfix/2.0.2/6-disable-analytics-2.patch b/server-ce/hotfix/2.0.2/6-disable-analytics-2.patch new file mode 100644 index 0000000000..9fb41c1cba --- /dev/null +++ b/server-ce/hotfix/2.0.2/6-disable-analytics-2.patch @@ -0,0 +1,10 @@ +--- Features.js ++++ Features.js +@@ -41,6 +41,7 @@ module.exports = Features = { + case 'templates-server-pro': + return Settings.overleaf == null + case 'affiliations': ++ case 'analytics': + // Checking both properties is needed for the time being to allow + // enabling the feature in web-api and disabling in Server Pro + // see https://github.com/overleaf/web-internal/pull/2127 diff --git a/server-ce/hotfix/2.0.2/Dockerfile b/server-ce/hotfix/2.0.2/Dockerfile new file mode 100644 index 0000000000..7a75ed97a5 --- /dev/null +++ b/server-ce/hotfix/2.0.2/Dockerfile @@ -0,0 +1,31 @@ +FROM sharelatex/sharelatex:2.0.1 + + +# Patch 1: Fixes anonymous link sharing +ADD 1-anon-upload.patch /var/www/sharelatex/web/app/src/Features/Uploads/1-anon-upload.patch +RUN cd /var/www/sharelatex/web/app/src/Features/Uploads/ && \ + patch < 1-anon-upload.patch + + +# Patch 2: Fixes read-only access +ADD 2-read-only-access.patch /var/www/sharelatex/web/app/src/Features/TokenAccess/3-read-only-access.patch +RUN cd /var/www/sharelatex/web/app/src/Features/TokenAccess/ && \ + patch < 3-read-only-access.patch + + +# Patch 3: Fixes url linking +ADD 3-url-linking-1.patch /var/www/sharelatex/web/app/src/infrastructure/6-url-linking-1.patch +RUN cd /var/www/sharelatex/web/app/src/infrastructure/ && \ + patch < 6-url-linking-1.patch +ADD 4-url-linking-2.patch /var/www/sharelatex/web/app/views/project/editor/7-url-linking-2.patch +RUN cd /var/www/sharelatex/web/app/views/project/editor/ && \ + patch < 7-url-linking-2.patch + + +# Patch 4: Disables analytics +ADD 5-disable-analytics-1.patch /var/www/sharelatex/web/app/src/Features/Analytics/8-disable-analytics-1.patch +RUN cd /var/www/sharelatex/web/app/src/Features/Analytics/ && \ + patch < 8-disable-analytics-1.patch +ADD 6-disable-analytics-2.patch /var/www/sharelatex/web/app/src/infrastructure/9-disable-analytics-2.patch +RUN cd /var/www/sharelatex/web/app/src/infrastructure/ && \ + patch < 9-disable-analytics-2.patch From 9878a1321f41ed14d87f47ba279a419b27d471bc Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 8 Jan 2020 10:03:59 +0100 Subject: [PATCH 431/525] Add environment variable to disable email confirmation banner (#676) --- server-ce/docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 6bc502d52b..4f32fafeb7 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -35,6 +35,9 @@ services: # Enables Thumbnail generation using ImageMagick ENABLE_CONVERSIONS: 'true' + + # Disables email confirmation requirement + EMAIL_CONFIRMATION_DISABLED: 'true' ## Set for SSL via nginx-proxy #VIRTUAL_HOST: 103.112.212.22 From 4a424096f231bc7ee4234fcf9c640854472fa55c Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 9 Jan 2020 15:55:57 +0100 Subject: [PATCH 432/525] Added environment variables for web-api user/pass (#131) --- server-ce/Dockerfile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index d3a6e69e29..3fcfb509f6 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -81,6 +81,15 @@ COPY ${baseDir}/init_scripts/ /etc/my_init.d/ RUN cd /var/www && node git-revision > revisions.txt +# Set Environment Variables +# -------------------------------- +ENV WEB_API_USER "sharelatex" +# password is regenerated in init_scripts/00_regen_sharelatex_secrets.sh +ENV WEB_API_PASSWORD "password" + +ENV SHARELATEX_APP_NAME "Overleaf Community Edition" + + EXPOSE 80 WORKDIR / From 103941eab38a6a1590f7df96dd7c624a9c9c3c52 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 9 Jan 2020 15:56:19 +0100 Subject: [PATCH 433/525] Updated location of synctex path in docker-compose.yml (#680) --- server-ce/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 4f32fafeb7..8158070f66 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -72,7 +72,7 @@ services: # SANDBOXED_COMPILES_SIBLING_CONTAINERS: 'true' # SANDBOXED_COMPILES_HOST_DIR: '/var/sharelatex_data/data/compiles' - # SYNCTEX_BIN_HOST_PATH: '/var/sharelatex_data/synctex' + # SYNCTEX_BIN_HOST_PATH: '/var/sharelatex_data/bin/synctex' # DOCKER_RUNNER: 'false' From 2bc1dc464bfb497e570dbd616d849d7f6cb0c14f Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 21 Jan 2020 12:37:40 +0100 Subject: [PATCH 434/525] Added missing recaptcha configuration (#132) --- server-ce/hotfix/2.1.1/Dockerfile | 8 ++++++++ server-ce/hotfix/2.1.1/add-recaptcha-config.patch | 14 ++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 server-ce/hotfix/2.1.1/Dockerfile create mode 100644 server-ce/hotfix/2.1.1/add-recaptcha-config.patch diff --git a/server-ce/hotfix/2.1.1/Dockerfile b/server-ce/hotfix/2.1.1/Dockerfile new file mode 100644 index 0000000000..313c596545 --- /dev/null +++ b/server-ce/hotfix/2.1.1/Dockerfile @@ -0,0 +1,8 @@ +FROM sharelatex/sharelatex:2.1.0 + +# Patch: defines recaptcha config to fix share-related issues +# - https://github.com/overleaf/overleaf/issues/684 +ADD add-recaptcha-config.patch /etc/sharelatex/add-recaptcha-config.patch +RUN cd /etc/sharelatex/ && \ + patch < add-recaptcha-config.patch + diff --git a/server-ce/hotfix/2.1.1/add-recaptcha-config.patch b/server-ce/hotfix/2.1.1/add-recaptcha-config.patch new file mode 100644 index 0000000000..cdca537c46 --- /dev/null +++ b/server-ce/hotfix/2.1.1/add-recaptcha-config.patch @@ -0,0 +1,14 @@ +--- a/settings.coffee ++++ b/settings.coffee +@@ -180,6 +180,11 @@ settings = + # cookie with a secure flag (recommended). + secureCookie: process.env["SHARELATEX_SECURE_COOKIE"]? + ++ recaptcha: ++ disabled: ++ invite: true ++ register: true ++ + # If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) + # then set this to true to allow it to correctly detect the forwarded IP + # address and http/https protocol information. From 5232f07ec50f6e4aada456bfbf4afe14e63705c1 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 22 Jan 2020 14:41:31 +0100 Subject: [PATCH 435/525] Removed compile:all from filestore and notifications services (#688) --- server-ce/bin/compile-services | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index f8c20ba4c6..fc3bb8ea38 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -12,7 +12,7 @@ grep 'name:' config/services.js | \ web) npm run webpack:production ;; - chat) + chat|filestore|notifications) echo "$service doesn't require a compilation" ;; *) From 3783f03a837fce0baa9f5c36bc2712716cf67f95 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 22 Jan 2020 17:40:47 +0100 Subject: [PATCH 436/525] [misc] export all git repository revisions There is a multi purpose shell script for the gathering of git revisions now. It will extract all revisions that can be found in traversing of the current working directory. This effectively includes the overleaf/overleaf repo and any others that may be added downstream. --- server-ce/Dockerfile | 4 ++-- server-ce/git-revision.js | 22 ---------------------- server-ce/git-revision.sh | 6 ++++++ 3 files changed, 8 insertions(+), 24 deletions(-) delete mode 100644 server-ce/git-revision.js create mode 100755 server-ce/git-revision.sh diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 3fcfb509f6..db3c98a793 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -22,7 +22,7 @@ RUN git clone https://github.com/overleaf/overleaf.git \ # Install dependencies needed to run configuration scripts # -------------------------------------------------------- ADD ${baseDir}/package.json /var/www/package.json -ADD ${baseDir}/git-revision.js /var/www/git-revision.js +ADD ${baseDir}/git-revision.sh /var/www/git-revision.sh RUN cd /var/www && npm install @@ -78,7 +78,7 @@ COPY ${baseDir}/init_scripts/ /etc/my_init.d/ # Stores the version installed for each service # --------------------------------------------- -RUN cd /var/www && node git-revision > revisions.txt +RUN cd /var/www && ./git-revision.sh > revisions.txt # Set Environment Variables diff --git a/server-ce/git-revision.js b/server-ce/git-revision.js deleted file mode 100644 index 89359cea2e..0000000000 --- a/server-ce/git-revision.js +++ /dev/null @@ -1,22 +0,0 @@ -var simple = require('simple-git'); -var services = require('./sharelatex/config/services'); -const fs = require('fs'); - -function print_latest(repoDir) { - git = simple(repoDir); - opt = []; - opt['max-count'] = 1; - git.log(opt, function(err, log) { - if (!err) { - console.log(repoDir + ',' + log.latest.hash); - } - }) -} - -for (id in services) { - service = services[id]; - dirPath = __dirname + '/sharelatex/'+service.name; - if (fs.existsSync(dirPath)) { - print_latest(dirPath); - } -} diff --git a/server-ce/git-revision.sh b/server-ce/git-revision.sh new file mode 100755 index 0000000000..e26f75bfd4 --- /dev/null +++ b/server-ce/git-revision.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +for gitDir in $(find "$PWD" -name .git); do + echo -n "$(dirname ${gitDir})," + git --git-dir="$gitDir" rev-parse HEAD +done From 6a5f1588cc4e0ba811d5563a120424159682857b Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 28 Jan 2020 07:16:23 +0100 Subject: [PATCH 437/525] Set CRYPTO_RANDOM as environment variable at startup time (#134) --- server-ce/Dockerfile | 2 -- .../00_regen_sharelatex_secrets.sh | 22 ++++++++++++++----- server-ce/settings.coffee | 4 ++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index db3c98a793..48c14a26ff 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -84,8 +84,6 @@ RUN cd /var/www && ./git-revision.sh > revisions.txt # Set Environment Variables # -------------------------------- ENV WEB_API_USER "sharelatex" -# password is regenerated in init_scripts/00_regen_sharelatex_secrets.sh -ENV WEB_API_PASSWORD "password" ENV SHARELATEX_APP_NAME "Overleaf Community Edition" diff --git a/server-ce/init_scripts/00_regen_sharelatex_secrets.sh b/server-ce/init_scripts/00_regen_sharelatex_secrets.sh index 80fd293260..695ca66f78 100755 --- a/server-ce/init_scripts/00_regen_sharelatex_secrets.sh +++ b/server-ce/init_scripts/00_regen_sharelatex_secrets.sh @@ -1,7 +1,19 @@ #!/bin/sh -# Create random secret keys (twice, once for http auth pass, once for cookie secret). -CRYPTO_RANDOM=$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 -w 0 | rev | cut -b 2- | rev | tr -d '\n+/') -sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$CRYPTO_RANDOM/" /etc/sharelatex/settings.coffee -CRYPTO_RANDOM=$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 -w 0 | rev | cut -b 2- | rev | tr -d '\n+/') -sed -i "0,/CRYPTO_RANDOM/s/CRYPTO_RANDOM/$CRYPTO_RANDOM/" /etc/sharelatex/settings.coffee +# generate secrets and defines them as environment variables +# https://github.com/phusion/baseimage-docker#centrally-defining-your-own-environment-variables + +WEB_API_PASSWORD_FILE=/etc/container_environment/WEB_API_PASSWORD +CRYPTO_RANDOM_FILE=/etc/container_environment/CRYPTO_RANDOM + +if [ ! -f "$WEB_API_PASSWORD_FILE" ] || [ ! -f "$CRYPTO_RANDOM_FILE" ]; then + + echo "generating random secrets" + + SECRET=$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 -w 0 | rev | cut -b 2- | rev | tr -d '\n+/') + echo ${SECRET} > ${WEB_API_PASSWORD_FILE} + + SECRET=$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 -w 0 | rev | cut -b 2- | rev | tr -d '\n+/') + echo ${SECRET} > ${CRYPTO_RANDOM_FILE} +fi + diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 922fb32c04..32e2b3ba81 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -3,7 +3,7 @@ Path = require('path') # These credentials are used for authenticating api requests # between services that may need to go over public channels httpAuthUser = "sharelatex" -httpAuthPass = "CRYPTO_RANDOM" # Randomly generated for you +httpAuthPass = process.env["WEB_API_PASSWORD"] httpAuthUsers = {} httpAuthUsers[httpAuthUser] = httpAuthPass @@ -162,7 +162,7 @@ settings = # If provided, a sessionSecret is used to sign cookies so that they cannot be # spoofed. This is recommended. security: - sessionSecret: process.env["SHARELATEX_SESSION_SECRET"] or "CRYPTO_RANDOM" # This was randomly generated for you + sessionSecret: process.env["SHARELATEX_SESSION_SECRET"] or process.env["CRYPTO_RANDOM"] # These credentials are used for authenticating api requests # between services that may need to go over public channels From 16ca8f25c45f1c5f6f2241c2f47c15356f4e8f2c Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 29 Jan 2020 12:14:32 +0100 Subject: [PATCH 438/525] [misc] narrow down the rw accessible directories for the run user (#119) --- server-ce/Dockerfile | 7 +------ server-ce/init_scripts/00_make_sharelatex_data_dirs.sh | 2 -- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 48c14a26ff..f00b6da4d1 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -26,7 +26,7 @@ ADD ${baseDir}/git-revision.sh /var/www/git-revision.sh RUN cd /var/www && npm install -# Replace overleaf/config/services.js with the list of available +# Replace overleaf/config/services.js with the list of available # services in Overleaf Community Edition # -------------------------------------------------------------- ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js @@ -49,11 +49,6 @@ RUN bash -c 'cd /var/www/sharelatex && source ./bin/compile-services' RUN ln -s /var/www/sharelatex/clsi/bin/synctex /opt/synctex -# Change application ownership to www-data -# ---------------------------------------- -RUN chown -R www-data:www-data /var/www/sharelatex; - - # Copy runit service startup scripts to its location # -------------------------------------------------- ADD ${baseDir}/runit /etc/service diff --git a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh index 7857b984fb..6085a087da 100755 --- a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh +++ b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh @@ -26,8 +26,6 @@ chown www-data:www-data /var/lib/sharelatex/tmp/uploads mkdir -p /var/lib/sharelatex/tmp/dumpFolder chown www-data:www-data /var/lib/sharelatex/tmp/dumpFolder -chown www-data:www-data /var/www/ - if [ ! -e "/var/lib/sharelatex/data/db.sqlite" ]; then touch /var/lib/sharelatex/data/db.sqlite fi From 45561cde0e8ac83910af64f6ee0868f6800ad1b3 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 6 Feb 2020 11:19:15 +0100 Subject: [PATCH 439/525] Removed node6 and updated modules to Node 10 (#135) --- server-ce/Dockerfile-base | 9 --------- server-ce/runit/filestore-sharelatex/run | 2 +- server-ce/runit/real-time-sharelatex/run | 2 +- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index 2cff8a830f..14b9550ed1 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -28,15 +28,6 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | sudo bash - RUN apt-get install -y nodejs RUN npm install -g grunt-cli - -# Install Node6 (required by some services) -# ----------------------------------------- -RUN wget https://nodejs.org/dist/v6.17.1/node-v6.17.1-linux-x64.tar.gz && \ - mkdir -p /opt/nodejs && tar -xzf node-v6.17.1-linux-x64.tar.gz -C /opt/nodejs/ && \ - cd /opt/nodejs && mv node-v6.17.1-linux-x64 6.17.1 && \ - ln -s /opt/nodejs/6.17.1/bin/node /usr/bin/node6 - - # Install TexLive # --------------- RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz && \ diff --git a/server-ce/runit/filestore-sharelatex/run b/server-ce/runit/filestore-sharelatex/run index 1ba126dda0..4237a38793 100755 --- a/server-ce/runit/filestore-sharelatex/run +++ b/server-ce/runit/filestore-sharelatex/run @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node6 /var/www/sharelatex/filestore/app.js >> /var/log/sharelatex/filestore.log 2>&1 +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/filestore/app.js >> /var/log/sharelatex/filestore.log 2>&1 diff --git a/server-ce/runit/real-time-sharelatex/run b/server-ce/runit/real-time-sharelatex/run index 1d00837def..ad005b624c 100755 --- a/server-ce/runit/real-time-sharelatex/run +++ b/server-ce/runit/real-time-sharelatex/run @@ -1,3 +1,3 @@ #!/bin/bash export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee -exec /sbin/setuser www-data /usr/bin/node6 /var/www/sharelatex/real-time/app.js >> /var/log/sharelatex/real-time.log 2>&1 +exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/real-time/app.js >> /var/log/sharelatex/real-time.log 2>&1 From 6dc57fafcc37a735440fabe78bf7836c6658555c Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Mon, 10 Feb 2020 12:08:54 +0100 Subject: [PATCH 440/525] Fixed mailing list link in README --- server-ce/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index f6500481b8..776088abe4 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -8,9 +8,9 @@

From 6f46b2c1450f7bf3e4313d1058c8cd301468eea7 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Thu, 13 Feb 2020 11:56:03 +0100 Subject: [PATCH 441/525] [settings] produce a consistent redis config for every service (#124) Signed-off-by: Jakob Ackermann --- server-ce/settings.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 32e2b3ba81..9d6b31206c 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -81,6 +81,9 @@ settings = lock: redisConfig history: redisConfig websessions: redisConfig + api: redisConfig + pubsub: redisConfig + project_history: redisConfig # The compile server (the clsi) uses a SQL database to cache files and # meta-data. sqllite is the default, and the load is low enough that this will From 991cb29d0b0b8f4ba62ca3db8bca5f6450272c6c Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Thu, 13 Feb 2020 11:59:20 +0100 Subject: [PATCH 442/525] [nginx] simplify the root specification for sendfile (#121) Signed-off-by: Jakob Ackermann --- server-ce/nginx/sharelatex.conf | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/server-ce/nginx/sharelatex.conf b/server-ce/nginx/sharelatex.conf index cf63f4c5c4..3a10a999f0 100644 --- a/server-ce/nginx/sharelatex.conf +++ b/server-ce/nginx/sharelatex.conf @@ -2,7 +2,7 @@ server { listen 80; server_name _; # Catch all, see http://nginx.org/en/docs/http/server_names.html - set $static_path /var/www/sharelatex/web/public; + root /var/www/sharelatex/web/public/; location / { proxy_pass http://127.0.0.1:3000; @@ -14,7 +14,7 @@ server { proxy_read_timeout 3m; proxy_send_timeout 3m; } - + location /socket.io { proxy_pass http://127.0.0.1:3026; proxy_http_version 1.1; @@ -29,16 +29,13 @@ server { location /stylesheets { expires 1y; - root $static_path/; } location /minjs { expires 1y; - root $static_path/; } location /img { expires 1y; - root $static_path/; } } From ac82600b74ff181c6a9f8948c9b561be23311d53 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Thu, 13 Feb 2020 12:00:03 +0100 Subject: [PATCH 443/525] [misc] minimize base image (#120) * [docker] drop sudo Signed-off-by: Jakob Ackermann * [docker] install qpdf in a single stage Signed-off-by: Jakob Ackermann * [docker] install texlive and additional tlmgr packages in a single stage Signed-off-by: Jakob Ackermann * [docker] drop the apt package lists Signed-off-by: Jakob Ackermann * [docker] pull the package lists only once move the installation of nodejs into the dependencies install section Signed-off-by: Jakob Ackermann * [docker] delete the default nginx configuration files immediately Signed-off-by: Jakob Ackermann * [docker] skip the downloading and storage of unused texlive artifacts Signed-off-by: Jakob Ackermann * [docker] drop the npm download cache Signed-off-by: Jakob Ackermann * [docker] apply review feedback - install qpdf as ubuntu package - add a comment on the nginx config removal - add back and update a note on changing the texlive mirror --- server-ce/Dockerfile | 1 - server-ce/Dockerfile-base | 78 ++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index f00b6da4d1..c6e16aec97 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -56,7 +56,6 @@ ADD ${baseDir}/runit /etc/service # Configure nginx # --------------- -RUN rm /etc/nginx/sites-enabled/default ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index 14b9550ed1..9f1ef5b913 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -9,47 +9,59 @@ ENV baseDir . # Install dependencies # -------------------- -RUN apt-get update -RUN apt-get install -y sudo -RUN apt-get install -y build-essential wget net-tools unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-nr aspell-ns aspell-pa aspell-pl aspell-pt aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu +RUN apt-get update \ +&& apt-get install -y \ + build-essential wget net-tools unzip time imagemagick optipng strace nginx git python zlib1g-dev libpcre3-dev \ + qpdf \ + aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-nr aspell-ns aspell-pa aspell-pl aspell-pt aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu \ + \ +# install Node.JS 10 +&& curl -sSL https://deb.nodesource.com/setup_10.x | bash - \ +&& apt-get install -y nodejs \ + \ +&& rm -rf \ +# We are adding a custom nginx config in the main Dockerfile. + /etc/nginx/nginx.conf \ + /etc/nginx/sites-enabled/default \ + /var/lib/apt/lists/* - -# Install qpdf +# Install Grunt # ------------ -WORKDIR /opt -RUN wget https://s3.amazonaws.com/sharelatex-random-files/qpdf-6.0.0.tar.gz && tar xzf qpdf-6.0.0.tar.gz -WORKDIR /opt/qpdf-6.0.0 -RUN ./configure && make && make install && ldconfig - - -# Install Node -# ------------ -RUN curl -sL https://deb.nodesource.com/setup_10.x | sudo bash - -RUN apt-get install -y nodejs -RUN npm install -g grunt-cli +RUN npm install -g \ + grunt-cli \ +&& rm -rf /root/.npm # Install TexLive # --------------- -RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz && \ - mkdir /install-tl-unx && \ - tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 -RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile && \ - /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile - # CTAN mirrors occasionally fail, in that case install TexLive against an # specific server, for example http://ctan.crest.fr -# RUN wget http://ctan.crest.fr/tex-archive/systems/texlive/tlnet/install-tl-unx.tar.gz && \ -# mkdir /install-tl-unx && \ -# tar -xvf install-tl-unx.tar.gz -C /install-tl-unx --strip-components=1 -# RUN echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile && \ -# /install-tl-unx/install-tl -profile /install-tl-unx/texlive.profile \ -# -repository http://ctan.crest.fr/tex-archive/systems/texlive/tlnet/ +# +# # docker build \ +# --build-arg TEXLIVE_MIRROR=http://ctan.crest.fr/tex-archive/systems/texlive/tlnet \ +# -f Dockerfile-base -t sharelatex/sharelatex-base . +ARG TEXLIVE_MIRROR=http://mirror.ctan.org/systems/texlive/tlnet -RUN rm -r /install-tl-unx; \ - rm install-tl-unx.tar.gz -ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/2019/bin/x86_64-linux/ -RUN tlmgr install latexmk -RUN tlmgr install texcount +ENV PATH "${PATH}:/usr/local/texlive/2019/bin/x86_64-linux" + +RUN mkdir /install-tl-unx \ +&& curl -sSL \ + ${TEXLIVE_MIRROR}/install-tl-unx.tar.gz \ + | tar -xzC /install-tl-unx --strip-components=1 \ + \ +&& echo "tlpdbopt_autobackup 0" >> /install-tl-unx/texlive.profile \ +&& echo "tlpdbopt_install_docfiles 0" >> /install-tl-unx/texlive.profile \ +&& echo "tlpdbopt_install_srcfiles 0" >> /install-tl-unx/texlive.profile \ +&& echo "selected_scheme scheme-basic" >> /install-tl-unx/texlive.profile \ + \ +&& /install-tl-unx/install-tl \ + -profile /install-tl-unx/texlive.profile \ + -repository ${TEXLIVE_MIRROR} \ + \ +&& tlmgr install --repository ${TEXLIVE_MIRROR} \ + latexmk \ + texcount \ + \ +&& rm -rf /install-tl-unx # Set up sharelatex user and home directory From 3170a27fb5872ff303fb88ca35e8c15d53b96c14 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Thu, 13 Feb 2020 13:33:56 +0100 Subject: [PATCH 444/525] [init] bail out in case the db access fails (#123) * [init] bail out in case the db access fails Signed-off-by: Jakob Ackermann * [misc] bail out in case any command in an init_script failed NOTE: sh does not support `-o pipefail`. Signed-off-by: Jakob Ackermann --- server-ce/init_scripts/00_make_sharelatex_data_dirs.sh | 2 ++ server-ce/init_scripts/00_regen_sharelatex_secrets.sh | 3 ++- server-ce/init_scripts/00_set_docker_host_ipaddress.sh | 6 ++++-- server-ce/init_scripts/98_check_db_access.sh | 2 ++ server-ce/init_scripts/99_migrate.sh | 2 ++ 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh index 6085a087da..0d7c643733 100755 --- a/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh +++ b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh @@ -1,4 +1,6 @@ #!/bin/sh +set -e + mkdir -p /var/lib/sharelatex/data chown www-data:www-data /var/lib/sharelatex/data diff --git a/server-ce/init_scripts/00_regen_sharelatex_secrets.sh b/server-ce/init_scripts/00_regen_sharelatex_secrets.sh index 695ca66f78..365be0869f 100755 --- a/server-ce/init_scripts/00_regen_sharelatex_secrets.sh +++ b/server-ce/init_scripts/00_regen_sharelatex_secrets.sh @@ -1,4 +1,5 @@ -#!/bin/sh +#!/bin/bash +set -e -o pipefail # generate secrets and defines them as environment variables # https://github.com/phusion/baseimage-docker#centrally-defining-your-own-environment-variables diff --git a/server-ce/init_scripts/00_set_docker_host_ipaddress.sh b/server-ce/init_scripts/00_set_docker_host_ipaddress.sh index afd31b69a1..0587a9b222 100755 --- a/server-ce/init_scripts/00_set_docker_host_ipaddress.sh +++ b/server-ce/init_scripts/00_set_docker_host_ipaddress.sh @@ -1,3 +1,5 @@ -#!/bin/sh +#!/bin/bash +set -e -o pipefail + # See the bottom of http://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach -echo "`route -n | awk '/UG[ \t]/{print $2}'` dockerhost" >> /etc/hosts \ No newline at end of file +echo "`route -n | awk '/UG[ \t]/{print $2}'` dockerhost" >> /etc/hosts diff --git a/server-ce/init_scripts/98_check_db_access.sh b/server-ce/init_scripts/98_check_db_access.sh index a90adba84f..f8507f582f 100755 --- a/server-ce/init_scripts/98_check_db_access.sh +++ b/server-ce/init_scripts/98_check_db_access.sh @@ -1,4 +1,6 @@ #!/bin/sh +set -e + echo "Checking can connect to mongo and redis" cd /var/www/sharelatex && grunt check:redis cd /var/www/sharelatex && grunt check:mongo diff --git a/server-ce/init_scripts/99_migrate.sh b/server-ce/init_scripts/99_migrate.sh index d062496581..f880fa816f 100755 --- a/server-ce/init_scripts/99_migrate.sh +++ b/server-ce/init_scripts/99_migrate.sh @@ -1,4 +1,6 @@ #!/bin/sh +set -e + which node which grunt ls -al /var/www/sharelatex/migrations From b715f16a3b6fa51f82d04b04cbd449d7752f7e4c Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Thu, 13 Feb 2020 16:38:58 +0100 Subject: [PATCH 445/525] [misc] minimize the main stage (#122) - cleanup git history - do not install not needed npm packages - The Gruntfile was removed in REF: 27dd97ecc59954a5ad2d8b140f7d5a83073ca2c8 - The simple-git package is not used since REF: df2d46df829872ccd6d9018dac3f2e6d9b9ae8d0 - cleanup npm cache - cleanup node-gyp build cache - cleanup /tmp - move copying of the settings defaults after the installation Signed-off-by: Jakob Ackermann --- server-ce/Dockerfile | 59 +++++++++++++++++++++++------------------- server-ce/package.json | 13 ---------- 2 files changed, 32 insertions(+), 40 deletions(-) delete mode 100644 server-ce/package.json diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index c6e16aec97..3d79194f14 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -4,12 +4,6 @@ FROM sharelatex/sharelatex-base:latest -ENV baseDir . - - -# Install app settings files -# -------------------------- -ADD ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee @@ -19,30 +13,43 @@ RUN git clone https://github.com/overleaf/overleaf.git \ --depth 1 /var/www/sharelatex -# Install dependencies needed to run configuration scripts -# -------------------------------------------------------- -ADD ${baseDir}/package.json /var/www/package.json +# Copy build dependencies +# ----------------------- ADD ${baseDir}/git-revision.sh /var/www/git-revision.sh -RUN cd /var/www && npm install - - -# Replace overleaf/config/services.js with the list of available -# services in Overleaf Community Edition -# -------------------------------------------------------------- ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js # Checkout services # ----------------- -RUN cd /var/www/sharelatex && \ - npm install && grunt install; - - -# install and compile services +RUN cd /var/www/sharelatex \ +&& npm install \ +&& grunt install \ + \ +# Cleanup not needed artifacts # ---------------------------- -RUN bash -c 'cd /var/www/sharelatex && source ./bin/install-services' -RUN bash -c 'cd /var/www/sharelatex && source ./bin/compile-services' +&& rm -rf /root/.cache /root/.npm $(find /tmp/ -mindepth 1 -maxdepth 1) \ +# Stores the version installed for each service +# --------------------------------------------- +&& cd /var/www \ +&& ./git-revision.sh > revisions.txt \ + \ +# Cleanup the git history +# ------------------- +&& rm -rf $(find /var/www/sharelatex -name .git) +# Install npm dependencies +# ------------------------ +RUN cd /var/www/sharelatex \ +&& bash ./bin/install-services \ + \ +# Cleanup not needed artifacts +# ---------------------------- +&& rm -rf /root/.cache /root/.npm $(find /tmp/ -mindepth 1 -maxdepth 1) + +# Compile CoffeeScript +# -------------------- +RUN cd /var/www/sharelatex \ +&& bash ./bin/compile-services # Links CLSI sycntex to its default location # ------------------------------------------ @@ -69,11 +76,9 @@ ADD ${baseDir}/logrotate/sharelatex /etc/logrotate.d/sharelatex # -------------------------------------------------- COPY ${baseDir}/init_scripts/ /etc/my_init.d/ - -# Stores the version installed for each service -# --------------------------------------------- -RUN cd /var/www && ./git-revision.sh > revisions.txt - +# Copy app settings files +# ----------------------- +COPY ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee # Set Environment Variables # -------------------------------- diff --git a/server-ce/package.json b/server-ce/package.json deleted file mode 100644 index 9a8f125940..0000000000 --- a/server-ce/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "none", - "author": "none", - "description": "none", - "dependencies": { - "grunt": "^0.4.5", - "grunt-contrib-rename": "0.0.3", - "grunt-docker-io": "^0.7.0", - "grunt-github-api": "^0.2.3", - "simple-git": "1.85.0", - "underscore": "^1.8.3" - } -} From 276281e7e43abdf2492e5e176851501300ecb3a5 Mon Sep 17 00:00:00 2001 From: mserranom Date: Mon, 17 Feb 2020 13:56:49 +0100 Subject: [PATCH 446/525] moved files from docker-image imported repo to root --- server-ce/{docker-image => }/.dockerignore | 0 server-ce/{docker-image => }/.editorconfig | 0 server-ce/{docker-image => }/Dockerfile | 0 server-ce/{docker-image => }/Dockerfile-base | 0 server-ce/{docker-image => }/Makefile | 0 server-ce/{docker-image => }/git-revision.sh | 0 server-ce/{docker-image => }/hotfix/2.0.1/Dockerfile | 0 .../hotfix/2.0.1/create_and_destroy_users.patch | 0 .../{docker-image => }/hotfix/2.0.1/disable_project_history.patch | 0 server-ce/{docker-image => }/hotfix/2.0.2/1-anon-upload.patch | 0 .../{docker-image => }/hotfix/2.0.2/2-read-only-access.patch | 0 server-ce/{docker-image => }/hotfix/2.0.2/3-url-linking-1.patch | 0 server-ce/{docker-image => }/hotfix/2.0.2/4-url-linking-2.patch | 0 .../{docker-image => }/hotfix/2.0.2/5-disable-analytics-1.patch | 0 .../{docker-image => }/hotfix/2.0.2/6-disable-analytics-2.patch | 0 server-ce/{docker-image => }/hotfix/2.0.2/Dockerfile | 0 server-ce/{docker-image => }/hotfix/2.1.1/Dockerfile | 0 .../{docker-image => }/hotfix/2.1.1/add-recaptcha-config.patch | 0 .../init_scripts/00_make_sharelatex_data_dirs.sh | 0 .../init_scripts/00_regen_sharelatex_secrets.sh | 0 .../init_scripts/00_set_docker_host_ipaddress.sh | 0 server-ce/{docker-image => }/init_scripts/98_check_db_access.sh | 0 server-ce/{docker-image => }/init_scripts/99_migrate.sh | 0 server-ce/{docker-image => }/logrotate/sharelatex | 0 server-ce/{docker-image => }/nginx/nginx.conf | 0 server-ce/{docker-image => }/nginx/sharelatex.conf | 0 server-ce/{docker-image => }/runit/chat-sharelatex/run | 0 server-ce/{docker-image => }/runit/clsi-sharelatex/run | 0 server-ce/{docker-image => }/runit/contacts-sharelatex/run | 0 server-ce/{docker-image => }/runit/docstore-sharelatex/run | 0 .../{docker-image => }/runit/document-updater-sharelatex/run | 0 server-ce/{docker-image => }/runit/filestore-sharelatex/run | 0 server-ce/{docker-image => }/runit/nginx/run | 0 server-ce/{docker-image => }/runit/notifications-sharelatex/run | 0 server-ce/{docker-image => }/runit/real-time-sharelatex/run | 0 server-ce/{docker-image => }/runit/spelling-sharelatex/run | 0 server-ce/{docker-image => }/runit/tags-sharelatex/run | 0 server-ce/{docker-image => }/runit/track-changes-sharelatex/run | 0 server-ce/{docker-image => }/runit/web-sharelatex/run | 0 server-ce/{docker-image => }/services.js | 0 server-ce/{docker-image => }/settings.coffee | 0 41 files changed, 0 insertions(+), 0 deletions(-) rename server-ce/{docker-image => }/.dockerignore (100%) rename server-ce/{docker-image => }/.editorconfig (100%) rename server-ce/{docker-image => }/Dockerfile (100%) rename server-ce/{docker-image => }/Dockerfile-base (100%) rename server-ce/{docker-image => }/Makefile (100%) rename server-ce/{docker-image => }/git-revision.sh (100%) rename server-ce/{docker-image => }/hotfix/2.0.1/Dockerfile (100%) rename server-ce/{docker-image => }/hotfix/2.0.1/create_and_destroy_users.patch (100%) rename server-ce/{docker-image => }/hotfix/2.0.1/disable_project_history.patch (100%) rename server-ce/{docker-image => }/hotfix/2.0.2/1-anon-upload.patch (100%) rename server-ce/{docker-image => }/hotfix/2.0.2/2-read-only-access.patch (100%) rename server-ce/{docker-image => }/hotfix/2.0.2/3-url-linking-1.patch (100%) rename server-ce/{docker-image => }/hotfix/2.0.2/4-url-linking-2.patch (100%) rename server-ce/{docker-image => }/hotfix/2.0.2/5-disable-analytics-1.patch (100%) rename server-ce/{docker-image => }/hotfix/2.0.2/6-disable-analytics-2.patch (100%) rename server-ce/{docker-image => }/hotfix/2.0.2/Dockerfile (100%) rename server-ce/{docker-image => }/hotfix/2.1.1/Dockerfile (100%) rename server-ce/{docker-image => }/hotfix/2.1.1/add-recaptcha-config.patch (100%) rename server-ce/{docker-image => }/init_scripts/00_make_sharelatex_data_dirs.sh (100%) rename server-ce/{docker-image => }/init_scripts/00_regen_sharelatex_secrets.sh (100%) rename server-ce/{docker-image => }/init_scripts/00_set_docker_host_ipaddress.sh (100%) rename server-ce/{docker-image => }/init_scripts/98_check_db_access.sh (100%) rename server-ce/{docker-image => }/init_scripts/99_migrate.sh (100%) rename server-ce/{docker-image => }/logrotate/sharelatex (100%) rename server-ce/{docker-image => }/nginx/nginx.conf (100%) rename server-ce/{docker-image => }/nginx/sharelatex.conf (100%) rename server-ce/{docker-image => }/runit/chat-sharelatex/run (100%) rename server-ce/{docker-image => }/runit/clsi-sharelatex/run (100%) rename server-ce/{docker-image => }/runit/contacts-sharelatex/run (100%) rename server-ce/{docker-image => }/runit/docstore-sharelatex/run (100%) rename server-ce/{docker-image => }/runit/document-updater-sharelatex/run (100%) rename server-ce/{docker-image => }/runit/filestore-sharelatex/run (100%) rename server-ce/{docker-image => }/runit/nginx/run (100%) rename server-ce/{docker-image => }/runit/notifications-sharelatex/run (100%) rename server-ce/{docker-image => }/runit/real-time-sharelatex/run (100%) rename server-ce/{docker-image => }/runit/spelling-sharelatex/run (100%) rename server-ce/{docker-image => }/runit/tags-sharelatex/run (100%) rename server-ce/{docker-image => }/runit/track-changes-sharelatex/run (100%) rename server-ce/{docker-image => }/runit/web-sharelatex/run (100%) rename server-ce/{docker-image => }/services.js (100%) rename server-ce/{docker-image => }/settings.coffee (100%) diff --git a/server-ce/docker-image/.dockerignore b/server-ce/.dockerignore similarity index 100% rename from server-ce/docker-image/.dockerignore rename to server-ce/.dockerignore diff --git a/server-ce/docker-image/.editorconfig b/server-ce/.editorconfig similarity index 100% rename from server-ce/docker-image/.editorconfig rename to server-ce/.editorconfig diff --git a/server-ce/docker-image/Dockerfile b/server-ce/Dockerfile similarity index 100% rename from server-ce/docker-image/Dockerfile rename to server-ce/Dockerfile diff --git a/server-ce/docker-image/Dockerfile-base b/server-ce/Dockerfile-base similarity index 100% rename from server-ce/docker-image/Dockerfile-base rename to server-ce/Dockerfile-base diff --git a/server-ce/docker-image/Makefile b/server-ce/Makefile similarity index 100% rename from server-ce/docker-image/Makefile rename to server-ce/Makefile diff --git a/server-ce/docker-image/git-revision.sh b/server-ce/git-revision.sh similarity index 100% rename from server-ce/docker-image/git-revision.sh rename to server-ce/git-revision.sh diff --git a/server-ce/docker-image/hotfix/2.0.1/Dockerfile b/server-ce/hotfix/2.0.1/Dockerfile similarity index 100% rename from server-ce/docker-image/hotfix/2.0.1/Dockerfile rename to server-ce/hotfix/2.0.1/Dockerfile diff --git a/server-ce/docker-image/hotfix/2.0.1/create_and_destroy_users.patch b/server-ce/hotfix/2.0.1/create_and_destroy_users.patch similarity index 100% rename from server-ce/docker-image/hotfix/2.0.1/create_and_destroy_users.patch rename to server-ce/hotfix/2.0.1/create_and_destroy_users.patch diff --git a/server-ce/docker-image/hotfix/2.0.1/disable_project_history.patch b/server-ce/hotfix/2.0.1/disable_project_history.patch similarity index 100% rename from server-ce/docker-image/hotfix/2.0.1/disable_project_history.patch rename to server-ce/hotfix/2.0.1/disable_project_history.patch diff --git a/server-ce/docker-image/hotfix/2.0.2/1-anon-upload.patch b/server-ce/hotfix/2.0.2/1-anon-upload.patch similarity index 100% rename from server-ce/docker-image/hotfix/2.0.2/1-anon-upload.patch rename to server-ce/hotfix/2.0.2/1-anon-upload.patch diff --git a/server-ce/docker-image/hotfix/2.0.2/2-read-only-access.patch b/server-ce/hotfix/2.0.2/2-read-only-access.patch similarity index 100% rename from server-ce/docker-image/hotfix/2.0.2/2-read-only-access.patch rename to server-ce/hotfix/2.0.2/2-read-only-access.patch diff --git a/server-ce/docker-image/hotfix/2.0.2/3-url-linking-1.patch b/server-ce/hotfix/2.0.2/3-url-linking-1.patch similarity index 100% rename from server-ce/docker-image/hotfix/2.0.2/3-url-linking-1.patch rename to server-ce/hotfix/2.0.2/3-url-linking-1.patch diff --git a/server-ce/docker-image/hotfix/2.0.2/4-url-linking-2.patch b/server-ce/hotfix/2.0.2/4-url-linking-2.patch similarity index 100% rename from server-ce/docker-image/hotfix/2.0.2/4-url-linking-2.patch rename to server-ce/hotfix/2.0.2/4-url-linking-2.patch diff --git a/server-ce/docker-image/hotfix/2.0.2/5-disable-analytics-1.patch b/server-ce/hotfix/2.0.2/5-disable-analytics-1.patch similarity index 100% rename from server-ce/docker-image/hotfix/2.0.2/5-disable-analytics-1.patch rename to server-ce/hotfix/2.0.2/5-disable-analytics-1.patch diff --git a/server-ce/docker-image/hotfix/2.0.2/6-disable-analytics-2.patch b/server-ce/hotfix/2.0.2/6-disable-analytics-2.patch similarity index 100% rename from server-ce/docker-image/hotfix/2.0.2/6-disable-analytics-2.patch rename to server-ce/hotfix/2.0.2/6-disable-analytics-2.patch diff --git a/server-ce/docker-image/hotfix/2.0.2/Dockerfile b/server-ce/hotfix/2.0.2/Dockerfile similarity index 100% rename from server-ce/docker-image/hotfix/2.0.2/Dockerfile rename to server-ce/hotfix/2.0.2/Dockerfile diff --git a/server-ce/docker-image/hotfix/2.1.1/Dockerfile b/server-ce/hotfix/2.1.1/Dockerfile similarity index 100% rename from server-ce/docker-image/hotfix/2.1.1/Dockerfile rename to server-ce/hotfix/2.1.1/Dockerfile diff --git a/server-ce/docker-image/hotfix/2.1.1/add-recaptcha-config.patch b/server-ce/hotfix/2.1.1/add-recaptcha-config.patch similarity index 100% rename from server-ce/docker-image/hotfix/2.1.1/add-recaptcha-config.patch rename to server-ce/hotfix/2.1.1/add-recaptcha-config.patch diff --git a/server-ce/docker-image/init_scripts/00_make_sharelatex_data_dirs.sh b/server-ce/init_scripts/00_make_sharelatex_data_dirs.sh similarity index 100% rename from server-ce/docker-image/init_scripts/00_make_sharelatex_data_dirs.sh rename to server-ce/init_scripts/00_make_sharelatex_data_dirs.sh diff --git a/server-ce/docker-image/init_scripts/00_regen_sharelatex_secrets.sh b/server-ce/init_scripts/00_regen_sharelatex_secrets.sh similarity index 100% rename from server-ce/docker-image/init_scripts/00_regen_sharelatex_secrets.sh rename to server-ce/init_scripts/00_regen_sharelatex_secrets.sh diff --git a/server-ce/docker-image/init_scripts/00_set_docker_host_ipaddress.sh b/server-ce/init_scripts/00_set_docker_host_ipaddress.sh similarity index 100% rename from server-ce/docker-image/init_scripts/00_set_docker_host_ipaddress.sh rename to server-ce/init_scripts/00_set_docker_host_ipaddress.sh diff --git a/server-ce/docker-image/init_scripts/98_check_db_access.sh b/server-ce/init_scripts/98_check_db_access.sh similarity index 100% rename from server-ce/docker-image/init_scripts/98_check_db_access.sh rename to server-ce/init_scripts/98_check_db_access.sh diff --git a/server-ce/docker-image/init_scripts/99_migrate.sh b/server-ce/init_scripts/99_migrate.sh similarity index 100% rename from server-ce/docker-image/init_scripts/99_migrate.sh rename to server-ce/init_scripts/99_migrate.sh diff --git a/server-ce/docker-image/logrotate/sharelatex b/server-ce/logrotate/sharelatex similarity index 100% rename from server-ce/docker-image/logrotate/sharelatex rename to server-ce/logrotate/sharelatex diff --git a/server-ce/docker-image/nginx/nginx.conf b/server-ce/nginx/nginx.conf similarity index 100% rename from server-ce/docker-image/nginx/nginx.conf rename to server-ce/nginx/nginx.conf diff --git a/server-ce/docker-image/nginx/sharelatex.conf b/server-ce/nginx/sharelatex.conf similarity index 100% rename from server-ce/docker-image/nginx/sharelatex.conf rename to server-ce/nginx/sharelatex.conf diff --git a/server-ce/docker-image/runit/chat-sharelatex/run b/server-ce/runit/chat-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/chat-sharelatex/run rename to server-ce/runit/chat-sharelatex/run diff --git a/server-ce/docker-image/runit/clsi-sharelatex/run b/server-ce/runit/clsi-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/clsi-sharelatex/run rename to server-ce/runit/clsi-sharelatex/run diff --git a/server-ce/docker-image/runit/contacts-sharelatex/run b/server-ce/runit/contacts-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/contacts-sharelatex/run rename to server-ce/runit/contacts-sharelatex/run diff --git a/server-ce/docker-image/runit/docstore-sharelatex/run b/server-ce/runit/docstore-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/docstore-sharelatex/run rename to server-ce/runit/docstore-sharelatex/run diff --git a/server-ce/docker-image/runit/document-updater-sharelatex/run b/server-ce/runit/document-updater-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/document-updater-sharelatex/run rename to server-ce/runit/document-updater-sharelatex/run diff --git a/server-ce/docker-image/runit/filestore-sharelatex/run b/server-ce/runit/filestore-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/filestore-sharelatex/run rename to server-ce/runit/filestore-sharelatex/run diff --git a/server-ce/docker-image/runit/nginx/run b/server-ce/runit/nginx/run similarity index 100% rename from server-ce/docker-image/runit/nginx/run rename to server-ce/runit/nginx/run diff --git a/server-ce/docker-image/runit/notifications-sharelatex/run b/server-ce/runit/notifications-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/notifications-sharelatex/run rename to server-ce/runit/notifications-sharelatex/run diff --git a/server-ce/docker-image/runit/real-time-sharelatex/run b/server-ce/runit/real-time-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/real-time-sharelatex/run rename to server-ce/runit/real-time-sharelatex/run diff --git a/server-ce/docker-image/runit/spelling-sharelatex/run b/server-ce/runit/spelling-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/spelling-sharelatex/run rename to server-ce/runit/spelling-sharelatex/run diff --git a/server-ce/docker-image/runit/tags-sharelatex/run b/server-ce/runit/tags-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/tags-sharelatex/run rename to server-ce/runit/tags-sharelatex/run diff --git a/server-ce/docker-image/runit/track-changes-sharelatex/run b/server-ce/runit/track-changes-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/track-changes-sharelatex/run rename to server-ce/runit/track-changes-sharelatex/run diff --git a/server-ce/docker-image/runit/web-sharelatex/run b/server-ce/runit/web-sharelatex/run similarity index 100% rename from server-ce/docker-image/runit/web-sharelatex/run rename to server-ce/runit/web-sharelatex/run diff --git a/server-ce/docker-image/services.js b/server-ce/services.js similarity index 100% rename from server-ce/docker-image/services.js rename to server-ce/services.js diff --git a/server-ce/docker-image/settings.coffee b/server-ce/settings.coffee similarity index 100% rename from server-ce/docker-image/settings.coffee rename to server-ce/settings.coffee From c3d0ba2aa6dcfbd266a7d35b174f15ce8a402b6b Mon Sep 17 00:00:00 2001 From: mserranom Date: Mon, 17 Feb 2020 13:57:53 +0100 Subject: [PATCH 447/525] merged README.md --- server-ce/README.md | 26 +++++++++++++++++-- server-ce/docker-image/README.md | 43 -------------------------------- 2 files changed, 24 insertions(+), 45 deletions(-) delete mode 100644 server-ce/docker-image/README.md diff --git a/server-ce/README.md b/server-ce/README.md index 776088abe4..8b1463d23c 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -8,9 +8,9 @@

Key FeaturesWiki • - Server Pro • + Server ProContributing • - Mailing List • + Mailing ListAuthorsLicense

@@ -54,6 +54,28 @@ This repository does not contain any code. It acts a wrapper and toolkit for man | **[tags](https://github.com/overleaf/tags)** | The backend API for managing project tags (folders). | | **[spelling](https://github.com/overleaf/spelling)** | An API for running server-side spelling checking on Overleaf documents. | +## Overleaf Docker Image + +This repo contains two dockerfiles, `Dockerfile-base`, which builds the +`sharelatex/sharelatex-base` image, and `Dockerfile` which builds the +`sharelatex/sharelatex` (or "community") image. + +The Base image generally contains the basic dependencies like `wget` and +`aspell`, plus `texlive`. We split this out because it's a pretty heavy set of +dependencies, and it's nice to not have to rebuild all of that every time. + +The `sharelatex/sharelatex` image extends the base image and adds the actual Overleaf code +and services. + +Use `make build-base` and `make build-community` to build these images. + +We use the [Phusion base-image](https://github.com/phusion/baseimage-docker) +(which is extended by our `base` image) to provide us with a VM-like container +in which to run the Overleaf services. Baseimage uses the `runit` service +manager to manage services, and we add our init-scripts from the `./runit` +folder. + + ## Contributing Please see the [CONTRIBUTING](https://github.com/overleaf/overleaf/blob/master/CONTRIBUTING.md) file for information on contributing to the development of Overleaf. See [our wiki](https://github.com/overleaf/overleaf/wiki/Developer-Guidelines) for information on setting up a development environment and how to recompile and run Overleaf after modifications. diff --git a/server-ce/docker-image/README.md b/server-ce/docker-image/README.md deleted file mode 100644 index c1894afce0..0000000000 --- a/server-ce/docker-image/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Overleaf Docker Image - -This is the source for building the Overleaf community-edition docker image. - - -## End-User Install -Please see the [offical wiki for install -guides](https://github.com/overleaf/overleaf/wiki) - - -## Development - -This repo contains two dockerfiles, `Dockerfile-base`, which builds the -`sharelatex/sharelatex-base` image, and `Dockerfile` which builds the -`sharelatex/sharelatex` (or "community") image. - -The Base image generally contains the basic dependencies like `wget` and -`aspell`, plus `texlive`. We split this out because it's a pretty heavy set of -dependencies, and it's nice to not have to rebuild all of that every time. - -The `sharelatex/sharelatex` image extends the base image and adds the actual Overleaf code -and services. - -Use `make build-base` and `make build-community` to build these images. - - -### How the Overleaf code gets here - -This repo uses [the public Overleaf -repository](https://github.com/overleaf/overleaf), which used to be the main -public source for the Overleaf system. - -That repo is cloned down into the docker image, and a script then installs all -the services. - - -### How services run inside the container - -We use the [Phusion base-image](https://github.com/phusion/baseimage-docker) -(which is extended by our `base` image) to provide us with a VM-like container -in which to run the Overleaf services. Baseimage uses the `runit` service -manager to manage services, and we add our init-scripts from the `./runit` -folder. From 1fe5394ca5cb0146a8ae2b76fd020fc0faa9fc7f Mon Sep 17 00:00:00 2001 From: mserranom Date: Mon, 17 Feb 2020 13:58:48 +0100 Subject: [PATCH 448/525] merged .gitignore --- server-ce/.gitignore | 7 +++++-- server-ce/docker-image/.gitignore | 4 ---- 2 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 server-ce/docker-image/.gitignore diff --git a/server-ce/.gitignore b/server-ce/.gitignore index abf5d3ff2f..008b9d7cae 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -1,6 +1,9 @@ /config config-local -node_modules + +node_modules/ +api-data +versions/ web document-updater @@ -20,4 +23,4 @@ tmp db.sqlite .DS_Store -.vagrant +.vagrant \ No newline at end of file diff --git a/server-ce/docker-image/.gitignore b/server-ce/docker-image/.gitignore deleted file mode 100644 index 877b99b865..0000000000 --- a/server-ce/docker-image/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.DS_Store -node_modules/ -api-data -versions/ From ead0f219652567f746960c285c56331218e9c268 Mon Sep 17 00:00:00 2001 From: mserranom Date: Mon, 17 Feb 2020 14:00:29 +0100 Subject: [PATCH 449/525] merged services.js --- server-ce/config/services.js | 52 ------------------------------------ server-ce/services.js | 10 +++---- 2 files changed, 5 insertions(+), 57 deletions(-) delete mode 100644 server-ce/config/services.js diff --git a/server-ce/config/services.js b/server-ce/config/services.js deleted file mode 100644 index 2072964383..0000000000 --- a/server-ce/config/services.js +++ /dev/null @@ -1,52 +0,0 @@ -module.exports = - -[{ - name: "web", - repo: "https://github.com/sharelatex/web-sharelatex.git", - version: "master" -}, { - name: "real-time", - repo: "https://github.com/sharelatex/real-time-sharelatex.git", - version: "master" -}, { - name: "document-updater", - repo: "https://github.com/sharelatex/document-updater-sharelatex.git", - version: "master" -}, { - name: "clsi", - repo: "https://github.com/sharelatex/clsi-sharelatex.git", - version: "master" -}, { - name: "filestore", - repo: "https://github.com/sharelatex/filestore-sharelatex.git", - version: "master" -}, { - name: "track-changes", - repo: "https://github.com/sharelatex/track-changes-sharelatex.git", - version: "master" -}, { - name: "docstore", - repo: "https://github.com/sharelatex/docstore-sharelatex.git", - version: "master" -}, { - name: "chat", - repo: "https://github.com/sharelatex/chat-sharelatex.git", - version: "master" -}, { - name: "tags", - repo: "https://github.com/sharelatex/tags-sharelatex.git", - version: "master" -}, { - name: "spelling", - repo: "https://github.com/sharelatex/spelling-sharelatex.git", - version: "master" -}, { - name: "contacts", - repo: "https://github.com/sharelatex/contacts-sharelatex.git", - version: "master" -}, { - name: "notifications", - repo: "https://github.com/sharelatex/notifications-sharelatex.git", - version: "master" -} -] diff --git a/server-ce/services.js b/server-ce/services.js index 941dd23a0e..654148bc52 100644 --- a/server-ce/services.js +++ b/server-ce/services.js @@ -1,4 +1,4 @@ -module.exports = +module.exports = [{ name: "web", @@ -43,9 +43,9 @@ module.exports = }, { name: "contacts", repo: "https://github.com/sharelatex/contacts-sharelatex.git", - version: "sk-update-mongojs" + version: "master" }, { - name: "notifications", - repo: "https://github.com/sharelatex/notifications-sharelatex.git", - version: "master" + name: "notifications", + repo: "https://github.com/sharelatex/notifications-sharelatex.git", + version: "master" }] From fa13f4f079e60440d303426dae729dc1eaf1cb7c Mon Sep 17 00:00:00 2001 From: mserranom Date: Mon, 17 Feb 2020 14:58:47 +0100 Subject: [PATCH 450/525] Updated dockerfile and build script with monorepo changes --- server-ce/Dockerfile | 14 ++++++++++---- server-ce/bin/compile-services | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 3d79194f14..c4478b6b29 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -7,10 +7,16 @@ FROM sharelatex/sharelatex-base:latest ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee -# Checkout Overleaf Community Edition repo -# ---------------------------------------- -RUN git clone https://github.com/overleaf/overleaf.git \ - --depth 1 /var/www/sharelatex +# Add required source files +# ------------------------- +ADD ${baseDir}/bin /var/www/sharelatex/bin +ADD ${baseDir}/doc /var/www/sharelatex/doc +ADD ${baseDir}/migrations /var/www/sharelatex/migrations +ADD ${baseDir}/tasks /var/www/sharelatex/tasks +ADD ${baseDir}/Gruntfile.coffee /var/www/sharelatex/Gruntfile.coffee +ADD ${baseDir}/package.json /var/www/sharelatex/package.json +ADD ${baseDir}/npm-shrinkwrap.json /var/www/sharelatex/npm-shrinkwrap.json +ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js # Copy build dependencies diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index fc3bb8ea38..017baa8fbc 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -12,7 +12,7 @@ grep 'name:' config/services.js | \ web) npm run webpack:production ;; - chat|filestore|notifications) + chat|filestore|notifications|tags) echo "$service doesn't require a compilation" ;; *) From b433dffc69dd453e9f8313774eef4f3ee45cabca Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 20 Feb 2020 15:09:00 +0000 Subject: [PATCH 451/525] Comment out the docker socket mount And add a note for server-pro users to un-comment the line if they want to use sibling containers. --- server-ce/docker-compose.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 8158070f66..a268291a7e 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -19,7 +19,11 @@ services: - redis volumes: - ~/sharelatex_data:/var/lib/sharelatex - - /var/run/docker.sock:/var/run/docker.sock + ######################################################################## + #### Server Pro: Un-comment the following line to mount the docker #### + #### socket, required for Sibling Containers to work #### + ######################################################################## + # - /var/run/docker.sock:/var/run/docker.sock environment: SHARELATEX_APP_NAME: Overleaf Community Edition From f7ac10cc973feaf119f306b233763357ac672b74 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Mon, 9 Mar 2020 13:15:40 +0100 Subject: [PATCH 452/525] Added 'currentImageName' setting plus migration (#701) --- .../migrations/11_set_project_image_name.js | 23 +++++++++++++++++++ server-ce/settings.coffee | 2 ++ 2 files changed, 25 insertions(+) create mode 100644 server-ce/migrations/11_set_project_image_name.js diff --git a/server-ce/migrations/11_set_project_image_name.js b/server-ce/migrations/11_set_project_image_name.js new file mode 100644 index 0000000000..17c06fd6fc --- /dev/null +++ b/server-ce/migrations/11_set_project_image_name.js @@ -0,0 +1,23 @@ +const Settings = require('settings-sharelatex') +const mongojs = require('mongojs') +const db = mongojs(Settings.mongo.url, ['projects']) + +exports.migrate = (client, done) => { + console.log(`>> Setting 'imageName' in projects`) + + if (!Settings.currentImageName) { + console.log(`>> 'currentImageName' is not defined, no projects updated`) + return done() + } + + console.log(`>> Setting 'imageName' = ${Settings.currentImageName}`) + + db.projects.update( + { imageName: { $exists: false } }, + { $set: { imageName: Settings.currentImageName } }, + { multi: true }, + done + ) +} + +exports.rollback = (client, done) => done() diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 9d6b31206c..7cfc234011 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -194,6 +194,8 @@ settings = www: {lngCode:process.env["SHARELATEX_SITE_LANGUAGE"] or "en", url: siteUrl} defaultLng: process.env["SHARELATEX_SITE_LANGUAGE"] or "en" + currentImageName: process.env["TEX_LIVE_DOCKER_IMAGE"] + apis: web: url: "http://localhost:3000" From 11e7f7d60efc5c733ccacfff294f15b78090f835 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 7 Apr 2020 16:17:51 +0200 Subject: [PATCH 453/525] Fixed compile scripts for non-coffee modules (#717) --- server-ce/bin/compile-services | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index 017baa8fbc..f20858f812 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -12,11 +12,11 @@ grep 'name:' config/services.js | \ web) npm run webpack:production ;; - chat|filestore|notifications|tags) - echo "$service doesn't require a compilation" + real-time|document-updater) + npm run compile:all ;; *) - npm run compile:all + echo "$service doesn't require a compilation" ;; esac popd From 27cd838c2a14a26f3ef4be822718225a0cf78627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Alby?= Date: Tue, 14 Apr 2020 12:08:59 +0200 Subject: [PATCH 454/525] add allowedImageNames setting from ENV vars (#718) Uses `ALL_TEX_LIVE_DOCKER_IMAGES` (required) and `ALL_TEX_LIVE_DOCKER_IMAGE_NAMES` (optional) to add the `allowedImageNames` setting, allowing users to change a project's Tex Live version. --- server-ce/settings.coffee | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 7cfc234011..9912fd1ea6 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -537,6 +537,18 @@ if process.env["SHARELATEX_ELASTICSEARCH_URL"]? settings.references.elasticsearch = host: process.env["SHARELATEX_ELASTICSEARCH_URL"] +# TeX Live Images +# ----------- +if process.env["ALL_TEX_LIVE_DOCKER_IMAGES"]? + allTexLiveDockerImages = process.env["ALL_TEX_LIVE_DOCKER_IMAGES"].split(',') +if process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"]? + allTexLiveDockerImageNames = process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"].split(',') +if allTexLiveDockerImages? + settings.allowedImageNames = [] + for fullImageName, index in allTexLiveDockerImages + imageName = Path.basename(fullImageName) + imageDesc = if allTexLiveDockerImageNames? then allTexLiveDockerImageNames[index] else imageName + settings.allowedImageNames.push({ imageName, imageDesc }) # With lots of incoming and outgoing HTTP connections to different services, # sometimes long running, it is a good idea to increase the default number From b690162f7c4b37fdb68392413028ae962ff96b99 Mon Sep 17 00:00:00 2001 From: zefyrr Date: Wed, 15 Apr 2020 04:15:10 -0700 Subject: [PATCH 455/525] updated texlive dir for path env variable (#719) Co-authored-by: Omer Kareem --- server-ce/Dockerfile-base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index 9f1ef5b913..f3334cda57 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -41,7 +41,7 @@ RUN npm install -g \ # -f Dockerfile-base -t sharelatex/sharelatex-base . ARG TEXLIVE_MIRROR=http://mirror.ctan.org/systems/texlive/tlnet -ENV PATH "${PATH}:/usr/local/texlive/2019/bin/x86_64-linux" +ENV PATH "${PATH}:/usr/local/texlive/2020/bin/x86_64-linux" RUN mkdir /install-tl-unx \ && curl -sSL \ From 3635e4b4f1590141582d229908e1042cd5330453 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Wed, 15 Apr 2020 15:11:31 +0100 Subject: [PATCH 456/525] Use variables for Makefile tagging --- server-ce/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server-ce/Makefile b/server-ce/Makefile index 75e967936a..f73a49a8bc 100644 --- a/server-ce/Makefile +++ b/server-ce/Makefile @@ -1,12 +1,14 @@ # Makefile +SHARELATEX_BASE_TAG := sharelatex/sharelatex-base +SHARELATEX_TAG := sharelatex/sharelatex build-base: - docker build -f Dockerfile-base -t sharelatex/sharelatex-base . + docker build -f Dockerfile-base -t $(SHARELATEX_BASE_TAG) . build-community: - docker build -f Dockerfile -t sharelatex/sharelatex . + docker build -f Dockerfile -t $(SHARELATEX_TAG) . PHONY: build-base build-community From 3bd49f6ea19247852303b6abe8e9a34085cc0be6 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 16 Apr 2020 12:08:37 +0200 Subject: [PATCH 457/525] Added pull request template (#723) --- server-ce/.github/PULL_REQUEST_TEMPLATE.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 server-ce/.github/PULL_REQUEST_TEMPLATE.md diff --git a/server-ce/.github/PULL_REQUEST_TEMPLATE.md b/server-ce/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..f9e3fda338 --- /dev/null +++ b/server-ce/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ +## Description + + + +## Related issues / Pull Requests + + + +## Contributor Agreement + +- [ ] I confirm I have signed the [Contributor License Agreement](https://github.com/overleaf/overleaf/blob/master/CONTRIBUTING.md#contributor-license-agreement) From d08a9ccfb7a3312dcb30f6a4fe08142a445985c6 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 22 Apr 2020 10:34:47 +0200 Subject: [PATCH 458/525] [docker-compose] add a temporary fix for LuaLatex compiles --- server-ce/docker-compose.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index a268291a7e..059221e0c6 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -43,6 +43,10 @@ services: # Disables email confirmation requirement EMAIL_CONFIRMATION_DISABLED: 'true' + # temporary fix for LuaLaTex compiles + # see https://github.com/overleaf/overleaf/issues/695 + TEXMFVAR: /var/lib/sharelatex/tmp/texmf-var + ## Set for SSL via nginx-proxy #VIRTUAL_HOST: 103.112.212.22 @@ -126,12 +130,12 @@ services: # container_name: ldap # expose: # - 389 - + # See https://github.com/jwilder/nginx-proxy for documentation on how to configure the nginx-proxy container, # and https://github.com/overleaf/overleaf/wiki/HTTPS-reverse-proxy-using-Nginx for an example of some recommended # settings. We recommend using a properly managed nginx instance outside of the Overleaf Server Pro setup, # but the example here can be used if you'd prefer to run everything with docker-compose - + # nginx-proxy: # image: jwilder/nginx-proxy # container_name: nginx-proxy From 0bcb552f6f8e3d2cb74b8a0cdd161c8e55a3c70c Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Wed, 6 May 2020 11:59:42 +0100 Subject: [PATCH 459/525] Try making the base image tag specifiable --- server-ce/Dockerfile | 3 ++- server-ce/Makefile | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index c4478b6b29..a8798a9e6c 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -2,7 +2,8 @@ # Overleaf Community Edition (overleaf/overleaf) # --------------------------------------------- -FROM sharelatex/sharelatex-base:latest +ARG SHARELATEX_BASE_TAG=sharelatex/sharelatex-base:latest +FROM $SHARELATEX_BASE_TAG ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee diff --git a/server-ce/Makefile b/server-ce/Makefile index f73a49a8bc..55eca07ac2 100644 --- a/server-ce/Makefile +++ b/server-ce/Makefile @@ -8,7 +8,7 @@ build-base: build-community: - docker build -f Dockerfile -t $(SHARELATEX_TAG) . + docker build --build-arg SHARELATEX_BASE_TAG=$(SHARELATEX_BASE_TAG) -f Dockerfile -t $(SHARELATEX_TAG) . PHONY: build-base build-community From 34a4b12b8b10ef211e2f89bebbe58771e6dad428 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 6 May 2020 14:32:53 +0200 Subject: [PATCH 460/525] Remove compilation step from document-updater --- server-ce/bin/compile-services | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index f20858f812..76c432143a 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -12,7 +12,7 @@ grep 'name:' config/services.js | \ web) npm run webpack:production ;; - real-time|document-updater) + real-time) npm run compile:all ;; *) From f31d94c4a12571197840c2bd25f122691396d964 Mon Sep 17 00:00:00 2001 From: Soptq <32592090+Soptq@users.noreply.github.com> Date: Sat, 9 May 2020 14:36:59 +0800 Subject: [PATCH 461/525] Update docker-compose.yml Restrict redis version to 5.0.0 --- server-ce/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 059221e0c6..678b88c84a 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -117,7 +117,7 @@ services: redis: restart: always - image: redis + image: redis:5.0.0 container_name: redis expose: - 6379 From 2dd8a08ab72182c395eefe054a5046a32535ce5a Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 20 May 2020 07:49:44 +0200 Subject: [PATCH 462/525] added 'OPTIMISE_PDF' environment variable --- server-ce/Dockerfile | 2 ++ server-ce/settings.coffee | 3 +++ 2 files changed, 5 insertions(+) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index a8798a9e6c..dce3f6d015 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -93,6 +93,8 @@ ENV WEB_API_USER "sharelatex" ENV SHARELATEX_APP_NAME "Overleaf Community Edition" +ENV OPTIMISE_PDF "true" + EXPOSE 80 diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 9912fd1ea6..ef2fdd4115 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -22,6 +22,9 @@ TMP_DIR = '/var/lib/sharelatex/tmp' settings = + clsi: + optimiseInDocker: process.env['OPTIMISE_PDF'] == 'true' + brandPrefix: "" allowAnonymousReadAndWriteSharing: From 8ef8a359e710cb4ebc1fd4151718489a658ed53c Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Mon, 25 May 2020 15:16:18 +0200 Subject: [PATCH 463/525] Set TEXMFVAR to a writable location (#739) --- server-ce/Dockerfile-base | 5 +++++ server-ce/docker-compose.yml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index f3334cda57..15ac43da33 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -7,6 +7,11 @@ FROM phusion/baseimage:0.11 ENV baseDir . +# Makes sure LuaTex cache is writable +# ----------------------------------- +ENV TEXMFVAR=/var/lib/sharelatex/tmp/texmf-var + + # Install dependencies # -------------------- RUN apt-get update \ diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 678b88c84a..2e66a127f5 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -39,7 +39,7 @@ services: # Enables Thumbnail generation using ImageMagick ENABLE_CONVERSIONS: 'true' - + # Disables email confirmation requirement EMAIL_CONFIRMATION_DISABLED: 'true' From 8c7f96c1056d385385bff40dff8b9dd4d88c016d Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Mon, 25 May 2020 16:46:25 +0200 Subject: [PATCH 464/525] removed tags service --- server-ce/.gitignore | 3 +-- server-ce/README.md | 3 +-- server-ce/runit/tags-sharelatex/run | 10 ---------- server-ce/services.js | 4 ---- 4 files changed, 2 insertions(+), 18 deletions(-) delete mode 100755 server-ce/runit/tags-sharelatex/run diff --git a/server-ce/.gitignore b/server-ce/.gitignore index 008b9d7cae..edcda84f24 100644 --- a/server-ce/.gitignore +++ b/server-ce/.gitignore @@ -11,7 +11,6 @@ clsi filestore track-changes docstore -tags chat spelling real-time @@ -23,4 +22,4 @@ tmp db.sqlite .DS_Store -.vagrant \ No newline at end of file +.vagrant diff --git a/server-ce/README.md b/server-ce/README.md index 8b1463d23c..0edb0a6b8d 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -41,7 +41,7 @@ If you are upgrading from a previous version of Overleaf, please see the [Releas This repository does not contain any code. It acts a wrapper and toolkit for managing the many different Overleaf services. These each run as their own Node.js process and have their own Github repository. These are all downloaded and set up when you run `grunt install` -| Service | Description | +| Service | Description | | ------- | ----------- | | **[web](https://github.com/overleaf/web)** | The front facing web server that serves all the HTML pages, CSS and JavaScript to the client. Also contains a lot of logic around creating and editing projects, and account management. | | **[document-updater](https://github.com/overleaf/document-updater)** | Processes updates that come in from the editor when users modify documents. Ensures that the updates are applied in the right order, and that only one operation is modifying the document at a time. Also caches the documents in redis for very fast but persistent modifications. | @@ -51,7 +51,6 @@ This repository does not contain any code. It acts a wrapper and toolkit for man | **[filestore](https://github.com/overleaf/filestore)** | An API for performing CRUD (Create, Read, Update and Delete) operations on binary files (like images) stored in Overleaf. | | **[track-changes](https://github.com/overleaf/track-changes)** | An API for compressing and storing the updates applied to a document, and then rendering a diff of the changes between any two time points. | | **[chat](https://github.com/overleaf/chat)** | The backend API for storing and fetching chat messages. | -| **[tags](https://github.com/overleaf/tags)** | The backend API for managing project tags (folders). | | **[spelling](https://github.com/overleaf/spelling)** | An API for running server-side spelling checking on Overleaf documents. | ## Overleaf Docker Image diff --git a/server-ce/runit/tags-sharelatex/run b/server-ce/runit/tags-sharelatex/run deleted file mode 100755 index 62fe058ad9..0000000000 --- a/server-ce/runit/tags-sharelatex/run +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee - -NODE_PARAMS="" -if [ "$DEBUG_NODE" == "true" ]; then - echo "running debug - tags" - NODE_PARAMS="--inspect=0.0.0.0:30120" -fi - -exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/tags/app.js >> /var/log/sharelatex/tags.log 2>&1 diff --git a/server-ce/services.js b/server-ce/services.js index 654148bc52..84fd7622f5 100644 --- a/server-ce/services.js +++ b/server-ce/services.js @@ -32,10 +32,6 @@ module.exports = name: "chat", repo: "https://github.com/sharelatex/chat-sharelatex.git", version: "master" -}, { - name: "tags", - repo: "https://github.com/sharelatex/tags-sharelatex.git", - version: "master" }, { name: "spelling", repo: "https://github.com/sharelatex/spelling-sharelatex.git", From 033db804fe485947e24a0bfa11ca1fcbf4bbf14c Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Mon, 25 May 2020 16:54:38 +0200 Subject: [PATCH 465/525] Removed privileged mode from docker-compose.yml --- server-ce/docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 2e66a127f5..2410c0208e 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -11,7 +11,6 @@ services: condition: service_healthy redis: condition: service_started - privileged: true ports: - 80:80 links: From ae3e7f03f08b83307e4dfedfe33cd23714dc8303 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 29 May 2020 15:07:51 +0200 Subject: [PATCH 466/525] Set tag '5' for redis image --- server-ce/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 2410c0208e..dbef5f8882 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -116,7 +116,7 @@ services: redis: restart: always - image: redis:5.0.0 + image: redis:5 container_name: redis expose: - 6379 From c2575ad6663f48cf581cd332c289302429600fdf Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 25 Jun 2020 12:29:29 +0200 Subject: [PATCH 467/525] Fixed syntex --- server-ce/hotfix/2.3.1/Dockerfile | 7 +++++++ .../hotfix/2.3.1/check-clsi-setting-exists.patch | 11 +++++++++++ 2 files changed, 18 insertions(+) create mode 100644 server-ce/hotfix/2.3.1/Dockerfile create mode 100644 server-ce/hotfix/2.3.1/check-clsi-setting-exists.patch diff --git a/server-ce/hotfix/2.3.1/Dockerfile b/server-ce/hotfix/2.3.1/Dockerfile new file mode 100644 index 0000000000..36f136aacc --- /dev/null +++ b/server-ce/hotfix/2.3.1/Dockerfile @@ -0,0 +1,7 @@ +FROM sharelatex/sharelatex:2.3.0 + + +# Patch: Fixes NPE when invoking synctex (https://github.com/overleaf/overleaf/issues/756) +ADD check-clsi-setting-exists.patch /var/www/sharelatex/clsi/app/js/check-clsi-setting-exists.patch +RUN cd /var/www/sharelatex/clsi/app/js && \ + patch < check-clsi-setting-exists.patch diff --git a/server-ce/hotfix/2.3.1/check-clsi-setting-exists.patch b/server-ce/hotfix/2.3.1/check-clsi-setting-exists.patch new file mode 100644 index 0000000000..6f6535bc69 --- /dev/null +++ b/server-ce/hotfix/2.3.1/check-clsi-setting-exists.patch @@ -0,0 +1,11 @@ +--- a/app/js/CompileManager.js ++++ b/app/js/CompileManager.js +@@ -536,7 +536,7 @@ module.exports = CompileManager = { + compileName, + command, + directory, +- Settings.clsi != null ? Settings.clsi.docker.image : undefined, ++ Settings.clsi && Settings.clsi.docker ? Settings.clsi.docker.image : undefined, + timeout, + {}, + function(error, output) { From 2766993c65fc790ffb140aa269395a0e76552000 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 8 Jul 2020 11:18:47 +0100 Subject: [PATCH 468/525] [bin/compile-services] all services are decaffeinated now --- server-ce/bin/compile-services | 3 --- 1 file changed, 3 deletions(-) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index 76c432143a..4045a49a4c 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -12,9 +12,6 @@ grep 'name:' config/services.js | \ web) npm run webpack:production ;; - real-time) - npm run compile:all - ;; *) echo "$service doesn't require a compilation" ;; From fe20868b5a9f20cd5f3d59c85a2c6a063b413d5e Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 19 Aug 2020 10:56:03 +0200 Subject: [PATCH 469/525] Hotfix 2.4.1 --- server-ce/hotfix/2.4.1/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 server-ce/hotfix/2.4.1/Dockerfile diff --git a/server-ce/hotfix/2.4.1/Dockerfile b/server-ce/hotfix/2.4.1/Dockerfile new file mode 100644 index 0000000000..d7655511c1 --- /dev/null +++ b/server-ce/hotfix/2.4.1/Dockerfile @@ -0,0 +1,6 @@ +FROM sharelatex/sharelatex:2.4.0 + + +# Patch: Fixes missing dependencies on web startup (https://github.com/overleaf/overleaf/issues/767) +RUN cd /var/www/sharelatex/web && \ + npm install i18next@^19.6.3 i18next-fs-backend@^1.0.7 i18next-http-middleware@^3.0.2 From 41ee63c1f15be9c11921e78126b08ab591624a74 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Fri, 4 Sep 2020 09:23:20 +0100 Subject: [PATCH 470/525] [misc] add the dependabot config of the buildscripts See inline docs for rationals of each (non-trivial) option. --- server-ce/.github/dependabot.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 server-ce/.github/dependabot.yml diff --git a/server-ce/.github/dependabot.yml b/server-ce/.github/dependabot.yml new file mode 100644 index 0000000000..c6f98d843d --- /dev/null +++ b/server-ce/.github/dependabot.yml @@ -0,0 +1,17 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + + pull-request-branch-name: + # Separate sections of the branch name with a hyphen + # Docker images use the branch name and do not support slashes in tags + # https://github.com/overleaf/google-ops/issues/822 + # https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#pull-request-branch-nameseparator + separator: "-" + + # Block informal upgrades -- security upgrades use a separate queue. + # https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#open-pull-requests-limit + open-pull-requests-limit: 0 From 53f2e2a2352f4a413b40b9a811f22b94deba1a7b Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 29 Sep 2020 10:30:20 +0200 Subject: [PATCH 471/525] Hotfix 2.4.2 - fix anon read/write sharing --- server-ce/hotfix/2.4.2/Dockerfile | 10 ++++++++ .../2.4.2/anonymous-metadata-contacts.patch | 20 ++++++++++++++++ .../2.4.2/anonymous-metadata-router.patch | 23 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 server-ce/hotfix/2.4.2/Dockerfile create mode 100644 server-ce/hotfix/2.4.2/anonymous-metadata-contacts.patch create mode 100644 server-ce/hotfix/2.4.2/anonymous-metadata-router.patch diff --git a/server-ce/hotfix/2.4.2/Dockerfile b/server-ce/hotfix/2.4.2/Dockerfile new file mode 100644 index 0000000000..1464cf469a --- /dev/null +++ b/server-ce/hotfix/2.4.2/Dockerfile @@ -0,0 +1,10 @@ +FROM sharelatex/sharelatex:2.4.1 + + +# Patch: Fixes anonymous read/write sharing +ADD anonymous-metadata-router.patch /var/www/sharelatex/web/app/src/anonymous-metadata-router.patch +RUN cd /var/www/sharelatex/web/app/src && \ + patch < anonymous-metadata-router.patch +ADD anonymous-metadata-contacts.patch /var/www/sharelatex/web/app/src/Features/Contacts/anonymous-metadata-contacts.patch +RUN cd /var/www/sharelatex/web/app/src/Features/Contacts && \ + patch < anonymous-metadata-contacts.patch diff --git a/server-ce/hotfix/2.4.2/anonymous-metadata-contacts.patch b/server-ce/hotfix/2.4.2/anonymous-metadata-contacts.patch new file mode 100644 index 0000000000..e0ff95c876 --- /dev/null +++ b/server-ce/hotfix/2.4.2/anonymous-metadata-contacts.patch @@ -0,0 +1,20 @@ +--- a/ContactRouter.js ++++ b/ContactRouter.js +@@ -5,6 +5,8 @@ + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ ++const Settings = require('settings-sharelatex') ++ + const AuthenticationController = require('../Authentication/AuthenticationController') + const ContactController = require('./ContactController') + +@@ -12,7 +14,7 @@ + apply(webRouter, apiRouter) { + return webRouter.get( + '/user/contacts', +- AuthenticationController.requireLogin(), ++ Settings.allowAnonymousReadAndWriteSharing ? (req, res, next) => { next() } : AuthenticationController.requireLogin(), + ContactController.getContacts + ) + } diff --git a/server-ce/hotfix/2.4.2/anonymous-metadata-router.patch b/server-ce/hotfix/2.4.2/anonymous-metadata-router.patch new file mode 100644 index 0000000000..f1a7a70525 --- /dev/null +++ b/server-ce/hotfix/2.4.2/anonymous-metadata-router.patch @@ -0,0 +1,23 @@ +--- a/router.js ++++ b/router.js +@@ -607,16 +607,17 @@ + ProjectDownloadsController.downloadMultipleProjects + ) + ++ console.log(`allowAnonymousReadAndWriteSharing: ${Settings.allowAnonymousReadAndWriteSharing}`) + webRouter.get( + '/project/:project_id/metadata', + AuthorizationMiddleware.ensureUserCanReadProject, +- AuthenticationController.requireLogin(), ++ Settings.allowAnonymousReadAndWriteSharing ? (req, res, next) => { next() } : AuthenticationController.requireLogin(), + MetaController.getMetadata +- ) ++ ) + webRouter.post( + '/project/:project_id/doc/:doc_id/metadata', + AuthorizationMiddleware.ensureUserCanReadProject, +- AuthenticationController.requireLogin(), ++ Settings.allowAnonymousReadAndWriteSharing ? (req, res, next) => { next() } : AuthenticationController.requireLogin(), + MetaController.broadcastMetadataForDoc + ) + privateApiRouter.post( \ No newline at end of file From ac48f31e008eba1acb0cb1ff92baaa78887d9e29 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 1 Oct 2020 11:53:11 +0200 Subject: [PATCH 472/525] using original single patch --- server-ce/hotfix/2.4.2/Dockerfile | 8 +--- .../2.4.2/anonymous-metadata-contacts.patch | 20 --------- .../2.4.2/anonymous-metadata-router.patch | 23 ---------- .../hotfix/2.4.2/anonymous-metadata.patch | 43 +++++++++++++++++++ 4 files changed, 45 insertions(+), 49 deletions(-) delete mode 100644 server-ce/hotfix/2.4.2/anonymous-metadata-contacts.patch delete mode 100644 server-ce/hotfix/2.4.2/anonymous-metadata-router.patch create mode 100644 server-ce/hotfix/2.4.2/anonymous-metadata.patch diff --git a/server-ce/hotfix/2.4.2/Dockerfile b/server-ce/hotfix/2.4.2/Dockerfile index 1464cf469a..8058aa687b 100644 --- a/server-ce/hotfix/2.4.2/Dockerfile +++ b/server-ce/hotfix/2.4.2/Dockerfile @@ -2,9 +2,5 @@ FROM sharelatex/sharelatex:2.4.1 # Patch: Fixes anonymous read/write sharing -ADD anonymous-metadata-router.patch /var/www/sharelatex/web/app/src/anonymous-metadata-router.patch -RUN cd /var/www/sharelatex/web/app/src && \ - patch < anonymous-metadata-router.patch -ADD anonymous-metadata-contacts.patch /var/www/sharelatex/web/app/src/Features/Contacts/anonymous-metadata-contacts.patch -RUN cd /var/www/sharelatex/web/app/src/Features/Contacts && \ - patch < anonymous-metadata-contacts.patch +COPY anonymous-metadata.patch ${baseDir} +RUN cd ${baseDir} && patch -p0 < anonymous-metadata.patch diff --git a/server-ce/hotfix/2.4.2/anonymous-metadata-contacts.patch b/server-ce/hotfix/2.4.2/anonymous-metadata-contacts.patch deleted file mode 100644 index e0ff95c876..0000000000 --- a/server-ce/hotfix/2.4.2/anonymous-metadata-contacts.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/ContactRouter.js -+++ b/ContactRouter.js -@@ -5,6 +5,8 @@ - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -+const Settings = require('settings-sharelatex') -+ - const AuthenticationController = require('../Authentication/AuthenticationController') - const ContactController = require('./ContactController') - -@@ -12,7 +14,7 @@ - apply(webRouter, apiRouter) { - return webRouter.get( - '/user/contacts', -- AuthenticationController.requireLogin(), -+ Settings.allowAnonymousReadAndWriteSharing ? (req, res, next) => { next() } : AuthenticationController.requireLogin(), - ContactController.getContacts - ) - } diff --git a/server-ce/hotfix/2.4.2/anonymous-metadata-router.patch b/server-ce/hotfix/2.4.2/anonymous-metadata-router.patch deleted file mode 100644 index f1a7a70525..0000000000 --- a/server-ce/hotfix/2.4.2/anonymous-metadata-router.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/router.js -+++ b/router.js -@@ -607,16 +607,17 @@ - ProjectDownloadsController.downloadMultipleProjects - ) - -+ console.log(`allowAnonymousReadAndWriteSharing: ${Settings.allowAnonymousReadAndWriteSharing}`) - webRouter.get( - '/project/:project_id/metadata', - AuthorizationMiddleware.ensureUserCanReadProject, -- AuthenticationController.requireLogin(), -+ Settings.allowAnonymousReadAndWriteSharing ? (req, res, next) => { next() } : AuthenticationController.requireLogin(), - MetaController.getMetadata -- ) -+ ) - webRouter.post( - '/project/:project_id/doc/:doc_id/metadata', - AuthorizationMiddleware.ensureUserCanReadProject, -- AuthenticationController.requireLogin(), -+ Settings.allowAnonymousReadAndWriteSharing ? (req, res, next) => { next() } : AuthenticationController.requireLogin(), - MetaController.broadcastMetadataForDoc - ) - privateApiRouter.post( \ No newline at end of file diff --git a/server-ce/hotfix/2.4.2/anonymous-metadata.patch b/server-ce/hotfix/2.4.2/anonymous-metadata.patch new file mode 100644 index 0000000000..ea041abf9c --- /dev/null +++ b/server-ce/hotfix/2.4.2/anonymous-metadata.patch @@ -0,0 +1,43 @@ +--- /var/www/sharelatex/web/app/src/router.js 2020-09-14 20:21:39.741433000 +0000 ++++ /var/www/sharelatex/web/app/src/router.js 2020-09-14 20:13:08.000000000 +0000 +@@ -607,16 +607,17 @@ + ProjectDownloadsController.downloadMultipleProjects + ) + ++ console.log(`allowAnonymousReadAndWriteSharing: ${Settings.allowAnonymousReadAndWriteSharing}`) + webRouter.get( + '/project/:project_id/metadata', + AuthorizationMiddleware.ensureUserCanReadProject, +- AuthenticationController.requireLogin(), ++ Settings.allowAnonymousReadAndWriteSharing ? (req, res, next) => { next() } : AuthenticationController.requireLogin(), + MetaController.getMetadata +- ) ++ ) + webRouter.post( + '/project/:project_id/doc/:doc_id/metadata', + AuthorizationMiddleware.ensureUserCanReadProject, +- AuthenticationController.requireLogin(), ++ Settings.allowAnonymousReadAndWriteSharing ? (req, res, next) => { next() } : AuthenticationController.requireLogin(), + MetaController.broadcastMetadataForDoc + ) + privateApiRouter.post( +--- /var/www/sharelatex/web/app/src/Features/Contacts/ContactRouter.js 2020-09-14 20:21:52.243779000 +0000 ++++ /var/www/sharelatex/web/app/src/Features/Contacts/ContactRouter.js 2020-09-14 20:13:08.000000000 +0000 +@@ -5,6 +5,8 @@ + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ ++const Settings = require('settings-sharelatex') ++ + const AuthenticationController = require('../Authentication/AuthenticationController') + const ContactController = require('./ContactController') + +@@ -12,7 +14,7 @@ + apply(webRouter, apiRouter) { + return webRouter.get( + '/user/contacts', +- AuthenticationController.requireLogin(), ++ Settings.allowAnonymousReadAndWriteSharing ? (req, res, next) => { next() } : AuthenticationController.requireLogin(), + ContactController.getContacts + ) + } From e50861841fdfb3396d6498c57ddd7d4a5cb5b7bd Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 1 Oct 2020 12:46:11 +0200 Subject: [PATCH 473/525] added patch to fix left footer with html links --- server-ce/hotfix/2.4.2/Dockerfile | 4 ++++ .../hotfix/2.4.2/left-footer-skip-translation.patch | 12 ++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 server-ce/hotfix/2.4.2/left-footer-skip-translation.patch diff --git a/server-ce/hotfix/2.4.2/Dockerfile b/server-ce/hotfix/2.4.2/Dockerfile index 8058aa687b..640eea78c3 100644 --- a/server-ce/hotfix/2.4.2/Dockerfile +++ b/server-ce/hotfix/2.4.2/Dockerfile @@ -4,3 +4,7 @@ FROM sharelatex/sharelatex:2.4.1 # Patch: Fixes anonymous read/write sharing COPY anonymous-metadata.patch ${baseDir} RUN cd ${baseDir} && patch -p0 < anonymous-metadata.patch + +# Patch: Fixes left footer with html text +COPY left-footer-skip-translation.patch ${baseDir} +RUN cd ${baseDir} && patch -p0 < left-footer-skip-translation.patch diff --git a/server-ce/hotfix/2.4.2/left-footer-skip-translation.patch b/server-ce/hotfix/2.4.2/left-footer-skip-translation.patch new file mode 100644 index 0000000000..ee6e33a417 --- /dev/null +++ b/server-ce/hotfix/2.4.2/left-footer-skip-translation.patch @@ -0,0 +1,12 @@ + +--- /var/www/sharelatex/web/app/views/layout/footer.pug ++++ /var/www/sharelatex/web/app/app/views/layout/footer.pug +@@ -32,7 +32,7 @@ footer.site-footer + if item.url + a(href=item.url, class=item.class) !{translate(item.text)} + else +- | !{translate(item.text)} ++ | !{item.text} + + ul.col-md-3.text-right + From fe3edd7197a6dbb1af877a6699914a409b1cdaf5 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Mon, 5 Oct 2020 09:45:43 +0100 Subject: [PATCH 474/525] [misc] keep up with web changes -- add waitForDb wrapper for tasks --- server-ce/tasks/CreateAndDestoryUsers.coffee | 70 +++++++++++--------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/server-ce/tasks/CreateAndDestoryUsers.coffee b/server-ce/tasks/CreateAndDestoryUsers.coffee index 14ed4ca360..79da259c67 100644 --- a/server-ce/tasks/CreateAndDestoryUsers.coffee +++ b/server-ce/tasks/CreateAndDestoryUsers.coffee @@ -9,31 +9,33 @@ module.exports = (grunt) -> process.exit(1) settings = require "settings-sharelatex" + mongodb = require "../web/app/src/infrastructure/mongodb" UserRegistrationHandler = require "../web/app/src/Features/User/UserRegistrationHandler" OneTimeTokenHandler = require "../web/app/src/Features/Security/OneTimeTokenHandler" - UserRegistrationHandler.registerNewUser { - email: email - password: require("crypto").randomBytes(32).toString("hex") - }, (error, user) -> - if error? and error?.message != "EmailAlreadyRegistered" - throw error - user.isAdmin = true - user.save (error) -> - throw error if error? - ONE_WEEK = 7 * 24 * 60 * 60 # seconds - OneTimeTokenHandler.getNewToken "password", { expiresIn: ONE_WEEK, email:user.email, user_id: user._id.toString() }, (err, token)-> - return next(err) if err? - - console.log "" - console.log """ - Successfully created #{email} as an admin user. - - Please visit the following URL to set a password for #{email} and log in: - - #{settings.siteUrl}/user/password/set?passwordResetToken=#{token} - - """ - done() + mongodb.waitForDb().then () -> + UserRegistrationHandler.registerNewUser { + email: email + password: require("crypto").randomBytes(32).toString("hex") + }, (error, user) -> + if error? and error?.message != "EmailAlreadyRegistered" + throw error + user.isAdmin = true + user.save (error) -> + throw error if error? + ONE_WEEK = 7 * 24 * 60 * 60 # seconds + OneTimeTokenHandler.getNewToken "password", { expiresIn: ONE_WEEK, email:user.email, user_id: user._id.toString() }, (err, token)-> + return next(err) if err? + + console.log "" + console.log """ + Successfully created #{email} as an admin user. + + Please visit the following URL to set a password for #{email} and log in: + + #{settings.siteUrl}/user/password/set?passwordResetToken=#{token} + + """ + done() grunt.registerTask 'user:delete', "deletes a user and all their data, Usage: grunt user:delete --email joe@example.com", () -> done = @async() @@ -42,15 +44,17 @@ module.exports = (grunt) -> console.error "Usage: grunt user:delete --email=joe@example.com" process.exit(1) settings = require "settings-sharelatex" + mongodb = require "../web/app/src/infrastructure/mongodb" UserGetter = require "../web/app/src/Features/User/UserGetter" UserDeleter = require "../web/app/src/Features/User/UserDeleter" - UserGetter.getUser email:email, (error, user) -> - if error? - throw error - if !user? - console.log("user #{email} not in database, potentially already deleted") - return done() - UserDeleter.deleteUser user._id, (err)-> - if err? - throw err - done() + mongodb.waitForDb().then () -> + UserGetter.getUser email:email, (error, user) -> + if error? + throw error + if !user? + console.log("user #{email} not in database, potentially already deleted") + return done() + UserDeleter.deleteUser user._id, (err)-> + if err? + throw err + done() From 49b45a1796da8117bdc46394d32280b3027c4b2d Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 9 Oct 2020 11:32:45 +0200 Subject: [PATCH 475/525] Fix typo in settings `templates`->`template` --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index ef2fdd4115..b4cc2abab0 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -283,7 +283,7 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"]) textEncoding: process.env["SHARELATEX_EMAIL_TEXT_ENCODING"] - templates: + template: customFooter: process.env["SHARELATEX_CUSTOM_EMAIL_FOOTER"] if process.env["SHARELATEX_EMAIL_SMTP_USER"]? or process.env["SHARELATEX_EMAIL_SMTP_PASS"]? From 0ea13ba637fea903a4e297ecb3e6594fc8139823 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 9 Oct 2020 11:33:06 +0200 Subject: [PATCH 476/525] removed
from email footer --- server-ce/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index dbef5f8882..d4498348f4 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -69,7 +69,7 @@ services: # SHARELATEX_EMAIL_SMTP_PASS: # SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH: true # SHARELATEX_EMAIL_SMTP_IGNORE_TLS: false - # SHARELATEX_CUSTOM_EMAIL_FOOTER: "
This system is run by department x
" + # SHARELATEX_CUSTOM_EMAIL_FOOTER: "This system is run by department x" ################ ## Server Pro ## From 02377af0ab6ed7cb4b5b4179356027f9fa25f82e Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 22 Oct 2020 13:38:14 +0200 Subject: [PATCH 477/525] added support for COMPILE_TIMEOUT env --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index b4cc2abab0..6d44c9d4b1 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -213,7 +213,7 @@ settings = collaborators: -1 dropbox: true versioning: true - compileTimeout: 180 + compileTimeout: process.env["COMPILE_TIMEOUT"] or 180 compileGroup: "standard" trackChanges: true templates: true From a017d08f0551f836b1feab2c394b7179844123c5 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 22 Oct 2020 13:38:33 +0200 Subject: [PATCH 478/525] updated nginx timeout to 4m --- server-ce/nginx/sharelatex.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server-ce/nginx/sharelatex.conf b/server-ce/nginx/sharelatex.conf index 3a10a999f0..eec4bb0938 100644 --- a/server-ce/nginx/sharelatex.conf +++ b/server-ce/nginx/sharelatex.conf @@ -11,8 +11,8 @@ server { proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_read_timeout 3m; - proxy_send_timeout 3m; + proxy_read_timeout 4m; + proxy_send_timeout 4m; } location /socket.io { @@ -23,8 +23,8 @@ server { proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_read_timeout 3m; - proxy_send_timeout 3m; + proxy_read_timeout 4m; + proxy_send_timeout 4m; } location /stylesheets { From 1a23887a8531fd1f6e8143c29c13a9eaabc5acd0 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 22 Oct 2020 18:24:40 +0200 Subject: [PATCH 479/525] addressed PR feedback --- server-ce/nginx/sharelatex.conf | 8 ++++---- server-ce/settings.coffee | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/server-ce/nginx/sharelatex.conf b/server-ce/nginx/sharelatex.conf index eec4bb0938..8123e65bcd 100644 --- a/server-ce/nginx/sharelatex.conf +++ b/server-ce/nginx/sharelatex.conf @@ -11,8 +11,8 @@ server { proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_read_timeout 4m; - proxy_send_timeout 4m; + proxy_read_timeout 10m; + proxy_send_timeout 10m; } location /socket.io { @@ -23,8 +23,8 @@ server { proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_read_timeout 4m; - proxy_send_timeout 4m; + proxy_read_timeout 10m; + proxy_send_timeout 10m; } location /stylesheets { diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 6d44c9d4b1..2bb812f6b2 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -213,7 +213,7 @@ settings = collaborators: -1 dropbox: true versioning: true - compileTimeout: process.env["COMPILE_TIMEOUT"] or 180 + compileTimeout: parseInt(process.env["COMPILE_TIMEOUT"]) or 180 compileGroup: "standard" trackChanges: true templates: true From a1109d3a1eeb389de79e1d2e9fbedea914be4ea0 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 23 Oct 2020 11:58:43 +0200 Subject: [PATCH 480/525] added radix to parseInt() call --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 2bb812f6b2..c7d5631f16 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -213,7 +213,7 @@ settings = collaborators: -1 dropbox: true versioning: true - compileTimeout: parseInt(process.env["COMPILE_TIMEOUT"]) or 180 + compileTimeout: parseInt(process.env["COMPILE_TIMEOUT"] or 180, 10) compileGroup: "standard" trackChanges: true templates: true From a9c02c6bf634fb977e746645841cabaff12b61d1 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Mon, 26 Oct 2020 11:08:00 +0100 Subject: [PATCH 481/525] added radix to parseInt() calls and make them fail fast (#806) --- server-ce/settings.coffee | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index c7d5631f16..f971584b55 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -13,9 +13,13 @@ parse = (option)-> opt = JSON.parse(option) return opt catch err - console.error "problem parsing #{option}, invalid JSON" - return undefined + throw new Error("problem parsing #{option}, invalid JSON") +parseIntOrFail = (value)-> + parsedValue = parseInt(value, 10) + if isNaN(parsedValue) + throw new Error("'#{value}' is an invalid integer") + return parsedValue DATA_DIR = '/var/lib/sharelatex/data' TMP_DIR = '/var/lib/sharelatex/tmp' @@ -213,7 +217,7 @@ settings = collaborators: -1 dropbox: true versioning: true - compileTimeout: parseInt(process.env["COMPILE_TIMEOUT"] or 180, 10) + compileTimeout: parseIntOrFail(process.env["COMPILE_TIMEOUT"] or 180) compileGroup: "standard" trackChanges: true templates: true @@ -379,7 +383,7 @@ if process.env["SHARELATEX_LDAP_URL"] timeout: ( if _ldap_timeout = process.env["SHARELATEX_LDAP_TIMEOUT"] try - parseInt(_ldap_timeout) + parseIntOrFail(_ldap_timeout) catch e console.error "Cannot parse SHARELATEX_LDAP_TIMEOUT" else @@ -388,7 +392,7 @@ if process.env["SHARELATEX_LDAP_URL"] connectTimeout: ( if _ldap_connect_timeout = process.env["SHARELATEX_LDAP_CONNECT_TIMEOUT"] try - parseInt(_ldap_connect_timeout) + parseIntOrFail(_ldap_connect_timeout) catch e console.error "Cannot parse SHARELATEX_LDAP_CONNECT_TIMEOUT" else @@ -446,7 +450,7 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] acceptedClockSkewMs: ( if _saml_skew = process.env["SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"] try - parseInt(_saml_skew) + parseIntOrFail(_saml_skew) catch e console.error "Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS" else @@ -455,7 +459,7 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] requestIdExpirationPeriodMs: ( if _saml_exiration = process.env["SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"] try - parseInt(_saml_expiration) + parseIntOrFail(_saml_expiration) catch e console.error "Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS" else From fc08b54d0a10e646d539323b8a8d76ad2ec5c728 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 19 Nov 2020 11:02:21 +0100 Subject: [PATCH 482/525] Updated mongo to 4.0 for release 2.5.0 (#815) --- server-ce/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index d4498348f4..f5ad685be1 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -102,7 +102,7 @@ services: mongo: restart: always - image: mongo + image: mongo:4.0 container_name: mongo expose: - 27017 From fe2a8f4780f0a743b274352d34635ea7bf2a0915 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Tue, 12 Jan 2021 10:15:38 +0000 Subject: [PATCH 483/525] [runit] fix the cycling of logs for the contacts service --- server-ce/runit/contacts-sharelatex/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/runit/contacts-sharelatex/run b/server-ce/runit/contacts-sharelatex/run index e220d9ac1d..4c01aa0985 100755 --- a/server-ce/runit/contacts-sharelatex/run +++ b/server-ce/runit/contacts-sharelatex/run @@ -7,4 +7,4 @@ if [ "$DEBUG_NODE" == "true" ]; then NODE_PARAMS="--inspect=0.0.0.0:30360" fi -exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/contacts/app.js >> /var/log/sharelatex/contacts 2>&1 +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/contacts/app.js >> /var/log/sharelatex/contacts.log 2>&1 From 89fe7ca11a2c71b49d7ec6b6ef8fb2ae42277249 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Tue, 12 Jan 2021 10:16:09 +0000 Subject: [PATCH 484/525] [init_scripts] delete old logs of the contacts service --- server-ce/init_scripts/10_delete_old_logs.sh | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100755 server-ce/init_scripts/10_delete_old_logs.sh diff --git a/server-ce/init_scripts/10_delete_old_logs.sh b/server-ce/init_scripts/10_delete_old_logs.sh new file mode 100755 index 0000000000..1b606dbf92 --- /dev/null +++ b/server-ce/init_scripts/10_delete_old_logs.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +# Up to version 2.5.0 the logs of the contacts service were written into a +# file that was not picked up by logrotate. +# The service is stable and we can safely discard any logs. +rm -vf /var/log/sharelatex/contacts From 5584ed78ad0adf85b4d28910ff4d7b3e2fc878af Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 14 Jan 2021 11:23:29 +0100 Subject: [PATCH 485/525] msm-change-logrotate-permissions (#827) --- server-ce/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index dce3f6d015..e9a9ec6fa2 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -77,6 +77,7 @@ ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf # Configure log rotation # ---------------------- ADD ${baseDir}/logrotate/sharelatex /etc/logrotate.d/sharelatex +RUN chmod 644 /etc/logrotate.d/sharelatex # Copy Phusion Image startup scripts to its location From 1d8ed4bb231865555d00fd9925b39db7841af54d Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Thu, 14 Jan 2021 10:33:37 +0000 Subject: [PATCH 486/525] [hotfix] produce version 2.5.1 with fixes for log rotation --- server-ce/hotfix/2.5.1/Dockerfile | 13 +++++++++++++ server-ce/hotfix/2.5.1/contacts-run.patch | 8 ++++++++ server-ce/hotfix/2.5.1/delete-old-logs.patch | 10 ++++++++++ 3 files changed, 31 insertions(+) create mode 100644 server-ce/hotfix/2.5.1/Dockerfile create mode 100644 server-ce/hotfix/2.5.1/contacts-run.patch create mode 100644 server-ce/hotfix/2.5.1/delete-old-logs.patch diff --git a/server-ce/hotfix/2.5.1/Dockerfile b/server-ce/hotfix/2.5.1/Dockerfile new file mode 100644 index 0000000000..d22f9123d1 --- /dev/null +++ b/server-ce/hotfix/2.5.1/Dockerfile @@ -0,0 +1,13 @@ +FROM sharelatex/sharelatex:2.5.0 + +# Patch #826: Fixes log path for contacts service to be picked up by logrotate +COPY contacts-run.patch /etc/service/contacts-sharelatex +RUN cd /etc/service/contacts-sharelatex && patch < contacts-run.patch + +# Patch #826: delete old logs for the contacts service +COPY delete-old-logs.patch /etc/my_init.d +RUN cd /etc/my_init.d && patch < delete-old-logs.patch \ +&& chmod +x /etc/my_init.d/10_delete_old_logs.sh + +# Patch #827: fix logrotate file permissions +RUN chmod 644 /etc/logrotate.d/sharelatex diff --git a/server-ce/hotfix/2.5.1/contacts-run.patch b/server-ce/hotfix/2.5.1/contacts-run.patch new file mode 100644 index 0000000000..81ef36ecb0 --- /dev/null +++ b/server-ce/hotfix/2.5.1/contacts-run.patch @@ -0,0 +1,8 @@ +--- a/run ++++ b/run +@@ -7,4 +7,4 @@ if [ "$DEBUG_NODE" == "true" ]; then + NODE_PARAMS="--inspect=0.0.0.0:30360" + fi + +-exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/contacts/app.js >> /var/log/sharelatex/contacts 2>&1 ++exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /var/www/sharelatex/contacts/app.js >> /var/log/sharelatex/contacts.log 2>&1 diff --git a/server-ce/hotfix/2.5.1/delete-old-logs.patch b/server-ce/hotfix/2.5.1/delete-old-logs.patch new file mode 100644 index 0000000000..bc2be14adf --- /dev/null +++ b/server-ce/hotfix/2.5.1/delete-old-logs.patch @@ -0,0 +1,10 @@ +--- /dev/null ++++ b/10_delete_old_logs.sh +@@ -0,0 +1,7 @@ ++#!/bin/sh ++set -e ++ ++# Up to version 2.5.0 the logs of the contacts service were written into a ++# file that was not picked up by logrotate. ++# The service is stable and we can safely discard any logs. ++rm -vf /var/log/sharelatex/contacts From 2594122fef329fb991f0e926920f4fcf3203b875 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Mon, 25 Jan 2021 13:08:04 +0100 Subject: [PATCH 487/525] Hotfix 2.5.2 (#831) --- .../hotfix/2.5.2/12_update_token_email.js | 28 +++++++++++++++++++ server-ce/hotfix/2.5.2/Dockerfile | 8 ++++++ .../2.5.2/create-token-lowercase-email.patch | 11 ++++++++ 3 files changed, 47 insertions(+) create mode 100644 server-ce/hotfix/2.5.2/12_update_token_email.js create mode 100644 server-ce/hotfix/2.5.2/Dockerfile create mode 100644 server-ce/hotfix/2.5.2/create-token-lowercase-email.patch diff --git a/server-ce/hotfix/2.5.2/12_update_token_email.js b/server-ce/hotfix/2.5.2/12_update_token_email.js new file mode 100644 index 0000000000..e4d6e32254 --- /dev/null +++ b/server-ce/hotfix/2.5.2/12_update_token_email.js @@ -0,0 +1,28 @@ +const Settings = require('settings-sharelatex') +const mongojs = require('mongojs') +const db = mongojs(Settings.mongo.url, ['tokens']) +const async = require('async') + +exports.migrate = (client, done) => { + console.log(`>> Updating 'data.email' to lower case in tokens`) + + db.tokens.find({}, { 'data.email': 1 }, (err, tokens) => { + if (err) { + return done(err) + } + + async.eachSeries( + tokens, + (token, callback) => { + db.tokens.update( + { _id: token._id }, + { $set: { 'data.email': token.data.email.toLowerCase() } }, + callback + ) + }, + done + ) + }) +} + +exports.rollback = (client, done) => done() diff --git a/server-ce/hotfix/2.5.2/Dockerfile b/server-ce/hotfix/2.5.2/Dockerfile new file mode 100644 index 0000000000..ddf596deea --- /dev/null +++ b/server-ce/hotfix/2.5.2/Dockerfile @@ -0,0 +1,8 @@ +FROM sharelatex/sharelatex:2.5.1 + +# Patch: fixes registration token creation +COPY create-token-lowercase-email.patch ${baseDir} +RUN cd ${baseDir} && patch -p0 < create-token-lowercase-email.patch + +# Migration for tokens with invalid email addresses +ADD 12_update_token_email.js /var/www/sharelatex/migrations/12_update_token_email.js diff --git a/server-ce/hotfix/2.5.2/create-token-lowercase-email.patch b/server-ce/hotfix/2.5.2/create-token-lowercase-email.patch new file mode 100644 index 0000000000..23dfaa3a43 --- /dev/null +++ b/server-ce/hotfix/2.5.2/create-token-lowercase-email.patch @@ -0,0 +1,11 @@ +--- /var/www/sharelatex/web/app/src/Features/User/UserRegistrationHandler.js ++++ /var/www/sharelatex/web/app/src/Features/User/UserRegistrationHandler.js +@@ -122,7 +122,7 @@ const UserRegistrationHandler = { + const ONE_WEEK = 7 * 24 * 60 * 60 // seconds + OneTimeTokenHandler.getNewToken( + 'password', +- { user_id: user._id.toString(), email }, ++ { user_id: user._id.toString(), email: user.email }, + { expiresIn: ONE_WEEK }, + (err, token) => { + if (err != null) { From a0e7ea16d21971a3ec07d5f8189645c21c45d3c1 Mon Sep 17 00:00:00 2001 From: Josh Soref Date: Tue, 2 Mar 2021 04:35:40 -0500 Subject: [PATCH 488/525] Fix spelling errors (#823) --- server-ce/CONTRIBUTING.md | 2 +- server-ce/Dockerfile | 2 +- server-ce/Gruntfile.coffee | 2 +- server-ce/README.md | 2 +- server-ce/docker-compose.yml | 2 +- .../1_move_doc_lines_to_doc_collection.coffee | 6 +++--- .../2_doc_lines_delete_from_project.coffee | 10 +++++----- .../migrations/3_pack_docHistory_collection.coffee | 4 ++-- server-ce/migrations/about_migrations.md | 2 +- server-ce/settings.coffee | 12 ++++++------ ...toryUsers.coffee => CreateAndDestroyUsers.coffee} | 0 11 files changed, 22 insertions(+), 22 deletions(-) rename server-ce/tasks/{CreateAndDestoryUsers.coffee => CreateAndDestroyUsers.coffee} (100%) diff --git a/server-ce/CONTRIBUTING.md b/server-ce/CONTRIBUTING.md index 5d9f82d9fc..814c1c6775 100644 --- a/server-ce/CONTRIBUTING.md +++ b/server-ce/CONTRIBUTING.md @@ -4,7 +4,7 @@ Contributing to ShareLaTeX Thank you for reading this! If you'd like to report a bug or join in the development of ShareLaTeX, then here are some notes on how to do that. -*Note that ShareLaTeX is actually made up of many seperate repositories (a list is available +*Note that ShareLaTeX is actually made up of many separate repositories (a list is available [here](https://github.com/sharelatex/sharelatex/blob/master/README.md#other-repositories)).* Reporting bugs and opening issues diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index e9a9ec6fa2..2f394fed64 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -58,7 +58,7 @@ RUN cd /var/www/sharelatex \ RUN cd /var/www/sharelatex \ && bash ./bin/compile-services -# Links CLSI sycntex to its default location +# Links CLSI synctex to its default location # ------------------------------------------ RUN ln -s /var/www/sharelatex/clsi/bin/synctex /opt/synctex diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 7fb8881930..3af76ef763 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -193,7 +193,7 @@ module.exports = (grunt) -> grunt.log.errorlns """ !!!!!!!!!!!!!! MONGO ERROR !!!!!!!!!!!!!! - ShareLaTeX can not talk to the mongdb instance + ShareLaTeX can not talk to the mongodb instance Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL diff --git a/server-ce/README.md b/server-ce/README.md index 0edb0a6b8d..03c1f4d47f 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -39,7 +39,7 @@ If you are upgrading from a previous version of Overleaf, please see the [Releas ## Other repositories -This repository does not contain any code. It acts a wrapper and toolkit for managing the many different Overleaf services. These each run as their own Node.js process and have their own Github repository. These are all downloaded and set up when you run `grunt install` +This repository does not contain any code. It acts a wrapper and toolkit for managing the many different Overleaf services. These each run as their own Node.js process and have their own GitHub repository. These are all downloaded and set up when you run `grunt install` | Service | Description | | ------- | ----------- | diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index f5ad685be1..0d7c80f70a 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -19,7 +19,7 @@ services: volumes: - ~/sharelatex_data:/var/lib/sharelatex ######################################################################## - #### Server Pro: Un-comment the following line to mount the docker #### + #### Server Pro: Uncomment the following line to mount the docker #### #### socket, required for Sibling Containers to work #### ######################################################################## # - /var/run/docker.sock:/var/run/docker.sock diff --git a/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee b/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee index e4433de7bd..ce8c208657 100644 --- a/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee +++ b/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee @@ -19,7 +19,7 @@ printProgress = -> exec "wc #{finished_projects_path}", (error, results) -> setTimeout printProgress, 1000 * 30 -checkIfFileHasBeenProccessed = (project_id, callback)-> +checkIfFileHasBeenProcessed = (project_id, callback)-> exec "grep #{project_id} #{finished_projects_path}", (error, results) -> hasBeenProcessed = _.include(results, project_id) callback(error, hasBeenProcessed) @@ -125,9 +125,9 @@ saveDocsIntoMongo = (project_id, docs, callback)-> processNext = (project_id, callback)-> - checkIfFileHasBeenProccessed project_id, (err, hasBeenProcessed)-> + checkIfFileHasBeenProcessed project_id, (err, hasBeenProcessed)-> if hasBeenProcessed - console.log "#{project_id} already procssed, skipping" + console.log "#{project_id} already processed, skipping" return callback() console.log "#{project_id} processing" getAllDocs project_id, (err, docs)-> diff --git a/server-ce/migrations/2_doc_lines_delete_from_project.coffee b/server-ce/migrations/2_doc_lines_delete_from_project.coffee index 2d5222f63d..0be28446d8 100644 --- a/server-ce/migrations/2_doc_lines_delete_from_project.coffee +++ b/server-ce/migrations/2_doc_lines_delete_from_project.coffee @@ -16,7 +16,7 @@ printProgress = -> exec "wc #{finished_projects_path}", (error, results) -> setTimeout printProgress, 1000 * 30 -checkIfFileHasBeenProccessed = (project_id, callback)-> +checkIfFileHasBeenProcessed = (project_id, callback)-> exec "grep #{project_id} #{finished_projects_path}", (error, results) -> hasBeenProcessed = _.include(results, project_id) callback(error, hasBeenProcessed) @@ -125,7 +125,7 @@ getWhichDocsCanBeDeleted = (docs, callback = (err, docsToBeDeleted, unmigratedDo async.series jobs, (err)-> callback err, docsToBeDeleted, unmigratedDocs -whipeDocLines = (project_id, mongoPath, callback)-> +wipeDocLines = (project_id, mongoPath, callback)-> update = $unset: {} update.$unset["#{mongoPath}.lines"] = "" @@ -137,15 +137,15 @@ removeDocLinesFromProject = (docs, project, callback)-> jobs = _.map docs, (doc)-> (cb)-> findDocInProject project, doc._id, (err, doc, mongoPath)-> - whipeDocLines project._id, mongoPath, cb + wipeDocLines project._id, mongoPath, cb async.parallelLimit jobs, 5, callback processNext = (project_id, callback)-> if !project_id? or project_id.length == 0 return callback() - checkIfFileHasBeenProccessed project_id, (err, hasBeenProcessed)-> + checkIfFileHasBeenProcessed project_id, (err, hasBeenProcessed)-> if hasBeenProcessed - console.log "#{project_id} already procssed, skipping" + console.log "#{project_id} already processed, skipping" return callback() console.log "#{project_id} processing" getAllDocs project_id, (err, docs, project)-> diff --git a/server-ce/migrations/3_pack_docHistory_collection.coffee b/server-ce/migrations/3_pack_docHistory_collection.coffee index c652dd7816..affe1fcfd1 100644 --- a/server-ce/migrations/3_pack_docHistory_collection.coffee +++ b/server-ce/migrations/3_pack_docHistory_collection.coffee @@ -65,7 +65,7 @@ markDocAsUnmigrated = (doc_id, callback)-> markDocAsProcessed doc_id, (err)-> fs.appendFile unmigrated_docs_path, "#{doc_id}\n", callback -checkIfDocHasBeenProccessed = (doc_id, callback)-> +checkIfDocHasBeenProcessed = (doc_id, callback)-> callback(null, finished_docs[doc_id]) processNext = (doc_id, callback)-> @@ -73,7 +73,7 @@ processNext = (doc_id, callback)-> return callback() if needToExit return callback(new Error("graceful shutdown")) - checkIfDocHasBeenProccessed doc_id, (err, hasBeenProcessed)-> + checkIfDocHasBeenProcessed doc_id, (err, hasBeenProcessed)-> if hasBeenProcessed console.log "#{doc_id} already processed, skipping" return callback() diff --git a/server-ce/migrations/about_migrations.md b/server-ce/migrations/about_migrations.md index 97f91442b1..8a9d7596ba 100644 --- a/server-ce/migrations/about_migrations.md +++ b/server-ce/migrations/about_migrations.md @@ -1,4 +1,4 @@ -If migration is stopped mid way it will start at the beginging next time +If migration is stopped mid way it will start at the beginning next time To see the run migrations do db.getCollection('_migrations').find() you can't do db._migrations.find() diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index f971584b55..43261774ab 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -37,7 +37,7 @@ settings = # Databases # --------- - # ShareLaTeX's main persistant data store is MongoDB (http://www.mongodb.org/) + # ShareLaTeX's main persistent data store is MongoDB (http://www.mongodb.org/) # Documentation about the URL connection string format can be found at: # # http://docs.mongodb.org/manual/reference/connection-string/ @@ -75,7 +75,7 @@ settings = # track-changes:lock historyLock: ({doc_id}) -> "HistoryLock:#{doc_id}" historyIndexLock: ({project_id}) -> "HistoryIndexLock:#{project_id}" - # track-chanegs:history + # track-changes:history uncompressedHistoryOps: ({doc_id}) -> "UncompressedHistoryOps:#{doc_id}" docsWithHistoryOps: ({project_id}) -> "DocsWithHistoryOps:#{project_id}" # realtime @@ -93,8 +93,8 @@ settings = project_history: redisConfig # The compile server (the clsi) uses a SQL database to cache files and - # meta-data. sqllite is the default, and the load is low enough that this will - # be fine in production (we use sqllite at sharelatex.com). + # meta-data. sqlite is the default, and the load is low enough that this will + # be fine in production (we use sqlite at sharelatex.com). # # If you want to configure a different database, see the Sequelize documentation # for available options: @@ -223,7 +223,7 @@ settings = templates: true references: true -## OPTIONAL CONFIGERABLE SETTINGS +## OPTIONAL CONFIGURABLE SETTINGS if process.env["SHARELATEX_LEFT_FOOTER"]? try @@ -457,7 +457,7 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] undefined ) requestIdExpirationPeriodMs: ( - if _saml_exiration = process.env["SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"] + if _saml_expiration = process.env["SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"] try parseIntOrFail(_saml_expiration) catch e diff --git a/server-ce/tasks/CreateAndDestoryUsers.coffee b/server-ce/tasks/CreateAndDestroyUsers.coffee similarity index 100% rename from server-ce/tasks/CreateAndDestoryUsers.coffee rename to server-ce/tasks/CreateAndDestroyUsers.coffee From 7e518a4b05c56eec4f7b4286014f985fbfa6e9b8 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Tue, 2 Mar 2021 17:29:12 +0100 Subject: [PATCH 489/525] Added configurable AWS region to email settings (#847) --- server-ce/settings.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 43261774ab..a0bd33abf6 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -290,6 +290,9 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? template: customFooter: process.env["SHARELATEX_CUSTOM_EMAIL_FOOTER"] + if process.env["SHARELATEX_EMAIL_AWS_SES_REGION"]? + settings.email.parameters.region = process.env["SHARELATEX_EMAIL_AWS_SES_REGION"] + if process.env["SHARELATEX_EMAIL_SMTP_USER"]? or process.env["SHARELATEX_EMAIL_SMTP_PASS"]? settings.email.parameters.auth = user: process.env["SHARELATEX_EMAIL_SMTP_USER"] From 065c6870e67ae4ba99cecd6ab501d2a819dab2df Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Fri, 19 Mar 2021 09:53:18 +0000 Subject: [PATCH 490/525] Update passport-saml URLs --- server-ce/settings.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index a0bd33abf6..c9ce1ad14d 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -424,7 +424,7 @@ if process.env["SHARELATEX_LDAP_URL"] if process.env["SHARELATEX_SAML_ENTRYPOINT"] - # NOTE: see https://github.com/bergie/passport-saml/blob/master/README.md for docs of `server` options + # NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options settings.externalAuth = true settings.saml = updateUserDetailsOnLogin: process.env["SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' @@ -497,7 +497,7 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] ) # SHARELATEX_SAML_CERT cannot be empty - # https://github.com/bergie/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 + # https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 if process.env["SHARELATEX_SAML_CERT"] settings.saml.server.cert = process.env["SHARELATEX_SAML_CERT"] settings.saml.server.privateCert = process.env["SHARELATEX_SAML_PRIVATE_CERT"] From 1540d1b891171169c4bce91a4afac6bdfbdcb30b Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 31 Mar 2021 11:11:23 +0200 Subject: [PATCH 491/525] Added `SHARELATEX_SAML_DECRYPTION_CERT` environment variable (#860) --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index c9ce1ad14d..91d07430a5 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -438,6 +438,7 @@ if process.env["SHARELATEX_SAML_ENTRYPOINT"] callbackUrl: process.env["SHARELATEX_SAML_CALLBACK_URL"] issuer: process.env["SHARELATEX_SAML_ISSUER"] decryptionPvk: process.env["SHARELATEX_SAML_DECRYPTION_PVK"] + decryptionCert: process.env["SHARELATEX_SAML_DECRYPTION_CERT"] signatureAlgorithm: process.env["SHARELATEX_SAML_SIGNATURE_ALGORITHM"] identifierFormat: process.env["SHARELATEX_SAML_IDENTIFIER_FORMAT"] attributeConsumingServiceIndex: process.env["SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX"] @@ -569,4 +570,3 @@ https = require('https') https.globalAgent.maxSockets = 300 module.exports = settings - From f849b9400519392038383ee6dd4503dd08c1b31e Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 7 Apr 2021 14:19:06 +0100 Subject: [PATCH 492/525] Variables in Nginx configuration (#853) * Add envsubst binary to image * Generate nginx.conf from template, with env-vars * Remove nginx.conf, now generated from template * Reload nginx config after writing file Co-authored-by: Shane Kilkelly --- server-ce/Dockerfile | 2 +- server-ce/Dockerfile-base | 5 +++ .../init_scripts/01_nginx_config_template.sh | 34 ++++++++++++++++++ .../nginx/{nginx.conf => nginx.conf.template} | 10 ++++-- server-ce/vendor/envsubst | Bin 0 -> 2413941 bytes 5 files changed, 47 insertions(+), 4 deletions(-) create mode 100755 server-ce/init_scripts/01_nginx_config_template.sh rename server-ce/nginx/{nginx.conf => nginx.conf.template} (80%) create mode 100644 server-ce/vendor/envsubst diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 2f394fed64..bf344b7c9a 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -70,7 +70,7 @@ ADD ${baseDir}/runit /etc/service # Configure nginx # --------------- -ADD ${baseDir}/nginx/nginx.conf /etc/nginx/nginx.conf +ADD ${baseDir}/nginx/nginx.conf.template /etc/nginx/templates/nginx.conf.template ADD ${baseDir}/nginx/sharelatex.conf /etc/nginx/sites-enabled/sharelatex.conf diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index 15ac43da33..4f88faef9e 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -30,6 +30,11 @@ RUN apt-get update \ /etc/nginx/sites-enabled/default \ /var/lib/apt/lists/* +# Add envsubst +# ------------ +ADD ./vendor/envsubst /usr/bin/envsubst +RUN chmod +x /usr/bin/envsubst + # Install Grunt # ------------ RUN npm install -g \ diff --git a/server-ce/init_scripts/01_nginx_config_template.sh b/server-ce/init_scripts/01_nginx_config_template.sh new file mode 100755 index 0000000000..84f39ea637 --- /dev/null +++ b/server-ce/init_scripts/01_nginx_config_template.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +set -e + +## Generate nginx config files from templates, +## with environment variables substituted + +nginx_dir='/etc/nginx' +nginx_templates_dir="${nginx_dir}/templates" + +if ! [ -d "${nginx_templates_dir}" ]; then + echo "Nginx: no template directory found, skipping" + exit 0 +fi + +nginx_template_file="${nginx_templates_dir}/nginx.conf.template" +nginx_config_file="${nginx_dir}/nginx.conf" + +if [ -f "${nginx_template_file}" ]; then + export NGINX_WORKER_PROCESSES="${NGINX_WORKER_PROCESSES:-4}" + export NGINX_WORKER_CONNECTIONS="${NGINX_WORKER_CONNECTIONS:-768}" + + echo "Nginx: generating config file from template" + + # Note the single-quotes, they are important. + # This is a pass-list of env-vars that envsubst + # should operate on. + envsubst '${NGINX_WORKER_PROCESSES} ${NGINX_WORKER_CONNECTIONS}' \ + < "${nginx_template_file}" \ + > "${nginx_config_file}" + + echo "Nginx: reloading config" + service nginx reload +fi diff --git a/server-ce/nginx/nginx.conf b/server-ce/nginx/nginx.conf.template similarity index 80% rename from server-ce/nginx/nginx.conf rename to server-ce/nginx/nginx.conf.template index c4311103b0..e3cf283e85 100644 --- a/server-ce/nginx/nginx.conf +++ b/server-ce/nginx/nginx.conf.template @@ -1,10 +1,14 @@ +## ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ## +## ! This file was generated from a template ! ## +## ! See /etc/nginx/templates/ ! ## +## ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ## daemon off; user www-data; -worker_processes 4; +worker_processes ${NGINX_WORKER_PROCESSES}; pid /run/nginx.pid; events { - worker_connections 768; + worker_connections ${NGINX_WORKER_CONNECTIONS}; # multi_accept on; } @@ -63,7 +67,7 @@ http { ## # Uncomment it if you installed nginx-passenger ## - + #passenger_root /usr; #passenger_ruby /usr/bin/ruby; diff --git a/server-ce/vendor/envsubst b/server-ce/vendor/envsubst new file mode 100644 index 0000000000000000000000000000000000000000..f7ad8081d0135953c0bdece3905b36b4e1847ce0 GIT binary patch literal 2413941 zcmeFadw5jU`7b_`WMEKm56ERekU?V&R%uePCd%kUqwK*!qoPJdNh?yUR3l6vC}QGF zAmgxWwAkXMEo!T_YHO=SK-7c);bN7G7m%u`RrfenP+Leq&G~%ZwfD@P5VYq!-{0?? zKbq&s?6ueBUGHtZ>s{A<+c}YQ^W1Ki{g>xD!zFL;og+~pD`9;$i!086S4y8dFtN7 z=|1tNcr=a-Q{`V3*58{2vBL1^+WR`$7tmMbD`pD!!^nm(3pg)%6pESUxWk zWAj(>`|PQ?QVV4AslZ=QIKNvQU#q7o1XdBa23G?3ThTe?{4J-R{4OX_q#sG=4B|5`|28ick(Y&|ANa^js-*I zSu;z$+P?uiU_FT?DYVPicdGLBovM8C{aMXokpO=jejl^_3aXX?S_Ujqzhj_PGs z3;622N6B*q72NTcs|_yKxbF3jo+7!2UZ?1<8R966VE6J@bt|6;sq%?>RsNFGzPbDj z-O9gxvnv1gN>#qQNpsRl$h-0HjPu^2%6p$v*ItN+u~k0j%#qXY6x ztad^_nEr>mm7nv3>UrjTGD^zd_=r3*Ki%tRYh@d-BQBRiQp{Dq{8$P6dw4GWxo;}(e}DhWf&X&gza024 z2mZ@}|8n5}J_k6Wycqv{j=$06`tjK(*G`!;{)cns)ZIAs`tozn|Nf;l-#h1`@``ES zzwoEiFZj{5l@-N$jef;R-@D?JvXf_5O_+Vs1!ZM3#$Gmd#t&!T^u1H2UOQv%g~c;2 z8-K|;rNt92y?)a4@vfLOE&;Zva66xkEn0jg2xdLSdLmL-qbK?nO0DZE3VkPsw zYe`GV20b|m*<r9Sg=Y@Ffp;Hu%0y}h6CKBLNCDu&2dg} ziz?wlDNtoww1s(0i**)gw||Pkt8QHWrJi_O-?vk5J#eNTd%r+W&MT~m7zHDBqui~R zZPpgPztzl|Hd1%#sWkvr+0>$duxqtM{RbU~c8EXXF5f>?dXA3|ebv5fr2vU(`MDyy&aay?Sv)Xn&F}W~A6)4pc z;|j@9Zv<~X(~rSx{k%fItM({unbe4?DE5$^B=3RN^mLP+?DtWc^bguDj|wE0t=D2H zk@4ih(sdQX{BGoGRk{Ac2Q#!G11Ky!KGYN)HZ+&W$zOGKndVn{&<4-H<{SaU(JtD7 z+0h`*)OzQmK1!a^2vn-(vac874bM-ZiV!q$#V#~bT9@^V zH#}z?gx8;tV17(+Ie4`nfcX*wz*c)XNXRtE3cj!zZgaFiC`pZOjO(Q*w(E(FdZIJ6 zS|E6yO;KO^J;nzN(a-J#mSRClwnC3%tpUyF*80Z_A49z6gK0x}xrD7ayf<0z5|8&K zc&}eoxD*dp^c1Rd9h*j_w(Nnz2N4(F89h=@KBMxT;nL!(ROEN;$fl$9uGMf6d&WDs4g?pHFk9o`UAU63^S1kDId`z2YjZ>v9^y_FC zE-Wh26S_|~`hCRrgbvvK-d4d%1YcFb8U!~=uu0U%==Z#OdkP#u+EeO{+K0D?)!QER z_Dl8VL!W}QJJegTdYiA_D%IOe^;Vg^Ks_LO=%N4;(4Tf4{i;ZPTs3=r&R z1!KVvZxw2G{xcOJ4;2j#~ zxtZ_3Q}0kS&kVlbqu!xwo~!uYDDNwj!g4&(S!{BUMzTih7q(E)`XyqBb+?pHGmE70oK@1xCH8qMlMw zzh_jtirTEA7BlJ@MkUs#!t4Qm{4?-r0D8}tUZO67S$(yKz;+)D!$9;1esl=Km093C zv`ceuMyeOFeRGTjYzDkmzuOUM*&jV5=BIQ*s1|l-LV2lPt}SkXJLYeL==NnTPL92q zJpr}`Mqvh;1Pn-kz@Tz1AzB;0l&TltLhI!d<9{E#V!B;^Ku4`C7F$!)X5MaK5U?}{ zzP3O*q#o)>>hSY?^w~=F1 zajrX5`bJo**dra}rgA{eITnj`DSfdn7I}q2)zSiR3Wy37n7EWxAXpy#Xti!9_PB#moGiMK|5AL{m zxXZ1@pG3CQ5d0wCH~Z=@v>SWjUz?^y*H6>lXw^^Y>Tl#8?HszcYP(+2a!22zPwP8U`(=x66r2P0c7+pe!D9B|da{?E)G+L* z)g~k>dUZ@lMtXPPHF}G#t=F{;dP%FUJ-V4 zsLT)2-U-QQuMU0Nr~0-JL-kz}dnRM&0q(Zl`nHdB?PXniMK9SG9Rkp=Fl+2Xg08hu z1Iie=fnnNjTC~Njx=~RsDEG_|t#J?vBJErselGCkvP)~+4Q*v=fT@A*sqI#3F;k1X zr~Zb0OKe>TYz=|k`0og53$8+J>PA$$_Uju5<9{Unrv>nHV_@wE(ba3edZPuR>guXJ zcI|7?f8lkVdL7;!)XV|tRckxuq$U9%pQl;RFJZJTHLDM{)j>I;p42gj%xc>mXr>WN zaRgFa7tiYCG+n!)WtvuP{nxa>ojc&0cSE?H!(Vg>`|uvn7Ov-uQE~L1^bk;P>)4hr zwB=jFZYWi|PcLhq{SQntXwj4O_EsPBkKPe(Uri+pZ`&W<_8tm)Eskx8jM{3IotS{H z*|;-Wq8sP>ru}}87X4lm%R#SE?!9pAV>b#O(Y;{8*A{L^7HMvWsxET$o*v582bauY z18V#(m@W*67?Y3QwdTEB>()amL)QK?x&uG z13(27m#?HK6~VbgA}eXl@}40}La>f#`B9CQ0k)iSIt%b%9|O+bvwQv{^yC#@X7{I# zRM~SnTf&bWfbsZ(xWx{HwA-IW2=v1`xuern)Nc_54vX!;^HMg8Dg2qnCU7HvW>ej7 zqq?`^e;fWk!2iB!+RoMZ{}BIcU~x9v`l`p$p@#hweDr~J6cDPO83fyU;a|i5rPTf@ zfwf;n-$e`fc z^vVTu0#;pLB~N8d7dUeLGxe&<)q75m=(sW4keuxK5+#^9ThnK$$B{7^E&Y-e^>u)F zBXySo;hl3VM{fkvsV7g>S=alLWK%U=Wz^=JZPx___drG{B?Yqe?M|J}%%~93Lyh-2 z0BuWgy8=k_%_)H*PLwJ?Lud%Ja0@i=bG-qk5DrfK8b`6WQzpe8>lis_id{bnRe1IY zkRHls(RnZR1j-`I z@cs0KHa5ss;n^j{dMI&twgkJ3$)&r{SazYI{L2D4(9W*xzr1RAzlT3-5yPgPeX#RK{uj9J_{?09UhJLecBJTzLByGv;7hGD|*?! zng3+e`CW{gbDwU^@6z3`L`J_6PMj|7!}e#;!@!e)1DYxVL+obJQxD{Iq#vUHnUv{x zWX@PRog8^4aao{7_G{BQevtFwu+NLHNPe>;|@_(#xbWz06RQ$n+{G z5q-Jr%~>16=vR>7=r|HPw!PQ-v5z^PU}}BvikpPB(*XVuy$8CIAv7ai2)FJ5!!bJy>_ z$faw4T2FEu-06XvGP73j%bvNZFV8?0=CCdY_}1>s?|U0YI3J-Y_QZc}fwC+I@#k~J zpJ^6@eh&sA{QnGx*r3h#?)jhL(8sreLm${2%F&{pIT{%${hwrQEU3{ZufBu^WnZqU1VI3 z=^8cvsT+efP2jZoB-j{x3WuT-D;6*(URogd7g_SQ<$B3>HP2g< zhY9d|Zh=xYLl`;wq%FAMoB7Sv%>QFvbC>%65U-bs+`EhIKj!tRhaZC1Q)IF35WIeO zQqR0jP0RB7r14H(zq6XW9(^--z1V8N-T3{1S}&-heq%C~KS{Ngqb<`1?rrsIjYlF2 zUWUZp9a-OrC59o;v--|~+QN^(g!<0@wbQwLzF5|Z(iPMVw2`V}PRk`Q^Q8R=6Tc6r zl_mGv)*Kt$cXKAXYl;KSO2?cNCVT9v^)fv)XPKT@EQ?xf1~q5~b#1J*u~j_Zx{#~( z6y|TDBoeeYaci}TGhB~k&5Bw<%K|xcAvY#ii4bf<_d@lZel4C7dWT|hQd%0POhctK z13%+L3JKRswvyInyka_sYsnZFp`~DruuV_wVUw?9Qwr$`m5X*HS%W552Qv}jPJ?+| zmW^@+7;SRo5Dyosy{_nq8Tyj!9=lq}Fdf6Hc}ot)mPAyuK>`Xmvn7?G*$ow?x8PXX z^O-4&S^o4xb}i{YWQrWb+m(0P%G(2*j+j$d-`OvEMt$cITH|18aEFr7-Pkp92zDR3 z^5DKh7OL;mzDXs{#%kODc6IZ=sSu3GB1`}1ie*ynn}X8tMC6PYXy!!+i3-Myg(~(>}*(pudz;T zIXc$k5bFUz9C}jf=G3k~>-}>44brq{Rr<8DgEB~ZQY9apYL(Zm4En)2q`Wi>TEViz zYSB0*AfS7DUXNgYFWprsh=3P9873XI`&&k}Hld$#A`hA+KixOUj{pWK-&DYcA1WYh zyOK)2`L!{d?3%POtF^_eS?TIgTb$L}^@Y5w%dWJNZ+_IA0f2Ci5OVDG?2CFF4{$96 z^h~1R9j2E}@J0__1%bkG85yd{^^L**?CO#=nDln@uqZsOCAL=l@79OuuClyC)h7cJ zOs$*0fF-c&yKmP2_w{jqnO)xrhptas@EI+45B^=MJJVkIO%VEqE*9v;|n% zKu43Y1+PSUwgqqC?1!itysx9qblQTyt)wj&G84AobMXjrP0 z?+`rMaNalYD=1JRCS)TMh!^x8snE7iq^KSxAKDE3gyESwhe`pIh(#sw5)Cad$ zbHNGAK!2A&pZegd4Ae%jdi?xV+$jOAfbZ-LurQry2F$-K#=etSzx$8_Yj=lu${c45 z>w?YeJX5b^PQ%k@iUVf74U+-$YQoHvF~3&>nofhCm8A#Bqd%H~{szvT57N&L=k;X$ zWν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≻{vz!`Un21?RY=T6=82Kx=8VBE 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

=*Rb<3bPuFtSVX%=6Hz53WE@Zc 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

* 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ïp?)-cm409lC=>q5)oMfT`k3*_bkXX} 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¬l>R<-GyX7nkwf~K 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

04A0!oR^*0CMrMAAj#+zln;9y>58$lK(O)!6J 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

-WR1P*}++##T}f> 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%0D#qSOg)r`Ui3TGsdV26mT$SXC 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 literal 0 HcmV?d00001 From cff06473ce14b0b455d99d54161f6fe04a441bb3 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 7 Apr 2021 14:19:17 +0100 Subject: [PATCH 493/525] Expose new smtp vars: 'name', and 'logger' (#854) Co-authored-by: Shane Kilkelly --- server-ce/docker-compose.yml | 2 ++ server-ce/settings.coffee | 2 ++ 2 files changed, 4 insertions(+) diff --git a/server-ce/docker-compose.yml b/server-ce/docker-compose.yml index 0d7c80f70a..58240a5687 100644 --- a/server-ce/docker-compose.yml +++ b/server-ce/docker-compose.yml @@ -69,6 +69,8 @@ services: # SHARELATEX_EMAIL_SMTP_PASS: # SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH: true # SHARELATEX_EMAIL_SMTP_IGNORE_TLS: false + # SHARELATEX_EMAIL_SMTP_NAME: '127.0.0.1' + # SHARELATEX_EMAIL_SMTP_LOGGER: true # SHARELATEX_CUSTOM_EMAIL_FOOTER: "This system is run by department x" ################ diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 91d07430a5..387532269a 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -285,6 +285,8 @@ if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? port: process.env["SHARELATEX_EMAIL_SMTP_PORT"], secure: parse(process.env["SHARELATEX_EMAIL_SMTP_SECURE"]) ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"]) + name: process.env["SHARELATEX_EMAIL_SMTP_NAME"] + logger: process.env["SHARELATEX_EMAIL_SMTP_LOGGER"] == 'true' textEncoding: process.env["SHARELATEX_EMAIL_TEXT_ENCODING"] template: From 41c2f0828885a3aafbf42c9e9484207ed06b427b Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 7 Apr 2021 14:20:19 +0100 Subject: [PATCH 494/525] Add the new `outputDir` setting for CLSI (#862) Co-authored-by: Shane Kilkelly Co-authored-by: Jakob Ackermann --- server-ce/settings.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 387532269a..475e7ca8f2 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -148,6 +148,8 @@ settings = compilesDir: Path.join(DATA_DIR, "compiles") # Where to cache downloaded URLs for the CLSI clsiCacheDir: Path.join(DATA_DIR, "cache") + # Where to write the output files to disk after running LaTeX + outputDir: Path.join(DATA_DIR, "output") # Server Config # ------------- From 9748c4421983b3ec1137600167a21759542d8bc6 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 7 Apr 2021 15:20:51 +0200 Subject: [PATCH 495/525] Updated base image to Node 12 (#865) --- server-ce/Dockerfile-base | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index 4f88faef9e..ff86658ce6 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -20,8 +20,8 @@ RUN apt-get update \ qpdf \ aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-nr aspell-ns aspell-pa aspell-pl aspell-pt aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu \ \ -# install Node.JS 10 -&& curl -sSL https://deb.nodesource.com/setup_10.x | bash - \ +# install Node.JS 12 +&& curl -sSL https://deb.nodesource.com/setup_12.x | bash - \ && apt-get install -y nodejs \ \ && rm -rf \ @@ -51,7 +51,7 @@ RUN npm install -g \ # -f Dockerfile-base -t sharelatex/sharelatex-base . ARG TEXLIVE_MIRROR=http://mirror.ctan.org/systems/texlive/tlnet -ENV PATH "${PATH}:/usr/local/texlive/2020/bin/x86_64-linux" +ENV PATH "${PATH}:/usr/local/texlive/2021/bin/x86_64-linux" RUN mkdir /install-tl-unx \ && curl -sSL \ From 3f7f2d5cedc32e64415285efdc644750c7e336ce Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Tue, 13 Apr 2021 21:50:32 +0200 Subject: [PATCH 496/525] [migrations] open source newly added indexes (#870) --- .../migrations/12_add_deletedFiles_indexes.js | 25 +++++++++++++++++ .../migrations/13_add_deleted_docs_index.js | 27 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 server-ce/migrations/12_add_deletedFiles_indexes.js create mode 100644 server-ce/migrations/13_add_deleted_docs_index.js diff --git a/server-ce/migrations/12_add_deletedFiles_indexes.js b/server-ce/migrations/12_add_deletedFiles_indexes.js new file mode 100644 index 0000000000..e16c77e7e5 --- /dev/null +++ b/server-ce/migrations/12_add_deletedFiles_indexes.js @@ -0,0 +1,25 @@ +// Internal ticket: https://github.com/overleaf/issues/issues/4094 + +const Settings = require('settings-sharelatex') +const mongojs = require('mongojs') +const db = mongojs(Settings.mongo.url, ['deletedFiles']) + +const INDEX_FILTER = { 'projectId_1': 1 } +const INDEX_OPTIONS = { + key: { + projectId: 1 + }, + background: 1 +} + +exports.migrate = (client, done) => { + db.deletedFiles.ensureIndex( + INDEX_FILTER, + INDEX_OPTIONS, + done + ) +} + +exports.rollback = (client, done) => { + db.deletedFiles.dropIndex(INDEX_FILTER, done) +} diff --git a/server-ce/migrations/13_add_deleted_docs_index.js b/server-ce/migrations/13_add_deleted_docs_index.js new file mode 100644 index 0000000000..be8f86c0d3 --- /dev/null +++ b/server-ce/migrations/13_add_deleted_docs_index.js @@ -0,0 +1,27 @@ +// Internal ticket: https://github.com/overleaf/issues/issues/4211 + +const Settings = require('settings-sharelatex') +const mongojs = require('mongojs') +const db = mongojs(Settings.mongo.url, ['docs']) + +const INDEX_FILTER = { 'project_id_deleted_deletedAt_1': 1 } +const INDEX_OPTIONS = { + key: { + project_id: 1, + deleted: 1, + deletedAt: -1 + }, + background: 1 +} + +exports.migrate = (client, done) => { + db.docs.ensureIndex( + INDEX_FILTER, + INDEX_OPTIONS, + done + ) +} + +exports.rollback = (client, done) => { + db.docs.dropIndex(INDEX_FILTER, done) +} From 507548d6615f9363d8047815b1172bbd0c0bb42a Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 14 Apr 2021 12:54:46 +0200 Subject: [PATCH 497/525] [migrations] fix index creation (#871) --- .../migrations/12_add_deletedFiles_indexes.js | 11 +++++------ .../migrations/13_add_deleted_docs_index.js | 17 +++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/server-ce/migrations/12_add_deletedFiles_indexes.js b/server-ce/migrations/12_add_deletedFiles_indexes.js index e16c77e7e5..cb6db59305 100644 --- a/server-ce/migrations/12_add_deletedFiles_indexes.js +++ b/server-ce/migrations/12_add_deletedFiles_indexes.js @@ -4,22 +4,21 @@ const Settings = require('settings-sharelatex') const mongojs = require('mongojs') const db = mongojs(Settings.mongo.url, ['deletedFiles']) -const INDEX_FILTER = { 'projectId_1': 1 } +const INDEX_NAME = 'projectId_1' +const INDEX_KEYS = { projectId: 1 } const INDEX_OPTIONS = { - key: { - projectId: 1 - }, + name: INDEX_NAME, background: 1 } exports.migrate = (client, done) => { db.deletedFiles.ensureIndex( - INDEX_FILTER, + INDEX_KEYS, INDEX_OPTIONS, done ) } exports.rollback = (client, done) => { - db.deletedFiles.dropIndex(INDEX_FILTER, done) + db.deletedFiles.dropIndex(INDEX_NAME, done) } diff --git a/server-ce/migrations/13_add_deleted_docs_index.js b/server-ce/migrations/13_add_deleted_docs_index.js index be8f86c0d3..be23e5ee3b 100644 --- a/server-ce/migrations/13_add_deleted_docs_index.js +++ b/server-ce/migrations/13_add_deleted_docs_index.js @@ -4,24 +4,25 @@ const Settings = require('settings-sharelatex') const mongojs = require('mongojs') const db = mongojs(Settings.mongo.url, ['docs']) -const INDEX_FILTER = { 'project_id_deleted_deletedAt_1': 1 } +const INDEX_NAME = 'project_id_deleted_deletedAt_1' +const INDEX_KEYS = { + project_id: 1, + deleted: 1, + deletedAt: -1 +} const INDEX_OPTIONS = { - key: { - project_id: 1, - deleted: 1, - deletedAt: -1 - }, + name: INDEX_NAME, background: 1 } exports.migrate = (client, done) => { db.docs.ensureIndex( - INDEX_FILTER, + INDEX_KEYS, INDEX_OPTIONS, done ) } exports.rollback = (client, done) => { - db.docs.dropIndex(INDEX_FILTER, done) + db.docs.dropIndex(INDEX_NAME, done) } From e63b28548702987af9f0d9bc22e62e5fa529f6e3 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 21 Apr 2021 13:13:47 +0200 Subject: [PATCH 498/525] hotfix 2.6.1 (#875) --- server-ce/hotfix/2.6.1/Dockerfile | 5 +++++ .../hotfix/2.6.1/document-deleter-object-id.patch | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 server-ce/hotfix/2.6.1/Dockerfile create mode 100644 server-ce/hotfix/2.6.1/document-deleter-object-id.patch diff --git a/server-ce/hotfix/2.6.1/Dockerfile b/server-ce/hotfix/2.6.1/Dockerfile new file mode 100644 index 0000000000..6df467b09b --- /dev/null +++ b/server-ce/hotfix/2.6.1/Dockerfile @@ -0,0 +1,5 @@ +FROM sharelatex/sharelatex:2.6.0-RC1 + +# Patch: fixes Project restore inserts bad projectId into deletedFiles +COPY document-deleter-object-id.patch ${baseDir} +RUN cd ${baseDir} && patch -p0 < document-deleter-object-id.patch diff --git a/server-ce/hotfix/2.6.1/document-deleter-object-id.patch b/server-ce/hotfix/2.6.1/document-deleter-object-id.patch new file mode 100644 index 0000000000..a92ce49a13 --- /dev/null +++ b/server-ce/hotfix/2.6.1/document-deleter-object-id.patch @@ -0,0 +1,10 @@ +--- /var/www/sharelatex/web/app/src/Features/Project/ProjectDeleter.js ++++ /var/www/sharelatex/web/app/src/Features/Project/ProjectDeleter.js +@@ -278,6 +278,7 @@ async function deleteProject(projectId, options = {}) { + } + + async function undeleteProject(projectId, options = {}) { ++ projectId = ObjectId(projectId) + let deletedProject = await DeletedProject.findOne({ + 'deleterData.deletedProjectId': projectId + }).exec() From 2045ae02d1223ef2a65fe2607e663ef9f9908518 Mon Sep 17 00:00:00 2001 From: John Lees-Miller Date: Thu, 13 May 2021 15:00:07 +0100 Subject: [PATCH 499/525] Make it clear that the screenshot is Server Pro --- server-ce/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-ce/README.md b/server-ce/README.md index 03c1f4d47f..8a1f300ddb 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -16,6 +16,9 @@

Overleaf +

+ Figure 1: A screenshot of Overleaf Server Pro's comments and tracked changes features. +

## Key Features From 00b6f094668c008c0a87d733e2bd404f47460688 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 20 May 2021 10:59:43 +0200 Subject: [PATCH 500/525] Hotfix 2.6.2 (#888) --- server-ce/hotfix/2.6.2/Dockerfile | 5 ++++ server-ce/hotfix/2.6.2/onboarding-email.patch | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 server-ce/hotfix/2.6.2/Dockerfile create mode 100644 server-ce/hotfix/2.6.2/onboarding-email.patch diff --git a/server-ce/hotfix/2.6.2/Dockerfile b/server-ce/hotfix/2.6.2/Dockerfile new file mode 100644 index 0000000000..2df365143e --- /dev/null +++ b/server-ce/hotfix/2.6.2/Dockerfile @@ -0,0 +1,5 @@ +FROM sharelatex/sharelatex:2.6.1 + +# Patch: fixes overleaf.com onboarding email being sent in CE/SP +COPY onboarding-email.patch ${baseDir} +RUN cd ${baseDir} && patch -p0 < onboarding-email.patch diff --git a/server-ce/hotfix/2.6.2/onboarding-email.patch b/server-ce/hotfix/2.6.2/onboarding-email.patch new file mode 100644 index 0000000000..2d1fed5686 --- /dev/null +++ b/server-ce/hotfix/2.6.2/onboarding-email.patch @@ -0,0 +1,25 @@ +--- /var/www/sharelatex/web/app/src/Features/User/UserCreator.js ++++ /var/www/sharelatex/web/app/src/Features/User/UserCreator.js +@@ -85,13 +85,15 @@ async function createNewUser(attributes, options = {}) { + } + + Analytics.recordEvent(user._id, 'user-registered') +- try { +- await UserOnboardingEmailQueueManager.scheduleOnboardingEmail(user) +- } catch (error) { +- logger.error( +- `Failed to schedule sending of onboarding email for user '${user._id}'`, +- error +- ) ++ if(Features.hasFeature('saas')) { ++ try { ++ await UserOnboardingEmailQueueManager.scheduleOnboardingEmail(user) ++ } catch (error) { ++ logger.error( ++ `Failed to schedule sending of onboarding email for user '${user._id}'`, ++ error ++ ) ++ } + } + + return user From acf603993b33e4cac35fabc8a0a577f4c759b57f Mon Sep 17 00:00:00 2001 From: John Lees-Miller Date: Mon, 14 Jun 2021 11:57:40 +0100 Subject: [PATCH 501/525] Fix some old README links Some of these were redirects / inconsistent. Also clarify wording for SP link. --- server-ce/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server-ce/README.md b/server-ce/README.md index 8a1f300ddb..8ed22e0e41 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -8,9 +8,9 @@

Key FeaturesWiki • - Server Pro • + Server ProContributing • - Mailing List • + Mailing ListAuthorsLicense

@@ -22,9 +22,9 @@ ## Key Features -[Overleaf](https://www.overleaf.com) is an open-source online real-time collaborative LaTeX editor. We run a hosted version at http://www.overleaf.com, but you can also run your own local version, and contribute to the development of Overleaf. +[Overleaf](https://www.overleaf.com) is an open-source online real-time collaborative LaTeX editor. We run a hosted version at [www.overleaf.com](https://www.overleaf.com), but you can also run your own local version, and contribute to the development of Overleaf. -*[If you want help installing and maintaining Overleaf at your university or workplace, we offer an officially supported version called Overleaf Server Pro. It also comes with extra security and admin features. Click here to find out more!](https://www.overleaf.com/university/onsite.html)* +*[If you want help installing and maintaining Overleaf in your lab or workplace, we offer an officially supported version called Overleaf Server Pro. It also comes with extra security and admin features. Click here to find out more!](https://www.overleaf.com/for/enterprises)* ## Keeping up to date From 35b414b624180bab32f31d13ba3dfda32d4f4ad1 Mon Sep 17 00:00:00 2001 From: Rainshaw Date: Tue, 15 Jun 2021 18:51:25 +0800 Subject: [PATCH 502/525] fix redis config (#895) * fix redis config when using redis on host machine without password auth --- server-ce/settings.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.coffee b/server-ce/settings.coffee index 475e7ca8f2..684bf18d53 100644 --- a/server-ce/settings.coffee +++ b/server-ce/settings.coffee @@ -54,7 +54,7 @@ settings = web: redisConfig = host: process.env["SHARELATEX_REDIS_HOST"] or "dockerhost" port: process.env["SHARELATEX_REDIS_PORT"] or "6379" - password: process.env["SHARELATEX_REDIS_PASS"] or "" + password: process.env["SHARELATEX_REDIS_PASS"] or undefined key_schema: # document-updater blockingKey: ({doc_id}) -> "Blocking:#{doc_id}" From 05885efe936282f728db61479eaa8491c30a5a3c Mon Sep 17 00:00:00 2001 From: Rainshaw Date: Thu, 24 Jun 2021 23:12:46 +0800 Subject: [PATCH 503/525] fix nginx conf (#896) * fix nginx conf --- server-ce/nginx/sharelatex.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server-ce/nginx/sharelatex.conf b/server-ce/nginx/sharelatex.conf index 8123e65bcd..723fb7fbe7 100644 --- a/server-ce/nginx/sharelatex.conf +++ b/server-ce/nginx/sharelatex.conf @@ -9,6 +9,7 @@ server { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 10m; @@ -20,6 +21,7 @@ server { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; From 984eb3bf2d4ede5a93eb8f338d4ccc8d80fd8a82 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 14:00:49 +0100 Subject: [PATCH 504/525] [perf] use docker layer caching from previous build --- server-ce/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server-ce/Makefile b/server-ce/Makefile index 55eca07ac2..4896799f31 100644 --- a/server-ce/Makefile +++ b/server-ce/Makefile @@ -2,9 +2,11 @@ SHARELATEX_BASE_TAG := sharelatex/sharelatex-base SHARELATEX_TAG := sharelatex/sharelatex +SHARELATEX_BASE_CACHE := $(shell echo $(SHARELATEX_BASE_TAG) | sed -E 's/(.+):.+/\1:latest/') build-base: - docker build -f Dockerfile-base -t $(SHARELATEX_BASE_TAG) . + docker pull $(SHARELATEX_BASE_CACHE) + docker build -f Dockerfile-base --pull --cache-from $(SHARELATEX_BASE_CACHE) -t $(SHARELATEX_BASE_TAG) . build-community: From d6928bc7fc00b09685087b7dc21ec474caf322dd Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 13:11:43 +0100 Subject: [PATCH 505/525] [perf] use npm ci --- server-ce/Dockerfile | 4 +- server-ce/bin/install-services | 2 +- server-ce/npm-shrinkwrap.json | 610 ------------- server-ce/package-lock.json | 1495 ++++++++++++++++++++++++++++++++ 4 files changed, 1498 insertions(+), 613 deletions(-) delete mode 100644 server-ce/npm-shrinkwrap.json create mode 100644 server-ce/package-lock.json diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index bf344b7c9a..f039da994e 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -16,7 +16,7 @@ ADD ${baseDir}/migrations /var/www/sharelatex/migrations ADD ${baseDir}/tasks /var/www/sharelatex/tasks ADD ${baseDir}/Gruntfile.coffee /var/www/sharelatex/Gruntfile.coffee ADD ${baseDir}/package.json /var/www/sharelatex/package.json -ADD ${baseDir}/npm-shrinkwrap.json /var/www/sharelatex/npm-shrinkwrap.json +ADD ${baseDir}/package-lock.json /var/www/sharelatex/package-lock.json ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js @@ -29,7 +29,7 @@ ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js # Checkout services # ----------------- RUN cd /var/www/sharelatex \ -&& npm install \ +&& npm ci \ && grunt install \ \ # Cleanup not needed artifacts diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services index b688a4b4f8..6f2d17e5b7 100755 --- a/server-ce/bin/install-services +++ b/server-ce/bin/install-services @@ -8,7 +8,7 @@ grep 'name:' config/services.js | \ do pushd $service echo "Installing service $service" - npm install --quiet + npm ci popd done diff --git a/server-ce/npm-shrinkwrap.json b/server-ce/npm-shrinkwrap.json deleted file mode 100644 index f5fd1370e1..0000000000 --- a/server-ce/npm-shrinkwrap.json +++ /dev/null @@ -1,610 +0,0 @@ -{ - "name": "sharelatex", - "version": "0.0.1", - "dependencies": { - "async": { - "version": "0.9.2", - "from": "async@>=0.9.0 <0.10.0", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz" - }, - "bson": { - "version": "1.0.4", - "from": "bson@>=1.0.4 <2.0.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz" - }, - "coffee-script": { - "version": "1.12.7", - "from": "coffee-script@>=1.11.1 <2.0.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz" - }, - "east": { - "version": "0.5.7", - "from": "east@0.5.7", - "resolved": "http://registry.npmjs.org/east/-/east-0.5.7.tgz", - "dependencies": { - "commander": { - "version": "2.9.0", - "from": "commander@2.9.0", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "dependencies": { - "graceful-readlink": { - "version": "1.0.1", - "from": "graceful-readlink@>=1.0.0", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" - } - } - }, - "expressionify": { - "version": "0.9.3", - "from": "expressionify@0.9.3", - "resolved": "http://registry.npmjs.org/expressionify/-/expressionify-0.9.3.tgz" - }, - "progress": { - "version": "1.1.8", - "from": "progress@1.1.8", - "resolved": "http://registry.npmjs.org/progress/-/progress-1.1.8.tgz" - }, - "twostep": { - "version": "0.4.2", - "from": "twostep@0.4.2", - "resolved": "http://registry.npmjs.org/twostep/-/twostep-0.4.2.tgz" - } - } - }, - "east-mongo": { - "version": "0.3.3", - "from": "east-mongo@0.3.3", - "resolved": "http://registry.npmjs.org/east-mongo/-/east-mongo-0.3.3.tgz" - }, - "grunt-shell": { - "version": "1.3.1", - "from": "grunt-shell@>=1.1.1 <2.0.0", - "resolved": "http://registry.npmjs.org/grunt-shell/-/grunt-shell-1.3.1.tgz", - "dependencies": { - "chalk": { - "version": "1.1.3", - "from": "chalk@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "from": "ansi-styles@>=2.2.1 <3.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" - }, - "escape-string-regexp": { - "version": "1.0.5", - "from": "escape-string-regexp@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - }, - "has-ansi": { - "version": "2.0.0", - "from": "has-ansi@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "from": "ansi-regex@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "from": "strip-ansi@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "from": "ansi-regex@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" - } - } - }, - "supports-color": { - "version": "2.0.0", - "from": "supports-color@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" - } - } - }, - "npm-run-path": { - "version": "1.0.0", - "from": "npm-run-path@>=1.0.0 <2.0.0", - "resolved": "http://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", - "dependencies": { - "path-key": { - "version": "1.0.0", - "from": "path-key@>=1.0.0 <2.0.0", - "resolved": "http://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz" - } - } - }, - "object-assign": { - "version": "4.1.1", - "from": "object-assign@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - } - } - }, - "load-grunt-config": { - "version": "0.19.2", - "from": "load-grunt-config@>=0.19.2 <0.20.0", - "resolved": "http://registry.npmjs.org/load-grunt-config/-/load-grunt-config-0.19.2.tgz", - "dependencies": { - "cson": { - "version": "3.0.2", - "from": "cson@>=3.0.2 <3.1.0", - "resolved": "http://registry.npmjs.org/cson/-/cson-3.0.2.tgz", - "dependencies": { - "cson-parser": { - "version": "1.3.5", - "from": "cson-parser@>=1.0.6 <2.0.0", - "resolved": "http://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz" - }, - "extract-opts": { - "version": "3.3.1", - "from": "extract-opts@>=3.0.1 <4.0.0", - "resolved": "http://registry.npmjs.org/extract-opts/-/extract-opts-3.3.1.tgz", - "dependencies": { - "eachr": { - "version": "3.2.0", - "from": "eachr@>=3.2.0 <4.0.0", - "resolved": "http://registry.npmjs.org/eachr/-/eachr-3.2.0.tgz" - }, - "editions": { - "version": "1.3.4", - "from": "editions@>=1.1.1 <2.0.0", - "resolved": "http://registry.npmjs.org/editions/-/editions-1.3.4.tgz" - }, - "typechecker": { - "version": "4.4.1", - "from": "typechecker@>=4.3.0 <5.0.0", - "resolved": "http://registry.npmjs.org/typechecker/-/typechecker-4.4.1.tgz" - } - } - }, - "requirefresh": { - "version": "2.1.0", - "from": "requirefresh@>=2.0.0 <3.0.0", - "resolved": "http://registry.npmjs.org/requirefresh/-/requirefresh-2.1.0.tgz", - "dependencies": { - "editions": { - "version": "1.3.4", - "from": "editions@>=1.1.1 <2.0.0", - "resolved": "http://registry.npmjs.org/editions/-/editions-1.3.4.tgz" - } - } - }, - "safefs": { - "version": "4.1.0", - "from": "safefs@>=4.0.0 <5.0.0", - "resolved": "http://registry.npmjs.org/safefs/-/safefs-4.1.0.tgz", - "dependencies": { - "editions": { - "version": "1.3.4", - "from": "editions@>=1.1.1 <2.0.0", - "resolved": "http://registry.npmjs.org/editions/-/editions-1.3.4.tgz" - }, - "graceful-fs": { - "version": "4.1.11", - "from": "graceful-fs@>=4.1.4 <5.0.0", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz" - } - } - } - } - }, - "glob": { - "version": "5.0.15", - "from": "glob@>=5.0.15 <5.1.0", - "resolved": "http://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "dependencies": { - "inflight": { - "version": "1.0.6", - "from": "inflight@>=1.0.4 <2.0.0", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "dependencies": { - "wrappy": { - "version": "1.0.2", - "from": "wrappy@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - } - } - }, - "inherits": { - "version": "2.0.3", - "from": "inherits@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - }, - "minimatch": { - "version": "3.0.4", - "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "dependencies": { - "brace-expansion": { - "version": "1.1.8", - "from": "brace-expansion@>=1.1.7 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "from": "balanced-match@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - } - } - } - } - }, - "once": { - "version": "1.4.0", - "from": "once@>=1.3.0 <2.0.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "dependencies": { - "wrappy": { - "version": "1.0.2", - "from": "wrappy@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - } - } - }, - "path-is-absolute": { - "version": "1.0.1", - "from": "path-is-absolute@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - } - } - }, - "jit-grunt": { - "version": "0.10.0", - "from": "jit-grunt@>=0.10.0 <0.11.0", - "resolved": "http://registry.npmjs.org/jit-grunt/-/jit-grunt-0.10.0.tgz" - }, - "js-yaml": { - "version": "3.4.6", - "from": "js-yaml@>=3.4.3 <3.5.0", - "resolved": "http://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz", - "dependencies": { - "argparse": { - "version": "1.0.9", - "from": "argparse@>=1.0.2 <2.0.0", - "resolved": "http://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "from": "sprintf-js@>=1.0.2 <1.1.0", - "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" - } - } - }, - "esprima": { - "version": "2.7.3", - "from": "esprima@>=2.6.0 <3.0.0", - "resolved": "http://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz" - }, - "inherit": { - "version": "2.2.6", - "from": "inherit@>=2.2.2 <3.0.0", - "resolved": "http://registry.npmjs.org/inherit/-/inherit-2.2.6.tgz" - } - } - }, - "load-grunt-tasks": { - "version": "3.3.0", - "from": "load-grunt-tasks@>=3.3.0 <3.4.0", - "resolved": "http://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.3.0.tgz", - "dependencies": { - "arrify": { - "version": "1.0.1", - "from": "arrify@>=1.0.0 <2.0.0", - "resolved": "http://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" - }, - "multimatch": { - "version": "2.1.0", - "from": "multimatch@>=2.0.0 <3.0.0", - "resolved": "http://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "dependencies": { - "array-differ": { - "version": "1.0.0", - "from": "array-differ@>=1.0.0 <2.0.0", - "resolved": "http://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz" - }, - "array-union": { - "version": "1.0.2", - "from": "array-union@>=1.0.1 <2.0.0", - "resolved": "http://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "dependencies": { - "array-uniq": { - "version": "1.0.3", - "from": "array-uniq@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" - } - } - }, - "minimatch": { - "version": "3.0.4", - "from": "minimatch@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "dependencies": { - "brace-expansion": { - "version": "1.1.8", - "from": "brace-expansion@>=1.1.7 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "from": "balanced-match@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - } - } - } - } - } - } - }, - "pkg-up": { - "version": "1.0.0", - "from": "pkg-up@>=1.0.0 <2.0.0", - "resolved": "http://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", - "dependencies": { - "find-up": { - "version": "1.1.2", - "from": "find-up@>=1.0.0 <2.0.0", - "resolved": "http://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "dependencies": { - "path-exists": { - "version": "2.1.0", - "from": "path-exists@>=2.0.0 <3.0.0", - "resolved": "http://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz" - }, - "pinkie-promise": { - "version": "2.0.1", - "from": "pinkie-promise@>=2.0.0 <3.0.0", - "resolved": "http://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "dependencies": { - "pinkie": { - "version": "2.0.4", - "from": "pinkie@>=2.0.0 <3.0.0", - "resolved": "http://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" - } - } - } - } - } - } - } - } - } - } - }, - "lodash": { - "version": "3.10.1", - "from": "lodash@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" - }, - "mongodb": { - "version": "2.2.34", - "from": "mongodb@>=2.2.34 <3.0.0", - "resolved": "http://registry.npmjs.org/mongodb/-/mongodb-2.2.34.tgz", - "dependencies": { - "es6-promise": { - "version": "3.2.1", - "from": "es6-promise@3.2.1", - "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz" - }, - "mongodb-core": { - "version": "2.1.18", - "from": "mongodb-core@2.1.18", - "resolved": "http://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", - "dependencies": { - "require_optional": { - "version": "1.0.1", - "from": "require_optional@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "dependencies": { - "semver": { - "version": "5.5.0", - "from": "semver@>=5.1.0 <6.0.0", - "resolved": "http://registry.npmjs.org/semver/-/semver-5.5.0.tgz" - }, - "resolve-from": { - "version": "2.0.0", - "from": "resolve-from@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz" - } - } - } - } - }, - "readable-stream": { - "version": "2.2.7", - "from": "readable-stream@2.2.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", - "dependencies": { - "buffer-shims": { - "version": "1.0.0", - "from": "buffer-shims@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" - }, - "core-util-is": { - "version": "1.0.2", - "from": "core-util-is@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - }, - "isarray": { - "version": "1.0.0", - "from": "isarray@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - }, - "inherits": { - "version": "2.0.3", - "from": "inherits@>=2.0.1 <2.1.0", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - }, - "process-nextick-args": { - "version": "1.0.7", - "from": "process-nextick-args@>=1.0.6 <1.1.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" - }, - "string_decoder": { - "version": "1.0.3", - "from": "string_decoder@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "dependencies": { - "safe-buffer": { - "version": "5.1.1", - "from": "safe-buffer@>=5.1.0 <5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "from": "util-deprecate@>=1.0.1 <1.1.0", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - } - } - } - } - }, - "mongojs": { - "version": "2.4.0", - "from": "mongojs@2.4.0", - "resolved": "http://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", - "dependencies": { - "each-series": { - "version": "1.0.0", - "from": "each-series@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz" - }, - "once": { - "version": "1.4.0", - "from": "once@>=1.3.2 <2.0.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "dependencies": { - "wrappy": { - "version": "1.0.2", - "from": "wrappy@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - } - } - }, - "parse-mongo-url": { - "version": "1.1.1", - "from": "parse-mongo-url@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz" - }, - "readable-stream": { - "version": "2.3.3", - "from": "readable-stream@>=2.0.2 <3.0.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "from": "core-util-is@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - }, - "inherits": { - "version": "2.0.3", - "from": "inherits@>=2.0.3 <2.1.0", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - }, - "isarray": { - "version": "1.0.0", - "from": "isarray@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - }, - "process-nextick-args": { - "version": "1.0.7", - "from": "process-nextick-args@>=1.0.6 <1.1.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" - }, - "safe-buffer": { - "version": "5.1.1", - "from": "safe-buffer@>=5.1.1 <5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" - }, - "string_decoder": { - "version": "1.0.3", - "from": "string_decoder@>=1.0.3 <1.1.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz" - }, - "util-deprecate": { - "version": "1.0.2", - "from": "util-deprecate@>=1.0.1 <1.1.0", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - } - } - }, - "thunky": { - "version": "0.1.0", - "from": "thunky@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz" - }, - "to-mongodb-core": { - "version": "2.0.0", - "from": "to-mongodb-core@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz" - }, - "xtend": { - "version": "4.0.1", - "from": "xtend@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" - } - } - }, - "redis": { - "version": "2.8.0", - "from": "redis@>=2.6.2 <3.0.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "dependencies": { - "double-ended-queue": { - "version": "2.1.0-0", - "from": "double-ended-queue@>=2.1.0-0 <3.0.0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz" - }, - "redis-commands": { - "version": "1.3.1", - "from": "redis-commands@>=1.2.0 <2.0.0", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz" - }, - "redis-parser": { - "version": "2.6.0", - "from": "redis-parser@>=2.6.0 <3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz" - } - } - }, - "rimraf": { - "version": "2.2.8", - "from": "rimraf@>=2.2.6 <2.3.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz" - }, - "settings-sharelatex": { - "version": "1.0.0", - "from": "git+https://github.com/sharelatex/settings-sharelatex.git", - "resolved": "git+https://github.com/sharelatex/settings-sharelatex.git#b4fb8404c5de571d029bf4c29e96a60b21206f94", - "dependencies": { - "coffee-script": { - "version": "1.6.0", - "from": "coffee-script@1.6.0", - "resolved": "http://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz" - } - } - }, - "underscore": { - "version": "1.8.3", - "from": "underscore@>=1.7.0 <2.0.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz" - } - } -} diff --git a/server-ce/package-lock.json b/server-ce/package-lock.json new file mode 100644 index 0000000000..62038e3213 --- /dev/null +++ b/server-ce/package-lock.json @@ -0,0 +1,1495 @@ +{ + "name": "sharelatex", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", + "dev": true + }, + "argparse": { + "version": "0.1.16", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", + "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=", + "dev": true, + "requires": { + "underscore": "~1.7.0", + "underscore.string": "~2.4.0" + }, + "dependencies": { + "underscore": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", + "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", + "dev": true + }, + "underscore.string": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz", + "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=", + "dev": true + } + } + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "bson": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz", + "integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw=" + }, + "bunyan": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.22.3.tgz", + "integrity": "sha1-ehncG0yMZF90AkGnQPIkUUfGfsI=", + "dev": true, + "requires": { + "dtrace-provider": "0.2.8", + "mv": "~2" + } + }, + "chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "dev": true, + "requires": { + "ansi-styles": "~1.0.0", + "has-color": "~0.1.0", + "strip-ansi": "~0.1.0" + } + }, + "coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" + }, + "colors": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "dateformat": { + "version": "1.0.2-1.2.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz", + "integrity": "sha1-sCIMAt6YYXQztyhRz0fePfLNvuk=", + "dev": true + }, + "debug": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", + "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", + "dev": true + }, + "dtrace-provider": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", + "integrity": "sha1-4kPxkhmqlfvw2PL/sH9b1k6U/iA=", + "dev": true, + "optional": true + }, + "east": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/east/-/east-0.5.7.tgz", + "integrity": "sha1-CCt+o8KzV5wEFlltDXCKznC0HLg=", + "requires": { + "commander": "2.9.0", + "expressionify": "0.9.3", + "progress": "1.1.8", + "twostep": "0.4.2" + }, + "dependencies": { + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "requires": { + "graceful-readlink": ">= 1.0.0" + }, + "dependencies": { + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + } + } + }, + "expressionify": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/expressionify/-/expressionify-0.9.3.tgz", + "integrity": "sha1-/iJnx+hpRXfxP02oML/DyNgXf5I=" + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" + }, + "twostep": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/twostep/-/twostep-0.4.2.tgz", + "integrity": "sha1-hLxQh6hxV00ev3vjB54D4SLUFbY=" + } + } + }, + "east-mongo": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/east-mongo/-/east-mongo-0.3.3.tgz", + "integrity": "sha1-WKtCdGaRy+ITtBweiG8EttyCq8A=" + }, + "esprima": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", + "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=", + "dev": true + }, + "eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "findup-sync": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz", + "integrity": "sha1-fz56l7gjksZTvwZYm9hRkOk8NoM=", + "dev": true, + "requires": { + "glob": "~3.2.9", + "lodash": "~2.4.1" + }, + "dependencies": { + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "dev": true, + "requires": { + "inherits": "2", + "minimatch": "0.3" + } + }, + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "dev": true, + "requires": { + "lru-cache": "2", + "sigmund": "~1.0.0" + } + } + } + }, + "getobject": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", + "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", + "dev": true + }, + "glob": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "dev": true, + "requires": { + "graceful-fs": "~1.2.0", + "inherits": "1", + "minimatch": "~0.2.11" + }, + "dependencies": { + "inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", + "dev": true + } + } + }, + "graceful-fs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", + "dev": true + }, + "grunt": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz", + "integrity": "sha1-VpN81RlDJK3/bSB2MYMqnWuk5/A=", + "dev": true, + "requires": { + "async": "~0.1.22", + "coffee-script": "~1.3.3", + "colors": "~0.6.2", + "dateformat": "1.0.2-1.2.3", + "eventemitter2": "~0.4.13", + "exit": "~0.1.1", + "findup-sync": "~0.1.2", + "getobject": "~0.1.0", + "glob": "~3.1.21", + "grunt-legacy-log": "~0.1.0", + "grunt-legacy-util": "~0.2.0", + "hooker": "~0.2.3", + "iconv-lite": "~0.2.11", + "js-yaml": "~2.0.5", + "lodash": "~0.9.2", + "minimatch": "~0.2.12", + "nopt": "~1.0.10", + "rimraf": "~2.2.8", + "underscore.string": "~2.2.1", + "which": "~1.0.5" + }, + "dependencies": { + "async": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", + "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=", + "dev": true + }, + "coffee-script": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz", + "integrity": "sha1-FQ1rTLUiiUNp7+1qIQHCC8f0pPQ=", + "dev": true + }, + "lodash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz", + "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=", + "dev": true + } + } + }, + "grunt-available-tasks": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/grunt-available-tasks/-/grunt-available-tasks-0.4.5.tgz", + "integrity": "sha1-a99ifacQJ7pD6ypjaIansUVh5dE=", + "dev": true, + "requires": { + "lodash": "~2.4.0", + "underscore.string": "~2.3.3" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "underscore.string": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", + "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", + "dev": true + } + } + }, + "grunt-bunyan": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/grunt-bunyan/-/grunt-bunyan-0.5.0.tgz", + "integrity": "sha1-aCnXbgGZQ9owQTk2MaNuKsgpsWw=", + "dev": true, + "requires": { + "lodash": "~2.4.1" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + } + } + }, + "grunt-concurrent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/grunt-concurrent/-/grunt-concurrent-0.4.3.tgz", + "integrity": "sha1-JFNJAYVZTInYOZ87GENHb2hp5J0=", + "dev": true, + "requires": { + "async": "~0.2.9", + "lpad": "~0.1.0" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true + } + } + }, + "grunt-contrib-coffee": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/grunt-contrib-coffee/-/grunt-contrib-coffee-0.10.1.tgz", + "integrity": "sha1-7SLGgp9FiqjqR/hnaEM+mBMUAYY=", + "dev": true, + "requires": { + "chalk": "~0.4.0", + "coffee-script": "~1.7.0", + "lodash": "~2.4.1" + }, + "dependencies": { + "coffee-script": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz", + "integrity": "sha1-YplqhheAx15tUGnROCJyO3NAS/w=", + "dev": true, + "requires": { + "mkdirp": "~0.3.5" + } + }, + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "dev": true + } + } + }, + "grunt-execute": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/grunt-execute/-/grunt-execute-0.1.5.tgz", + "integrity": "sha1-yX64lDYS/vu3L749Mu+VIzxfouk=", + "dev": true + }, + "grunt-legacy-log": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz", + "integrity": "sha1-7ClCboAwIa9ZAp+H0vnNczWgVTE=", + "dev": true, + "requires": { + "colors": "~0.6.2", + "grunt-legacy-log-utils": "~0.1.1", + "hooker": "~0.2.3", + "lodash": "~2.4.1", + "underscore.string": "~2.3.3" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "underscore.string": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", + "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", + "dev": true + } + } + }, + "grunt-legacy-log-utils": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz", + "integrity": "sha1-wHBrndkGThFvNvI/5OawSGcsD34=", + "dev": true, + "requires": { + "colors": "~0.6.2", + "lodash": "~2.4.1", + "underscore.string": "~2.3.3" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "underscore.string": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", + "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", + "dev": true + } + } + }, + "grunt-legacy-util": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz", + "integrity": "sha1-kzJIhNv343qf98Am3/RR2UqeVUs=", + "dev": true, + "requires": { + "async": "~0.1.22", + "exit": "~0.1.1", + "getobject": "~0.1.0", + "hooker": "~0.2.3", + "lodash": "~0.9.2", + "underscore.string": "~2.2.1", + "which": "~1.0.5" + }, + "dependencies": { + "async": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", + "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=", + "dev": true + }, + "lodash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz", + "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=", + "dev": true + } + } + }, + "grunt-shell": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-1.3.1.tgz", + "integrity": "sha1-XivuzQXV03h/pAECjVcz1dQ7m9E=", + "requires": { + "chalk": "^1.0.0", + "npm-run-path": "^1.0.0", + "object-assign": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "npm-run-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", + "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", + "requires": { + "path-key": "^1.0.0" + }, + "dependencies": { + "path-key": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", + "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=" + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, + "has-color": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", + "dev": true + }, + "hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true + }, + "iconv-lite": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz", + "integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "js-yaml": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz", + "integrity": "sha1-olrmUJmZ6X3yeMZxnaEb0Gh3Q6g=", + "dev": true, + "requires": { + "argparse": "~ 0.1.11", + "esprima": "~ 1.0.2" + } + }, + "knox": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/knox/-/knox-0.8.10.tgz", + "integrity": "sha1-ai7c2sHSrjedHhmU1Vm5XCg7JYg=", + "dev": true, + "requires": { + "debug": "~0.7.0", + "mime": "*", + "stream-counter": "~0.1.0", + "xml2js": "0.2.x" + } + }, + "load-grunt-config": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/load-grunt-config/-/load-grunt-config-0.19.2.tgz", + "integrity": "sha1-UgkNSiDG5j90p2SPJJsZ57f87CQ=", + "requires": { + "cson": "~3.0.2", + "glob": "~5.0.15", + "jit-grunt": "~0.10.0", + "js-yaml": "~3.4.3", + "load-grunt-tasks": "~3.3.0", + "lodash": "~3.10.1" + }, + "dependencies": { + "cson": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/cson/-/cson-3.0.2.tgz", + "integrity": "sha1-g+6Qids8JUvsHpjkmNmqzxGtzFQ=", + "requires": { + "coffee-script": "^1.9.0", + "cson-parser": "^1.0.6", + "extract-opts": "^3.0.1", + "requirefresh": "^2.0.0", + "safefs": "^4.0.0" + }, + "dependencies": { + "cson-parser": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz", + "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=", + "requires": { + "coffee-script": "^1.10.0" + } + }, + "extract-opts": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/extract-opts/-/extract-opts-3.3.1.tgz", + "integrity": "sha1-WrvtyYwNUgLjJ4cn+Rktfghsa+E=", + "requires": { + "eachr": "^3.2.0", + "editions": "^1.1.1", + "typechecker": "^4.3.0" + }, + "dependencies": { + "eachr": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eachr/-/eachr-3.2.0.tgz", + "integrity": "sha1-LDXkPqCGUW95l8+At6pk1VpKRIQ=", + "requires": { + "editions": "^1.1.1", + "typechecker": "^4.3.0" + } + }, + "editions": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", + "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" + }, + "typechecker": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-4.4.1.tgz", + "integrity": "sha1-+XuV9RsDhBchLWd9RaNz7nvO1+Y=", + "requires": { + "editions": "^1.3.3" + } + } + } + }, + "requirefresh": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/requirefresh/-/requirefresh-2.1.0.tgz", + "integrity": "sha1-dC3Mwg86lpGNZsbxWX3I/+vE9vU=", + "requires": { + "editions": "^1.1.1" + }, + "dependencies": { + "editions": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", + "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" + } + } + }, + "safefs": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/safefs/-/safefs-4.1.0.tgz", + "integrity": "sha1-+CrrS9165R9lPrIPZyizBYyNZEU=", + "requires": { + "editions": "^1.1.1", + "graceful-fs": "^4.1.4" + }, + "dependencies": { + "editions": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", + "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + } + } + } + } + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + } + } + } + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + } + } + }, + "jit-grunt": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/jit-grunt/-/jit-grunt-0.10.0.tgz", + "integrity": "sha1-AIw6f+Hpa9DYTiYOofoXg0V/ecI=" + }, + "js-yaml": { + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz", + "integrity": "sha1-a+GyP2JJ9T0pM3D9TRqqY84bTrA=", + "requires": { + "argparse": "^1.0.2", + "esprima": "^2.6.0", + "inherit": "^2.2.2" + }, + "dependencies": { + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "requires": { + "sprintf-js": "~1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + } + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" + }, + "inherit": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/inherit/-/inherit-2.2.6.tgz", + "integrity": "sha1-8WFLBshUToEo5CKchjR9tzrZeI0=" + } + } + }, + "load-grunt-tasks": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.3.0.tgz", + "integrity": "sha1-vliSkJRY2T3fdp60vGhRAggMYyE=", + "requires": { + "arrify": "^1.0.0", + "multimatch": "^2.0.0", + "pkg-up": "^1.0.0" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "requires": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + }, + "dependencies": { + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "^1.0.1" + }, + "dependencies": { + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + } + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + } + } + } + } + } + } + }, + "pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", + "requires": { + "find-up": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + } + } + } + } + } + } + } + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + }, + "lpad": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lpad/-/lpad-0.1.0.tgz", + "integrity": "sha1-5MYMKROTIcWXDeSTtJauDXdM0qc=", + "dev": true + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "dev": true, + "requires": { + "lru-cache": "2", + "sigmund": "~1.0.0" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true, + "optional": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mongodb": { + "version": "2.2.34", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.34.tgz", + "integrity": "sha1-o09Zu+thdUrsQy3nLD/iFSakTBo=", + "requires": { + "es6-promise": "3.2.1", + "mongodb-core": "2.1.18", + "readable-stream": "2.2.7" + }, + "dependencies": { + "es6-promise": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, + "mongodb-core": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", + "integrity": "sha1-TEYTm986HwMt7ZHbSfOO7AFlkFA=", + "requires": { + "bson": "~1.0.4", + "require_optional": "~1.0.0" + }, + "dependencies": { + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + }, + "dependencies": { + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + } + } + } + } + }, + "readable-stream": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", + "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "requires": { + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + } + } + } + } + }, + "mongojs": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", + "integrity": "sha1-8of7/UV/7fWItakBHmhRPZ3TK/s=", + "requires": { + "each-series": "^1.0.0", + "mongodb": "^2.0.45", + "once": "^1.3.2", + "parse-mongo-url": "^1.1.0", + "readable-stream": "^2.0.2", + "thunky": "^0.1.0", + "to-mongodb-core": "^2.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", + "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } + }, + "parse-mongo-url": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", + "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + } + } + }, + "thunky": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", + "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" + }, + "to-mongodb-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", + "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } + }, + "mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "dev": true, + "optional": true, + "requires": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "optional": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "dev": true, + "optional": true, + "requires": { + "glob": "^6.0.1" + } + } + } + }, + "ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "dev": true, + "optional": true + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "optional": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "redis": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", + "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", + "requires": { + "double-ended-queue": "^2.1.0-0", + "redis-commands": "^1.2.0", + "redis-parser": "^2.6.0" + }, + "dependencies": { + "double-ended-queue": { + "version": "2.1.0-0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" + }, + "redis-commands": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz", + "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=" + }, + "redis-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", + "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" + } + } + }, + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" + }, + "sax": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", + "dev": true + }, + "semver": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-2.2.1.tgz", + "integrity": "sha1-eUEYKz/8xYC/8cF5QqzfeVHA0hM=", + "dev": true + }, + "settings-sharelatex": { + "version": "git+https://github.com/sharelatex/settings-sharelatex.git#b4fb8404c5de571d029bf4c29e96a60b21206f94", + "from": "git+https://github.com/sharelatex/settings-sharelatex.git", + "requires": { + "coffee-script": "1.6.0" + }, + "dependencies": { + "coffee-script": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", + "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" + } + } + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "stream-counter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-0.1.0.tgz", + "integrity": "sha1-oDXkKTYftX82Fgbhf82Ki5Z3Mns=", + "dev": true, + "requires": { + "readable-stream": "~1.0.2" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "underscore.string": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz", + "integrity": "sha1-18D6KvXVoaZ/QlPa7pgTLnM/Dxk=", + "dev": true + }, + "which": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", + "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true, + "optional": true + }, + "xml2js": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.8.tgz", + "integrity": "sha1-m4FpCTFjH/CdGVdUn69U9PmAs8I=", + "dev": true, + "requires": { + "sax": "0.5.x" + } + } + } +} From aa5a9b0e65715de1a87842784aa8674c72752ee7 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 13:14:55 +0100 Subject: [PATCH 506/525] [perf] use npm ci --only=production for all but web --- server-ce/bin/install-services | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services index 6f2d17e5b7..becf174cc1 100755 --- a/server-ce/bin/install-services +++ b/server-ce/bin/install-services @@ -8,7 +8,15 @@ grep 'name:' config/services.js | \ do pushd $service echo "Installing service $service" - npm ci + case $service in + web) + # install webpack and friends from dev-dependencies. + npm ci + ;; + *) + npm ci --only=production + ;; + esac popd done From c8dcf853bc3d2e6f6e17d315a92dc6af73e4683c Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 8 Jul 2021 10:08:34 +0100 Subject: [PATCH 507/525] Remove migrations These will be replaced by migrations in the web project --- server-ce/Dockerfile | 1 - server-ce/Gruntfile.coffee | 16 - server-ce/init_scripts/99_migrate.sh | 8 - .../migrations/10_update_project_tokens.js | 109 ------ .../migrations/11_set_project_image_name.js | 23 -- .../migrations/12_add_deletedFiles_indexes.js | 24 -- .../migrations/13_add_deleted_docs_index.js | 28 -- .../1_move_doc_lines_to_doc_collection.coffee | 164 --------- .../2_doc_lines_delete_from_project.coffee | 185 ---------- .../3_pack_docHistory_collection.coffee | 342 ------------------ .../migrations/4_update_user_features.coffee | 38 -- .../5_remove_holding_accounts.coffee | 103 ------ .../6_add_track_changes_feature.coffee | 30 -- .../migrations/7_add_token_indexes.coffee | 51 --- .../7_add_track_changes_feature_again.coffee | 31 -- .../migrations/9_create_user_emails_array.js | 49 --- server-ce/migrations/about_migrations.md | 9 - 17 files changed, 1211 deletions(-) delete mode 100755 server-ce/init_scripts/99_migrate.sh delete mode 100644 server-ce/migrations/10_update_project_tokens.js delete mode 100644 server-ce/migrations/11_set_project_image_name.js delete mode 100644 server-ce/migrations/12_add_deletedFiles_indexes.js delete mode 100644 server-ce/migrations/13_add_deleted_docs_index.js delete mode 100644 server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee delete mode 100644 server-ce/migrations/2_doc_lines_delete_from_project.coffee delete mode 100644 server-ce/migrations/3_pack_docHistory_collection.coffee delete mode 100644 server-ce/migrations/4_update_user_features.coffee delete mode 100644 server-ce/migrations/5_remove_holding_accounts.coffee delete mode 100644 server-ce/migrations/6_add_track_changes_feature.coffee delete mode 100644 server-ce/migrations/7_add_token_indexes.coffee delete mode 100644 server-ce/migrations/7_add_track_changes_feature_again.coffee delete mode 100644 server-ce/migrations/9_create_user_emails_array.js delete mode 100644 server-ce/migrations/about_migrations.md diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index f039da994e..ace431967f 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -12,7 +12,6 @@ ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee # ------------------------- ADD ${baseDir}/bin /var/www/sharelatex/bin ADD ${baseDir}/doc /var/www/sharelatex/doc -ADD ${baseDir}/migrations /var/www/sharelatex/migrations ADD ${baseDir}/tasks /var/www/sharelatex/tasks ADD ${baseDir}/Gruntfile.coffee /var/www/sharelatex/Gruntfile.coffee ADD ${baseDir}/package.json /var/www/sharelatex/package.json diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.coffee index 3af76ef763..9375096d62 100644 --- a/server-ce/Gruntfile.coffee +++ b/server-ce/Gruntfile.coffee @@ -38,20 +38,6 @@ module.exports = (grunt) -> options: limit: SERVICES.length logConcurrentOutput: true - coffee: - migrate: - expand: true, - flatten: false, - cwd: './', - src: ['./migrations/*.coffee'], - dest: './', - ext: '.js' - options: - bare:true - - shell: - migrate: - command: "./node_modules/east/bin/east migrate --adapter east-mongo --url #{settings?.mongo?.url}" availabletasks: tasks: @@ -115,8 +101,6 @@ module.exports = (grunt) -> grunt.registerTask "check:make", "Check that make is installed", () -> Helpers.checkMake @async() - grunt.registerTask 'migrate', "compile migrations and run them", ["coffee:migrate", 'shell:migrate'] - Helpers = installService: (service, callback = (error) ->) -> diff --git a/server-ce/init_scripts/99_migrate.sh b/server-ce/init_scripts/99_migrate.sh deleted file mode 100755 index f880fa816f..0000000000 --- a/server-ce/init_scripts/99_migrate.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -set -e - -which node -which grunt -ls -al /var/www/sharelatex/migrations -cd /var/www/sharelatex && grunt migrate -v -echo "All migrations finished" diff --git a/server-ce/migrations/10_update_project_tokens.js b/server-ce/migrations/10_update_project_tokens.js deleted file mode 100644 index 57095308f8..0000000000 --- a/server-ce/migrations/10_update_project_tokens.js +++ /dev/null @@ -1,109 +0,0 @@ -const Settings = require('settings-sharelatex') -const Async = require('async') -const mongojs = require('mongojs') -const db = mongojs(Settings.mongo.url, ['users']) - -const indexKeys = { 'tokens.readAndWritePrefix': 1 } -const indexOpts = { - unique: true, - partialFilterExpression: { - 'tokens.readAndWritePrefix': { $exists: true } - }, - background: true -} - -// Index on Prefix -const addReadAndWritePrefixIndex = (db, callback) => { - db.projects.ensureIndex(indexKeys, indexOpts, callback) -} - -const removeReadAndWritePrefixIndex = (db, callback) => { - db.projects.dropIndex(indexKeys, callback) -} - -// Extract prefix data -const extractPrefix = (db, callback) => { - db.projects.find( - { - 'tokens.readAndWrite': { $exists: true }, - 'tokens.readAndWritePrefix': { $exists: false } - }, - { tokens: 1 }, - (err, projects) => { - if (err) { - return callback(err) - } - console.log(`>> Updating ${projects.length} projects`) - Async.eachLimit( - projects, - 5, - (project, cb) => { - const rwToken = project.tokens.readAndWrite - const prefixMatch = rwToken.match(/^(\d+).*$/) - if (!prefixMatch) { - const err = new Error( - `no prefix on token: ${project._id}, ${rwToken}` - ) - console.log(`>> Error, ${err.message}`) - return cb(err) - } - db.projects.update( - { _id: project._id }, - { $set: { 'tokens.readAndWritePrefix': prefixMatch[1] } }, - cb - ) - }, - err => { - if (err) { - return callback(err) - } - console.log('>> done') - callback() - } - ) - } - ) -} - -const erasePrefix = (db, callback) => { - db.projects.update({$unset: 'tokens.readAndWritePrefix'}, callback) -} - - -// Migrations - -exports.migrate = (client, done) => { - console.log(`>> Adding index to projects: ${JSON.stringify(indexKeys)}, with options: ${JSON.stringify(indexOpts)}`) - addReadAndWritePrefixIndex(db, (err) => { - if(err) { - console.log(">> Error while adding index") - return done(err) - } - console.log(">> Extracting tokens.readAndWritePrefix field for existing projects") - extractPrefix(db, (err) => { - if(err) { - console.log(">> Error while extracting prefix data") - return done(err) - } - done() - }) - }) -} - -exports.rollback = (client, done) => { - console.log(`>> Dropping index on projects: ${JSON.stringify(indexKeys)}`) - removeReadAndWritePrefixIndex(db, (err) => { - if(err) { - console.log(">> Error while dropping index") - return done(err) - } - console.log(">> Erasing tokens.readAndWritePrefix field for existing projects") - erasePrefix(db, (err) => { - if(err) { - console.log(">> Error while erasing prefix data") - return done(err) - } - done() - }) - }) -} diff --git a/server-ce/migrations/11_set_project_image_name.js b/server-ce/migrations/11_set_project_image_name.js deleted file mode 100644 index 17c06fd6fc..0000000000 --- a/server-ce/migrations/11_set_project_image_name.js +++ /dev/null @@ -1,23 +0,0 @@ -const Settings = require('settings-sharelatex') -const mongojs = require('mongojs') -const db = mongojs(Settings.mongo.url, ['projects']) - -exports.migrate = (client, done) => { - console.log(`>> Setting 'imageName' in projects`) - - if (!Settings.currentImageName) { - console.log(`>> 'currentImageName' is not defined, no projects updated`) - return done() - } - - console.log(`>> Setting 'imageName' = ${Settings.currentImageName}`) - - db.projects.update( - { imageName: { $exists: false } }, - { $set: { imageName: Settings.currentImageName } }, - { multi: true }, - done - ) -} - -exports.rollback = (client, done) => done() diff --git a/server-ce/migrations/12_add_deletedFiles_indexes.js b/server-ce/migrations/12_add_deletedFiles_indexes.js deleted file mode 100644 index cb6db59305..0000000000 --- a/server-ce/migrations/12_add_deletedFiles_indexes.js +++ /dev/null @@ -1,24 +0,0 @@ -// Internal ticket: https://github.com/overleaf/issues/issues/4094 - -const Settings = require('settings-sharelatex') -const mongojs = require('mongojs') -const db = mongojs(Settings.mongo.url, ['deletedFiles']) - -const INDEX_NAME = 'projectId_1' -const INDEX_KEYS = { projectId: 1 } -const INDEX_OPTIONS = { - name: INDEX_NAME, - background: 1 -} - -exports.migrate = (client, done) => { - db.deletedFiles.ensureIndex( - INDEX_KEYS, - INDEX_OPTIONS, - done - ) -} - -exports.rollback = (client, done) => { - db.deletedFiles.dropIndex(INDEX_NAME, done) -} diff --git a/server-ce/migrations/13_add_deleted_docs_index.js b/server-ce/migrations/13_add_deleted_docs_index.js deleted file mode 100644 index be23e5ee3b..0000000000 --- a/server-ce/migrations/13_add_deleted_docs_index.js +++ /dev/null @@ -1,28 +0,0 @@ -// Internal ticket: https://github.com/overleaf/issues/issues/4211 - -const Settings = require('settings-sharelatex') -const mongojs = require('mongojs') -const db = mongojs(Settings.mongo.url, ['docs']) - -const INDEX_NAME = 'project_id_deleted_deletedAt_1' -const INDEX_KEYS = { - project_id: 1, - deleted: 1, - deletedAt: -1 -} -const INDEX_OPTIONS = { - name: INDEX_NAME, - background: 1 -} - -exports.migrate = (client, done) => { - db.docs.ensureIndex( - INDEX_KEYS, - INDEX_OPTIONS, - done - ) -} - -exports.rollback = (client, done) => { - db.docs.dropIndex(INDEX_NAME, done) -} diff --git a/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee b/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee deleted file mode 100644 index ce8c208657..0000000000 --- a/server-ce/migrations/1_move_doc_lines_to_doc_collection.coffee +++ /dev/null @@ -1,164 +0,0 @@ -Settings = require "settings-sharelatex" -bson = require('bson') -BSON = new bson() -fs = require("fs") -mongojs = require("mongojs") -ObjectId = mongojs.ObjectId -console.log Settings.mongo.url -db = mongojs(Settings.mongo.url, ['projects', 'docs']) -_ = require("lodash") -async = require("async") -exec = require("child_process").exec - -finished_projects_path = "/tmp/finished-projects" -all_projects_path = "/tmp/all-projects" -project_too_large_path = "/tmp/large_projects" - - -printProgress = -> - exec "wc #{finished_projects_path}", (error, results) -> - setTimeout printProgress, 1000 * 30 - -checkIfFileHasBeenProcessed = (project_id, callback)-> - exec "grep #{project_id} #{finished_projects_path}", (error, results) -> - hasBeenProcessed = _.include(results, project_id) - callback(error, hasBeenProcessed) - -loadProjectIds = (callback)-> - console.log "loading project ids from #{all_projects_path}" - fs.readFile all_projects_path, "utf-8", (err, data)-> - ids = data.split("\n") - ids = _.filter ids, (id)-> id? and id.length == 24 - console.log "loaded #{ids.length} project ids from #{all_projects_path}" - callback err, ids - -getAndWriteProjectids = (callback)-> - console.log "finding all project id's - #{new Date().toString()}" - db.projects.find {}, {_id:1}, (err, ids)-> - console.log "total found projects in mongo #{ids.length} - #{new Date().toString()}" - ids = _.pluck ids, '_id' - ids = _.filter ids, (id)-> id? - fileData = ids.join("\n") - fs.writeFile all_projects_path, fileData, -> - callback(err, ids) - -markProjectAsToLargeAndFinished = (project_id, callback)-> - console.log "#{project_id} too large" - markProjectAsProcessed project_id, (err)-> - fs.appendFile project_too_large_path, "#{project_id}\n", callback - -getProjectIds = (callback)-> - exists = fs.existsSync all_projects_path - if exists - loadProjectIds callback - else - getAndWriteProjectids callback - -markProjectAsProcessed = (project_id, callback)-> - fs.appendFile finished_projects_path, "#{project_id}\n", callback - -getAllDocs = (project_id, callback = (error, docs) ->) -> - db.projects.findOne _id:ObjectId(project_id), (error, project) -> - return callback(error) if error? - if !project? - console.log "no such project #{project_id}" - return callback() - size = BSON.calculateObjectSize(project) - if size > 12000000 #12mb - return markProjectAsToLargeAndFinished project_id, callback - findAllDocsInProject project, (error, docs) -> - return callback(error) if error? - return callback null, docs - -findAllDocsInProject = (project, callback = (error, docs) ->) -> - callback null, _findAllDocsInFolder project.rootFolder[0] - -_findDocInFolder = (folder = {}, doc_id, currentPath) -> - for doc, i in folder.docs or [] - if doc?._id? and doc._id.toString() == doc_id.toString() - return { - doc: doc - mongoPath: "#{currentPath}.docs.#{i}" - } - - for childFolder, i in folder.folders or [] - result = _findDocInFolder childFolder, doc_id, "#{currentPath}.folders.#{i}" - return result if result? - - return null - -_findAllDocsInFolder = (folder = {}) -> - docs = folder.docs or [] - for childFolder in folder.folders or [] - docs = docs.concat _findAllDocsInFolder childFolder - return docs - -insertDocIntoDocCollection = (project_id, doc_id, lines, oldRev, callback)-> - if !project_id? - return callback("no project id") - if !doc_id? - return callback() - if !lines? - lines = [""] - update = {} - update["_id"] = ObjectId(doc_id.toString()) - update["lines"] = lines - update["project_id"] = ObjectId(project_id) - update["rev"] = oldRev || 0 - db.docs.insert update, callback - -saveDocsIntoMongo = (project_id, docs, callback)-> - jobs = _.map docs, (doc)-> - (cb)-> - if !doc? - console.error "null doc in project #{project_id}" #just skip it, not a big deal - return cb() - insertDocIntoDocCollection project_id, doc._id, doc.lines, doc.rev, (err)-> - if err?.code == 11000 #duplicate key, doc already in there so its not a problem. - err = undefined - if err? - console.log "error inserting doc into doc collection", err - cb(err) - - - async.series jobs, callback - - -processNext = (project_id, callback)-> - checkIfFileHasBeenProcessed project_id, (err, hasBeenProcessed)-> - if hasBeenProcessed - console.log "#{project_id} already processed, skipping" - return callback() - console.log "#{project_id} processing" - getAllDocs project_id, (err, docs)-> - if err? - console.error err, project_id, "could not get all docs" - return callback(err) - else - saveDocsIntoMongo project_id, docs, (err)-> - if err? - console.error err, project_id, "could not save docs into mongo" - return callback(err) - markProjectAsProcessed project_id, (err)-> - setTimeout( - -> callback(err) - ,0) - - - -exports.migrate = (client, done = ->)-> - getProjectIds (err, ids)-> - printProgress() - jobs = _.map ids, (id)-> - return (cb)-> - processNext(id, cb) - async.series jobs, (err)-> - if err? - console.error err, "at end of jobs" - else - console.log "finished" - done(err) - - -exports.rollback = (next)-> - next() diff --git a/server-ce/migrations/2_doc_lines_delete_from_project.coffee b/server-ce/migrations/2_doc_lines_delete_from_project.coffee deleted file mode 100644 index 0be28446d8..0000000000 --- a/server-ce/migrations/2_doc_lines_delete_from_project.coffee +++ /dev/null @@ -1,185 +0,0 @@ -Settings = require "settings-sharelatex" -fs = require("fs") -mongojs = require("mongojs") -ObjectId = mongojs.ObjectId -db = mongojs(Settings.mongo.url, ['projects', 'docs']) -_ = require("lodash") -async = require("async") -exec = require("child_process").exec - -finished_projects_path = "/tmp/finished-projects-2" -all_projects_path = "/tmp/all-projects-2" -unmigrated_docs_path = "/tmp/unmigrated-2" - - -printProgress = -> - exec "wc #{finished_projects_path}", (error, results) -> - setTimeout printProgress, 1000 * 30 - -checkIfFileHasBeenProcessed = (project_id, callback)-> - exec "grep #{project_id} #{finished_projects_path}", (error, results) -> - hasBeenProcessed = _.include(results, project_id) - callback(error, hasBeenProcessed) - -loadProjectIds = (callback)-> - console.log "loading project ids from #{all_projects_path}" - fs.readFile all_projects_path, "utf-8", (err, data)-> - ids = data.split("\n") - ids = _.filter ids, (id)-> id? and id.length == 24 - console.log "loaded #{ids.length} project ids from #{all_projects_path}" - callback err, ids - -getAndWriteProjectids = (callback)-> - console.log "finding all project id's - #{new Date().toString()}" - db.projects.find {}, {_id:1}, (err, ids)-> - console.log "total found projects in mongo #{ids.length} - #{new Date().toString()}" - ids = _.pluck ids, '_id' - ids = _.filter ids, (id)-> id? - fileData = ids.join("\n") - fs.writeFile all_projects_path, fileData, -> - callback(err, ids) - -markDocAsUnmigrated = (project_id, doc_id, callback)-> - console.log "#{project_id} #{doc_id} unmigrated" - markProjectAsProcessed project_id, (err)-> - fs.appendFile unmigrated_docs_path, "#{project_id} #{doc_id}\n", callback - -markUnmigratedDocs = (project_id, docs, callback)-> - console.log docs.length, project_id, "unmigrated" - jobs = _.map docs, (doc)-> - (cb)-> - markDocAsUnmigrated project_id, doc._id, cb - async.series jobs, callback - -getProjectIds = (callback)-> - exists = fs.existsSync all_projects_path - if exists - loadProjectIds callback - else - getAndWriteProjectids callback - -markProjectAsProcessed = (project_id, callback)-> - fs.appendFile finished_projects_path, "#{project_id}\n", callback - -getAllDocs = (project_id, callback = (error, docs) ->) -> - excludes = {} - for i in [0..12] - excludes["rootFolder#{Array(i).join(".folders")}.docs.lines"] = 0 - db.projects.findOne _id: ObjectId(project_id.toString()), excludes, (error, project) -> - return callback(error) if error? - if !project? - console.log "no such project #{project_id}" - return callback() - findAllDocsInProject project, (error, docs) -> - return callback(error) if error? - return callback null, docs, project - -findAllDocsInProject = (project, callback = (error, docs) ->) -> - callback null, _findAllDocsInFolder project.rootFolder[0] - -findDocInProject = (project, doc_id, callback = (error, doc, mongoPath) ->) -> - result = _findDocInFolder project.rootFolder[0], doc_id, "rootFolder.0" - if result? - callback null, result.doc, result.mongoPath - else - callback null, null, null - -_findDocInFolder = (folder = {}, doc_id, currentPath) -> - for doc, i in folder.docs or [] - if doc?._id? and doc._id.toString() == doc_id.toString() - return { - doc: doc - mongoPath: "#{currentPath}.docs.#{i}" - } - for childFolder, i in folder.folders or [] - result = _findDocInFolder childFolder, doc_id, "#{currentPath}.folders.#{i}" - return result if result? - - return null - -_findAllDocsInFolder = (folder = {}) -> - docs = folder.docs or [] - for childFolder in folder.folders or [] - docs = docs.concat _findAllDocsInFolder childFolder - return docs - -isDocInDocCollection = (doc, callback)-> - if !doc?._id? or doc._id.length == 0 - return callback(null, true) - db.docs.find({_id: ObjectId(doc._id+"")}, {_id: 1}).limit 1, (err, foundDocs)-> - exists = foundDocs.length > 0 - callback err, exists - -getWhichDocsCanBeDeleted = (docs, callback = (err, docsToBeDeleted, unmigratedDocs)->)-> - docsToBeDeleted = [] - unmigratedDocs = [] - - jobs = _.map docs, (doc)-> - return (cb)-> - isDocInDocCollection doc, (err, exists)-> - if exists - docsToBeDeleted.push doc - else - unmigratedDocs.push doc - cb(err) - async.series jobs, (err)-> - callback err, docsToBeDeleted, unmigratedDocs - -wipeDocLines = (project_id, mongoPath, callback)-> - update = - $unset: {} - update.$unset["#{mongoPath}.lines"] = "" - update.$unset["#{mongoPath}.rev"] = "" - db.projects.update _id: ObjectId(project_id+''), update, callback - - -removeDocLinesFromProject = (docs, project, callback)-> - jobs = _.map docs, (doc)-> - (cb)-> - findDocInProject project, doc._id, (err, doc, mongoPath)-> - wipeDocLines project._id, mongoPath, cb - async.parallelLimit jobs, 5, callback - -processNext = (project_id, callback)-> - if !project_id? or project_id.length == 0 - return callback() - checkIfFileHasBeenProcessed project_id, (err, hasBeenProcessed)-> - if hasBeenProcessed - console.log "#{project_id} already processed, skipping" - return callback() - console.log "#{project_id} processing" - getAllDocs project_id, (err, docs, project)-> - if err? - console.error err, project_id, "could not get all docs" - return callback(err) - else - getWhichDocsCanBeDeleted docs, (err, docsToBeDeleted, unmigratedDocs)-> - if err? - console.error err, project_id, "could not save docs into mongo" - return callback(err) - markUnmigratedDocs project_id, unmigratedDocs, (err)-> - removeDocLinesFromProject docsToBeDeleted, project, (err)-> - if err? - return callback(err) - markProjectAsProcessed project_id, (err)-> - setTimeout( - -> callback(err) - ,0) - -exports.migrate = (client, done = ->)-> - getProjectIds (err, ids)-> - printProgress() - jobs = _.map ids, (id)-> - return (cb)-> - processNext(id, cb) - async.series jobs, (err)-> - if err? - console.error err, "at end of jobs" - else - console.log "finished" - done(err) - - -exports.rollback = (next)-> - next() - diff --git a/server-ce/migrations/3_pack_docHistory_collection.coffee b/server-ce/migrations/3_pack_docHistory_collection.coffee deleted file mode 100644 index affe1fcfd1..0000000000 --- a/server-ce/migrations/3_pack_docHistory_collection.coffee +++ /dev/null @@ -1,342 +0,0 @@ -Settings = require "settings-sharelatex" -fs = require("fs") -mongojs = require("mongojs") -ObjectId = mongojs.ObjectId -db = mongojs(Settings.mongo.url, ['docs','docHistory', 'docHistoryStats']) -_ = require("underscore") -async = require("async") -exec = require("child_process").exec -bson = require('bson') -BSON = new bson() - -logger = { - log: -> - err: -> -} - -needToExit = false -handleExit = () -> - needToExit = true - console.log('Got signal. Shutting down.') - -process.on 'SIGINT', handleExit -process.on 'SIGHUP', handleExit - -finished_docs_path = "/tmp/finished-docs-3" -all_docs_path = "/tmp/all-docs-3" -unmigrated_docs_path = "/tmp/unmigrated-docs-3" - -finished_docs = {} -if fs.existsSync(finished_docs_path) - for id in fs.readFileSync(finished_docs_path,'utf-8').split("\n") - finished_docs[id] = true - -getAndWriteDocids = (callback)-> - console.log "finding all doc id's - #{new Date().toString()}" - db.docs.find {}, {_id:1}, (err, ids)-> - console.log "total found docs in mongo #{ids.length} - #{new Date().toString()}" - ids = _.pluck ids, '_id' - ids = _.filter ids, (id)-> id? - fileData = ids.join("\n") - fs.writeFileSync all_docs_path + ".tmp", fileData - fs.renameSync all_docs_path + ".tmp", all_docs_path - callback(err, ids) - -loadDocIds = (callback)-> - console.log "loading doc ids from #{all_docs_path}" - data = fs.readFileSync all_docs_path, "utf-8" - ids = data.split("\n") - console.log "loaded #{ids.length} doc ids from #{all_docs_path}" - callback null, ids - -getDocIds = (callback)-> - exists = fs.existsSync all_docs_path - if exists - loadDocIds callback - else - getAndWriteDocids callback - -markDocAsProcessed = (doc_id, callback)-> - finished_docs[doc_id] = true - fs.appendFile finished_docs_path, "#{doc_id}\n", callback - -markDocAsUnmigrated = (doc_id, callback)-> - console.log "#{doc_id} unmigrated" - markDocAsProcessed doc_id, (err)-> - fs.appendFile unmigrated_docs_path, "#{doc_id}\n", callback - -checkIfDocHasBeenProcessed = (doc_id, callback)-> - callback(null, finished_docs[doc_id]) - -processNext = (doc_id, callback)-> - if !doc_id? or doc_id.length == 0 - return callback() - if needToExit - return callback(new Error("graceful shutdown")) - checkIfDocHasBeenProcessed doc_id, (err, hasBeenProcessed)-> - if hasBeenProcessed - console.log "#{doc_id} already processed, skipping" - return callback() - PackManager._packDocHistory doc_id, {}, (err) -> - if err? - console.log "error processing #{doc_id}" - markDocAsUnmigrated doc_id, callback - else - markDocAsProcessed doc_id, callback - -updateIndexes = (callback) -> - async.series [ - (cb) -> - console.log "create index" - db.docHistory.ensureIndex { project_id: 1, "meta.end_ts": 1, "meta.start_ts": -1 }, { background: true }, cb - (cb) -> - console.log "drop index" - db.docHistory.dropIndex { project_id: 1, "meta.end_ts": 1 }, cb - (cb) -> - console.log "drop index" - db.docHistory.dropIndex { project_id: 1, "pack.0.meta.end_ts": 1, "meta.end_ts": 1}, cb - ], (err, results) -> - console.log "all done" - callback(err) - -exports.migrate = (client, done = ->)-> - getDocIds (err, ids)-> - totalDocCount = ids.length - alreadyFinishedCount = Object.keys(finished_docs).length - t0 = Date.now() - printProgress = () -> - count = Object.keys(finished_docs).length - processedFraction = (count-alreadyFinishedCount)/totalDocCount - remainingFraction = (totalDocCount-count)/totalDocCount - t = Date.now() - dt = (t-t0)*remainingFraction/processedFraction - estFinishTime = new Date(t + dt) - console.log "completed #{count}/#{totalDocCount} processed=#{processedFraction.toFixed(2)} remaining=#{remainingFraction.toFixed(2)} elapsed=#{(t-t0)/1000} est Finish=#{estFinishTime}" - interval = setInterval printProgress, 3*1000 - - nextId = null - - testFn = () -> - return false if needToExit - id = ids.shift() - while id? and finished_docs[id] # skip finished - id = ids.shift() - nextId = id - return nextId? - - executeFn = (cb) -> - processNext nextId, cb - - async.whilst testFn, executeFn, (err)-> - if err? - console.error err, "at end of jobs" - else - console.log "finished at #{new Date}" - clearInterval interval - done(err) - -exports.rollback = (client, done)-> - done() - -# process.nextTick () -> -# exports.migrate () -> -# console.log "done" - -DAYS = 24 * 3600 * 1000 # one day in milliseconds - -# copied from track-changes/app/coffee/PackManager.coffee - -PackManager = - MAX_SIZE: 1024*1024 # make these configurable parameters - MAX_COUNT: 512 - - convertDocsToPacks: (docs, callback) -> - packs = [] - top = null - docs.forEach (d,i) -> - # skip existing packs - if d.pack? - top = null - return - sz = BSON.calculateObjectSize(d) - # decide if this doc can be added to the current pack - validLength = top? && (top.pack.length < PackManager.MAX_COUNT) - validSize = top? && (top.sz + sz < PackManager.MAX_SIZE) - bothPermanent = top? && (top.expiresAt? is false) && (d.expiresAt? is false) - bothTemporary = top? && (top.expiresAt? is true) && (d.expiresAt? is true) - within1Day = bothTemporary && (d.meta.start_ts - top.meta.start_ts < 24 * 3600 * 1000) - if top? && validLength && validSize && (bothPermanent || (bothTemporary && within1Day)) - top.pack = top.pack.concat {v: d.v, meta: d.meta, op: d.op, _id: d._id} - top.sz += sz - top.n += 1 - top.v_end = d.v - top.meta.end_ts = d.meta.end_ts - top.expiresAt = d.expiresAt if top.expiresAt? - return - else - # create a new pack - top = _.clone(d) - top.pack = [ {v: d.v, meta: d.meta, op: d.op, _id: d._id} ] - top.meta = { start_ts: d.meta.start_ts, end_ts: d.meta.end_ts } - top.sz = sz - top.n = 1 - top.v_end = d.v - delete top.op - delete top._id - packs.push top - - callback(null, packs) - - checkHistory: (docs, callback) -> - errors = [] - prev = null - error = (args...) -> - errors.push args - docs.forEach (d,i) -> - if d.pack? - n = d.pack.length - last = d.pack[n-1] - error('bad pack v_end', d) if d.v_end != last.v - error('bad pack start_ts', d) if d.meta.start_ts != d.pack[0].meta.start_ts - error('bad pack end_ts', d) if d.meta.end_ts != last.meta.end_ts - d.pack.forEach (p, i) -> - prev = v - v = p.v - error('bad version', v, 'in', p) if v <= prev - #error('expired op', p, 'in pack') if p.expiresAt? - else - prev = v - v = d.v - error('bad version', v, 'in', d) if v <= prev - if errors.length - callback(errors) - else - callback() - - insertPack: (packObj, callback) -> - bulk = db.docHistory.initializeOrderedBulkOp() - doc_id = packObj.doc_id - expect_nInserted = 1 - expect_nRemoved = packObj.pack.length - logger.log {doc_id: doc_id}, "adding pack, removing #{expect_nRemoved} ops" - bulk.insert packObj - ids = (op._id for op in packObj.pack) - bulk.find({_id:{$in:ids}}).remove() - bulk.execute (err, result) -> - if err? - logger.error {doc_id: doc_id}, "error adding pack" - callback(err, result) - else if result.nInserted != expect_nInserted or result.nRemoved != expect_nRemoved - logger.error {doc_id: doc_id, result}, "unexpected result adding pack" - callback(new Error( - msg: 'unexpected result' - expected: {expect_nInserted, expect_nRemoved} - ), result) - else - db.docHistoryStats.update {doc_id:doc_id}, { - $inc:{update_count:-expect_nRemoved}, - $currentDate:{last_packed:true} - }, {upsert:true}, () -> - callback(err, result) - - # retrieve document ops/packs and check them - getDocHistory: (doc_id, callback) -> - db.docHistory.find({doc_id:ObjectId(doc_id)}).sort {v:1}, (err, docs) -> - return callback(err) if err? - # for safety, do a consistency check of the history - logger.log {doc_id}, "checking history for document" - PackManager.checkHistory docs, (err) -> - return callback(err) if err? - callback(err, docs) - #PackManager.deleteExpiredPackOps docs, (err) -> - # return callback(err) if err? - # callback err, docs - - packDocHistory: (doc_id, options, callback) -> - if typeof callback == "undefined" and typeof options == 'function' - callback = options - options = {} - LockManager.runWithLock( - "HistoryLock:#{doc_id}", - (releaseLock) -> - PackManager._packDocHistory(doc_id, options, releaseLock) - , callback - ) - - _packDocHistory: (doc_id, options, callback) -> - logger.log {doc_id},"starting pack operation for document history" - - PackManager.getDocHistory doc_id, (err, docs) -> - return callback(err) if err? - origDocs = 0 - origPacks = 0 - for d in docs - if d.pack? then origPacks++ else origDocs++ - PackManager.convertDocsToPacks docs, (err, packs) -> - return callback(err) if err? - total = 0 - for p in packs - total = total + p.pack.length - logger.log {doc_id, origDocs, origPacks, newPacks: packs.length, totalOps: total}, "document stats" - if packs.length - if options['dry-run'] - logger.log {doc_id}, 'dry-run, skipping write packs' - return callback() - PackManager.savePacks packs, (err) -> - return callback(err) if err? - # check the history again - PackManager.getDocHistory doc_id, callback - else - logger.log {doc_id}, "no packs to write" - # keep a record that we checked this one to avoid rechecking it - db.docHistoryStats.update {doc_id:doc_id}, { - $currentDate:{last_checked:true} - }, {upsert:true}, () -> - callback null, null - - DB_WRITE_DELAY: 100 - - savePacks: (packs, callback) -> - async.eachSeries packs, PackManager.safeInsert, (err, result) -> - if err? - logger.log {err, result}, "error writing packs" - callback err, result - else - callback() - - safeInsert: (packObj, callback) -> - PackManager.insertPack packObj, (err, result) -> - setTimeout () -> - callback(err,result) - , PackManager.DB_WRITE_DELAY - - deleteExpiredPackOps: (docs, callback) -> - now = Date.now() - toRemove = [] - toUpdate = [] - docs.forEach (d,i) -> - if d.pack? - newPack = d.pack.filter (op) -> - if op.expiresAt? then op.expiresAt > now else true - if newPack.length == 0 - toRemove.push d - else if newPack.length < d.pack.length - # adjust the pack properties - d.pack = newPack - first = d.pack[0] - last = d.pack[d.pack.length - 1] - d.v_end = last.v - d.meta.start_ts = first.meta.start_ts - d.meta.end_ts = last.meta.end_ts - toUpdate.push d - if toRemove.length or toUpdate.length - bulk = db.docHistory.initializeOrderedBulkOp() - toRemove.forEach (pack) -> - console.log "would remove", pack - #bulk.find({_id:pack._id}).removeOne() - toUpdate.forEach (pack) -> - console.log "would update", pack - #bulk.find({_id:pack._id}).updateOne(pack); - bulk.execute callback - else - callback() diff --git a/server-ce/migrations/4_update_user_features.coffee b/server-ce/migrations/4_update_user_features.coffee deleted file mode 100644 index 680df3c459..0000000000 --- a/server-ce/migrations/4_update_user_features.coffee +++ /dev/null @@ -1,38 +0,0 @@ -Settings = require "settings-sharelatex" -fs = require("fs") -mongojs = require("mongojs") -ObjectId = mongojs.ObjectId -db = mongojs(Settings.mongo.url, ['users']) -_ = require("underscore") - - -handleExit = () -> - console.log('Got signal. Shutting down.') - - -process.on 'SIGINT', handleExit -process.on 'SIGHUP', handleExit - - -exports.migrate = (client, done=()->) -> - patch = { - $set: { - features: { - collaborators: -1 - dropbox: true - versioning: true - references: true - templates: true - compileTimeout: 180 - compileGroup: "standard" - } - } - } - console.log ">> updating all user features: ", patch - db.users.update {}, patch, {multi: true}, (err) -> - console.log "finished updating all user features" - return done(err) - - -exports.rollback = (client, done) -> - done() diff --git a/server-ce/migrations/5_remove_holding_accounts.coffee b/server-ce/migrations/5_remove_holding_accounts.coffee deleted file mode 100644 index ee796b3023..0000000000 --- a/server-ce/migrations/5_remove_holding_accounts.coffee +++ /dev/null @@ -1,103 +0,0 @@ -Settings = require "settings-sharelatex" -mongojs = require("mongojs") -ObjectId = mongojs.ObjectId -db = mongojs(Settings.mongo.url, ['users', 'projects', 'subscriptions']) -async = require "async" - -module.exports = HoldingAccountMigration = - DRY_RUN: true - - findHoldingAccounts: (callback = (error, users) ->) -> - db.users.find({holdingAccount: true, hashedPassword: { $exists: false }}, {holdingAccount: 1, email: 1}, callback) - - deleteUserProjects: (user_id, callback = (error) ->) -> - # Holding accounts can't own projects, so only remove from - # collaberator_refs and readOnly_refs - console.log "[Removing user from projects]", user_id - db.projects.find { - $or: [ - {collaberator_refs: user_id}, - {readOnly_refs: user_id} - ] - }, { collaberator_refs: 1, readOnly_refs: 1 }, (error, projects = []) -> - return callback(error) if error? - jobs = projects.map (project) -> - (cb) -> - console.log "[Removing user from project]", user_id, JSON.stringify(project) - if !project?._id? - throw new Error("no project id") - - if !HoldingAccountMigration.DRY_RUN - db.projects.update { - _id: project._id - }, { - $pull: { - collaberator_refs: user_id, - readOnly_refs: user_id - } - }, (error, result) -> - return cb(error) if error? - console.log "[Removed user from project]", user_id, project._id, result - cb() - else - console.log "[Would have removed user from project]", user_id, project._id - cb() - - async.series jobs, callback - - deleteUser: (user_id, callback = (error) ->) -> - if !user_id? - throw new Error("must have user_id") - if !HoldingAccountMigration.DRY_RUN - db.users.remove {_id: user_id, holdingAccount: true}, (error, result) -> - return callback(error) if error? - console.log "[Removed user]", user_id, result - if result.n != 1 - return callback(new Error("failed to remove user as expected")) - callback() - else - console.log "[Would have removed user]", user_id - callback() - - migrateGroupInvites: (user_id, email, callback = (error) ->) -> - if !user_id? - throw new Error("must have user_id") - if !HoldingAccountMigration.DRY_RUN - db.subscriptions.update {member_ids: user_id}, { - $pull: { member_ids: user_id }, - $addToSet : { invited_emails: email } - }, { multi : true }, (error, result) -> - return callback(error) if error? - console.log "[Migrated user in group accounts]", user_id, email, result - callback() - else - console.log "[Would have migrated user in group accounts]", user_id, email - callback() - - run: (done = () ->) -> - console.log "[Getting list of holding accounts]" - HoldingAccountMigration.findHoldingAccounts (error, users) -> - throw error if error? - console.log "[Got #{users.length} holding accounts]" - i = 0 - jobs = users.map (u) -> - (cb) -> - console.log "[Removing user #{i++}/#{users.length}]" - HoldingAccountMigration.migrateGroupInvites u._id, u.email, (error) -> - return cb(error) if error? - HoldingAccountMigration.deleteUser u._id, (error) -> - return cb(error) if error? - HoldingAccountMigration.deleteUserProjects u._id, (error) -> - return cb(error) if error? - setTimeout cb, 50 # Small delay to not hammer DB - async.series jobs, (error) -> - throw error if error? - console.log "[FINISHED]" - done() - - migrate: (client, done=()->) -> - HoldingAccountMigration.DRY_RUN = false - HoldingAccountMigration.run(done) - - rollback: (client, done) -> - done() diff --git a/server-ce/migrations/6_add_track_changes_feature.coffee b/server-ce/migrations/6_add_track_changes_feature.coffee deleted file mode 100644 index e807102faa..0000000000 --- a/server-ce/migrations/6_add_track_changes_feature.coffee +++ /dev/null @@ -1,30 +0,0 @@ -Settings = require "settings-sharelatex" -fs = require("fs") -mongojs = require("mongojs") -ObjectId = mongojs.ObjectId -db = mongojs(Settings.mongo.url, ['users']) -_ = require("underscore") - - -handleExit = () -> - console.log('Got signal. Shutting down.') - - -process.on 'SIGINT', handleExit -process.on 'SIGHUP', handleExit - - -exports.migrate = (client, done=()->) -> - patch = { - $set: { - 'features.trackChanges': true - } - } - console.log ">> enabling trackChanges feature: ", patch - db.users.update {}, patch, {multi: true}, (err) -> - console.log "finished enabling trackChanges feature" - return done(err) - - -exports.rollback = (client, done) -> - done() diff --git a/server-ce/migrations/7_add_token_indexes.coffee b/server-ce/migrations/7_add_token_indexes.coffee deleted file mode 100644 index 867c209753..0000000000 --- a/server-ce/migrations/7_add_token_indexes.coffee +++ /dev/null @@ -1,51 +0,0 @@ -Settings = require "settings-sharelatex" -fs = require("fs") -mongojs = require("mongojs") -ObjectId = mongojs.ObjectId -db = mongojs(Settings.mongo.url, ['docs','docHistory', 'docHistoryStats']) -_ = require("underscore") -async = require("async") -exec = require("child_process").exec -bson = require('bson') -BSON = new bson() - - -handleExit = () -> - console.log('Got signal. Shutting down.') - - -exports.migrate = (client, done=()->) -> - console.log ">> Adding indexes for token-based project access: " - db.projects.ensureIndex {'tokens.readAndWrite': 1}, { - partialFilterExpression: { 'tokens.readAndWrite': { $exists: true } }, - unique: true, - background: true - }, (err) -> - if err? - return done(err) - db.projects.ensureIndex {'tokens.readOnly': 1}, { - partialFilterExpression: { 'tokens.readOnly': { $exists: true } }, - unique: true, - background: true - }, (err) -> - if err? - return done(err) - db.projects.ensureIndex {tokenAccessReadAndWrite_refs: 1}, { - background: true - }, (err) -> - if err? - return done(err) - db.projects.ensureIndex {tokenAccessOnly_refs: 1}, { - background: true - }, (err) -> - console.log ">> done adding indexes for token-based project access" - done() - - -exports.rollback = (client, done) -> - done() - - -process.on 'SIGINT', handleExit -process.on 'SIGHUP', handleExit - diff --git a/server-ce/migrations/7_add_track_changes_feature_again.coffee b/server-ce/migrations/7_add_track_changes_feature_again.coffee deleted file mode 100644 index b942e61f3f..0000000000 --- a/server-ce/migrations/7_add_track_changes_feature_again.coffee +++ /dev/null @@ -1,31 +0,0 @@ -#This is needed because we forgot to add track changes into the default settings -Settings = require "settings-sharelatex" -fs = require("fs") -mongojs = require("mongojs") -ObjectId = mongojs.ObjectId -db = mongojs(Settings.mongo.url, ['users']) -_ = require("underscore") - - -handleExit = () -> - console.log('Got signal. Shutting down.') - - -process.on 'SIGINT', handleExit -process.on 'SIGHUP', handleExit - - -exports.migrate = (client, done=()->) -> - patch = { - $set: { - 'features.trackChanges': true - } - } - console.log ">> enabling trackChanges feature: ", patch - db.users.update {}, patch, {multi: true}, (err) -> - console.log "finished enabling trackChanges feature" - return done(err) - - -exports.rollback = (client, done) -> - done() diff --git a/server-ce/migrations/9_create_user_emails_array.js b/server-ce/migrations/9_create_user_emails_array.js deleted file mode 100644 index b9216c2a4c..0000000000 --- a/server-ce/migrations/9_create_user_emails_array.js +++ /dev/null @@ -1,49 +0,0 @@ -const Settings = require('settings-sharelatex') -const mongojs = require('mongojs') -const db = mongojs(Settings.mongo.url, ['users']) -const async = require('async') - -const handleExit = () => console.log('Got signal. Shutting down.') -process.on('SIGINT', handleExit) -process.on('SIGHUP', handleExit) - -const initUserEmailsAttribute = (user, callback) => { - const update = { - $set: { - emails: [ - { - email: user.email, - createdAt: new Date() - } - ] - } - } - db.users.update({ _id: user._id }, update, callback) -} - -const updateAllUsersEmailsAttribute = (users, callback) => { - console.log(`updating ${users.length} users`) - async.eachSeries(users, initUserEmailsAttribute, callback) -} - -exports.migrate = (client, done) => - db.users.find( - { emails: { $exists: false } }, - { email: 1 }, - (error, users) => { - if (error) { - callback(error) - } else { - updateAllUsersEmailsAttribute(users, done) - } - } - ) - -exports.rollback = (client, done) => { - const update = { - $unset: { - emails: 1 - } - } - db.users.update({ emails: { $exists: true } }, update, done) -} diff --git a/server-ce/migrations/about_migrations.md b/server-ce/migrations/about_migrations.md deleted file mode 100644 index 8a9d7596ba..0000000000 --- a/server-ce/migrations/about_migrations.md +++ /dev/null @@ -1,9 +0,0 @@ -If migration is stopped mid way it will start at the beginning next time - -To see the run migrations do db.getCollection('_migrations').find() you can't do db._migrations.find() - -When testing, to roll back a migration run: - -``` -./node_modules/east/bin/east rollback 5 --adapter east-mongo --url mongodb://localhost:27017/sharelatex -``` From 8f1da35befc3bec4f7e8883bd4dd0e33cb798de5 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:39:10 +0100 Subject: [PATCH 508/525] [misc] setup eslint and prettier and fix any errors --- server-ce/.eslintrc | 17 + server-ce/.prettierrc | 8 + server-ce/package-lock.json | 1764 ++++++++++++++++++++++++++++++++++- server-ce/package.json | 17 + server-ce/services.js | 104 ++- 5 files changed, 1851 insertions(+), 59 deletions(-) create mode 100644 server-ce/.eslintrc create mode 100644 server-ce/.prettierrc diff --git a/server-ce/.eslintrc b/server-ce/.eslintrc new file mode 100644 index 0000000000..1efb79d093 --- /dev/null +++ b/server-ce/.eslintrc @@ -0,0 +1,17 @@ +{ + "extends": [ + "eslint:recommended", + "standard", + "prettier" + ], + "parserOptions": { + "ecmaVersion": 2018 + }, + "env": { + "node": true + }, + "rules": { + // Do not allow importing of implicit dependencies. + "import/no-extraneous-dependencies": "error" + } +} diff --git a/server-ce/.prettierrc b/server-ce/.prettierrc new file mode 100644 index 0000000000..e692368d0e --- /dev/null +++ b/server-ce/.prettierrc @@ -0,0 +1,8 @@ +{ + "arrowParens": "avoid", + "semi": false, + "singleQuote": true, + "trailingComma": "es5", + "tabWidth": 2, + "useTabs": false +} diff --git a/server-ce/package-lock.json b/server-ce/package-lock.json index 62038e3213..69bb8563cf 100644 --- a/server-ce/package-lock.json +++ b/server-ce/package-lock.json @@ -4,12 +4,201 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + } + } + }, + "@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", @@ -40,6 +229,36 @@ } } }, + "array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + } + }, + "array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, "async": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", @@ -49,15 +268,13 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -78,6 +295,22 @@ "mv": "~2" } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "chalk": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", @@ -94,6 +327,21 @@ "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "colors": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", @@ -104,8 +352,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -113,6 +360,28 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "dateformat": { "version": "1.0.2-1.2.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz", @@ -125,6 +394,30 @@ "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", "dev": true }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "dtrace-provider": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", @@ -180,12 +473,543 @@ "resolved": "https://registry.npmjs.org/east-mongo/-/east-mongo-0.3.3.tgz", "integrity": "sha1-WKtCdGaRy+ITtBweiG8EttyCq8A=" }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "eslint-config-prettier": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true + }, + "eslint-config-standard": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", + "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-chai-expect": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-2.2.0.tgz", + "integrity": "sha512-ExTJKhgeYMfY8wDj3UiZmgpMKJOUHGNHmWMlxT49JUDB1vTnw0sSNfXJSxnX+LcebyBD/gudXzjzD136WqPJrQ==", + "dev": true + }, + "eslint-plugin-chai-friendly": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.6.0.tgz", + "integrity": "sha512-Uvvv1gkbRGp/qfN15B0kQyQWg+oFA8buDSqrwmW3egNSk/FpqH2MjQqKOuKwmEL6w4QIQrIjDp+gg6kGGmD3oQ==", + "dev": true + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.23.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz", + "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==", + "dev": true, + "requires": { + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.1", + "find-up": "^2.0.0", + "has": "^1.0.3", + "is-core-module": "^2.4.0", + "minimatch": "^3.0.4", + "object.values": "^1.1.3", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-mocha": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-8.2.0.tgz", + "integrity": "sha512-8oOR47Ejt+YJPNQzedbiklDqS1zurEaNrxXpRs+Uk4DMDPVmKNagShFeUaYsfvWP55AhI+P1non5QZAHV6K78A==", + "dev": true, + "requires": { + "eslint-utils": "^2.1.0", + "ramda": "^0.27.1" + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-promise": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", + "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", + "dev": true + }, + "eslint-plugin-standard": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-5.0.0.tgz", + "integrity": "sha512-eSIXPc9wBM4BrniMzJRBm2uoVuXz2EPa+NXPk2+itrVt+r5SbKFERx/IgrK/HmfjddyKVz2f+j+7gBRvu19xLg==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, "esprima": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=", "dev": true }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, "eventemitter2": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", @@ -198,6 +1022,42 @@ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "findup-sync": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz", @@ -236,6 +1096,85 @@ } } }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.0.tgz", + "integrity": "sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "getobject": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", @@ -261,6 +1200,24 @@ } } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, "graceful-fs": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", @@ -586,30 +1543,84 @@ } } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, "has-color": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", "dev": true }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, "hooker": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", "dev": true }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, "iconv-lite": { "version": "0.2.11", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz", "integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=", "dev": true }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, - "optional": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -621,12 +1632,124 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true + }, + "is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "js-yaml": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz", @@ -637,6 +1760,33 @@ "esprima": "~ 1.0.2" } }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "knox": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/knox/-/knox-0.8.10.tgz", @@ -649,6 +1799,16 @@ "xml2js": "0.2.x" } }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, "load-grunt-config": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/load-grunt-config/-/load-grunt-config-0.19.2.tgz", @@ -1009,11 +2169,59 @@ } } }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "lodash": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "lpad": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/lpad/-/lpad-0.1.0.tgz", @@ -1046,8 +2254,7 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true, - "optional": true + "dev": true }, "mkdirp": { "version": "0.5.5", @@ -1280,6 +2487,12 @@ } } }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", @@ -1328,6 +2541,12 @@ } } }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", @@ -1344,22 +2563,226 @@ "abbrev": "1" } }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.values": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "optional": true, "requires": { "wrappy": "1" } }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, - "optional": true + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } }, "readable-stream": { "version": "1.0.34", @@ -1400,6 +2823,34 @@ } } }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "rimraf": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", @@ -1431,12 +2882,102 @@ } } }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "stream-counter": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-0.1.0.tgz", @@ -1446,6 +2987,48 @@ "readable-stream": "~1.0.2" } }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -1458,6 +3041,114 @@ "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", "dev": true }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "tsconfig-paths": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "dev": true, + "requires": { + "json5": "^2.2.0", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, "underscore": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", @@ -1469,18 +3160,61 @@ "integrity": "sha1-18D6KvXVoaZ/QlPa7pgTLnM/Dxk=", "dev": true }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "which": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=", "dev": true }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true + "dev": true }, "xml2js": { "version": "0.2.8", @@ -1490,6 +3224,12 @@ "requires": { "sax": "0.5.x" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } } diff --git a/server-ce/package.json b/server-ce/package.json index 4b32165fcd..b9f180e084 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -2,6 +2,12 @@ "name": "sharelatex", "version": "0.0.1", "description": "An online collaborative LaTeX editor", + "scripts": { + "lint": "eslint --max-warnings 0 --format unix .", + "lint:fix": "eslint --fix .", + "format": "prettier --list-different $PWD/'**/*.js'", + "format:fix": "prettier --write $PWD/'**/*.js'" + }, "dependencies": { "async": "^0.9.0", "bson": "^1.0.4", @@ -21,11 +27,22 @@ "devDependencies": { "grunt": "~0.4.2", "bunyan": "~0.22.1", + "eslint": "^7.21.0", + "eslint-config-prettier": "^8.1.0", + "eslint-config-standard": "^16.0.2", + "eslint-plugin-chai-expect": "^2.2.0", + "eslint-plugin-chai-friendly": "^0.6.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-mocha": "^8.0.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "^5.0.0", "grunt-bunyan": "~0.5.0", "grunt-execute": "~0.1.5", "grunt-available-tasks": "~0.4.1", "grunt-concurrent": "~0.4.3", "grunt-contrib-coffee": "~0.10.1", + "prettier": "^2.2.1", "semver": "~2.2.1", "knox": "~0.8.9" } diff --git a/server-ce/services.js b/server-ce/services.js index 84fd7622f5..4fc6365f6b 100644 --- a/server-ce/services.js +++ b/server-ce/services.js @@ -1,47 +1,57 @@ -module.exports = - -[{ - name: "web", - repo: "https://github.com/sharelatex/web-sharelatex.git", - version: "master" -}, { - name: "real-time", - repo: "https://github.com/sharelatex/real-time-sharelatex.git", - version: "master" -}, { - name: "document-updater", - repo: "https://github.com/sharelatex/document-updater-sharelatex.git", - version: "master" -}, { - name: "clsi", - repo: "https://github.com/sharelatex/clsi-sharelatex.git", - version: "master" -}, { - name: "filestore", - repo: "https://github.com/sharelatex/filestore-sharelatex.git", - version: "master" -}, { - name: "track-changes", - repo: "https://github.com/sharelatex/track-changes-sharelatex.git", - version: "master" -}, { - name: "docstore", - repo: "https://github.com/sharelatex/docstore-sharelatex.git", - version: "master" -}, { - name: "chat", - repo: "https://github.com/sharelatex/chat-sharelatex.git", - version: "master" -}, { - name: "spelling", - repo: "https://github.com/sharelatex/spelling-sharelatex.git", - version: "master" -}, { - name: "contacts", - repo: "https://github.com/sharelatex/contacts-sharelatex.git", - version: "master" -}, { - name: "notifications", - repo: "https://github.com/sharelatex/notifications-sharelatex.git", - version: "master" -}] +module.exports = [ + { + name: 'web', + repo: 'https://github.com/sharelatex/web-sharelatex.git', + version: 'master', + }, + { + name: 'real-time', + repo: 'https://github.com/sharelatex/real-time-sharelatex.git', + version: 'master', + }, + { + name: 'document-updater', + repo: 'https://github.com/sharelatex/document-updater-sharelatex.git', + version: 'master', + }, + { + name: 'clsi', + repo: 'https://github.com/sharelatex/clsi-sharelatex.git', + version: 'master', + }, + { + name: 'filestore', + repo: 'https://github.com/sharelatex/filestore-sharelatex.git', + version: 'master', + }, + { + name: 'track-changes', + repo: 'https://github.com/sharelatex/track-changes-sharelatex.git', + version: 'master', + }, + { + name: 'docstore', + repo: 'https://github.com/sharelatex/docstore-sharelatex.git', + version: 'master', + }, + { + name: 'chat', + repo: 'https://github.com/sharelatex/chat-sharelatex.git', + version: 'master', + }, + { + name: 'spelling', + repo: 'https://github.com/sharelatex/spelling-sharelatex.git', + version: 'master', + }, + { + name: 'contacts', + repo: 'https://github.com/sharelatex/contacts-sharelatex.git', + version: 'master', + }, + { + name: 'notifications', + repo: 'https://github.com/sharelatex/notifications-sharelatex.git', + version: 'master', + }, +] From d152a798102f110314ee3dea4896fb89a77b0495 Mon Sep 17 00:00:00 2001 From: decaffeinate Date: Wed, 7 Jul 2021 11:39:38 +0000 Subject: [PATCH 509/525] decaffeinate: Rename coffee files from .coffee to .js --- server-ce/{Gruntfile.coffee => Gruntfile.js} | 0 server-ce/{settings.coffee => settings.js} | 0 .../{CreateAndDestroyUsers.coffee => CreateAndDestroyUsers.js} | 0 server-ce/tasks/{ProjectSize.coffee => ProjectSize.js} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename server-ce/{Gruntfile.coffee => Gruntfile.js} (100%) rename server-ce/{settings.coffee => settings.js} (100%) rename server-ce/tasks/{CreateAndDestroyUsers.coffee => CreateAndDestroyUsers.js} (100%) rename server-ce/tasks/{ProjectSize.coffee => ProjectSize.js} (100%) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.js similarity index 100% rename from server-ce/Gruntfile.coffee rename to server-ce/Gruntfile.js diff --git a/server-ce/settings.coffee b/server-ce/settings.js similarity index 100% rename from server-ce/settings.coffee rename to server-ce/settings.js diff --git a/server-ce/tasks/CreateAndDestroyUsers.coffee b/server-ce/tasks/CreateAndDestroyUsers.js similarity index 100% rename from server-ce/tasks/CreateAndDestroyUsers.coffee rename to server-ce/tasks/CreateAndDestroyUsers.js diff --git a/server-ce/tasks/ProjectSize.coffee b/server-ce/tasks/ProjectSize.js similarity index 100% rename from server-ce/tasks/ProjectSize.coffee rename to server-ce/tasks/ProjectSize.js From efd16d99d6136c1d06164b5897d73e07006103f8 Mon Sep 17 00:00:00 2001 From: decaffeinate Date: Wed, 7 Jul 2021 11:39:42 +0000 Subject: [PATCH 510/525] decaffeinate: Convert coffee files to JS --- server-ce/Gruntfile.js | 417 ++++++---- server-ce/settings.js | 992 +++++++++++++---------- server-ce/tasks/CreateAndDestroyUsers.js | 125 +-- server-ce/tasks/ProjectSize.js | 42 +- 4 files changed, 899 insertions(+), 677 deletions(-) diff --git a/server-ce/Gruntfile.js b/server-ce/Gruntfile.js index 9375096d62..a1173ed864 100644 --- a/server-ce/Gruntfile.js +++ b/server-ce/Gruntfile.js @@ -1,216 +1,311 @@ -coffee = require("coffee-script") -fs = require "fs" -spawn = require("child_process").spawn -exec = require("child_process").exec -rimraf = require "rimraf" -Path = require "path" -semver = require "semver" -knox = require "knox" -crypto = require "crypto" -async = require "async" -settings = require("settings-sharelatex") -_ = require("underscore") +/* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS103: Rewrite code to no longer use __guard__, or convert again using --optional-chaining + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const coffee = require("coffee-script"); +const fs = require("fs"); +const { + spawn +} = require("child_process"); +const { + exec +} = require("child_process"); +const rimraf = require("rimraf"); +const Path = require("path"); +const semver = require("semver"); +const knox = require("knox"); +const crypto = require("crypto"); +const async = require("async"); +const settings = require("settings-sharelatex"); +const _ = require("underscore"); -SERVICES = require("./config/services") +const SERVICES = require("./config/services"); -module.exports = (grunt) -> - grunt.loadNpmTasks 'grunt-bunyan' - grunt.loadNpmTasks 'grunt-execute' - grunt.loadNpmTasks 'grunt-available-tasks' - grunt.loadNpmTasks 'grunt-concurrent' - grunt.loadNpmTasks "grunt-contrib-coffee" - grunt.loadNpmTasks "grunt-shell" +module.exports = function(grunt) { + let Helpers; + let service; + grunt.loadNpmTasks('grunt-bunyan'); + grunt.loadNpmTasks('grunt-execute'); + grunt.loadNpmTasks('grunt-available-tasks'); + grunt.loadNpmTasks('grunt-concurrent'); + grunt.loadNpmTasks("grunt-contrib-coffee"); + grunt.loadNpmTasks("grunt-shell"); - grunt.task.loadTasks "./tasks" + grunt.task.loadTasks("./tasks"); - execute = {} - for service in SERVICES + const execute = {}; + for (service of Array.from(SERVICES)) { execute[service.name] = - src: "#{service.name}/app.js" + {src: `${service.name}/app.js`}; + } - grunt.initConfig - execute: execute + grunt.initConfig({ + execute, - concurrent: - all: - tasks: ("run:#{service.name}" for service in SERVICES) - options: - limit: SERVICES.length + concurrent: { + all: { + tasks: (((() => { + const result = []; + for (service of Array.from(SERVICES)) { result.push(`run:${service.name}`); + } + return result; + })())), + options: { + limit: SERVICES.length, logConcurrentOutput: true - availabletasks: - tasks: - options: + availabletasks: { + tasks: { + options: { filter: 'exclude', tasks: [ - 'concurrent' - 'execute' - 'bunyan' + 'concurrent', + 'execute', + 'bunyan', 'availabletasks' - ] - groups: + ], + groups: { "Run tasks": [ - "run" - "run:all" + "run", + "run:all", "default" - ].concat ("run:#{service.name}" for service in SERVICES) + ].concat(((() => { + const result1 = []; + for (service of Array.from(SERVICES)) { result1.push(`run:${service.name}`); + } + return result1; + })())), "Misc": [ "help" - ] - "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install"]) - "Update tasks": ("update:#{service.name}" for service in SERVICES).concat(["update:all", "update"]) + ], + "Install tasks": ((() => { + const result2 = []; + for (service of Array.from(SERVICES)) { result2.push(`install:${service.name}`); + } + return result2; + })()).concat(["install:all", "install"]), + "Update tasks": ((() => { + const result3 = []; + for (service of Array.from(SERVICES)) { result3.push(`update:${service.name}`); + } + return result3; + })()).concat(["update:all", "update"]), "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make", "check:mongo"] + } + } + } + }}); - for service in SERVICES - do (service) -> - grunt.registerTask "install:#{service.name}", "Download and set up the #{service.name} service", () -> - done = @async() - Helpers.installService(service, done) + for (service of Array.from(SERVICES)) { + ((service => grunt.registerTask(`install:${service.name}`, `Download and set up the ${service.name} service`, function() { + const done = this.async(); + return Helpers.installService(service, done); + })))(service); + } - grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", + grunt.registerTask('install:all', "Download and set up all ShareLaTeX services", [].concat( - ("install:#{service.name}" for service in SERVICES) + ((() => { + const result4 = []; + for (service of Array.from(SERVICES)) { result4.push(`install:${service.name}`); + } + return result4; + })()) ).concat(['postinstall']) + ); - grunt.registerTask 'install', 'install:all' - grunt.registerTask 'postinstall', 'Explain postinstall steps', () -> - Helpers.postinstallMessage @async() + grunt.registerTask('install', 'install:all'); + grunt.registerTask('postinstall', 'Explain postinstall steps', function() { + return Helpers.postinstallMessage(this.async()); + }); - grunt.registerTask 'update:all', "Checkout and update all ShareLaTeX services", + grunt.registerTask('update:all', "Checkout and update all ShareLaTeX services", ["check:make"].concat( - ("update:#{service.name}" for service in SERVICES) + ((() => { + const result5 = []; + for (service of Array.from(SERVICES)) { result5.push(`update:${service.name}`); + } + return result5; + })()) ) - grunt.registerTask 'update', 'update:all' - grunt.registerTask 'run', "Run all of the sharelatex processes", ['concurrent:all'] - grunt.registerTask 'run:all', 'run' + ); + grunt.registerTask('update', 'update:all'); + grunt.registerTask('run', "Run all of the sharelatex processes", ['concurrent:all']); + grunt.registerTask('run:all', 'run'); - grunt.registerTask 'help', 'Display this help list', 'availabletasks' - grunt.registerTask 'default', 'run' + grunt.registerTask('help', 'Display this help list', 'availabletasks'); + grunt.registerTask('default', 'run'); - grunt.registerTask "check:redis", "Check that redis is installed and running", () -> - Helpers.checkRedisConnect @async() + grunt.registerTask("check:redis", "Check that redis is installed and running", function() { + return Helpers.checkRedisConnect(this.async()); + }); - grunt.registerTask "check:mongo", "Check that mongo is installed", () -> - Helpers.checkMongoConnect @async() + grunt.registerTask("check:mongo", "Check that mongo is installed", function() { + return Helpers.checkMongoConnect(this.async()); + }); - grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:mongo", "check:make"] + grunt.registerTask("check", "Check that you have the required dependencies installed", ["check:redis", "check:mongo", "check:make"]); - grunt.registerTask "check:make", "Check that make is installed", () -> - Helpers.checkMake @async() + grunt.registerTask("check:make", "Check that make is installed", function() { + return Helpers.checkMake(this.async()); + }); - Helpers = - installService: (service, callback = (error) ->) -> - console.log "Installing #{service.name}" - Helpers.cloneGitRepo service, (error) -> - if error? - callback(error) - else - callback() + return Helpers = { + installService(service, callback) { + if (callback == null) { callback = function(error) {}; } + console.log(`Installing ${service.name}`); + return Helpers.cloneGitRepo(service, function(error) { + if (error != null) { + return callback(error); + } else { + return callback(); + } + }); + }, - cloneGitRepo: (service, callback = (error) ->) -> - repo_src = service.repo - dir = service.name - if !fs.existsSync(dir) - proc = spawn "git", [ + cloneGitRepo(service, callback) { + if (callback == null) { callback = function(error) {}; } + const repo_src = service.repo; + const dir = service.name; + if (!fs.existsSync(dir)) { + const proc = spawn("git", [ "clone", repo_src, dir - ], stdio: "inherit" - proc.on "close", () -> - Helpers.checkoutVersion service, callback - else - console.log "#{dir} already installed, skipping." - callback() + ], {stdio: "inherit"}); + return proc.on("close", () => Helpers.checkoutVersion(service, callback)); + } else { + console.log(`${dir} already installed, skipping.`); + return callback(); + } + }, - checkoutVersion: (service, callback = (error) ->) -> - dir = service.name - grunt.log.write "checking out #{service.name} #{service.version}" - proc = spawn "git", ["checkout", service.version], stdio: "inherit", cwd: dir - proc.on "close", () -> - callback() + checkoutVersion(service, callback) { + if (callback == null) { callback = function(error) {}; } + const dir = service.name; + grunt.log.write(`checking out ${service.name} ${service.version}`); + const proc = spawn("git", ["checkout", service.version], {stdio: "inherit", cwd: dir}); + return proc.on("close", () => callback()); + }, - postinstallMessage: (callback = (error) ->) -> - grunt.log.write """ - Services cloned: - #{service.name for service in SERVICES} - To install services run: - $ source bin/install-services - This will install the required node versions and run `npm install` for each service. - See https://github.com/sharelatex/sharelatex/pull/549 for more info. - """ - callback() + postinstallMessage(callback) { + if (callback == null) { callback = function(error) {}; } + grunt.log.write(`\ +Services cloned: + ${(() => { + const result6 = []; + for (service of Array.from(SERVICES)) { result6.push(service.name); + } + return result6; + })()} +To install services run: + $ source bin/install-services +This will install the required node versions and run \`npm install\` for each service. +See https://github.com/sharelatex/sharelatex/pull/549 for more info.\ +` + ); + return callback(); + }, - checkMake: (callback = (error) ->) -> - grunt.log.write "Checking make is installed... " - exec "make --version", (error, stdout, stderr) -> - if error? and error.message.match("not found") - grunt.log.error "FAIL." - grunt.log.errorlns """ - Either make is not installed or is not in your path. + checkMake(callback) { + if (callback == null) { callback = function(error) {}; } + grunt.log.write("Checking make is installed... "); + return exec("make --version", function(error, stdout, stderr) { + if ((error != null) && error.message.match("not found")) { + grunt.log.error("FAIL."); + grunt.log.errorlns(`\ +Either make is not installed or is not in your path. - On Ubuntu you can install make with: +On Ubuntu you can install make with: - sudo apt-get install build-essential + sudo apt-get install build-essential +\ +` + ); + return callback(error); + } else if (error != null) { + return callback(error); + } else { + grunt.log.write("OK."); + return callback(); + } + }); + }, + checkMongoConnect(callback) { + if (callback == null) { callback = function(error) {}; } + grunt.log.write("Checking can connect to mongo"); + const mongojs = require("mongojs"); + const db = mongojs(settings.mongo.url, ["tags"]); + db.runCommand({ ping: 1 }, function(err, res) { + if (!err && res.ok) { + grunt.log.write("OK."); + } + return callback(); + }); + return db.on('error', function(err){ + err = "Can not connect to mongodb"; + grunt.log.error("FAIL."); + grunt.log.errorlns(`\ +!!!!!!!!!!!!!! MONGO ERROR !!!!!!!!!!!!!! - """ - return callback(error) - else if error? - return callback(error) - else - grunt.log.write "OK." - return callback() - checkMongoConnect: (callback = (error) ->) -> - grunt.log.write "Checking can connect to mongo" - mongojs = require("mongojs") - db = mongojs(settings.mongo.url, ["tags"]) - db.runCommand { ping: 1 }, (err, res) -> - if !err and res.ok - grunt.log.write "OK." - return callback() - db.on 'error', (err)-> - err = "Can not connect to mongodb" - grunt.log.error "FAIL." - grunt.log.errorlns """ - !!!!!!!!!!!!!! MONGO ERROR !!!!!!!!!!!!!! +ShareLaTeX can not talk to the mongodb instance - ShareLaTeX can not talk to the mongodb instance +Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL - Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL - - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - """ - throw new Error("Can not connect to Mongodb") - return callback(err) +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\ +` + ); + throw new Error("Can not connect to Mongodb"); + return callback(err); + }); + }, - checkRedisConnect: (callback = (error) ->) -> - grunt.log.write "Checking can connect to redis\n" - rclient = require("redis").createClient(settings.redis.web) + checkRedisConnect(callback) { + if (callback == null) { callback = function(error) {}; } + grunt.log.write("Checking can connect to redis\n"); + const rclient = require("redis").createClient(settings.redis.web); - rclient.ping (err, res) -> - if !err? - grunt.log.write "OK." - else - throw new Error("Can not connect to redis") - return callback() - errorHandler = _.once (err)-> - err = "Can not connect to redis" - grunt.log.error "FAIL." - grunt.log.errorlns """ - !!!!!!!!!!!!!! REDIS ERROR !!!!!!!!!!!!!! + rclient.ping(function(err, res) { + if ((err == null)) { + grunt.log.write("OK."); + } else { + throw new Error("Can not connect to redis"); + } + return callback(); + }); + const errorHandler = _.once(function(err){ + err = "Can not connect to redis"; + grunt.log.error("FAIL."); + grunt.log.errorlns(`\ +!!!!!!!!!!!!!! REDIS ERROR !!!!!!!!!!!!!! - ShareLaTeX can not talk to the redis instance +ShareLaTeX can not talk to the redis instance - Check the redis instance is running and accessible on env var SHARELATEX_REDIS_HOST +Check the redis instance is running and accessible on env var SHARELATEX_REDIS_HOST - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - """ - throw new Error("Can not connect to redis") - return callback(err) - rclient.on 'error', errorHandler +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\ +` + ); + throw new Error("Can not connect to redis"); + return callback(err); + }); + return rclient.on('error', errorHandler); + } + }; +}; + +function __guard__(value, transform) { + return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined; +} diff --git a/server-ce/settings.js b/server-ce/settings.js index 684bf18d53..1d2fc7a018 100644 --- a/server-ce/settings.js +++ b/server-ce/settings.js @@ -1,576 +1,684 @@ -Path = require('path') +/* + * decaffeinate suggestions: + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +let allTexLiveDockerImageNames, allTexLiveDockerImages, redisConfig, siteUrl; +let e; +const Path = require('path'); -# These credentials are used for authenticating api requests -# between services that may need to go over public channels -httpAuthUser = "sharelatex" -httpAuthPass = process.env["WEB_API_PASSWORD"] -httpAuthUsers = {} -httpAuthUsers[httpAuthUser] = httpAuthPass +// These credentials are used for authenticating api requests +// between services that may need to go over public channels +const httpAuthUser = "sharelatex"; +const httpAuthPass = process.env["WEB_API_PASSWORD"]; +const httpAuthUsers = {}; +httpAuthUsers[httpAuthUser] = httpAuthPass; -parse = (option)-> - if option? - try - opt = JSON.parse(option) - return opt - catch err - throw new Error("problem parsing #{option}, invalid JSON") +const parse = function(option){ + if (option != null) { + try { + const opt = JSON.parse(option); + return opt; + } catch (err) { + throw new Error(`problem parsing ${option}, invalid JSON`); + } + } +}; -parseIntOrFail = (value)-> - parsedValue = parseInt(value, 10) - if isNaN(parsedValue) - throw new Error("'#{value}' is an invalid integer") - return parsedValue +const parseIntOrFail = function(value){ + const parsedValue = parseInt(value, 10); + if (isNaN(parsedValue)) { + throw new Error(`'${value}' is an invalid integer`); + } + return parsedValue; +}; -DATA_DIR = '/var/lib/sharelatex/data' -TMP_DIR = '/var/lib/sharelatex/tmp' +const DATA_DIR = '/var/lib/sharelatex/data'; +const TMP_DIR = '/var/lib/sharelatex/tmp'; -settings = +const settings = { - clsi: - optimiseInDocker: process.env['OPTIMISE_PDF'] == 'true' + clsi: { + optimiseInDocker: process.env['OPTIMISE_PDF'] === 'true' + }, - brandPrefix: "" + brandPrefix: "", allowAnonymousReadAndWriteSharing: - process.env['SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING'] == 'true' + process.env['SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING'] === 'true', - # Databases - # --------- + // Databases + // --------- - # ShareLaTeX's main persistent data store is MongoDB (http://www.mongodb.org/) - # Documentation about the URL connection string format can be found at: - # - # http://docs.mongodb.org/manual/reference/connection-string/ - # - # The following works out of the box with Mongo's default settings: - mongo: - url : process.env["SHARELATEX_MONGO_URL"] or 'mongodb://dockerhost/sharelatex' + // ShareLaTeX's main persistent data store is MongoDB (http://www.mongodb.org/) + // Documentation about the URL connection string format can be found at: + // + // http://docs.mongodb.org/manual/reference/connection-string/ + // + // The following works out of the box with Mongo's default settings: + mongo: { + url : process.env["SHARELATEX_MONGO_URL"] || 'mongodb://dockerhost/sharelatex' + }, - # Redis is used in ShareLaTeX for high volume queries, like real-time - # editing, and session management. - # - # The following config will work with Redis's default settings: - redis: - web: redisConfig = - host: process.env["SHARELATEX_REDIS_HOST"] or "dockerhost" - port: process.env["SHARELATEX_REDIS_PORT"] or "6379" - password: process.env["SHARELATEX_REDIS_PASS"] or undefined - key_schema: - # document-updater - blockingKey: ({doc_id}) -> "Blocking:#{doc_id}" - docLines: ({doc_id}) -> "doclines:#{doc_id}" - docOps: ({doc_id}) -> "DocOps:#{doc_id}" - docVersion: ({doc_id}) -> "DocVersion:#{doc_id}" - docHash: ({doc_id}) -> "DocHash:#{doc_id}" - projectKey: ({doc_id}) -> "ProjectId:#{doc_id}" - docsInProject: ({project_id}) -> "DocsIn:#{project_id}" - ranges: ({doc_id}) -> "Ranges:#{doc_id}" - # document-updater:realtime - pendingUpdates: ({doc_id}) -> "PendingUpdates:#{doc_id}" - # document-updater:history - uncompressedHistoryOps: ({doc_id}) -> "UncompressedHistoryOps:#{doc_id}" - docsWithHistoryOps: ({project_id}) -> "DocsWithHistoryOps:#{project_id}" - # document-updater:lock - blockingKey: ({doc_id}) -> "Blocking:#{doc_id}" - # track-changes:lock - historyLock: ({doc_id}) -> "HistoryLock:#{doc_id}" - historyIndexLock: ({project_id}) -> "HistoryIndexLock:#{project_id}" - # track-changes:history - uncompressedHistoryOps: ({doc_id}) -> "UncompressedHistoryOps:#{doc_id}" - docsWithHistoryOps: ({project_id}) -> "DocsWithHistoryOps:#{project_id}" - # realtime - clientsInProject: ({project_id}) -> "clients_in_project:#{project_id}" - connectedUser: ({project_id, client_id})-> "connected_user:#{project_id}:#{client_id}" - fairy: redisConfig - # track-changes and document-updater - realtime: redisConfig - documentupdater: redisConfig - lock: redisConfig - history: redisConfig - websessions: redisConfig - api: redisConfig - pubsub: redisConfig + // Redis is used in ShareLaTeX for high volume queries, like real-time + // editing, and session management. + // + // The following config will work with Redis's default settings: + redis: { + web: (redisConfig = { + host: process.env["SHARELATEX_REDIS_HOST"] || "dockerhost", + port: process.env["SHARELATEX_REDIS_PORT"] || "6379", + password: process.env["SHARELATEX_REDIS_PASS"] || undefined, + key_schema: { + // document-updater + blockingKey({doc_id}) { return `Blocking:${doc_id}`; }, + docLines({doc_id}) { return `doclines:${doc_id}`; }, + docOps({doc_id}) { return `DocOps:${doc_id}`; }, + docVersion({doc_id}) { return `DocVersion:${doc_id}`; }, + docHash({doc_id}) { return `DocHash:${doc_id}`; }, + projectKey({doc_id}) { return `ProjectId:${doc_id}`; }, + docsInProject({project_id}) { return `DocsIn:${project_id}`; }, + ranges({doc_id}) { return `Ranges:${doc_id}`; }, + // document-updater:realtime + pendingUpdates({doc_id}) { return `PendingUpdates:${doc_id}`; }, + // document-updater:history + uncompressedHistoryOps({doc_id}) { return `UncompressedHistoryOps:${doc_id}`; }, + docsWithHistoryOps({project_id}) { return `DocsWithHistoryOps:${project_id}`; }, + // document-updater:lock + blockingKey({doc_id}) { return `Blocking:${doc_id}`; }, + // track-changes:lock + historyLock({doc_id}) { return `HistoryLock:${doc_id}`; }, + historyIndexLock({project_id}) { return `HistoryIndexLock:${project_id}`; }, + // track-changes:history + uncompressedHistoryOps({doc_id}) { return `UncompressedHistoryOps:${doc_id}`; }, + docsWithHistoryOps({project_id}) { return `DocsWithHistoryOps:${project_id}`; }, + // realtime + clientsInProject({project_id}) { return `clients_in_project:${project_id}`; }, + connectedUser({project_id, client_id}){ return `connected_user:${project_id}:${client_id}`; } + } + }), + fairy: redisConfig, + // track-changes and document-updater + realtime: redisConfig, + documentupdater: redisConfig, + lock: redisConfig, + history: redisConfig, + websessions: redisConfig, + api: redisConfig, + pubsub: redisConfig, project_history: redisConfig + }, - # The compile server (the clsi) uses a SQL database to cache files and - # meta-data. sqlite is the default, and the load is low enough that this will - # be fine in production (we use sqlite at sharelatex.com). - # - # If you want to configure a different database, see the Sequelize documentation - # for available options: - # - # https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage - # - mysql: - clsi: - database: "clsi" - username: "clsi" - password: "" - dialect: "sqlite" + // The compile server (the clsi) uses a SQL database to cache files and + // meta-data. sqlite is the default, and the load is low enough that this will + // be fine in production (we use sqlite at sharelatex.com). + // + // If you want to configure a different database, see the Sequelize documentation + // for available options: + // + // https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage + // + mysql: { + clsi: { + database: "clsi", + username: "clsi", + password: "", + dialect: "sqlite", storage: Path.join(DATA_DIR, "db.sqlite") + } + }, - # File storage - # ------------ + // File storage + // ------------ - # ShareLaTeX can store binary files like images either locally or in Amazon - # S3. The default is locally: - filestore: - backend: "fs" - stores: - user_files: Path.join(DATA_DIR, "user_files") + // ShareLaTeX can store binary files like images either locally or in Amazon + // S3. The default is locally: + filestore: { + backend: "fs", + stores: { + user_files: Path.join(DATA_DIR, "user_files"), template_files: Path.join(DATA_DIR, "template_files") + } + }, - # To use Amazon S3 as a storage backend, comment out the above config, and - # uncomment the following, filling in your key, secret, and bucket name: - # - # filestore: - # backend: "s3" - # stores: - # user_files: "BUCKET_NAME" - # s3: - # key: "AWS_KEY" - # secret: "AWS_SECRET" - # + // To use Amazon S3 as a storage backend, comment out the above config, and + // uncomment the following, filling in your key, secret, and bucket name: + // + // filestore: + // backend: "s3" + // stores: + // user_files: "BUCKET_NAME" + // s3: + // key: "AWS_KEY" + // secret: "AWS_SECRET" + // - trackchanges: + trackchanges: { continueOnError: true + }, - # Local disk caching - # ------------------ - path: - # If we ever need to write something to disk (e.g. incoming requests - # that need processing but may be too big for memory), then write - # them to disk here: - dumpFolder: Path.join(TMP_DIR, "dumpFolder") - # Where to write uploads before they are processed - uploadFolder: Path.join(TMP_DIR, "uploads") - # Where to write the project to disk before running LaTeX on it - compilesDir: Path.join(DATA_DIR, "compiles") - # Where to cache downloaded URLs for the CLSI - clsiCacheDir: Path.join(DATA_DIR, "cache") - # Where to write the output files to disk after running LaTeX + // Local disk caching + // ------------------ + path: { + // If we ever need to write something to disk (e.g. incoming requests + // that need processing but may be too big for memory), then write + // them to disk here: + dumpFolder: Path.join(TMP_DIR, "dumpFolder"), + // Where to write uploads before they are processed + uploadFolder: Path.join(TMP_DIR, "uploads"), + // Where to write the project to disk before running LaTeX on it + compilesDir: Path.join(DATA_DIR, "compiles"), + // Where to cache downloaded URLs for the CLSI + clsiCacheDir: Path.join(DATA_DIR, "cache"), + // Where to write the output files to disk after running LaTeX outputDir: Path.join(DATA_DIR, "output") + }, - # Server Config - # ------------- + // Server Config + // ------------- - # Where your instance of ShareLaTeX can be found publicly. This is used - # when emails are sent out and in generated links: - siteUrl: siteUrl = process.env["SHARELATEX_SITE_URL"] or 'http://localhost' + // Where your instance of ShareLaTeX can be found publicly. This is used + // when emails are sent out and in generated links: + siteUrl: (siteUrl = process.env["SHARELATEX_SITE_URL"] || 'http://localhost'), - # The name this is used to describe your ShareLaTeX Installation - appName: process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX (Community Edition)" + // The name this is used to describe your ShareLaTeX Installation + appName: process.env["SHARELATEX_APP_NAME"] || "ShareLaTeX (Community Edition)", - restrictInvitesToExistingAccounts: process.env["SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS"] == 'true' + restrictInvitesToExistingAccounts: process.env["SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS"] === 'true', - nav: - title: process.env["SHARELATEX_NAV_TITLE"] or process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX Community Edition" + nav: { + title: process.env["SHARELATEX_NAV_TITLE"] || process.env["SHARELATEX_APP_NAME"] || "ShareLaTeX Community Edition" + }, - # The email address which users will be directed to as the main point of - # contact for this installation of ShareLaTeX. - adminEmail: process.env["SHARELATEX_ADMIN_EMAIL"] or "placeholder@example.com" + // The email address which users will be directed to as the main point of + // contact for this installation of ShareLaTeX. + adminEmail: process.env["SHARELATEX_ADMIN_EMAIL"] || "placeholder@example.com", - # If provided, a sessionSecret is used to sign cookies so that they cannot be - # spoofed. This is recommended. - security: - sessionSecret: process.env["SHARELATEX_SESSION_SECRET"] or process.env["CRYPTO_RANDOM"] + // If provided, a sessionSecret is used to sign cookies so that they cannot be + // spoofed. This is recommended. + security: { + sessionSecret: process.env["SHARELATEX_SESSION_SECRET"] || process.env["CRYPTO_RANDOM"] + }, - # These credentials are used for authenticating api requests - # between services that may need to go over public channels - httpAuthUsers: httpAuthUsers + // These credentials are used for authenticating api requests + // between services that may need to go over public channels + httpAuthUsers, - # Should javascript assets be served minified or not. - useMinifiedJs: true + // Should javascript assets be served minified or not. + useMinifiedJs: true, - # Should static assets be sent with a header to tell the browser to cache - # them. This should be false in development where changes are being made, - # but should be set to true in production. - cacheStaticAssets: true + // Should static assets be sent with a header to tell the browser to cache + // them. This should be false in development where changes are being made, + // but should be set to true in production. + cacheStaticAssets: true, - # If you are running ShareLaTeX over https, set this to true to send the - # cookie with a secure flag (recommended). - secureCookie: process.env["SHARELATEX_SECURE_COOKIE"]? + // If you are running ShareLaTeX over https, set this to true to send the + // cookie with a secure flag (recommended). + secureCookie: (process.env["SHARELATEX_SECURE_COOKIE"] != null), - # If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) - # then set this to true to allow it to correctly detect the forwarded IP - # address and http/https protocol information. + // If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) + // then set this to true to allow it to correctly detect the forwarded IP + // address and http/https protocol information. - behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] or false + behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] || false, - i18n: - subdomainLang: - www: {lngCode:process.env["SHARELATEX_SITE_LANGUAGE"] or "en", url: siteUrl} - defaultLng: process.env["SHARELATEX_SITE_LANGUAGE"] or "en" + i18n: { + subdomainLang: { + www: {lngCode:process.env["SHARELATEX_SITE_LANGUAGE"] || "en", url: siteUrl} + }, + defaultLng: process.env["SHARELATEX_SITE_LANGUAGE"] || "en" + }, - currentImageName: process.env["TEX_LIVE_DOCKER_IMAGE"] + currentImageName: process.env["TEX_LIVE_DOCKER_IMAGE"], - apis: - web: - url: "http://localhost:3000" - user: httpAuthUser + apis: { + web: { + url: "http://localhost:3000", + user: httpAuthUser, pass: httpAuthPass - project_history: + }, + project_history: { enabled: false - references:{} - notifications:undefined + } + }, + references:{}, + notifications:undefined, - defaultFeatures: - collaborators: -1 - dropbox: true - versioning: true - compileTimeout: parseIntOrFail(process.env["COMPILE_TIMEOUT"] or 180) - compileGroup: "standard" - trackChanges: true - templates: true + defaultFeatures: { + collaborators: -1, + dropbox: true, + versioning: true, + compileTimeout: parseIntOrFail(process.env["COMPILE_TIMEOUT"] || 180), + compileGroup: "standard", + trackChanges: true, + templates: true, references: true + } +}; -## OPTIONAL CONFIGURABLE SETTINGS +//# OPTIONAL CONFIGURABLE SETTINGS -if process.env["SHARELATEX_LEFT_FOOTER"]? - try - settings.nav.left_footer = JSON.parse(process.env["SHARELATEX_LEFT_FOOTER"]) - catch e - console.error("could not parse SHARELATEX_LEFT_FOOTER, not valid JSON") +if (process.env["SHARELATEX_LEFT_FOOTER"] != null) { + try { + settings.nav.left_footer = JSON.parse(process.env["SHARELATEX_LEFT_FOOTER"]); + } catch (error) { + e = error; + console.error("could not parse SHARELATEX_LEFT_FOOTER, not valid JSON"); + } +} -if process.env["SHARELATEX_RIGHT_FOOTER"]? - settings.nav.right_footer = process.env["SHARELATEX_RIGHT_FOOTER"] - try - settings.nav.right_footer = JSON.parse(process.env["SHARELATEX_RIGHT_FOOTER"]) - catch e - console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON") +if (process.env["SHARELATEX_RIGHT_FOOTER"] != null) { + settings.nav.right_footer = process.env["SHARELATEX_RIGHT_FOOTER"]; + try { + settings.nav.right_footer = JSON.parse(process.env["SHARELATEX_RIGHT_FOOTER"]); + } catch (error1) { + e = error1; + console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON"); + } +} -if process.env["SHARELATEX_HEADER_IMAGE_URL"]? - settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"] +if (process.env["SHARELATEX_HEADER_IMAGE_URL"] != null) { + settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"]; +} -if process.env["SHARELATEX_HEADER_NAV_LINKS"]? - console.error """ +if (process.env["SHARELATEX_HEADER_NAV_LINKS"] != null) { + console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # WARNING: SHARELATEX_HEADER_NAV_LINKS is no longer supported # See https://github.com/sharelatex/sharelatex/wiki/Configuring-Headers,-Footers-&-Logo # -# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -""" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\ +` + ); +} -if process.env["SHARELATEX_HEADER_EXTRAS"]? - try - settings.nav.header_extras = JSON.parse(process.env["SHARELATEX_HEADER_EXTRAS"]) - catch e - console.error("could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON") +if (process.env["SHARELATEX_HEADER_EXTRAS"] != null) { + try { + settings.nav.header_extras = JSON.parse(process.env["SHARELATEX_HEADER_EXTRAS"]); + } catch (error2) { + e = error2; + console.error("could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON"); + } +} -# Sending Email -# ------------- -# -# You must configure a mail server to be able to send invite emails from -# ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer -# documentation for available options: -# -# http://www.nodemailer.com/docs/transports +// Sending Email +// ------------- +// +// You must configure a mail server to be able to send invite emails from +// ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer +// documentation for available options: +// +// http://www.nodemailer.com/docs/transports -if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? +if (process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] != null) { - settings.email = - fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] - replyTo: process.env["SHARELATEX_EMAIL_REPLY_TO"] or "" - driver: process.env["SHARELATEX_EMAIL_DRIVER"] - parameters: - #AWS Creds - AWSAccessKeyID: process.env["SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID"] - AWSSecretKey: process.env["SHARELATEX_EMAIL_AWS_SES_SECRET_KEY"] + settings.email = { + fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"], + replyTo: process.env["SHARELATEX_EMAIL_REPLY_TO"] || "", + driver: process.env["SHARELATEX_EMAIL_DRIVER"], + parameters: { + //AWS Creds + AWSAccessKeyID: process.env["SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID"], + AWSSecretKey: process.env["SHARELATEX_EMAIL_AWS_SES_SECRET_KEY"], - #SMTP Creds - host: process.env["SHARELATEX_EMAIL_SMTP_HOST"] + //SMTP Creds + host: process.env["SHARELATEX_EMAIL_SMTP_HOST"], port: process.env["SHARELATEX_EMAIL_SMTP_PORT"], - secure: parse(process.env["SHARELATEX_EMAIL_SMTP_SECURE"]) - ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"]) - name: process.env["SHARELATEX_EMAIL_SMTP_NAME"] - logger: process.env["SHARELATEX_EMAIL_SMTP_LOGGER"] == 'true' + secure: parse(process.env["SHARELATEX_EMAIL_SMTP_SECURE"]), + ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"]), + name: process.env["SHARELATEX_EMAIL_SMTP_NAME"], + logger: process.env["SHARELATEX_EMAIL_SMTP_LOGGER"] === 'true' + }, - textEncoding: process.env["SHARELATEX_EMAIL_TEXT_ENCODING"] - template: + textEncoding: process.env["SHARELATEX_EMAIL_TEXT_ENCODING"], + template: { customFooter: process.env["SHARELATEX_CUSTOM_EMAIL_FOOTER"] + } + }; - if process.env["SHARELATEX_EMAIL_AWS_SES_REGION"]? - settings.email.parameters.region = process.env["SHARELATEX_EMAIL_AWS_SES_REGION"] + if (process.env["SHARELATEX_EMAIL_AWS_SES_REGION"] != null) { + settings.email.parameters.region = process.env["SHARELATEX_EMAIL_AWS_SES_REGION"]; + } - if process.env["SHARELATEX_EMAIL_SMTP_USER"]? or process.env["SHARELATEX_EMAIL_SMTP_PASS"]? - settings.email.parameters.auth = - user: process.env["SHARELATEX_EMAIL_SMTP_USER"] + if ((process.env["SHARELATEX_EMAIL_SMTP_USER"] != null) || (process.env["SHARELATEX_EMAIL_SMTP_PASS"] != null)) { + settings.email.parameters.auth = { + user: process.env["SHARELATEX_EMAIL_SMTP_USER"], pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"] + }; + } - if process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]? + if (process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"] != null) { settings.email.parameters.tls = - rejectUnauthorized: parse(process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]) + {rejectUnauthorized: parse(process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"])}; + } +} -# i18n -if process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]? +// i18n +if (process.env["SHARELATEX_LANG_DOMAIN_MAPPING"] != null) { - settings.i18n.subdomainLang = parse(process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]) + settings.i18n.subdomainLang = parse(process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]); +} -# Password Settings -# ----------- -# These restrict the passwords users can use when registering -# opts are from http://antelle.github.io/passfield -if process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] +// Password Settings +// ----------- +// These restrict the passwords users can use when registering +// opts are from http://antelle.github.io/passfield +if (process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] || process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] || process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"]) { - settings.passwordStrengthOptions = - pattern: process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or "aA$3" - length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] or 150} + settings.passwordStrengthOptions = { + pattern: process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] || "aA$3", + length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] || 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] || 150} + }; +} -####################### -# ShareLaTeX Server Pro -####################### +//###################### +// ShareLaTeX Server Pro +//###################### -if parse(process.env["SHARELATEX_IS_SERVER_PRO"]) == true - settings.bypassPercentageRollouts = true +if (parse(process.env["SHARELATEX_IS_SERVER_PRO"]) === true) { + settings.bypassPercentageRollouts = true; settings.apis.references = - url: "http://localhost:3040" + {url: "http://localhost:3040"}; +} -# LDAP - SERVER PRO ONLY -# ---------- +// LDAP - SERVER PRO ONLY +// ---------- -if process.env["SHARELATEX_LDAP_HOST"] - console.error """ +if (process.env["SHARELATEX_LDAP_HOST"]) { + console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # WARNING: The LDAP configuration format has changed in version 0.5.1 # See https://github.com/sharelatex/sharelatex/wiki/Server-Pro:-LDAP-Config # -# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -""" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\ +` + ); +} -if process.env["SHARELATEX_LDAP_URL"] - settings.externalAuth = true - settings.ldap = - emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"] - nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"] - lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"] - updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' - placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"] - server: - url: process.env["SHARELATEX_LDAP_URL"] - bindDn: process.env["SHARELATEX_LDAP_BIND_DN"] - bindCredentials: process.env["SHARELATEX_LDAP_BIND_CREDENTIALS"] - bindProperty: process.env["SHARELATEX_LDAP_BIND_PROPERTY"] - searchBase: process.env["SHARELATEX_LDAP_SEARCH_BASE"] - searchScope: process.env["SHARELATEX_LDAP_SEARCH_SCOPE"] - searchFilter: process.env["SHARELATEX_LDAP_SEARCH_FILTER"] +if (process.env["SHARELATEX_LDAP_URL"]) { + let _ldap_connect_timeout, _ldap_group_search_attribs, _ldap_search_attribs, _ldap_timeout; + settings.externalAuth = true; + settings.ldap = { + emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"], + nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"], + lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"], + updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] === 'true', + placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"], + server: { + url: process.env["SHARELATEX_LDAP_URL"], + bindDn: process.env["SHARELATEX_LDAP_BIND_DN"], + bindCredentials: process.env["SHARELATEX_LDAP_BIND_CREDENTIALS"], + bindProperty: process.env["SHARELATEX_LDAP_BIND_PROPERTY"], + searchBase: process.env["SHARELATEX_LDAP_SEARCH_BASE"], + searchScope: process.env["SHARELATEX_LDAP_SEARCH_SCOPE"], + searchFilter: process.env["SHARELATEX_LDAP_SEARCH_FILTER"], searchAttributes: ( - if _ldap_search_attribs = process.env["SHARELATEX_LDAP_SEARCH_ATTRIBUTES"] - try - JSON.parse(_ldap_search_attribs) - catch e - console.error "could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES" - else + (_ldap_search_attribs = process.env["SHARELATEX_LDAP_SEARCH_ATTRIBUTES"]) ? + (() => { try { + return JSON.parse(_ldap_search_attribs); + } catch (error3) { + e = error3; + return console.error("could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES"); + } })() + : undefined - ) - groupDnProperty: process.env["SHARELATEX_LDAP_GROUP_DN_PROPERTY"] - groupSearchBase: process.env["SHARELATEX_LDAP_GROUP_SEARCH_BASE"] - groupSearchScope: process.env["SHARELATEX_LDAP_GROUP_SEARCH_SCOPE"] - groupSearchFilter: process.env["SHARELATEX_LDAP_GROUP_SEARCH_FILTER"] + ), + groupDnProperty: process.env["SHARELATEX_LDAP_GROUP_DN_PROPERTY"], + groupSearchBase: process.env["SHARELATEX_LDAP_GROUP_SEARCH_BASE"], + groupSearchScope: process.env["SHARELATEX_LDAP_GROUP_SEARCH_SCOPE"], + groupSearchFilter: process.env["SHARELATEX_LDAP_GROUP_SEARCH_FILTER"], groupSearchAttributes: ( - if _ldap_group_search_attribs = process.env["SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"] - try - JSON.parse(_ldap_group_search_attribs) - catch e - console.error "could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES" - else + (_ldap_group_search_attribs = process.env["SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"]) ? + (() => { try { + return JSON.parse(_ldap_group_search_attribs); + } catch (error4) { + e = error4; + return console.error("could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"); + } })() + : undefined - ) - cache: process.env["SHARELATEX_LDAP_CACHE"] == 'true' + ), + cache: process.env["SHARELATEX_LDAP_CACHE"] === 'true', timeout: ( - if _ldap_timeout = process.env["SHARELATEX_LDAP_TIMEOUT"] - try - parseIntOrFail(_ldap_timeout) - catch e - console.error "Cannot parse SHARELATEX_LDAP_TIMEOUT" - else + (_ldap_timeout = process.env["SHARELATEX_LDAP_TIMEOUT"]) ? + (() => { try { + return parseIntOrFail(_ldap_timeout); + } catch (error5) { + e = error5; + return console.error("Cannot parse SHARELATEX_LDAP_TIMEOUT"); + } })() + : undefined - ) + ), connectTimeout: ( - if _ldap_connect_timeout = process.env["SHARELATEX_LDAP_CONNECT_TIMEOUT"] - try - parseIntOrFail(_ldap_connect_timeout) - catch e - console.error "Cannot parse SHARELATEX_LDAP_CONNECT_TIMEOUT" - else + (_ldap_connect_timeout = process.env["SHARELATEX_LDAP_CONNECT_TIMEOUT"]) ? + (() => { try { + return parseIntOrFail(_ldap_connect_timeout); + } catch (error6) { + e = error6; + return console.error("Cannot parse SHARELATEX_LDAP_CONNECT_TIMEOUT"); + } })() + : undefined ) + } + }; - if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] - try - ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]) - catch e - console.error "could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON" + if (process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]) { + let ca, ca_paths; + try { + ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]); + } catch (error7) { + e = error7; + console.error("could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON"); + } - if typeof(ca) == 'string' - ca_paths = [ca] - else if typeof(ca) == 'object' && ca?.length? - ca_paths = ca - else - console.error "problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH" + if (typeof(ca) === 'string') { + ca_paths = [ca]; + } else if ((typeof(ca) === 'object') && ((ca != null ? ca.length : undefined) != null)) { + ca_paths = ca; + } else { + console.error("problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH"); + } - settings.ldap.server.tlsOptions = - rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true" - ca:ca_paths # e.g.'/etc/ldap/ca_certs.pem' + settings.ldap.server.tlsOptions = { + rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] === "true", + ca:ca_paths // e.g.'/etc/ldap/ca_certs.pem' + }; + } +} -if process.env["SHARELATEX_SAML_ENTRYPOINT"] - # NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options - settings.externalAuth = true - settings.saml = - updateUserDetailsOnLogin: process.env["SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' - identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"] - emailField: process.env["SHARELATEX_SAML_EMAIL_FIELD"] || process.env["SHARELATEX_SAML_EMAIL_FIELD_NAME"] - firstNameField: process.env["SHARELATEX_SAML_FIRST_NAME_FIELD"] - lastNameField: process.env["SHARELATEX_SAML_LAST_NAME_FIELD"] - server: - # strings - entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"] - callbackUrl: process.env["SHARELATEX_SAML_CALLBACK_URL"] - issuer: process.env["SHARELATEX_SAML_ISSUER"] - decryptionPvk: process.env["SHARELATEX_SAML_DECRYPTION_PVK"] - decryptionCert: process.env["SHARELATEX_SAML_DECRYPTION_CERT"] - signatureAlgorithm: process.env["SHARELATEX_SAML_SIGNATURE_ALGORITHM"] - identifierFormat: process.env["SHARELATEX_SAML_IDENTIFIER_FORMAT"] - attributeConsumingServiceIndex: process.env["SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX"] - authnContext: process.env["SHARELATEX_SAML_AUTHN_CONTEXT"] - authnRequestBinding: process.env["SHARELATEX_SAML_AUTHN_REQUEST_BINDING"] - validateInResponseTo: process.env["SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO"] - cacheProvider: process.env["SHARELATEX_SAML_CACHE_PROVIDER"] - logoutUrl: process.env["SHARELATEX_SAML_LOGOUT_URL"] - logoutCallbackUrl: process.env["SHARELATEX_SAML_LOGOUT_CALLBACK_URL"] - disableRequestedAuthnContext: process.env["SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT"] == 'true' - forceAuthn: process.env["SHARELATEX_SAML_FORCE_AUTHN"] == 'true' - skipRequestCompression: process.env["SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION"] == 'true' +if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { + // NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options + let _saml_additionalAuthorizeParams, _saml_additionalLogoutParams, _saml_additionalParams, _saml_expiration, _saml_skew; + settings.externalAuth = true; + settings.saml = { + updateUserDetailsOnLogin: process.env["SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN"] === 'true', + identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"], + emailField: process.env["SHARELATEX_SAML_EMAIL_FIELD"] || process.env["SHARELATEX_SAML_EMAIL_FIELD_NAME"], + firstNameField: process.env["SHARELATEX_SAML_FIRST_NAME_FIELD"], + lastNameField: process.env["SHARELATEX_SAML_LAST_NAME_FIELD"], + server: { + // strings + entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"], + callbackUrl: process.env["SHARELATEX_SAML_CALLBACK_URL"], + issuer: process.env["SHARELATEX_SAML_ISSUER"], + decryptionPvk: process.env["SHARELATEX_SAML_DECRYPTION_PVK"], + decryptionCert: process.env["SHARELATEX_SAML_DECRYPTION_CERT"], + signatureAlgorithm: process.env["SHARELATEX_SAML_SIGNATURE_ALGORITHM"], + identifierFormat: process.env["SHARELATEX_SAML_IDENTIFIER_FORMAT"], + attributeConsumingServiceIndex: process.env["SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX"], + authnContext: process.env["SHARELATEX_SAML_AUTHN_CONTEXT"], + authnRequestBinding: process.env["SHARELATEX_SAML_AUTHN_REQUEST_BINDING"], + validateInResponseTo: process.env["SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO"], + cacheProvider: process.env["SHARELATEX_SAML_CACHE_PROVIDER"], + logoutUrl: process.env["SHARELATEX_SAML_LOGOUT_URL"], + logoutCallbackUrl: process.env["SHARELATEX_SAML_LOGOUT_CALLBACK_URL"], + disableRequestedAuthnContext: process.env["SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT"] === 'true', + forceAuthn: process.env["SHARELATEX_SAML_FORCE_AUTHN"] === 'true', + skipRequestCompression: process.env["SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION"] === 'true', acceptedClockSkewMs: ( - if _saml_skew = process.env["SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"] - try - parseIntOrFail(_saml_skew) - catch e - console.error "Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS" - else + (_saml_skew = process.env["SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"]) ? + (() => { try { + return parseIntOrFail(_saml_skew); + } catch (error8) { + e = error8; + return console.error("Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"); + } })() + : undefined - ) + ), requestIdExpirationPeriodMs: ( - if _saml_expiration = process.env["SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"] - try - parseIntOrFail(_saml_expiration) - catch e - console.error "Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS" - else + (_saml_expiration = process.env["SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"]) ? + (() => { try { + return parseIntOrFail(_saml_expiration); + } catch (error9) { + e = error9; + return console.error("Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"); + } })() + : undefined - ) + ), additionalParams: ( - if _saml_additionalParams = process.env["SHARELATEX_SAML_ADDITIONAL_PARAMS"] - try - JSON.parse(_saml_additionalParams) - catch e - console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS" - else + (_saml_additionalParams = process.env["SHARELATEX_SAML_ADDITIONAL_PARAMS"]) ? + (() => { try { + return JSON.parse(_saml_additionalParams); + } catch (error10) { + e = error10; + return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS"); + } })() + : undefined - ) + ), additionalAuthorizeParams: ( - if _saml_additionalAuthorizeParams = process.env["SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"] - try - JSON.parse(_saml_additionalAuthorizeParams ) - catch e - console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS" - else + (_saml_additionalAuthorizeParams = process.env["SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"]) ? + (() => { try { + return JSON.parse(_saml_additionalAuthorizeParams ); + } catch (error11) { + e = error11; + return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"); + } })() + : undefined - ) + ), additionalLogoutParams: ( - if _saml_additionalLogoutParams = process.env["SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"] - try - JSON.parse(_saml_additionalLogoutParams ) - catch e - console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS" - else + (_saml_additionalLogoutParams = process.env["SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"]) ? + (() => { try { + return JSON.parse(_saml_additionalLogoutParams ); + } catch (error12) { + e = error12; + return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"); + } })() + : undefined ) + } + }; - # SHARELATEX_SAML_CERT cannot be empty - # https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 - if process.env["SHARELATEX_SAML_CERT"] - settings.saml.server.cert = process.env["SHARELATEX_SAML_CERT"] - settings.saml.server.privateCert = process.env["SHARELATEX_SAML_PRIVATE_CERT"] + // SHARELATEX_SAML_CERT cannot be empty + // https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 + if (process.env["SHARELATEX_SAML_CERT"]) { + settings.saml.server.cert = process.env["SHARELATEX_SAML_CERT"]; + settings.saml.server.privateCert = process.env["SHARELATEX_SAML_PRIVATE_CERT"]; + } +} -# Compiler -# -------- -if process.env["SANDBOXED_COMPILES"] == "true" - settings.clsi = - dockerRunner: true - docker: - image: process.env["TEX_LIVE_DOCKER_IMAGE"] - env: - HOME: "/tmp" - PATH: process.env["COMPILER_PATH"] or "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +// Compiler +// -------- +if (process.env["SANDBOXED_COMPILES"] === "true") { + settings.clsi = { + dockerRunner: true, + docker: { + image: process.env["TEX_LIVE_DOCKER_IMAGE"], + env: { + HOME: "/tmp", + PATH: process.env["COMPILER_PATH"] || "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + }, user: "www-data" + } + }; - if !settings.path? - settings.path = {} - settings.path.synctexBaseDir = () -> "/compile" - if process.env['SANDBOXED_COMPILES_SIBLING_CONTAINERS'] == 'true' - console.log("Using sibling containers for sandboxed compiles") - if process.env['SANDBOXED_COMPILES_HOST_DIR'] - settings.path.sandboxedCompilesHostDir = process.env['SANDBOXED_COMPILES_HOST_DIR'] - else - console.error('Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set') + if ((settings.path == null)) { + settings.path = {}; + } + settings.path.synctexBaseDir = () => "/compile"; + if (process.env['SANDBOXED_COMPILES_SIBLING_CONTAINERS'] === 'true') { + console.log("Using sibling containers for sandboxed compiles"); + if (process.env['SANDBOXED_COMPILES_HOST_DIR']) { + settings.path.sandboxedCompilesHostDir = process.env['SANDBOXED_COMPILES_HOST_DIR']; + } else { + console.error('Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set'); + } + } +} -# Templates -# --------- -if process.env["SHARELATEX_TEMPLATES_USER_ID"] - settings.templates = - mountPointUrl: "/templates" +// Templates +// --------- +if (process.env["SHARELATEX_TEMPLATES_USER_ID"]) { + settings.templates = { + mountPointUrl: "/templates", user_id: process.env["SHARELATEX_TEMPLATES_USER_ID"] + }; - settings.templateLinks = parse(process.env["SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS"]) + settings.templateLinks = parse(process.env["SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS"]); +} -# /Learn -# ------- -if process.env["SHARELATEX_PROXY_LEARN"]? - settings.proxyLearn = parse(process.env["SHARELATEX_PROXY_LEARN"]) +// /Learn +// ------- +if (process.env["SHARELATEX_PROXY_LEARN"] != null) { + settings.proxyLearn = parse(process.env["SHARELATEX_PROXY_LEARN"]); +} -# /References -# ----------- -if process.env["SHARELATEX_ELASTICSEARCH_URL"]? +// /References +// ----------- +if (process.env["SHARELATEX_ELASTICSEARCH_URL"] != null) { settings.references.elasticsearch = - host: process.env["SHARELATEX_ELASTICSEARCH_URL"] + {host: process.env["SHARELATEX_ELASTICSEARCH_URL"]}; +} -# TeX Live Images -# ----------- -if process.env["ALL_TEX_LIVE_DOCKER_IMAGES"]? - allTexLiveDockerImages = process.env["ALL_TEX_LIVE_DOCKER_IMAGES"].split(',') -if process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"]? - allTexLiveDockerImageNames = process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"].split(',') -if allTexLiveDockerImages? - settings.allowedImageNames = [] - for fullImageName, index in allTexLiveDockerImages - imageName = Path.basename(fullImageName) - imageDesc = if allTexLiveDockerImageNames? then allTexLiveDockerImageNames[index] else imageName - settings.allowedImageNames.push({ imageName, imageDesc }) +// TeX Live Images +// ----------- +if (process.env["ALL_TEX_LIVE_DOCKER_IMAGES"] != null) { + allTexLiveDockerImages = process.env["ALL_TEX_LIVE_DOCKER_IMAGES"].split(','); +} +if (process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"] != null) { + allTexLiveDockerImageNames = process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"].split(','); +} +if (allTexLiveDockerImages != null) { + settings.allowedImageNames = []; + for (let index = 0; index < allTexLiveDockerImages.length; index++) { + const fullImageName = allTexLiveDockerImages[index]; + const imageName = Path.basename(fullImageName); + const imageDesc = (allTexLiveDockerImageNames != null) ? allTexLiveDockerImageNames[index] : imageName; + settings.allowedImageNames.push({ imageName, imageDesc }); + } +} -# With lots of incoming and outgoing HTTP connections to different services, -# sometimes long running, it is a good idea to increase the default number -# of sockets that Node will hold open. -http = require('http') -http.globalAgent.maxSockets = 300 -https = require('https') -https.globalAgent.maxSockets = 300 +// With lots of incoming and outgoing HTTP connections to different services, +// sometimes long running, it is a good idea to increase the default number +// of sockets that Node will hold open. +const http = require('http'); +http.globalAgent.maxSockets = 300; +const https = require('https'); +https.globalAgent.maxSockets = 300; -module.exports = settings +module.exports = settings; diff --git a/server-ce/tasks/CreateAndDestroyUsers.js b/server-ce/tasks/CreateAndDestroyUsers.js index 79da259c67..cff38d35be 100644 --- a/server-ce/tasks/CreateAndDestroyUsers.js +++ b/server-ce/tasks/CreateAndDestroyUsers.js @@ -1,60 +1,79 @@ +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ -module.exports = (grunt) -> +module.exports = function(grunt) { - grunt.registerTask 'user:create-admin', "Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt user:create-admin --email joe@example.com", () -> - done = @async() - email = grunt.option("email") - if !email? - console.error "Usage: grunt user:create-admin --email=joe@example.com" - process.exit(1) + grunt.registerTask('user:create-admin', "Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt user:create-admin --email joe@example.com", function() { + const done = this.async(); + const email = grunt.option("email"); + if ((email == null)) { + console.error("Usage: grunt user:create-admin --email=joe@example.com"); + process.exit(1); + } - settings = require "settings-sharelatex" - mongodb = require "../web/app/src/infrastructure/mongodb" - UserRegistrationHandler = require "../web/app/src/Features/User/UserRegistrationHandler" - OneTimeTokenHandler = require "../web/app/src/Features/Security/OneTimeTokenHandler" - mongodb.waitForDb().then () -> - UserRegistrationHandler.registerNewUser { - email: email - password: require("crypto").randomBytes(32).toString("hex") - }, (error, user) -> - if error? and error?.message != "EmailAlreadyRegistered" - throw error - user.isAdmin = true - user.save (error) -> - throw error if error? - ONE_WEEK = 7 * 24 * 60 * 60 # seconds - OneTimeTokenHandler.getNewToken "password", { expiresIn: ONE_WEEK, email:user.email, user_id: user._id.toString() }, (err, token)-> - return next(err) if err? + const settings = require("settings-sharelatex"); + const mongodb = require("../web/app/src/infrastructure/mongodb"); + const UserRegistrationHandler = require("../web/app/src/Features/User/UserRegistrationHandler"); + const OneTimeTokenHandler = require("../web/app/src/Features/Security/OneTimeTokenHandler"); + return mongodb.waitForDb().then(() => UserRegistrationHandler.registerNewUser({ + email, + password: require("crypto").randomBytes(32).toString("hex") + }, function(error, user) { + if ((error != null) && ((error != null ? error.message : undefined) !== "EmailAlreadyRegistered")) { + throw error; + } + user.isAdmin = true; + return user.save(function(error) { + if (error != null) { throw error; } + const ONE_WEEK = 7 * 24 * 60 * 60; // seconds + return OneTimeTokenHandler.getNewToken("password", { expiresIn: ONE_WEEK, email:user.email, user_id: user._id.toString() }, function(err, token){ + if (err != null) { return next(err); } - console.log "" - console.log """ - Successfully created #{email} as an admin user. + console.log(""); + console.log(`\ +Successfully created ${email} as an admin user. - Please visit the following URL to set a password for #{email} and log in: +Please visit the following URL to set a password for ${email} and log in: - #{settings.siteUrl}/user/password/set?passwordResetToken=#{token} +${settings.siteUrl}/user/password/set?passwordResetToken=${token} +\ +` + ); + return done(); + }); + }); + })); + }); - """ - done() - - grunt.registerTask 'user:delete', "deletes a user and all their data, Usage: grunt user:delete --email joe@example.com", () -> - done = @async() - email = grunt.option("email") - if !email? - console.error "Usage: grunt user:delete --email=joe@example.com" - process.exit(1) - settings = require "settings-sharelatex" - mongodb = require "../web/app/src/infrastructure/mongodb" - UserGetter = require "../web/app/src/Features/User/UserGetter" - UserDeleter = require "../web/app/src/Features/User/UserDeleter" - mongodb.waitForDb().then () -> - UserGetter.getUser email:email, (error, user) -> - if error? - throw error - if !user? - console.log("user #{email} not in database, potentially already deleted") - return done() - UserDeleter.deleteUser user._id, (err)-> - if err? - throw err - done() + return grunt.registerTask('user:delete', "deletes a user and all their data, Usage: grunt user:delete --email joe@example.com", function() { + const done = this.async(); + const email = grunt.option("email"); + if ((email == null)) { + console.error("Usage: grunt user:delete --email=joe@example.com"); + process.exit(1); + } + const settings = require("settings-sharelatex"); + const mongodb = require("../web/app/src/infrastructure/mongodb"); + const UserGetter = require("../web/app/src/Features/User/UserGetter"); + const UserDeleter = require("../web/app/src/Features/User/UserDeleter"); + return mongodb.waitForDb().then(() => UserGetter.getUser({email}, function(error, user) { + if (error != null) { + throw error; + } + if ((user == null)) { + console.log(`user ${email} not in database, potentially already deleted`); + return done(); + } + return UserDeleter.deleteUser(user._id, function(err){ + if (err != null) { + throw err; + } + return done(); + }); + })); + }); +}; diff --git a/server-ce/tasks/ProjectSize.js b/server-ce/tasks/ProjectSize.js index 1d02d33d26..77565724cd 100644 --- a/server-ce/tasks/ProjectSize.js +++ b/server-ce/tasks/ProjectSize.js @@ -1,24 +1,24 @@ -# require("coffee-script") +// require("coffee-script") -# fs = require("fs") -# _ = require("underscore") +// fs = require("fs") +// _ = require("underscore") -# if not process.argv[2] -# console.log "Usage: coffee project_size.coffee user_files_path" -# else -# dirPath = process.argv[2] -# if not fs.lstatSync(dirPath).isDirectory() -# console.log dirPath + " directory not exist" -# else -# fs.readdir dirPath, (err, files)-> -# projects = [] -# files.forEach (file)-> -# project_id = file.split("_")[0] -# if !projects[project_id] -# projects[project_id] = 0 -# projects[project_id] += fs.lstatSync(dirPath+"/"+file).size +// if not process.argv[2] +// console.log "Usage: coffee project_size.coffee user_files_path" +// else +// dirPath = process.argv[2] +// if not fs.lstatSync(dirPath).isDirectory() +// console.log dirPath + " directory not exist" +// else +// fs.readdir dirPath, (err, files)-> +// projects = [] +// files.forEach (file)-> +// project_id = file.split("_")[0] +// if !projects[project_id] +// projects[project_id] = 0 +// projects[project_id] += fs.lstatSync(dirPath+"/"+file).size -# ids = _.keys projects -# console.log "project \t size" -# ids.forEach (id)-> -# console.log id + "\t" + projects[id] +// ids = _.keys projects +// console.log "project \t size" +// ids.forEach (id)-> +// console.log id + "\t" + projects[id] From d812c86c517ccfcd3494486b0cb769451528d2c2 Mon Sep 17 00:00:00 2001 From: decaffeinate Date: Wed, 7 Jul 2021 11:39:45 +0000 Subject: [PATCH 511/525] decaffeinate: Run post-processing cleanups on coffee files --- server-ce/Gruntfile.js | 9 + server-ce/settings.js | 278 ++++++++++++----------- server-ce/tasks/CreateAndDestroyUsers.js | 6 + server-ce/tasks/ProjectSize.js | 2 + 4 files changed, 160 insertions(+), 135 deletions(-) diff --git a/server-ce/Gruntfile.js b/server-ce/Gruntfile.js index a1173ed864..bee096789c 100644 --- a/server-ce/Gruntfile.js +++ b/server-ce/Gruntfile.js @@ -1,3 +1,12 @@ +/* eslint-disable + camelcase, + no-return-assign, + no-unreachable, + no-unused-vars, + node/handle-callback-err, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS101: Remove unnecessary use of Array.from diff --git a/server-ce/settings.js b/server-ce/settings.js index 1d2fc7a018..09d21d0015 100644 --- a/server-ce/settings.js +++ b/server-ce/settings.js @@ -1,3 +1,11 @@ +/* eslint-disable + camelcase, + no-cond-assign, + no-dupe-keys, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS205: Consider reworking code to avoid use of IIFEs @@ -11,7 +19,7 @@ const Path = require('path'); // These credentials are used for authenticating api requests // between services that may need to go over public channels const httpAuthUser = "sharelatex"; -const httpAuthPass = process.env["WEB_API_PASSWORD"]; +const httpAuthPass = process.env.WEB_API_PASSWORD; const httpAuthUsers = {}; httpAuthUsers[httpAuthUser] = httpAuthPass; @@ -40,13 +48,13 @@ const TMP_DIR = '/var/lib/sharelatex/tmp'; const settings = { clsi: { - optimiseInDocker: process.env['OPTIMISE_PDF'] === 'true' + optimiseInDocker: process.env.OPTIMISE_PDF === 'true' }, brandPrefix: "", allowAnonymousReadAndWriteSharing: - process.env['SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING'] === 'true', + process.env.SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING === 'true', // Databases // --------- @@ -58,7 +66,7 @@ const settings = { // // The following works out of the box with Mongo's default settings: mongo: { - url : process.env["SHARELATEX_MONGO_URL"] || 'mongodb://dockerhost/sharelatex' + url : process.env.SHARELATEX_MONGO_URL || 'mongodb://dockerhost/sharelatex' }, // Redis is used in ShareLaTeX for high volume queries, like real-time @@ -67,9 +75,9 @@ const settings = { // The following config will work with Redis's default settings: redis: { web: (redisConfig = { - host: process.env["SHARELATEX_REDIS_HOST"] || "dockerhost", - port: process.env["SHARELATEX_REDIS_PORT"] || "6379", - password: process.env["SHARELATEX_REDIS_PASS"] || undefined, + host: process.env.SHARELATEX_REDIS_HOST || "dockerhost", + port: process.env.SHARELATEX_REDIS_PORT || "6379", + password: process.env.SHARELATEX_REDIS_PASS || undefined, key_schema: { // document-updater blockingKey({doc_id}) { return `Blocking:${doc_id}`; }, @@ -180,26 +188,26 @@ const settings = { // Where your instance of ShareLaTeX can be found publicly. This is used // when emails are sent out and in generated links: - siteUrl: (siteUrl = process.env["SHARELATEX_SITE_URL"] || 'http://localhost'), + siteUrl: (siteUrl = process.env.SHARELATEX_SITE_URL || 'http://localhost'), // The name this is used to describe your ShareLaTeX Installation - appName: process.env["SHARELATEX_APP_NAME"] || "ShareLaTeX (Community Edition)", + appName: process.env.SHARELATEX_APP_NAME || "ShareLaTeX (Community Edition)", - restrictInvitesToExistingAccounts: process.env["SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS"] === 'true', + restrictInvitesToExistingAccounts: process.env.SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS === 'true', nav: { - title: process.env["SHARELATEX_NAV_TITLE"] || process.env["SHARELATEX_APP_NAME"] || "ShareLaTeX Community Edition" + title: process.env.SHARELATEX_NAV_TITLE || process.env.SHARELATEX_APP_NAME || "ShareLaTeX Community Edition" }, // The email address which users will be directed to as the main point of // contact for this installation of ShareLaTeX. - adminEmail: process.env["SHARELATEX_ADMIN_EMAIL"] || "placeholder@example.com", + adminEmail: process.env.SHARELATEX_ADMIN_EMAIL || "placeholder@example.com", // If provided, a sessionSecret is used to sign cookies so that they cannot be // spoofed. This is recommended. security: { - sessionSecret: process.env["SHARELATEX_SESSION_SECRET"] || process.env["CRYPTO_RANDOM"] + sessionSecret: process.env.SHARELATEX_SESSION_SECRET || process.env.CRYPTO_RANDOM }, // These credentials are used for authenticating api requests @@ -216,22 +224,22 @@ const settings = { // If you are running ShareLaTeX over https, set this to true to send the // cookie with a secure flag (recommended). - secureCookie: (process.env["SHARELATEX_SECURE_COOKIE"] != null), + secureCookie: (process.env.SHARELATEX_SECURE_COOKIE != null), // If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) // then set this to true to allow it to correctly detect the forwarded IP // address and http/https protocol information. - behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] || false, + behindProxy: process.env.SHARELATEX_BEHIND_PROXY || false, i18n: { subdomainLang: { - www: {lngCode:process.env["SHARELATEX_SITE_LANGUAGE"] || "en", url: siteUrl} + www: {lngCode:process.env.SHARELATEX_SITE_LANGUAGE || "en", url: siteUrl} }, - defaultLng: process.env["SHARELATEX_SITE_LANGUAGE"] || "en" + defaultLng: process.env.SHARELATEX_SITE_LANGUAGE || "en" }, - currentImageName: process.env["TEX_LIVE_DOCKER_IMAGE"], + currentImageName: process.env.TEX_LIVE_DOCKER_IMAGE, apis: { web: { @@ -250,7 +258,7 @@ const settings = { collaborators: -1, dropbox: true, versioning: true, - compileTimeout: parseIntOrFail(process.env["COMPILE_TIMEOUT"] || 180), + compileTimeout: parseIntOrFail(process.env.COMPILE_TIMEOUT || 180), compileGroup: "standard", trackChanges: true, templates: true, @@ -258,32 +266,32 @@ const settings = { } }; -//# OPTIONAL CONFIGURABLE SETTINGS +// # OPTIONAL CONFIGURABLE SETTINGS -if (process.env["SHARELATEX_LEFT_FOOTER"] != null) { +if (process.env.SHARELATEX_LEFT_FOOTER != null) { try { - settings.nav.left_footer = JSON.parse(process.env["SHARELATEX_LEFT_FOOTER"]); + settings.nav.left_footer = JSON.parse(process.env.SHARELATEX_LEFT_FOOTER); } catch (error) { e = error; console.error("could not parse SHARELATEX_LEFT_FOOTER, not valid JSON"); } } -if (process.env["SHARELATEX_RIGHT_FOOTER"] != null) { - settings.nav.right_footer = process.env["SHARELATEX_RIGHT_FOOTER"]; +if (process.env.SHARELATEX_RIGHT_FOOTER != null) { + settings.nav.right_footer = process.env.SHARELATEX_RIGHT_FOOTER; try { - settings.nav.right_footer = JSON.parse(process.env["SHARELATEX_RIGHT_FOOTER"]); + settings.nav.right_footer = JSON.parse(process.env.SHARELATEX_RIGHT_FOOTER); } catch (error1) { e = error1; console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON"); } } -if (process.env["SHARELATEX_HEADER_IMAGE_URL"] != null) { - settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"]; +if (process.env.SHARELATEX_HEADER_IMAGE_URL != null) { + settings.nav.custom_logo = process.env.SHARELATEX_HEADER_IMAGE_URL; } -if (process.env["SHARELATEX_HEADER_NAV_LINKS"] != null) { +if (process.env.SHARELATEX_HEADER_NAV_LINKS != null) { console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # @@ -295,9 +303,9 @@ if (process.env["SHARELATEX_HEADER_NAV_LINKS"] != null) { ); } -if (process.env["SHARELATEX_HEADER_EXTRAS"] != null) { +if (process.env.SHARELATEX_HEADER_EXTRAS != null) { try { - settings.nav.header_extras = JSON.parse(process.env["SHARELATEX_HEADER_EXTRAS"]); + settings.nav.header_extras = JSON.parse(process.env.SHARELATEX_HEADER_EXTRAS); } catch (error2) { e = error2; console.error("could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON"); @@ -316,76 +324,76 @@ if (process.env["SHARELATEX_HEADER_EXTRAS"] != null) { // http://www.nodemailer.com/docs/transports -if (process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] != null) { +if (process.env.SHARELATEX_EMAIL_FROM_ADDRESS != null) { settings.email = { - fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"], - replyTo: process.env["SHARELATEX_EMAIL_REPLY_TO"] || "", - driver: process.env["SHARELATEX_EMAIL_DRIVER"], + fromAddress: process.env.SHARELATEX_EMAIL_FROM_ADDRESS, + replyTo: process.env.SHARELATEX_EMAIL_REPLY_TO || "", + driver: process.env.SHARELATEX_EMAIL_DRIVER, parameters: { - //AWS Creds - AWSAccessKeyID: process.env["SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID"], - AWSSecretKey: process.env["SHARELATEX_EMAIL_AWS_SES_SECRET_KEY"], + // AWS Creds + AWSAccessKeyID: process.env.SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID, + AWSSecretKey: process.env.SHARELATEX_EMAIL_AWS_SES_SECRET_KEY, - //SMTP Creds - host: process.env["SHARELATEX_EMAIL_SMTP_HOST"], - port: process.env["SHARELATEX_EMAIL_SMTP_PORT"], - secure: parse(process.env["SHARELATEX_EMAIL_SMTP_SECURE"]), - ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"]), - name: process.env["SHARELATEX_EMAIL_SMTP_NAME"], - logger: process.env["SHARELATEX_EMAIL_SMTP_LOGGER"] === 'true' + // SMTP Creds + host: process.env.SHARELATEX_EMAIL_SMTP_HOST, + port: process.env.SHARELATEX_EMAIL_SMTP_PORT, + secure: parse(process.env.SHARELATEX_EMAIL_SMTP_SECURE), + ignoreTLS: parse(process.env.SHARELATEX_EMAIL_SMTP_IGNORE_TLS), + name: process.env.SHARELATEX_EMAIL_SMTP_NAME, + logger: process.env.SHARELATEX_EMAIL_SMTP_LOGGER === 'true' }, - textEncoding: process.env["SHARELATEX_EMAIL_TEXT_ENCODING"], + textEncoding: process.env.SHARELATEX_EMAIL_TEXT_ENCODING, template: { - customFooter: process.env["SHARELATEX_CUSTOM_EMAIL_FOOTER"] + customFooter: process.env.SHARELATEX_CUSTOM_EMAIL_FOOTER } }; - if (process.env["SHARELATEX_EMAIL_AWS_SES_REGION"] != null) { - settings.email.parameters.region = process.env["SHARELATEX_EMAIL_AWS_SES_REGION"]; + if (process.env.SHARELATEX_EMAIL_AWS_SES_REGION != null) { + settings.email.parameters.region = process.env.SHARELATEX_EMAIL_AWS_SES_REGION; } - if ((process.env["SHARELATEX_EMAIL_SMTP_USER"] != null) || (process.env["SHARELATEX_EMAIL_SMTP_PASS"] != null)) { + if ((process.env.SHARELATEX_EMAIL_SMTP_USER != null) || (process.env.SHARELATEX_EMAIL_SMTP_PASS != null)) { settings.email.parameters.auth = { - user: process.env["SHARELATEX_EMAIL_SMTP_USER"], - pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"] + user: process.env.SHARELATEX_EMAIL_SMTP_USER, + pass: process.env.SHARELATEX_EMAIL_SMTP_PASS }; } - if (process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"] != null) { + if (process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH != null) { settings.email.parameters.tls = - {rejectUnauthorized: parse(process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"])}; + {rejectUnauthorized: parse(process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH)}; } } // i18n -if (process.env["SHARELATEX_LANG_DOMAIN_MAPPING"] != null) { +if (process.env.SHARELATEX_LANG_DOMAIN_MAPPING != null) { - settings.i18n.subdomainLang = parse(process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]); + settings.i18n.subdomainLang = parse(process.env.SHARELATEX_LANG_DOMAIN_MAPPING); } // Password Settings // ----------- // These restrict the passwords users can use when registering // opts are from http://antelle.github.io/passfield -if (process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] || process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] || process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"]) { +if (process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH) { settings.passwordStrengthOptions = { - pattern: process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] || "aA$3", - length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] || 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] || 150} + pattern: process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || "aA$3", + length: {min:process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || 8, max: process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH || 150} }; } -//###################### +// ###################### // ShareLaTeX Server Pro -//###################### +// ###################### -if (parse(process.env["SHARELATEX_IS_SERVER_PRO"]) === true) { +if (parse(process.env.SHARELATEX_IS_SERVER_PRO) === true) { settings.bypassPercentageRollouts = true; settings.apis.references = {url: "http://localhost:3040"}; @@ -395,7 +403,7 @@ if (parse(process.env["SHARELATEX_IS_SERVER_PRO"]) === true) { // LDAP - SERVER PRO ONLY // ---------- -if (process.env["SHARELATEX_LDAP_HOST"]) { +if (process.env.SHARELATEX_LDAP_HOST) { console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # @@ -407,25 +415,25 @@ if (process.env["SHARELATEX_LDAP_HOST"]) { ); } -if (process.env["SHARELATEX_LDAP_URL"]) { +if (process.env.SHARELATEX_LDAP_URL) { let _ldap_connect_timeout, _ldap_group_search_attribs, _ldap_search_attribs, _ldap_timeout; settings.externalAuth = true; settings.ldap = { - emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"], - nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"], - lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"], - updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] === 'true', - placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"], + emailAtt: process.env.SHARELATEX_LDAP_EMAIL_ATT, + nameAtt: process.env.SHARELATEX_LDAP_NAME_ATT, + lastNameAtt: process.env.SHARELATEX_LDAP_LAST_NAME_ATT, + updateUserDetailsOnLogin: process.env.SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN === 'true', + placeholder: process.env.SHARELATEX_LDAP_PLACEHOLDER, server: { - url: process.env["SHARELATEX_LDAP_URL"], - bindDn: process.env["SHARELATEX_LDAP_BIND_DN"], - bindCredentials: process.env["SHARELATEX_LDAP_BIND_CREDENTIALS"], - bindProperty: process.env["SHARELATEX_LDAP_BIND_PROPERTY"], - searchBase: process.env["SHARELATEX_LDAP_SEARCH_BASE"], - searchScope: process.env["SHARELATEX_LDAP_SEARCH_SCOPE"], - searchFilter: process.env["SHARELATEX_LDAP_SEARCH_FILTER"], + url: process.env.SHARELATEX_LDAP_URL, + bindDn: process.env.SHARELATEX_LDAP_BIND_DN, + bindCredentials: process.env.SHARELATEX_LDAP_BIND_CREDENTIALS, + bindProperty: process.env.SHARELATEX_LDAP_BIND_PROPERTY, + searchBase: process.env.SHARELATEX_LDAP_SEARCH_BASE, + searchScope: process.env.SHARELATEX_LDAP_SEARCH_SCOPE, + searchFilter: process.env.SHARELATEX_LDAP_SEARCH_FILTER, searchAttributes: ( - (_ldap_search_attribs = process.env["SHARELATEX_LDAP_SEARCH_ATTRIBUTES"]) ? + (_ldap_search_attribs = process.env.SHARELATEX_LDAP_SEARCH_ATTRIBUTES) ? (() => { try { return JSON.parse(_ldap_search_attribs); } catch (error3) { @@ -435,12 +443,12 @@ if (process.env["SHARELATEX_LDAP_URL"]) { : undefined ), - groupDnProperty: process.env["SHARELATEX_LDAP_GROUP_DN_PROPERTY"], - groupSearchBase: process.env["SHARELATEX_LDAP_GROUP_SEARCH_BASE"], - groupSearchScope: process.env["SHARELATEX_LDAP_GROUP_SEARCH_SCOPE"], - groupSearchFilter: process.env["SHARELATEX_LDAP_GROUP_SEARCH_FILTER"], + groupDnProperty: process.env.SHARELATEX_LDAP_GROUP_DN_PROPERTY, + groupSearchBase: process.env.SHARELATEX_LDAP_GROUP_SEARCH_BASE, + groupSearchScope: process.env.SHARELATEX_LDAP_GROUP_SEARCH_SCOPE, + groupSearchFilter: process.env.SHARELATEX_LDAP_GROUP_SEARCH_FILTER, groupSearchAttributes: ( - (_ldap_group_search_attribs = process.env["SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"]) ? + (_ldap_group_search_attribs = process.env.SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES) ? (() => { try { return JSON.parse(_ldap_group_search_attribs); } catch (error4) { @@ -450,9 +458,9 @@ if (process.env["SHARELATEX_LDAP_URL"]) { : undefined ), - cache: process.env["SHARELATEX_LDAP_CACHE"] === 'true', + cache: process.env.SHARELATEX_LDAP_CACHE === 'true', timeout: ( - (_ldap_timeout = process.env["SHARELATEX_LDAP_TIMEOUT"]) ? + (_ldap_timeout = process.env.SHARELATEX_LDAP_TIMEOUT) ? (() => { try { return parseIntOrFail(_ldap_timeout); } catch (error5) { @@ -463,7 +471,7 @@ if (process.env["SHARELATEX_LDAP_URL"]) { undefined ), connectTimeout: ( - (_ldap_connect_timeout = process.env["SHARELATEX_LDAP_CONNECT_TIMEOUT"]) ? + (_ldap_connect_timeout = process.env.SHARELATEX_LDAP_CONNECT_TIMEOUT) ? (() => { try { return parseIntOrFail(_ldap_connect_timeout); } catch (error6) { @@ -476,10 +484,10 @@ if (process.env["SHARELATEX_LDAP_URL"]) { } }; - if (process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]) { + if (process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH) { let ca, ca_paths; try { - ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]); + ca = JSON.parse(process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH); } catch (error7) { e = error7; console.error("could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON"); @@ -494,7 +502,7 @@ if (process.env["SHARELATEX_LDAP_URL"]) { } settings.ldap.server.tlsOptions = { - rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] === "true", + rejectUnauthorized: process.env.SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH === "true", ca:ca_paths // e.g.'/etc/ldap/ca_certs.pem' }; } @@ -504,37 +512,37 @@ if (process.env["SHARELATEX_LDAP_URL"]) { -if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { +if (process.env.SHARELATEX_SAML_ENTRYPOINT) { // NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options let _saml_additionalAuthorizeParams, _saml_additionalLogoutParams, _saml_additionalParams, _saml_expiration, _saml_skew; settings.externalAuth = true; settings.saml = { - updateUserDetailsOnLogin: process.env["SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN"] === 'true', - identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"], - emailField: process.env["SHARELATEX_SAML_EMAIL_FIELD"] || process.env["SHARELATEX_SAML_EMAIL_FIELD_NAME"], - firstNameField: process.env["SHARELATEX_SAML_FIRST_NAME_FIELD"], - lastNameField: process.env["SHARELATEX_SAML_LAST_NAME_FIELD"], + updateUserDetailsOnLogin: process.env.SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN === 'true', + identityServiceName: process.env.SHARELATEX_SAML_IDENTITY_SERVICE_NAME, + emailField: process.env.SHARELATEX_SAML_EMAIL_FIELD || process.env.SHARELATEX_SAML_EMAIL_FIELD_NAME, + firstNameField: process.env.SHARELATEX_SAML_FIRST_NAME_FIELD, + lastNameField: process.env.SHARELATEX_SAML_LAST_NAME_FIELD, server: { // strings - entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"], - callbackUrl: process.env["SHARELATEX_SAML_CALLBACK_URL"], - issuer: process.env["SHARELATEX_SAML_ISSUER"], - decryptionPvk: process.env["SHARELATEX_SAML_DECRYPTION_PVK"], - decryptionCert: process.env["SHARELATEX_SAML_DECRYPTION_CERT"], - signatureAlgorithm: process.env["SHARELATEX_SAML_SIGNATURE_ALGORITHM"], - identifierFormat: process.env["SHARELATEX_SAML_IDENTIFIER_FORMAT"], - attributeConsumingServiceIndex: process.env["SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX"], - authnContext: process.env["SHARELATEX_SAML_AUTHN_CONTEXT"], - authnRequestBinding: process.env["SHARELATEX_SAML_AUTHN_REQUEST_BINDING"], - validateInResponseTo: process.env["SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO"], - cacheProvider: process.env["SHARELATEX_SAML_CACHE_PROVIDER"], - logoutUrl: process.env["SHARELATEX_SAML_LOGOUT_URL"], - logoutCallbackUrl: process.env["SHARELATEX_SAML_LOGOUT_CALLBACK_URL"], - disableRequestedAuthnContext: process.env["SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT"] === 'true', - forceAuthn: process.env["SHARELATEX_SAML_FORCE_AUTHN"] === 'true', - skipRequestCompression: process.env["SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION"] === 'true', + entryPoint: process.env.SHARELATEX_SAML_ENTRYPOINT, + callbackUrl: process.env.SHARELATEX_SAML_CALLBACK_URL, + issuer: process.env.SHARELATEX_SAML_ISSUER, + decryptionPvk: process.env.SHARELATEX_SAML_DECRYPTION_PVK, + decryptionCert: process.env.SHARELATEX_SAML_DECRYPTION_CERT, + signatureAlgorithm: process.env.SHARELATEX_SAML_SIGNATURE_ALGORITHM, + identifierFormat: process.env.SHARELATEX_SAML_IDENTIFIER_FORMAT, + attributeConsumingServiceIndex: process.env.SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX, + authnContext: process.env.SHARELATEX_SAML_AUTHN_CONTEXT, + authnRequestBinding: process.env.SHARELATEX_SAML_AUTHN_REQUEST_BINDING, + validateInResponseTo: process.env.SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO, + cacheProvider: process.env.SHARELATEX_SAML_CACHE_PROVIDER, + logoutUrl: process.env.SHARELATEX_SAML_LOGOUT_URL, + logoutCallbackUrl: process.env.SHARELATEX_SAML_LOGOUT_CALLBACK_URL, + disableRequestedAuthnContext: process.env.SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT === 'true', + forceAuthn: process.env.SHARELATEX_SAML_FORCE_AUTHN === 'true', + skipRequestCompression: process.env.SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION === 'true', acceptedClockSkewMs: ( - (_saml_skew = process.env["SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"]) ? + (_saml_skew = process.env.SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS) ? (() => { try { return parseIntOrFail(_saml_skew); } catch (error8) { @@ -545,7 +553,7 @@ if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { undefined ), requestIdExpirationPeriodMs: ( - (_saml_expiration = process.env["SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"]) ? + (_saml_expiration = process.env.SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS) ? (() => { try { return parseIntOrFail(_saml_expiration); } catch (error9) { @@ -556,7 +564,7 @@ if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { undefined ), additionalParams: ( - (_saml_additionalParams = process.env["SHARELATEX_SAML_ADDITIONAL_PARAMS"]) ? + (_saml_additionalParams = process.env.SHARELATEX_SAML_ADDITIONAL_PARAMS) ? (() => { try { return JSON.parse(_saml_additionalParams); } catch (error10) { @@ -567,7 +575,7 @@ if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { undefined ), additionalAuthorizeParams: ( - (_saml_additionalAuthorizeParams = process.env["SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"]) ? + (_saml_additionalAuthorizeParams = process.env.SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS) ? (() => { try { return JSON.parse(_saml_additionalAuthorizeParams ); } catch (error11) { @@ -578,7 +586,7 @@ if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { undefined ), additionalLogoutParams: ( - (_saml_additionalLogoutParams = process.env["SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"]) ? + (_saml_additionalLogoutParams = process.env.SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS) ? (() => { try { return JSON.parse(_saml_additionalLogoutParams ); } catch (error12) { @@ -593,22 +601,22 @@ if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { // SHARELATEX_SAML_CERT cannot be empty // https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 - if (process.env["SHARELATEX_SAML_CERT"]) { - settings.saml.server.cert = process.env["SHARELATEX_SAML_CERT"]; - settings.saml.server.privateCert = process.env["SHARELATEX_SAML_PRIVATE_CERT"]; + if (process.env.SHARELATEX_SAML_CERT) { + settings.saml.server.cert = process.env.SHARELATEX_SAML_CERT; + settings.saml.server.privateCert = process.env.SHARELATEX_SAML_PRIVATE_CERT; } } // Compiler // -------- -if (process.env["SANDBOXED_COMPILES"] === "true") { +if (process.env.SANDBOXED_COMPILES === "true") { settings.clsi = { dockerRunner: true, docker: { - image: process.env["TEX_LIVE_DOCKER_IMAGE"], + image: process.env.TEX_LIVE_DOCKER_IMAGE, env: { HOME: "/tmp", - PATH: process.env["COMPILER_PATH"] || "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + PATH: process.env.COMPILER_PATH || "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" }, user: "www-data" } @@ -618,10 +626,10 @@ if (process.env["SANDBOXED_COMPILES"] === "true") { settings.path = {}; } settings.path.synctexBaseDir = () => "/compile"; - if (process.env['SANDBOXED_COMPILES_SIBLING_CONTAINERS'] === 'true') { + if (process.env.SANDBOXED_COMPILES_SIBLING_CONTAINERS === 'true') { console.log("Using sibling containers for sandboxed compiles"); - if (process.env['SANDBOXED_COMPILES_HOST_DIR']) { - settings.path.sandboxedCompilesHostDir = process.env['SANDBOXED_COMPILES_HOST_DIR']; + if (process.env.SANDBOXED_COMPILES_HOST_DIR) { + settings.path.sandboxedCompilesHostDir = process.env.SANDBOXED_COMPILES_HOST_DIR; } else { console.error('Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set'); } @@ -631,37 +639,37 @@ if (process.env["SANDBOXED_COMPILES"] === "true") { // Templates // --------- -if (process.env["SHARELATEX_TEMPLATES_USER_ID"]) { +if (process.env.SHARELATEX_TEMPLATES_USER_ID) { settings.templates = { mountPointUrl: "/templates", - user_id: process.env["SHARELATEX_TEMPLATES_USER_ID"] + user_id: process.env.SHARELATEX_TEMPLATES_USER_ID }; - settings.templateLinks = parse(process.env["SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS"]); + settings.templateLinks = parse(process.env.SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS); } // /Learn // ------- -if (process.env["SHARELATEX_PROXY_LEARN"] != null) { - settings.proxyLearn = parse(process.env["SHARELATEX_PROXY_LEARN"]); +if (process.env.SHARELATEX_PROXY_LEARN != null) { + settings.proxyLearn = parse(process.env.SHARELATEX_PROXY_LEARN); } // /References // ----------- -if (process.env["SHARELATEX_ELASTICSEARCH_URL"] != null) { +if (process.env.SHARELATEX_ELASTICSEARCH_URL != null) { settings.references.elasticsearch = - {host: process.env["SHARELATEX_ELASTICSEARCH_URL"]}; + {host: process.env.SHARELATEX_ELASTICSEARCH_URL}; } // TeX Live Images // ----------- -if (process.env["ALL_TEX_LIVE_DOCKER_IMAGES"] != null) { - allTexLiveDockerImages = process.env["ALL_TEX_LIVE_DOCKER_IMAGES"].split(','); +if (process.env.ALL_TEX_LIVE_DOCKER_IMAGES != null) { + allTexLiveDockerImages = process.env.ALL_TEX_LIVE_DOCKER_IMAGES.split(','); } -if (process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"] != null) { - allTexLiveDockerImageNames = process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"].split(','); +if (process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES != null) { + allTexLiveDockerImageNames = process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES.split(','); } if (allTexLiveDockerImages != null) { settings.allowedImageNames = []; diff --git a/server-ce/tasks/CreateAndDestroyUsers.js b/server-ce/tasks/CreateAndDestroyUsers.js index cff38d35be..9417396b73 100644 --- a/server-ce/tasks/CreateAndDestroyUsers.js +++ b/server-ce/tasks/CreateAndDestroyUsers.js @@ -1,3 +1,9 @@ +/* eslint-disable + no-undef, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns diff --git a/server-ce/tasks/ProjectSize.js b/server-ce/tasks/ProjectSize.js index 77565724cd..5e663f5b2c 100644 --- a/server-ce/tasks/ProjectSize.js +++ b/server-ce/tasks/ProjectSize.js @@ -1,3 +1,5 @@ +// TODO: This file was created by bulk-decaffeinate. +// Sanity-check the conversion and remove this comment. // require("coffee-script") // fs = require("fs") From d7c641eaf7f9e67df9c8aa024e664a8bf53ece95 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:43:33 +0100 Subject: [PATCH 512/525] [misc] run format:fix --- server-ce/Gruntfile.js | 537 +++++----- server-ce/settings.js | 1142 ++++++++++++---------- server-ce/tasks/CreateAndDestroyUsers.js | 153 +-- 3 files changed, 993 insertions(+), 839 deletions(-) diff --git a/server-ce/Gruntfile.js b/server-ce/Gruntfile.js index bee096789c..9cee93ccb6 100644 --- a/server-ce/Gruntfile.js +++ b/server-ce/Gruntfile.js @@ -16,254 +16,292 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const coffee = require("coffee-script"); -const fs = require("fs"); -const { - spawn -} = require("child_process"); -const { - exec -} = require("child_process"); -const rimraf = require("rimraf"); -const Path = require("path"); -const semver = require("semver"); -const knox = require("knox"); -const crypto = require("crypto"); -const async = require("async"); -const settings = require("settings-sharelatex"); -const _ = require("underscore"); +const coffee = require('coffee-script') +const fs = require('fs') +const { spawn } = require('child_process') +const { exec } = require('child_process') +const rimraf = require('rimraf') +const Path = require('path') +const semver = require('semver') +const knox = require('knox') +const crypto = require('crypto') +const async = require('async') +const settings = require('settings-sharelatex') +const _ = require('underscore') +const SERVICES = require('./config/services') -const SERVICES = require("./config/services"); +module.exports = function (grunt) { + let Helpers + let service + grunt.loadNpmTasks('grunt-bunyan') + grunt.loadNpmTasks('grunt-execute') + grunt.loadNpmTasks('grunt-available-tasks') + grunt.loadNpmTasks('grunt-concurrent') + grunt.loadNpmTasks('grunt-contrib-coffee') + grunt.loadNpmTasks('grunt-shell') -module.exports = function(grunt) { - let Helpers; - let service; - grunt.loadNpmTasks('grunt-bunyan'); - grunt.loadNpmTasks('grunt-execute'); - grunt.loadNpmTasks('grunt-available-tasks'); - grunt.loadNpmTasks('grunt-concurrent'); - grunt.loadNpmTasks("grunt-contrib-coffee"); - grunt.loadNpmTasks("grunt-shell"); + grunt.task.loadTasks('./tasks') - grunt.task.loadTasks("./tasks"); + const execute = {} + for (service of Array.from(SERVICES)) { + execute[service.name] = { src: `${service.name}/app.js` } + } - const execute = {}; - for (service of Array.from(SERVICES)) { - execute[service.name] = - {src: `${service.name}/app.js`}; - } + grunt.initConfig({ + execute, - grunt.initConfig({ - execute, + concurrent: { + all: { + tasks: (() => { + const result = [] + for (service of Array.from(SERVICES)) { + result.push(`run:${service.name}`) + } + return result + })(), + options: { + limit: SERVICES.length, + logConcurrentOutput: true, + }, + }, + }, - concurrent: { - all: { - tasks: (((() => { - const result = []; - for (service of Array.from(SERVICES)) { result.push(`run:${service.name}`); - } - return result; - })())), - options: { - limit: SERVICES.length, - logConcurrentOutput: true + availabletasks: { + tasks: { + options: { + filter: 'exclude', + tasks: ['concurrent', 'execute', 'bunyan', 'availabletasks'], + groups: { + 'Run tasks': ['run', 'run:all', 'default'].concat( + (() => { + const result1 = [] + for (service of Array.from(SERVICES)) { + result1.push(`run:${service.name}`) + } + return result1 + })() + ), + Misc: ['help'], + 'Install tasks': (() => { + const result2 = [] + for (service of Array.from(SERVICES)) { + result2.push(`install:${service.name}`) + } + return result2 + })().concat(['install:all', 'install']), + 'Update tasks': (() => { + const result3 = [] + for (service of Array.from(SERVICES)) { + result3.push(`update:${service.name}`) + } + return result3 + })().concat(['update:all', 'update']), + Checks: [ + 'check', + 'check:redis', + 'check:latexmk', + 'check:s3', + 'check:make', + 'check:mongo', + ], + }, + }, + }, + }, + }) - availabletasks: { - tasks: { - options: { - filter: 'exclude', - tasks: [ - 'concurrent', - 'execute', - 'bunyan', - 'availabletasks' - ], - groups: { - "Run tasks": [ - "run", - "run:all", - "default" - ].concat(((() => { - const result1 = []; - for (service of Array.from(SERVICES)) { result1.push(`run:${service.name}`); - } - return result1; - })())), - "Misc": [ - "help" - ], - "Install tasks": ((() => { - const result2 = []; - for (service of Array.from(SERVICES)) { result2.push(`install:${service.name}`); - } - return result2; - })()).concat(["install:all", "install"]), - "Update tasks": ((() => { - const result3 = []; - for (service of Array.from(SERVICES)) { result3.push(`update:${service.name}`); - } - return result3; - })()).concat(["update:all", "update"]), - "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make", "check:mongo"] - } - } - } - }}); + for (service of Array.from(SERVICES)) { + ;(service => + grunt.registerTask( + `install:${service.name}`, + `Download and set up the ${service.name} service`, + function () { + const done = this.async() + return Helpers.installService(service, done) + } + ))(service) + } - for (service of Array.from(SERVICES)) { - ((service => grunt.registerTask(`install:${service.name}`, `Download and set up the ${service.name} service`, function() { - const done = this.async(); - return Helpers.installService(service, done); - })))(service); - } + grunt.registerTask( + 'install:all', + 'Download and set up all ShareLaTeX services', + [] + .concat( + (() => { + const result4 = [] + for (service of Array.from(SERVICES)) { + result4.push(`install:${service.name}`) + } + return result4 + })() + ) + .concat(['postinstall']) + ) + grunt.registerTask('install', 'install:all') + grunt.registerTask('postinstall', 'Explain postinstall steps', function () { + return Helpers.postinstallMessage(this.async()) + }) + grunt.registerTask( + 'update:all', + 'Checkout and update all ShareLaTeX services', + ['check:make'].concat( + (() => { + const result5 = [] + for (service of Array.from(SERVICES)) { + result5.push(`update:${service.name}`) + } + return result5 + })() + ) + ) + grunt.registerTask('update', 'update:all') + grunt.registerTask('run', 'Run all of the sharelatex processes', [ + 'concurrent:all', + ]) + grunt.registerTask('run:all', 'run') - grunt.registerTask('install:all', "Download and set up all ShareLaTeX services", - [].concat( - ((() => { - const result4 = []; - for (service of Array.from(SERVICES)) { result4.push(`install:${service.name}`); - } - return result4; - })()) - ).concat(['postinstall']) - ); + grunt.registerTask('help', 'Display this help list', 'availabletasks') + grunt.registerTask('default', 'run') - grunt.registerTask('install', 'install:all'); - grunt.registerTask('postinstall', 'Explain postinstall steps', function() { - return Helpers.postinstallMessage(this.async()); - }); + grunt.registerTask( + 'check:redis', + 'Check that redis is installed and running', + function () { + return Helpers.checkRedisConnect(this.async()) + } + ) - grunt.registerTask('update:all', "Checkout and update all ShareLaTeX services", - ["check:make"].concat( - ((() => { - const result5 = []; - for (service of Array.from(SERVICES)) { result5.push(`update:${service.name}`); - } - return result5; - })()) - ) - ); - grunt.registerTask('update', 'update:all'); - grunt.registerTask('run', "Run all of the sharelatex processes", ['concurrent:all']); - grunt.registerTask('run:all', 'run'); + grunt.registerTask( + 'check:mongo', + 'Check that mongo is installed', + function () { + return Helpers.checkMongoConnect(this.async()) + } + ) - grunt.registerTask('help', 'Display this help list', 'availabletasks'); - grunt.registerTask('default', 'run'); + grunt.registerTask( + 'check', + 'Check that you have the required dependencies installed', + ['check:redis', 'check:mongo', 'check:make'] + ) - grunt.registerTask("check:redis", "Check that redis is installed and running", function() { - return Helpers.checkRedisConnect(this.async()); - }); + grunt.registerTask('check:make', 'Check that make is installed', function () { + return Helpers.checkMake(this.async()) + }) - grunt.registerTask("check:mongo", "Check that mongo is installed", function() { - return Helpers.checkMongoConnect(this.async()); - }); + return (Helpers = { + installService(service, callback) { + if (callback == null) { + callback = function (error) {} + } + console.log(`Installing ${service.name}`) + return Helpers.cloneGitRepo(service, function (error) { + if (error != null) { + return callback(error) + } else { + return callback() + } + }) + }, - grunt.registerTask("check", "Check that you have the required dependencies installed", ["check:redis", "check:mongo", "check:make"]); + cloneGitRepo(service, callback) { + if (callback == null) { + callback = function (error) {} + } + const repo_src = service.repo + const dir = service.name + if (!fs.existsSync(dir)) { + const proc = spawn('git', ['clone', repo_src, dir], { + stdio: 'inherit', + }) + return proc.on('close', () => + Helpers.checkoutVersion(service, callback) + ) + } else { + console.log(`${dir} already installed, skipping.`) + return callback() + } + }, - grunt.registerTask("check:make", "Check that make is installed", function() { - return Helpers.checkMake(this.async()); - }); + checkoutVersion(service, callback) { + if (callback == null) { + callback = function (error) {} + } + const dir = service.name + grunt.log.write(`checking out ${service.name} ${service.version}`) + const proc = spawn('git', ['checkout', service.version], { + stdio: 'inherit', + cwd: dir, + }) + return proc.on('close', () => callback()) + }, - - return Helpers = { - installService(service, callback) { - if (callback == null) { callback = function(error) {}; } - console.log(`Installing ${service.name}`); - return Helpers.cloneGitRepo(service, function(error) { - if (error != null) { - return callback(error); - } else { - return callback(); - } - }); - }, - - cloneGitRepo(service, callback) { - if (callback == null) { callback = function(error) {}; } - const repo_src = service.repo; - const dir = service.name; - if (!fs.existsSync(dir)) { - const proc = spawn("git", [ - "clone", - repo_src, - dir - ], {stdio: "inherit"}); - return proc.on("close", () => Helpers.checkoutVersion(service, callback)); - } else { - console.log(`${dir} already installed, skipping.`); - return callback(); - } - }, - - checkoutVersion(service, callback) { - if (callback == null) { callback = function(error) {}; } - const dir = service.name; - grunt.log.write(`checking out ${service.name} ${service.version}`); - const proc = spawn("git", ["checkout", service.version], {stdio: "inherit", cwd: dir}); - return proc.on("close", () => callback()); - }, - - postinstallMessage(callback) { - if (callback == null) { callback = function(error) {}; } - grunt.log.write(`\ + postinstallMessage(callback) { + if (callback == null) { + callback = function (error) {} + } + grunt.log.write(`\ Services cloned: ${(() => { - const result6 = []; - for (service of Array.from(SERVICES)) { result6.push(service.name); - } - return result6; - })()} + const result6 = [] + for (service of Array.from(SERVICES)) { + result6.push(service.name) + } + return result6 + })()} To install services run: $ source bin/install-services This will install the required node versions and run \`npm install\` for each service. See https://github.com/sharelatex/sharelatex/pull/549 for more info.\ -` - ); - return callback(); - }, +`) + return callback() + }, - checkMake(callback) { - if (callback == null) { callback = function(error) {}; } - grunt.log.write("Checking make is installed... "); - return exec("make --version", function(error, stdout, stderr) { - if ((error != null) && error.message.match("not found")) { - grunt.log.error("FAIL."); - grunt.log.errorlns(`\ + checkMake(callback) { + if (callback == null) { + callback = function (error) {} + } + grunt.log.write('Checking make is installed... ') + return exec('make --version', function (error, stdout, stderr) { + if (error != null && error.message.match('not found')) { + grunt.log.error('FAIL.') + grunt.log.errorlns(`\ Either make is not installed or is not in your path. On Ubuntu you can install make with: sudo apt-get install build-essential \ -` - ); - return callback(error); - } else if (error != null) { - return callback(error); - } else { - grunt.log.write("OK."); - return callback(); - } - }); - }, - checkMongoConnect(callback) { - if (callback == null) { callback = function(error) {}; } - grunt.log.write("Checking can connect to mongo"); - const mongojs = require("mongojs"); - const db = mongojs(settings.mongo.url, ["tags"]); - db.runCommand({ ping: 1 }, function(err, res) { - if (!err && res.ok) { - grunt.log.write("OK."); - } - return callback(); - }); - return db.on('error', function(err){ - err = "Can not connect to mongodb"; - grunt.log.error("FAIL."); - grunt.log.errorlns(`\ +`) + return callback(error) + } else if (error != null) { + return callback(error) + } else { + grunt.log.write('OK.') + return callback() + } + }) + }, + checkMongoConnect(callback) { + if (callback == null) { + callback = function (error) {} + } + grunt.log.write('Checking can connect to mongo') + const mongojs = require('mongojs') + const db = mongojs(settings.mongo.url, ['tags']) + db.runCommand({ ping: 1 }, function (err, res) { + if (!err && res.ok) { + grunt.log.write('OK.') + } + return callback() + }) + return db.on('error', function (err) { + err = 'Can not connect to mongodb' + grunt.log.error('FAIL.') + grunt.log.errorlns(`\ !!!!!!!!!!!!!! MONGO ERROR !!!!!!!!!!!!!! ShareLaTeX can not talk to the mongodb instance @@ -271,30 +309,31 @@ ShareLaTeX can not talk to the mongodb instance Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\ -` - ); - throw new Error("Can not connect to Mongodb"); - return callback(err); - }); - }, +`) + throw new Error('Can not connect to Mongodb') + return callback(err) + }) + }, - checkRedisConnect(callback) { - if (callback == null) { callback = function(error) {}; } - grunt.log.write("Checking can connect to redis\n"); - const rclient = require("redis").createClient(settings.redis.web); + checkRedisConnect(callback) { + if (callback == null) { + callback = function (error) {} + } + grunt.log.write('Checking can connect to redis\n') + const rclient = require('redis').createClient(settings.redis.web) - rclient.ping(function(err, res) { - if ((err == null)) { - grunt.log.write("OK."); - } else { - throw new Error("Can not connect to redis"); - } - return callback(); - }); - const errorHandler = _.once(function(err){ - err = "Can not connect to redis"; - grunt.log.error("FAIL."); - grunt.log.errorlns(`\ + rclient.ping(function (err, res) { + if (err == null) { + grunt.log.write('OK.') + } else { + throw new Error('Can not connect to redis') + } + return callback() + }) + const errorHandler = _.once(function (err) { + err = 'Can not connect to redis' + grunt.log.error('FAIL.') + grunt.log.errorlns(`\ !!!!!!!!!!!!!! REDIS ERROR !!!!!!!!!!!!!! ShareLaTeX can not talk to the redis instance @@ -302,19 +341,17 @@ ShareLaTeX can not talk to the redis instance Check the redis instance is running and accessible on env var SHARELATEX_REDIS_HOST !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\ -` - ); - throw new Error("Can not connect to redis"); - return callback(err); - }); - return rclient.on('error', errorHandler); - } - }; -}; - - - +`) + throw new Error('Can not connect to redis') + return callback(err) + }) + return rclient.on('error', errorHandler) + }, + }) +} function __guard__(value, transform) { - return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined; + return typeof value !== 'undefined' && value !== null + ? transform(value) + : undefined } diff --git a/server-ce/settings.js b/server-ce/settings.js index 09d21d0015..25de871789 100644 --- a/server-ce/settings.js +++ b/server-ce/settings.js @@ -12,308 +12,349 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let allTexLiveDockerImageNames, allTexLiveDockerImages, redisConfig, siteUrl; -let e; -const Path = require('path'); +let allTexLiveDockerImageNames, allTexLiveDockerImages, redisConfig, siteUrl +let e +const Path = require('path') // These credentials are used for authenticating api requests // between services that may need to go over public channels -const httpAuthUser = "sharelatex"; -const httpAuthPass = process.env.WEB_API_PASSWORD; -const httpAuthUsers = {}; -httpAuthUsers[httpAuthUser] = httpAuthPass; +const httpAuthUser = 'sharelatex' +const httpAuthPass = process.env.WEB_API_PASSWORD +const httpAuthUsers = {} +httpAuthUsers[httpAuthUser] = httpAuthPass -const parse = function(option){ - if (option != null) { - try { - const opt = JSON.parse(option); - return opt; - } catch (err) { - throw new Error(`problem parsing ${option}, invalid JSON`); - } - } -}; +const parse = function (option) { + if (option != null) { + try { + const opt = JSON.parse(option) + return opt + } catch (err) { + throw new Error(`problem parsing ${option}, invalid JSON`) + } + } +} -const parseIntOrFail = function(value){ - const parsedValue = parseInt(value, 10); - if (isNaN(parsedValue)) { - throw new Error(`'${value}' is an invalid integer`); - } - return parsedValue; -}; +const parseIntOrFail = function (value) { + const parsedValue = parseInt(value, 10) + if (isNaN(parsedValue)) { + throw new Error(`'${value}' is an invalid integer`) + } + return parsedValue +} -const DATA_DIR = '/var/lib/sharelatex/data'; -const TMP_DIR = '/var/lib/sharelatex/tmp'; +const DATA_DIR = '/var/lib/sharelatex/data' +const TMP_DIR = '/var/lib/sharelatex/tmp' const settings = { + clsi: { + optimiseInDocker: process.env.OPTIMISE_PDF === 'true', + }, - clsi: { - optimiseInDocker: process.env.OPTIMISE_PDF === 'true' - }, + brandPrefix: '', - brandPrefix: "", + allowAnonymousReadAndWriteSharing: + process.env.SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING === 'true', - allowAnonymousReadAndWriteSharing: - process.env.SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING === 'true', + // Databases + // --------- - // Databases - // --------- + // ShareLaTeX's main persistent data store is MongoDB (http://www.mongodb.org/) + // Documentation about the URL connection string format can be found at: + // + // http://docs.mongodb.org/manual/reference/connection-string/ + // + // The following works out of the box with Mongo's default settings: + mongo: { + url: process.env.SHARELATEX_MONGO_URL || 'mongodb://dockerhost/sharelatex', + }, - // ShareLaTeX's main persistent data store is MongoDB (http://www.mongodb.org/) - // Documentation about the URL connection string format can be found at: - // - // http://docs.mongodb.org/manual/reference/connection-string/ - // - // The following works out of the box with Mongo's default settings: - mongo: { - url : process.env.SHARELATEX_MONGO_URL || 'mongodb://dockerhost/sharelatex' - }, + // Redis is used in ShareLaTeX for high volume queries, like real-time + // editing, and session management. + // + // The following config will work with Redis's default settings: + redis: { + web: (redisConfig = { + host: process.env.SHARELATEX_REDIS_HOST || 'dockerhost', + port: process.env.SHARELATEX_REDIS_PORT || '6379', + password: process.env.SHARELATEX_REDIS_PASS || undefined, + key_schema: { + // document-updater + blockingKey({ doc_id }) { + return `Blocking:${doc_id}` + }, + docLines({ doc_id }) { + return `doclines:${doc_id}` + }, + docOps({ doc_id }) { + return `DocOps:${doc_id}` + }, + docVersion({ doc_id }) { + return `DocVersion:${doc_id}` + }, + docHash({ doc_id }) { + return `DocHash:${doc_id}` + }, + projectKey({ doc_id }) { + return `ProjectId:${doc_id}` + }, + docsInProject({ project_id }) { + return `DocsIn:${project_id}` + }, + ranges({ doc_id }) { + return `Ranges:${doc_id}` + }, + // document-updater:realtime + pendingUpdates({ doc_id }) { + return `PendingUpdates:${doc_id}` + }, + // document-updater:history + uncompressedHistoryOps({ doc_id }) { + return `UncompressedHistoryOps:${doc_id}` + }, + docsWithHistoryOps({ project_id }) { + return `DocsWithHistoryOps:${project_id}` + }, + // document-updater:lock + blockingKey({ doc_id }) { + return `Blocking:${doc_id}` + }, + // track-changes:lock + historyLock({ doc_id }) { + return `HistoryLock:${doc_id}` + }, + historyIndexLock({ project_id }) { + return `HistoryIndexLock:${project_id}` + }, + // track-changes:history + uncompressedHistoryOps({ doc_id }) { + return `UncompressedHistoryOps:${doc_id}` + }, + docsWithHistoryOps({ project_id }) { + return `DocsWithHistoryOps:${project_id}` + }, + // realtime + clientsInProject({ project_id }) { + return `clients_in_project:${project_id}` + }, + connectedUser({ project_id, client_id }) { + return `connected_user:${project_id}:${client_id}` + }, + }, + }), + fairy: redisConfig, + // track-changes and document-updater + realtime: redisConfig, + documentupdater: redisConfig, + lock: redisConfig, + history: redisConfig, + websessions: redisConfig, + api: redisConfig, + pubsub: redisConfig, + project_history: redisConfig, + }, - // Redis is used in ShareLaTeX for high volume queries, like real-time - // editing, and session management. - // - // The following config will work with Redis's default settings: - redis: { - web: (redisConfig = { - host: process.env.SHARELATEX_REDIS_HOST || "dockerhost", - port: process.env.SHARELATEX_REDIS_PORT || "6379", - password: process.env.SHARELATEX_REDIS_PASS || undefined, - key_schema: { - // document-updater - blockingKey({doc_id}) { return `Blocking:${doc_id}`; }, - docLines({doc_id}) { return `doclines:${doc_id}`; }, - docOps({doc_id}) { return `DocOps:${doc_id}`; }, - docVersion({doc_id}) { return `DocVersion:${doc_id}`; }, - docHash({doc_id}) { return `DocHash:${doc_id}`; }, - projectKey({doc_id}) { return `ProjectId:${doc_id}`; }, - docsInProject({project_id}) { return `DocsIn:${project_id}`; }, - ranges({doc_id}) { return `Ranges:${doc_id}`; }, - // document-updater:realtime - pendingUpdates({doc_id}) { return `PendingUpdates:${doc_id}`; }, - // document-updater:history - uncompressedHistoryOps({doc_id}) { return `UncompressedHistoryOps:${doc_id}`; }, - docsWithHistoryOps({project_id}) { return `DocsWithHistoryOps:${project_id}`; }, - // document-updater:lock - blockingKey({doc_id}) { return `Blocking:${doc_id}`; }, - // track-changes:lock - historyLock({doc_id}) { return `HistoryLock:${doc_id}`; }, - historyIndexLock({project_id}) { return `HistoryIndexLock:${project_id}`; }, - // track-changes:history - uncompressedHistoryOps({doc_id}) { return `UncompressedHistoryOps:${doc_id}`; }, - docsWithHistoryOps({project_id}) { return `DocsWithHistoryOps:${project_id}`; }, - // realtime - clientsInProject({project_id}) { return `clients_in_project:${project_id}`; }, - connectedUser({project_id, client_id}){ return `connected_user:${project_id}:${client_id}`; } - } - }), - fairy: redisConfig, - // track-changes and document-updater - realtime: redisConfig, - documentupdater: redisConfig, - lock: redisConfig, - history: redisConfig, - websessions: redisConfig, - api: redisConfig, - pubsub: redisConfig, - project_history: redisConfig - }, + // The compile server (the clsi) uses a SQL database to cache files and + // meta-data. sqlite is the default, and the load is low enough that this will + // be fine in production (we use sqlite at sharelatex.com). + // + // If you want to configure a different database, see the Sequelize documentation + // for available options: + // + // https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage + // + mysql: { + clsi: { + database: 'clsi', + username: 'clsi', + password: '', + dialect: 'sqlite', + storage: Path.join(DATA_DIR, 'db.sqlite'), + }, + }, - // The compile server (the clsi) uses a SQL database to cache files and - // meta-data. sqlite is the default, and the load is low enough that this will - // be fine in production (we use sqlite at sharelatex.com). - // - // If you want to configure a different database, see the Sequelize documentation - // for available options: - // - // https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage - // - mysql: { - clsi: { - database: "clsi", - username: "clsi", - password: "", - dialect: "sqlite", - storage: Path.join(DATA_DIR, "db.sqlite") - } - }, + // File storage + // ------------ - // File storage - // ------------ + // ShareLaTeX can store binary files like images either locally or in Amazon + // S3. The default is locally: + filestore: { + backend: 'fs', + stores: { + user_files: Path.join(DATA_DIR, 'user_files'), + template_files: Path.join(DATA_DIR, 'template_files'), + }, + }, - // ShareLaTeX can store binary files like images either locally or in Amazon - // S3. The default is locally: - filestore: { - backend: "fs", - stores: { - user_files: Path.join(DATA_DIR, "user_files"), - template_files: Path.join(DATA_DIR, "template_files") - } - }, + // To use Amazon S3 as a storage backend, comment out the above config, and + // uncomment the following, filling in your key, secret, and bucket name: + // + // filestore: + // backend: "s3" + // stores: + // user_files: "BUCKET_NAME" + // s3: + // key: "AWS_KEY" + // secret: "AWS_SECRET" + // - // To use Amazon S3 as a storage backend, comment out the above config, and - // uncomment the following, filling in your key, secret, and bucket name: - // - // filestore: - // backend: "s3" - // stores: - // user_files: "BUCKET_NAME" - // s3: - // key: "AWS_KEY" - // secret: "AWS_SECRET" - // + trackchanges: { + continueOnError: true, + }, - trackchanges: { - continueOnError: true - }, + // Local disk caching + // ------------------ + path: { + // If we ever need to write something to disk (e.g. incoming requests + // that need processing but may be too big for memory), then write + // them to disk here: + dumpFolder: Path.join(TMP_DIR, 'dumpFolder'), + // Where to write uploads before they are processed + uploadFolder: Path.join(TMP_DIR, 'uploads'), + // Where to write the project to disk before running LaTeX on it + compilesDir: Path.join(DATA_DIR, 'compiles'), + // Where to cache downloaded URLs for the CLSI + clsiCacheDir: Path.join(DATA_DIR, 'cache'), + // Where to write the output files to disk after running LaTeX + outputDir: Path.join(DATA_DIR, 'output'), + }, - // Local disk caching - // ------------------ - path: { - // If we ever need to write something to disk (e.g. incoming requests - // that need processing but may be too big for memory), then write - // them to disk here: - dumpFolder: Path.join(TMP_DIR, "dumpFolder"), - // Where to write uploads before they are processed - uploadFolder: Path.join(TMP_DIR, "uploads"), - // Where to write the project to disk before running LaTeX on it - compilesDir: Path.join(DATA_DIR, "compiles"), - // Where to cache downloaded URLs for the CLSI - clsiCacheDir: Path.join(DATA_DIR, "cache"), - // Where to write the output files to disk after running LaTeX - outputDir: Path.join(DATA_DIR, "output") - }, + // Server Config + // ------------- - // Server Config - // ------------- + // Where your instance of ShareLaTeX can be found publicly. This is used + // when emails are sent out and in generated links: + siteUrl: (siteUrl = process.env.SHARELATEX_SITE_URL || 'http://localhost'), - // Where your instance of ShareLaTeX can be found publicly. This is used - // when emails are sent out and in generated links: - siteUrl: (siteUrl = process.env.SHARELATEX_SITE_URL || 'http://localhost'), + // The name this is used to describe your ShareLaTeX Installation + appName: process.env.SHARELATEX_APP_NAME || 'ShareLaTeX (Community Edition)', - // The name this is used to describe your ShareLaTeX Installation - appName: process.env.SHARELATEX_APP_NAME || "ShareLaTeX (Community Edition)", + restrictInvitesToExistingAccounts: + process.env.SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS === 'true', - restrictInvitesToExistingAccounts: process.env.SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS === 'true', + nav: { + title: + process.env.SHARELATEX_NAV_TITLE || + process.env.SHARELATEX_APP_NAME || + 'ShareLaTeX Community Edition', + }, - nav: { - title: process.env.SHARELATEX_NAV_TITLE || process.env.SHARELATEX_APP_NAME || "ShareLaTeX Community Edition" - }, + // The email address which users will be directed to as the main point of + // contact for this installation of ShareLaTeX. + adminEmail: process.env.SHARELATEX_ADMIN_EMAIL || 'placeholder@example.com', + // If provided, a sessionSecret is used to sign cookies so that they cannot be + // spoofed. This is recommended. + security: { + sessionSecret: + process.env.SHARELATEX_SESSION_SECRET || process.env.CRYPTO_RANDOM, + }, - // The email address which users will be directed to as the main point of - // contact for this installation of ShareLaTeX. - adminEmail: process.env.SHARELATEX_ADMIN_EMAIL || "placeholder@example.com", + // These credentials are used for authenticating api requests + // between services that may need to go over public channels + httpAuthUsers, - // If provided, a sessionSecret is used to sign cookies so that they cannot be - // spoofed. This is recommended. - security: { - sessionSecret: process.env.SHARELATEX_SESSION_SECRET || process.env.CRYPTO_RANDOM - }, + // Should javascript assets be served minified or not. + useMinifiedJs: true, - // These credentials are used for authenticating api requests - // between services that may need to go over public channels - httpAuthUsers, + // Should static assets be sent with a header to tell the browser to cache + // them. This should be false in development where changes are being made, + // but should be set to true in production. + cacheStaticAssets: true, - // Should javascript assets be served minified or not. - useMinifiedJs: true, + // If you are running ShareLaTeX over https, set this to true to send the + // cookie with a secure flag (recommended). + secureCookie: process.env.SHARELATEX_SECURE_COOKIE != null, - // Should static assets be sent with a header to tell the browser to cache - // them. This should be false in development where changes are being made, - // but should be set to true in production. - cacheStaticAssets: true, + // If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) + // then set this to true to allow it to correctly detect the forwarded IP + // address and http/https protocol information. - // If you are running ShareLaTeX over https, set this to true to send the - // cookie with a secure flag (recommended). - secureCookie: (process.env.SHARELATEX_SECURE_COOKIE != null), + behindProxy: process.env.SHARELATEX_BEHIND_PROXY || false, - // If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) - // then set this to true to allow it to correctly detect the forwarded IP - // address and http/https protocol information. + i18n: { + subdomainLang: { + www: { + lngCode: process.env.SHARELATEX_SITE_LANGUAGE || 'en', + url: siteUrl, + }, + }, + defaultLng: process.env.SHARELATEX_SITE_LANGUAGE || 'en', + }, - behindProxy: process.env.SHARELATEX_BEHIND_PROXY || false, + currentImageName: process.env.TEX_LIVE_DOCKER_IMAGE, - i18n: { - subdomainLang: { - www: {lngCode:process.env.SHARELATEX_SITE_LANGUAGE || "en", url: siteUrl} - }, - defaultLng: process.env.SHARELATEX_SITE_LANGUAGE || "en" - }, + apis: { + web: { + url: 'http://localhost:3000', + user: httpAuthUser, + pass: httpAuthPass, + }, + project_history: { + enabled: false, + }, + }, + references: {}, + notifications: undefined, - currentImageName: process.env.TEX_LIVE_DOCKER_IMAGE, - - apis: { - web: { - url: "http://localhost:3000", - user: httpAuthUser, - pass: httpAuthPass - }, - project_history: { - enabled: false - } - }, - references:{}, - notifications:undefined, - - defaultFeatures: { - collaborators: -1, - dropbox: true, - versioning: true, - compileTimeout: parseIntOrFail(process.env.COMPILE_TIMEOUT || 180), - compileGroup: "standard", - trackChanges: true, - templates: true, - references: true - } -}; + defaultFeatures: { + collaborators: -1, + dropbox: true, + versioning: true, + compileTimeout: parseIntOrFail(process.env.COMPILE_TIMEOUT || 180), + compileGroup: 'standard', + trackChanges: true, + templates: true, + references: true, + }, +} // # OPTIONAL CONFIGURABLE SETTINGS if (process.env.SHARELATEX_LEFT_FOOTER != null) { - try { - settings.nav.left_footer = JSON.parse(process.env.SHARELATEX_LEFT_FOOTER); - } catch (error) { - e = error; - console.error("could not parse SHARELATEX_LEFT_FOOTER, not valid JSON"); - } + try { + settings.nav.left_footer = JSON.parse(process.env.SHARELATEX_LEFT_FOOTER) + } catch (error) { + e = error + console.error('could not parse SHARELATEX_LEFT_FOOTER, not valid JSON') + } } if (process.env.SHARELATEX_RIGHT_FOOTER != null) { - settings.nav.right_footer = process.env.SHARELATEX_RIGHT_FOOTER; - try { - settings.nav.right_footer = JSON.parse(process.env.SHARELATEX_RIGHT_FOOTER); - } catch (error1) { - e = error1; - console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON"); - } + settings.nav.right_footer = process.env.SHARELATEX_RIGHT_FOOTER + try { + settings.nav.right_footer = JSON.parse(process.env.SHARELATEX_RIGHT_FOOTER) + } catch (error1) { + e = error1 + console.error('could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON') + } } if (process.env.SHARELATEX_HEADER_IMAGE_URL != null) { - settings.nav.custom_logo = process.env.SHARELATEX_HEADER_IMAGE_URL; + settings.nav.custom_logo = process.env.SHARELATEX_HEADER_IMAGE_URL } if (process.env.SHARELATEX_HEADER_NAV_LINKS != null) { - console.error(`\ + console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # WARNING: SHARELATEX_HEADER_NAV_LINKS is no longer supported # See https://github.com/sharelatex/sharelatex/wiki/Configuring-Headers,-Footers-&-Logo # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\ -` - ); +`) } if (process.env.SHARELATEX_HEADER_EXTRAS != null) { - try { - settings.nav.header_extras = JSON.parse(process.env.SHARELATEX_HEADER_EXTRAS); - } catch (error2) { - e = error2; - console.error("could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON"); - } + try { + settings.nav.header_extras = JSON.parse( + process.env.SHARELATEX_HEADER_EXTRAS + ) + } catch (error2) { + e = error2 + console.error('could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON') + } } - - // Sending Email // ------------- // @@ -323,370 +364,415 @@ if (process.env.SHARELATEX_HEADER_EXTRAS != null) { // // http://www.nodemailer.com/docs/transports - if (process.env.SHARELATEX_EMAIL_FROM_ADDRESS != null) { + settings.email = { + fromAddress: process.env.SHARELATEX_EMAIL_FROM_ADDRESS, + replyTo: process.env.SHARELATEX_EMAIL_REPLY_TO || '', + driver: process.env.SHARELATEX_EMAIL_DRIVER, + parameters: { + // AWS Creds + AWSAccessKeyID: process.env.SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID, + AWSSecretKey: process.env.SHARELATEX_EMAIL_AWS_SES_SECRET_KEY, - settings.email = { - fromAddress: process.env.SHARELATEX_EMAIL_FROM_ADDRESS, - replyTo: process.env.SHARELATEX_EMAIL_REPLY_TO || "", - driver: process.env.SHARELATEX_EMAIL_DRIVER, - parameters: { - // AWS Creds - AWSAccessKeyID: process.env.SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID, - AWSSecretKey: process.env.SHARELATEX_EMAIL_AWS_SES_SECRET_KEY, + // SMTP Creds + host: process.env.SHARELATEX_EMAIL_SMTP_HOST, + port: process.env.SHARELATEX_EMAIL_SMTP_PORT, + secure: parse(process.env.SHARELATEX_EMAIL_SMTP_SECURE), + ignoreTLS: parse(process.env.SHARELATEX_EMAIL_SMTP_IGNORE_TLS), + name: process.env.SHARELATEX_EMAIL_SMTP_NAME, + logger: process.env.SHARELATEX_EMAIL_SMTP_LOGGER === 'true', + }, - // SMTP Creds - host: process.env.SHARELATEX_EMAIL_SMTP_HOST, - port: process.env.SHARELATEX_EMAIL_SMTP_PORT, - secure: parse(process.env.SHARELATEX_EMAIL_SMTP_SECURE), - ignoreTLS: parse(process.env.SHARELATEX_EMAIL_SMTP_IGNORE_TLS), - name: process.env.SHARELATEX_EMAIL_SMTP_NAME, - logger: process.env.SHARELATEX_EMAIL_SMTP_LOGGER === 'true' - }, + textEncoding: process.env.SHARELATEX_EMAIL_TEXT_ENCODING, + template: { + customFooter: process.env.SHARELATEX_CUSTOM_EMAIL_FOOTER, + }, + } - textEncoding: process.env.SHARELATEX_EMAIL_TEXT_ENCODING, - template: { - customFooter: process.env.SHARELATEX_CUSTOM_EMAIL_FOOTER - } - }; + if (process.env.SHARELATEX_EMAIL_AWS_SES_REGION != null) { + settings.email.parameters.region = + process.env.SHARELATEX_EMAIL_AWS_SES_REGION + } - if (process.env.SHARELATEX_EMAIL_AWS_SES_REGION != null) { - settings.email.parameters.region = process.env.SHARELATEX_EMAIL_AWS_SES_REGION; - } + if ( + process.env.SHARELATEX_EMAIL_SMTP_USER != null || + process.env.SHARELATEX_EMAIL_SMTP_PASS != null + ) { + settings.email.parameters.auth = { + user: process.env.SHARELATEX_EMAIL_SMTP_USER, + pass: process.env.SHARELATEX_EMAIL_SMTP_PASS, + } + } - if ((process.env.SHARELATEX_EMAIL_SMTP_USER != null) || (process.env.SHARELATEX_EMAIL_SMTP_PASS != null)) { - settings.email.parameters.auth = { - user: process.env.SHARELATEX_EMAIL_SMTP_USER, - pass: process.env.SHARELATEX_EMAIL_SMTP_PASS - }; - } - - if (process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH != null) { - settings.email.parameters.tls = - {rejectUnauthorized: parse(process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH)}; - } + if (process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH != null) { + settings.email.parameters.tls = { + rejectUnauthorized: parse( + process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH + ), + } + } } - // i18n if (process.env.SHARELATEX_LANG_DOMAIN_MAPPING != null) { - - settings.i18n.subdomainLang = parse(process.env.SHARELATEX_LANG_DOMAIN_MAPPING); + settings.i18n.subdomainLang = parse( + process.env.SHARELATEX_LANG_DOMAIN_MAPPING + ) } // Password Settings // ----------- // These restrict the passwords users can use when registering // opts are from http://antelle.github.io/passfield -if (process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH) { - - settings.passwordStrengthOptions = { - pattern: process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || "aA$3", - length: {min:process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || 8, max: process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH || 150} - }; +if ( + process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || + process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || + process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH +) { + settings.passwordStrengthOptions = { + pattern: process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || 'aA$3', + length: { + min: process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || 8, + max: process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH || 150, + }, + } } - - - // ###################### // ShareLaTeX Server Pro // ###################### if (parse(process.env.SHARELATEX_IS_SERVER_PRO) === true) { - settings.bypassPercentageRollouts = true; - settings.apis.references = - {url: "http://localhost:3040"}; + settings.bypassPercentageRollouts = true + settings.apis.references = { url: 'http://localhost:3040' } } - // LDAP - SERVER PRO ONLY // ---------- if (process.env.SHARELATEX_LDAP_HOST) { - console.error(`\ + console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # WARNING: The LDAP configuration format has changed in version 0.5.1 # See https://github.com/sharelatex/sharelatex/wiki/Server-Pro:-LDAP-Config # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\ -` - ); +`) } if (process.env.SHARELATEX_LDAP_URL) { - let _ldap_connect_timeout, _ldap_group_search_attribs, _ldap_search_attribs, _ldap_timeout; - settings.externalAuth = true; - settings.ldap = { - emailAtt: process.env.SHARELATEX_LDAP_EMAIL_ATT, - nameAtt: process.env.SHARELATEX_LDAP_NAME_ATT, - lastNameAtt: process.env.SHARELATEX_LDAP_LAST_NAME_ATT, - updateUserDetailsOnLogin: process.env.SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN === 'true', - placeholder: process.env.SHARELATEX_LDAP_PLACEHOLDER, - server: { - url: process.env.SHARELATEX_LDAP_URL, - bindDn: process.env.SHARELATEX_LDAP_BIND_DN, - bindCredentials: process.env.SHARELATEX_LDAP_BIND_CREDENTIALS, - bindProperty: process.env.SHARELATEX_LDAP_BIND_PROPERTY, - searchBase: process.env.SHARELATEX_LDAP_SEARCH_BASE, - searchScope: process.env.SHARELATEX_LDAP_SEARCH_SCOPE, - searchFilter: process.env.SHARELATEX_LDAP_SEARCH_FILTER, - searchAttributes: ( - (_ldap_search_attribs = process.env.SHARELATEX_LDAP_SEARCH_ATTRIBUTES) ? - (() => { try { - return JSON.parse(_ldap_search_attribs); - } catch (error3) { - e = error3; - return console.error("could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES"); - } })() - : - undefined - ), - groupDnProperty: process.env.SHARELATEX_LDAP_GROUP_DN_PROPERTY, - groupSearchBase: process.env.SHARELATEX_LDAP_GROUP_SEARCH_BASE, - groupSearchScope: process.env.SHARELATEX_LDAP_GROUP_SEARCH_SCOPE, - groupSearchFilter: process.env.SHARELATEX_LDAP_GROUP_SEARCH_FILTER, - groupSearchAttributes: ( - (_ldap_group_search_attribs = process.env.SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES) ? - (() => { try { - return JSON.parse(_ldap_group_search_attribs); - } catch (error4) { - e = error4; - return console.error("could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"); - } })() - : - undefined - ), - cache: process.env.SHARELATEX_LDAP_CACHE === 'true', - timeout: ( - (_ldap_timeout = process.env.SHARELATEX_LDAP_TIMEOUT) ? - (() => { try { - return parseIntOrFail(_ldap_timeout); - } catch (error5) { - e = error5; - return console.error("Cannot parse SHARELATEX_LDAP_TIMEOUT"); - } })() - : - undefined - ), - connectTimeout: ( - (_ldap_connect_timeout = process.env.SHARELATEX_LDAP_CONNECT_TIMEOUT) ? - (() => { try { - return parseIntOrFail(_ldap_connect_timeout); - } catch (error6) { - e = error6; - return console.error("Cannot parse SHARELATEX_LDAP_CONNECT_TIMEOUT"); - } })() - : - undefined - ) - } - }; + let _ldap_connect_timeout, + _ldap_group_search_attribs, + _ldap_search_attribs, + _ldap_timeout + settings.externalAuth = true + settings.ldap = { + emailAtt: process.env.SHARELATEX_LDAP_EMAIL_ATT, + nameAtt: process.env.SHARELATEX_LDAP_NAME_ATT, + lastNameAtt: process.env.SHARELATEX_LDAP_LAST_NAME_ATT, + updateUserDetailsOnLogin: + process.env.SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN === 'true', + placeholder: process.env.SHARELATEX_LDAP_PLACEHOLDER, + server: { + url: process.env.SHARELATEX_LDAP_URL, + bindDn: process.env.SHARELATEX_LDAP_BIND_DN, + bindCredentials: process.env.SHARELATEX_LDAP_BIND_CREDENTIALS, + bindProperty: process.env.SHARELATEX_LDAP_BIND_PROPERTY, + searchBase: process.env.SHARELATEX_LDAP_SEARCH_BASE, + searchScope: process.env.SHARELATEX_LDAP_SEARCH_SCOPE, + searchFilter: process.env.SHARELATEX_LDAP_SEARCH_FILTER, + searchAttributes: (_ldap_search_attribs = + process.env.SHARELATEX_LDAP_SEARCH_ATTRIBUTES) + ? (() => { + try { + return JSON.parse(_ldap_search_attribs) + } catch (error3) { + e = error3 + return console.error( + 'could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES' + ) + } + })() + : undefined, + groupDnProperty: process.env.SHARELATEX_LDAP_GROUP_DN_PROPERTY, + groupSearchBase: process.env.SHARELATEX_LDAP_GROUP_SEARCH_BASE, + groupSearchScope: process.env.SHARELATEX_LDAP_GROUP_SEARCH_SCOPE, + groupSearchFilter: process.env.SHARELATEX_LDAP_GROUP_SEARCH_FILTER, + groupSearchAttributes: (_ldap_group_search_attribs = + process.env.SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES) + ? (() => { + try { + return JSON.parse(_ldap_group_search_attribs) + } catch (error4) { + e = error4 + return console.error( + 'could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES' + ) + } + })() + : undefined, + cache: process.env.SHARELATEX_LDAP_CACHE === 'true', + timeout: (_ldap_timeout = process.env.SHARELATEX_LDAP_TIMEOUT) + ? (() => { + try { + return parseIntOrFail(_ldap_timeout) + } catch (error5) { + e = error5 + return console.error('Cannot parse SHARELATEX_LDAP_TIMEOUT') + } + })() + : undefined, + connectTimeout: (_ldap_connect_timeout = + process.env.SHARELATEX_LDAP_CONNECT_TIMEOUT) + ? (() => { + try { + return parseIntOrFail(_ldap_connect_timeout) + } catch (error6) { + e = error6 + return console.error( + 'Cannot parse SHARELATEX_LDAP_CONNECT_TIMEOUT' + ) + } + })() + : undefined, + }, + } - if (process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH) { - let ca, ca_paths; - try { - ca = JSON.parse(process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH); - } catch (error7) { - e = error7; - console.error("could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON"); - } + if (process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH) { + let ca, ca_paths + try { + ca = JSON.parse(process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH) + } catch (error7) { + e = error7 + console.error( + 'could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON' + ) + } - if (typeof(ca) === 'string') { - ca_paths = [ca]; - } else if ((typeof(ca) === 'object') && ((ca != null ? ca.length : undefined) != null)) { - ca_paths = ca; - } else { - console.error("problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH"); - } + if (typeof ca === 'string') { + ca_paths = [ca] + } else if ( + typeof ca === 'object' && + (ca != null ? ca.length : undefined) != null + ) { + ca_paths = ca + } else { + console.error('problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH') + } - settings.ldap.server.tlsOptions = { - rejectUnauthorized: process.env.SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH === "true", - ca:ca_paths // e.g.'/etc/ldap/ca_certs.pem' - }; - } + settings.ldap.server.tlsOptions = { + rejectUnauthorized: + process.env.SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH === 'true', + ca: ca_paths, // e.g.'/etc/ldap/ca_certs.pem' + } + } } - - - - if (process.env.SHARELATEX_SAML_ENTRYPOINT) { - // NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options - let _saml_additionalAuthorizeParams, _saml_additionalLogoutParams, _saml_additionalParams, _saml_expiration, _saml_skew; - settings.externalAuth = true; - settings.saml = { - updateUserDetailsOnLogin: process.env.SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN === 'true', - identityServiceName: process.env.SHARELATEX_SAML_IDENTITY_SERVICE_NAME, - emailField: process.env.SHARELATEX_SAML_EMAIL_FIELD || process.env.SHARELATEX_SAML_EMAIL_FIELD_NAME, - firstNameField: process.env.SHARELATEX_SAML_FIRST_NAME_FIELD, - lastNameField: process.env.SHARELATEX_SAML_LAST_NAME_FIELD, - server: { - // strings - entryPoint: process.env.SHARELATEX_SAML_ENTRYPOINT, - callbackUrl: process.env.SHARELATEX_SAML_CALLBACK_URL, - issuer: process.env.SHARELATEX_SAML_ISSUER, - decryptionPvk: process.env.SHARELATEX_SAML_DECRYPTION_PVK, - decryptionCert: process.env.SHARELATEX_SAML_DECRYPTION_CERT, - signatureAlgorithm: process.env.SHARELATEX_SAML_SIGNATURE_ALGORITHM, - identifierFormat: process.env.SHARELATEX_SAML_IDENTIFIER_FORMAT, - attributeConsumingServiceIndex: process.env.SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX, - authnContext: process.env.SHARELATEX_SAML_AUTHN_CONTEXT, - authnRequestBinding: process.env.SHARELATEX_SAML_AUTHN_REQUEST_BINDING, - validateInResponseTo: process.env.SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO, - cacheProvider: process.env.SHARELATEX_SAML_CACHE_PROVIDER, - logoutUrl: process.env.SHARELATEX_SAML_LOGOUT_URL, - logoutCallbackUrl: process.env.SHARELATEX_SAML_LOGOUT_CALLBACK_URL, - disableRequestedAuthnContext: process.env.SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT === 'true', - forceAuthn: process.env.SHARELATEX_SAML_FORCE_AUTHN === 'true', - skipRequestCompression: process.env.SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION === 'true', - acceptedClockSkewMs: ( - (_saml_skew = process.env.SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS) ? - (() => { try { - return parseIntOrFail(_saml_skew); - } catch (error8) { - e = error8; - return console.error("Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"); - } })() - : - undefined - ), - requestIdExpirationPeriodMs: ( - (_saml_expiration = process.env.SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS) ? - (() => { try { - return parseIntOrFail(_saml_expiration); - } catch (error9) { - e = error9; - return console.error("Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"); - } })() - : - undefined - ), - additionalParams: ( - (_saml_additionalParams = process.env.SHARELATEX_SAML_ADDITIONAL_PARAMS) ? - (() => { try { - return JSON.parse(_saml_additionalParams); - } catch (error10) { - e = error10; - return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS"); - } })() - : - undefined - ), - additionalAuthorizeParams: ( - (_saml_additionalAuthorizeParams = process.env.SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS) ? - (() => { try { - return JSON.parse(_saml_additionalAuthorizeParams ); - } catch (error11) { - e = error11; - return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"); - } })() - : - undefined - ), - additionalLogoutParams: ( - (_saml_additionalLogoutParams = process.env.SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS) ? - (() => { try { - return JSON.parse(_saml_additionalLogoutParams ); - } catch (error12) { - e = error12; - return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"); - } })() - : - undefined - ) - } - }; + // NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options + let _saml_additionalAuthorizeParams, + _saml_additionalLogoutParams, + _saml_additionalParams, + _saml_expiration, + _saml_skew + settings.externalAuth = true + settings.saml = { + updateUserDetailsOnLogin: + process.env.SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN === 'true', + identityServiceName: process.env.SHARELATEX_SAML_IDENTITY_SERVICE_NAME, + emailField: + process.env.SHARELATEX_SAML_EMAIL_FIELD || + process.env.SHARELATEX_SAML_EMAIL_FIELD_NAME, + firstNameField: process.env.SHARELATEX_SAML_FIRST_NAME_FIELD, + lastNameField: process.env.SHARELATEX_SAML_LAST_NAME_FIELD, + server: { + // strings + entryPoint: process.env.SHARELATEX_SAML_ENTRYPOINT, + callbackUrl: process.env.SHARELATEX_SAML_CALLBACK_URL, + issuer: process.env.SHARELATEX_SAML_ISSUER, + decryptionPvk: process.env.SHARELATEX_SAML_DECRYPTION_PVK, + decryptionCert: process.env.SHARELATEX_SAML_DECRYPTION_CERT, + signatureAlgorithm: process.env.SHARELATEX_SAML_SIGNATURE_ALGORITHM, + identifierFormat: process.env.SHARELATEX_SAML_IDENTIFIER_FORMAT, + attributeConsumingServiceIndex: + process.env.SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX, + authnContext: process.env.SHARELATEX_SAML_AUTHN_CONTEXT, + authnRequestBinding: process.env.SHARELATEX_SAML_AUTHN_REQUEST_BINDING, + validateInResponseTo: process.env.SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO, + cacheProvider: process.env.SHARELATEX_SAML_CACHE_PROVIDER, + logoutUrl: process.env.SHARELATEX_SAML_LOGOUT_URL, + logoutCallbackUrl: process.env.SHARELATEX_SAML_LOGOUT_CALLBACK_URL, + disableRequestedAuthnContext: + process.env.SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT === 'true', + forceAuthn: process.env.SHARELATEX_SAML_FORCE_AUTHN === 'true', + skipRequestCompression: + process.env.SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION === 'true', + acceptedClockSkewMs: (_saml_skew = + process.env.SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS) + ? (() => { + try { + return parseIntOrFail(_saml_skew) + } catch (error8) { + e = error8 + return console.error( + 'Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS' + ) + } + })() + : undefined, + requestIdExpirationPeriodMs: (_saml_expiration = + process.env.SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS) + ? (() => { + try { + return parseIntOrFail(_saml_expiration) + } catch (error9) { + e = error9 + return console.error( + 'Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS' + ) + } + })() + : undefined, + additionalParams: (_saml_additionalParams = + process.env.SHARELATEX_SAML_ADDITIONAL_PARAMS) + ? (() => { + try { + return JSON.parse(_saml_additionalParams) + } catch (error10) { + e = error10 + return console.error( + 'Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS' + ) + } + })() + : undefined, + additionalAuthorizeParams: (_saml_additionalAuthorizeParams = + process.env.SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS) + ? (() => { + try { + return JSON.parse(_saml_additionalAuthorizeParams) + } catch (error11) { + e = error11 + return console.error( + 'Cannot parse SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS' + ) + } + })() + : undefined, + additionalLogoutParams: (_saml_additionalLogoutParams = + process.env.SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS) + ? (() => { + try { + return JSON.parse(_saml_additionalLogoutParams) + } catch (error12) { + e = error12 + return console.error( + 'Cannot parse SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS' + ) + } + })() + : undefined, + }, + } - // SHARELATEX_SAML_CERT cannot be empty - // https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 - if (process.env.SHARELATEX_SAML_CERT) { - settings.saml.server.cert = process.env.SHARELATEX_SAML_CERT; - settings.saml.server.privateCert = process.env.SHARELATEX_SAML_PRIVATE_CERT; - } + // SHARELATEX_SAML_CERT cannot be empty + // https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 + if (process.env.SHARELATEX_SAML_CERT) { + settings.saml.server.cert = process.env.SHARELATEX_SAML_CERT + settings.saml.server.privateCert = process.env.SHARELATEX_SAML_PRIVATE_CERT + } } // Compiler // -------- -if (process.env.SANDBOXED_COMPILES === "true") { - settings.clsi = { - dockerRunner: true, - docker: { - image: process.env.TEX_LIVE_DOCKER_IMAGE, - env: { - HOME: "/tmp", - PATH: process.env.COMPILER_PATH || "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - }, - user: "www-data" - } - }; +if (process.env.SANDBOXED_COMPILES === 'true') { + settings.clsi = { + dockerRunner: true, + docker: { + image: process.env.TEX_LIVE_DOCKER_IMAGE, + env: { + HOME: '/tmp', + PATH: + process.env.COMPILER_PATH || + '/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + }, + user: 'www-data', + }, + } - if ((settings.path == null)) { - settings.path = {}; - } - settings.path.synctexBaseDir = () => "/compile"; - if (process.env.SANDBOXED_COMPILES_SIBLING_CONTAINERS === 'true') { - console.log("Using sibling containers for sandboxed compiles"); - if (process.env.SANDBOXED_COMPILES_HOST_DIR) { - settings.path.sandboxedCompilesHostDir = process.env.SANDBOXED_COMPILES_HOST_DIR; - } else { - console.error('Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set'); - } - } + if (settings.path == null) { + settings.path = {} + } + settings.path.synctexBaseDir = () => '/compile' + if (process.env.SANDBOXED_COMPILES_SIBLING_CONTAINERS === 'true') { + console.log('Using sibling containers for sandboxed compiles') + if (process.env.SANDBOXED_COMPILES_HOST_DIR) { + settings.path.sandboxedCompilesHostDir = + process.env.SANDBOXED_COMPILES_HOST_DIR + } else { + console.error( + 'Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set' + ) + } + } } - // Templates // --------- if (process.env.SHARELATEX_TEMPLATES_USER_ID) { - settings.templates = { - mountPointUrl: "/templates", - user_id: process.env.SHARELATEX_TEMPLATES_USER_ID - }; + settings.templates = { + mountPointUrl: '/templates', + user_id: process.env.SHARELATEX_TEMPLATES_USER_ID, + } - settings.templateLinks = parse(process.env.SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS); + settings.templateLinks = parse( + process.env.SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS + ) } - // /Learn // ------- if (process.env.SHARELATEX_PROXY_LEARN != null) { - settings.proxyLearn = parse(process.env.SHARELATEX_PROXY_LEARN); + settings.proxyLearn = parse(process.env.SHARELATEX_PROXY_LEARN) } - // /References // ----------- if (process.env.SHARELATEX_ELASTICSEARCH_URL != null) { - settings.references.elasticsearch = - {host: process.env.SHARELATEX_ELASTICSEARCH_URL}; + settings.references.elasticsearch = { + host: process.env.SHARELATEX_ELASTICSEARCH_URL, + } } // TeX Live Images // ----------- if (process.env.ALL_TEX_LIVE_DOCKER_IMAGES != null) { - allTexLiveDockerImages = process.env.ALL_TEX_LIVE_DOCKER_IMAGES.split(','); + allTexLiveDockerImages = process.env.ALL_TEX_LIVE_DOCKER_IMAGES.split(',') } if (process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES != null) { - allTexLiveDockerImageNames = process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES.split(','); + allTexLiveDockerImageNames = + process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES.split(',') } if (allTexLiveDockerImages != null) { - settings.allowedImageNames = []; - for (let index = 0; index < allTexLiveDockerImages.length; index++) { - const fullImageName = allTexLiveDockerImages[index]; - const imageName = Path.basename(fullImageName); - const imageDesc = (allTexLiveDockerImageNames != null) ? allTexLiveDockerImageNames[index] : imageName; - settings.allowedImageNames.push({ imageName, imageDesc }); - } + settings.allowedImageNames = [] + for (let index = 0; index < allTexLiveDockerImages.length; index++) { + const fullImageName = allTexLiveDockerImages[index] + const imageName = Path.basename(fullImageName) + const imageDesc = + allTexLiveDockerImageNames != null + ? allTexLiveDockerImageNames[index] + : imageName + settings.allowedImageNames.push({ imageName, imageDesc }) + } } // With lots of incoming and outgoing HTTP connections to different services, // sometimes long running, it is a good idea to increase the default number // of sockets that Node will hold open. -const http = require('http'); -http.globalAgent.maxSockets = 300; -const https = require('https'); -https.globalAgent.maxSockets = 300; +const http = require('http') +http.globalAgent.maxSockets = 300 +const https = require('https') +https.globalAgent.maxSockets = 300 -module.exports = settings; +module.exports = settings diff --git a/server-ce/tasks/CreateAndDestroyUsers.js b/server-ce/tasks/CreateAndDestroyUsers.js index 9417396b73..22be44ae88 100644 --- a/server-ce/tasks/CreateAndDestroyUsers.js +++ b/server-ce/tasks/CreateAndDestroyUsers.js @@ -11,75 +11,106 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -module.exports = function(grunt) { +module.exports = function (grunt) { + grunt.registerTask( + 'user:create-admin', + 'Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt user:create-admin --email joe@example.com', + function () { + const done = this.async() + const email = grunt.option('email') + if (email == null) { + console.error('Usage: grunt user:create-admin --email=joe@example.com') + process.exit(1) + } - grunt.registerTask('user:create-admin', "Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt user:create-admin --email joe@example.com", function() { - const done = this.async(); - const email = grunt.option("email"); - if ((email == null)) { - console.error("Usage: grunt user:create-admin --email=joe@example.com"); - process.exit(1); - } - - const settings = require("settings-sharelatex"); - const mongodb = require("../web/app/src/infrastructure/mongodb"); - const UserRegistrationHandler = require("../web/app/src/Features/User/UserRegistrationHandler"); - const OneTimeTokenHandler = require("../web/app/src/Features/Security/OneTimeTokenHandler"); - return mongodb.waitForDb().then(() => UserRegistrationHandler.registerNewUser({ + const settings = require('settings-sharelatex') + const mongodb = require('../web/app/src/infrastructure/mongodb') + const UserRegistrationHandler = require('../web/app/src/Features/User/UserRegistrationHandler') + const OneTimeTokenHandler = require('../web/app/src/Features/Security/OneTimeTokenHandler') + return mongodb.waitForDb().then(() => + UserRegistrationHandler.registerNewUser( + { email, - password: require("crypto").randomBytes(32).toString("hex") - }, function(error, user) { - if ((error != null) && ((error != null ? error.message : undefined) !== "EmailAlreadyRegistered")) { - throw error; + password: require('crypto').randomBytes(32).toString('hex'), + }, + function (error, user) { + if ( + error != null && + (error != null ? error.message : undefined) !== + 'EmailAlreadyRegistered' + ) { + throw error } - user.isAdmin = true; - return user.save(function(error) { - if (error != null) { throw error; } - const ONE_WEEK = 7 * 24 * 60 * 60; // seconds - return OneTimeTokenHandler.getNewToken("password", { expiresIn: ONE_WEEK, email:user.email, user_id: user._id.toString() }, function(err, token){ - if (err != null) { return next(err); } + user.isAdmin = true + return user.save(function (error) { + if (error != null) { + throw error + } + const ONE_WEEK = 7 * 24 * 60 * 60 // seconds + return OneTimeTokenHandler.getNewToken( + 'password', + { + expiresIn: ONE_WEEK, + email: user.email, + user_id: user._id.toString(), + }, + function (err, token) { + if (err != null) { + return next(err) + } - console.log(""); - console.log(`\ + console.log('') + console.log(`\ Successfully created ${email} as an admin user. Please visit the following URL to set a password for ${email} and log in: ${settings.siteUrl}/user/password/set?passwordResetToken=${token} \ -` - ); - return done(); - }); - }); - })); - }); - - return grunt.registerTask('user:delete', "deletes a user and all their data, Usage: grunt user:delete --email joe@example.com", function() { - const done = this.async(); - const email = grunt.option("email"); - if ((email == null)) { - console.error("Usage: grunt user:delete --email=joe@example.com"); - process.exit(1); - } - const settings = require("settings-sharelatex"); - const mongodb = require("../web/app/src/infrastructure/mongodb"); - const UserGetter = require("../web/app/src/Features/User/UserGetter"); - const UserDeleter = require("../web/app/src/Features/User/UserDeleter"); - return mongodb.waitForDb().then(() => UserGetter.getUser({email}, function(error, user) { - if (error != null) { - throw error; - } - if ((user == null)) { - console.log(`user ${email} not in database, potentially already deleted`); - return done(); - } - return UserDeleter.deleteUser(user._id, function(err){ - if (err != null) { - throw err; +`) + return done() } - return done(); - }); - })); - }); -}; + ) + }) + } + ) + ) + } + ) + + return grunt.registerTask( + 'user:delete', + 'deletes a user and all their data, Usage: grunt user:delete --email joe@example.com', + function () { + const done = this.async() + const email = grunt.option('email') + if (email == null) { + console.error('Usage: grunt user:delete --email=joe@example.com') + process.exit(1) + } + const settings = require('settings-sharelatex') + const mongodb = require('../web/app/src/infrastructure/mongodb') + const UserGetter = require('../web/app/src/Features/User/UserGetter') + const UserDeleter = require('../web/app/src/Features/User/UserDeleter') + return mongodb.waitForDb().then(() => + UserGetter.getUser({ email }, function (error, user) { + if (error != null) { + throw error + } + if (user == null) { + console.log( + `user ${email} not in database, potentially already deleted` + ) + return done() + } + return UserDeleter.deleteUser(user._id, function (err) { + if (err != null) { + throw err + } + return done() + }) + }) + ) + } + ) +} From 763e25fbdfb6ff1fc87efa7e674205d9daaf4063 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 11:58:33 +0100 Subject: [PATCH 513/525] [misc] delete commented ProjectSize task --- server-ce/tasks/ProjectSize.js | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 server-ce/tasks/ProjectSize.js diff --git a/server-ce/tasks/ProjectSize.js b/server-ce/tasks/ProjectSize.js deleted file mode 100644 index 5e663f5b2c..0000000000 --- a/server-ce/tasks/ProjectSize.js +++ /dev/null @@ -1,26 +0,0 @@ -// TODO: This file was created by bulk-decaffeinate. -// Sanity-check the conversion and remove this comment. -// require("coffee-script") - -// fs = require("fs") -// _ = require("underscore") - -// if not process.argv[2] -// console.log "Usage: coffee project_size.coffee user_files_path" -// else -// dirPath = process.argv[2] -// if not fs.lstatSync(dirPath).isDirectory() -// console.log dirPath + " directory not exist" -// else -// fs.readdir dirPath, (err, files)-> -// projects = [] -// files.forEach (file)-> -// project_id = file.split("_")[0] -// if !projects[project_id] -// projects[project_id] = 0 -// projects[project_id] += fs.lstatSync(dirPath+"/"+file).size - -// ids = _.keys projects -// console.log "project \t size" -// ids.forEach (id)-> -// console.log id + "\t" + projects[id] From 6c6335ce9831b756fcb26885e46e6db4dfd8ea0f Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:00:50 +0100 Subject: [PATCH 514/525] [misc] do not set SHARELATEX_CONFIG in run scripts --- server-ce/runit/chat-sharelatex/run | 1 - server-ce/runit/clsi-sharelatex/run | 1 - server-ce/runit/contacts-sharelatex/run | 1 - server-ce/runit/docstore-sharelatex/run | 1 - server-ce/runit/document-updater-sharelatex/run | 1 - server-ce/runit/filestore-sharelatex/run | 1 - server-ce/runit/notifications-sharelatex/run | 1 - server-ce/runit/real-time-sharelatex/run | 1 - server-ce/runit/spelling-sharelatex/run | 1 - server-ce/runit/track-changes-sharelatex/run | 1 - server-ce/runit/web-sharelatex/run | 1 - 11 files changed, 11 deletions(-) diff --git a/server-ce/runit/chat-sharelatex/run b/server-ce/runit/chat-sharelatex/run index cc5f75057f..c000f7d80d 100755 --- a/server-ce/runit/chat-sharelatex/run +++ b/server-ce/runit/chat-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/clsi-sharelatex/run b/server-ce/runit/clsi-sharelatex/run index c1469b6cfe..e8e7bbaf4c 100755 --- a/server-ce/runit/clsi-sharelatex/run +++ b/server-ce/runit/clsi-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/contacts-sharelatex/run b/server-ce/runit/contacts-sharelatex/run index 4c01aa0985..8de491ac6a 100755 --- a/server-ce/runit/contacts-sharelatex/run +++ b/server-ce/runit/contacts-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/docstore-sharelatex/run b/server-ce/runit/docstore-sharelatex/run index 2a171f0968..f6b3285358 100755 --- a/server-ce/runit/docstore-sharelatex/run +++ b/server-ce/runit/docstore-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/document-updater-sharelatex/run b/server-ce/runit/document-updater-sharelatex/run index 51472b3d48..7d688a17de 100755 --- a/server-ce/runit/document-updater-sharelatex/run +++ b/server-ce/runit/document-updater-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/filestore-sharelatex/run b/server-ce/runit/filestore-sharelatex/run index 4237a38793..8baccbfe0b 100755 --- a/server-ce/runit/filestore-sharelatex/run +++ b/server-ce/runit/filestore-sharelatex/run @@ -1,3 +1,2 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/filestore/app.js >> /var/log/sharelatex/filestore.log 2>&1 diff --git a/server-ce/runit/notifications-sharelatex/run b/server-ce/runit/notifications-sharelatex/run index 89f8ad54f9..721b1cf1e9 100755 --- a/server-ce/runit/notifications-sharelatex/run +++ b/server-ce/runit/notifications-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/real-time-sharelatex/run b/server-ce/runit/real-time-sharelatex/run index ad005b624c..392c4525ef 100755 --- a/server-ce/runit/real-time-sharelatex/run +++ b/server-ce/runit/real-time-sharelatex/run @@ -1,3 +1,2 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/real-time/app.js >> /var/log/sharelatex/real-time.log 2>&1 diff --git a/server-ce/runit/spelling-sharelatex/run b/server-ce/runit/spelling-sharelatex/run index a9a73f8ae0..af7941a4b4 100755 --- a/server-ce/runit/spelling-sharelatex/run +++ b/server-ce/runit/spelling-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/track-changes-sharelatex/run b/server-ce/runit/track-changes-sharelatex/run index 45b3b77ebc..a137098588 100755 --- a/server-ce/runit/track-changes-sharelatex/run +++ b/server-ce/runit/track-changes-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/web-sharelatex/run b/server-ce/runit/web-sharelatex/run index c1371de0f4..15fba8f806 100755 --- a/server-ce/runit/web-sharelatex/run +++ b/server-ce/runit/web-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then From 42b680c7c7d08414670eb2fc4561f5f7382184b9 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:09:09 +0100 Subject: [PATCH 515/525] [misc] update references to decaffeinated coffee-script files --- server-ce/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index ace431967f..33f2e0baab 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -5,7 +5,7 @@ ARG SHARELATEX_BASE_TAG=sharelatex/sharelatex-base:latest FROM $SHARELATEX_BASE_TAG -ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee +ENV SHARELATEX_CONFIG /etc/sharelatex/settings.js # Add required source files @@ -13,7 +13,7 @@ ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee ADD ${baseDir}/bin /var/www/sharelatex/bin ADD ${baseDir}/doc /var/www/sharelatex/doc ADD ${baseDir}/tasks /var/www/sharelatex/tasks -ADD ${baseDir}/Gruntfile.coffee /var/www/sharelatex/Gruntfile.coffee +ADD ${baseDir}/Gruntfile.js /var/www/sharelatex/Gruntfile.js ADD ${baseDir}/package.json /var/www/sharelatex/package.json ADD ${baseDir}/package-lock.json /var/www/sharelatex/package-lock.json ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js @@ -85,7 +85,7 @@ COPY ${baseDir}/init_scripts/ /etc/my_init.d/ # Copy app settings files # ----------------------- -COPY ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee +COPY ${baseDir}/settings.js /etc/sharelatex/settings.js # Set Environment Variables # -------------------------------- From faca804fc176c1fe80c18277892cb1b7938ce15b Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:48:36 +0100 Subject: [PATCH 516/525] [misc] upgrade settings module to v2 --- server-ce/Gruntfile.js | 2 +- server-ce/package-lock.json | 19 +++++-------------- server-ce/package.json | 2 +- server-ce/tasks/CreateAndDestroyUsers.js | 4 ++-- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/server-ce/Gruntfile.js b/server-ce/Gruntfile.js index 9cee93ccb6..c38511386f 100644 --- a/server-ce/Gruntfile.js +++ b/server-ce/Gruntfile.js @@ -26,7 +26,7 @@ const semver = require('semver') const knox = require('knox') const crypto = require('crypto') const async = require('async') -const settings = require('settings-sharelatex') +const settings = require('@overleaf/settings') const _ = require('underscore') const SERVICES = require('./config/services') diff --git a/server-ce/package-lock.json b/server-ce/package-lock.json index 69bb8563cf..2f074b3a51 100644 --- a/server-ce/package-lock.json +++ b/server-ce/package-lock.json @@ -157,6 +157,11 @@ "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", "dev": true }, + "@overleaf/settings": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@overleaf/settings/-/settings-2.1.1.tgz", + "integrity": "sha512-vcJwqCGFKmQxTP/syUqCeMaSRjHmBcQgKOACR9He2uJcErg2GZPa1go+nGvszMbkElM4HfRKm/MfxvqHhoN4TQ==" + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -2868,20 +2873,6 @@ "integrity": "sha1-eUEYKz/8xYC/8cF5QqzfeVHA0hM=", "dev": true }, - "settings-sharelatex": { - "version": "git+https://github.com/sharelatex/settings-sharelatex.git#b4fb8404c5de571d029bf4c29e96a60b21206f94", - "from": "git+https://github.com/sharelatex/settings-sharelatex.git", - "requires": { - "coffee-script": "1.6.0" - }, - "dependencies": { - "coffee-script": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" - } - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/server-ce/package.json b/server-ce/package.json index b9f180e084..c46ac96be4 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -9,6 +9,7 @@ "format:fix": "prettier --write $PWD/'**/*.js'" }, "dependencies": { + "@overleaf/settings": "^2.1.1", "async": "^0.9.0", "bson": "^1.0.4", "coffee-script": "^1.11.1", @@ -21,7 +22,6 @@ "mongojs": "2.4.0", "redis": "^2.6.2", "rimraf": "~2.2.6", - "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git", "underscore": "^1.7.0" }, "devDependencies": { diff --git a/server-ce/tasks/CreateAndDestroyUsers.js b/server-ce/tasks/CreateAndDestroyUsers.js index 22be44ae88..b7d519cc6c 100644 --- a/server-ce/tasks/CreateAndDestroyUsers.js +++ b/server-ce/tasks/CreateAndDestroyUsers.js @@ -23,7 +23,7 @@ module.exports = function (grunt) { process.exit(1) } - const settings = require('settings-sharelatex') + const settings = require('@overleaf/settings') const mongodb = require('../web/app/src/infrastructure/mongodb') const UserRegistrationHandler = require('../web/app/src/Features/User/UserRegistrationHandler') const OneTimeTokenHandler = require('../web/app/src/Features/Security/OneTimeTokenHandler') @@ -88,7 +88,7 @@ ${settings.siteUrl}/user/password/set?passwordResetToken=${token} console.error('Usage: grunt user:delete --email=joe@example.com') process.exit(1) } - const settings = require('settings-sharelatex') + const settings = require('@overleaf/settings') const mongodb = require('../web/app/src/infrastructure/mongodb') const UserGetter = require('../web/app/src/Features/User/UserGetter') const UserDeleter = require('../web/app/src/Features/User/UserDeleter') From 859252696b6b9d4b202b21c0cf0d697cdc7c7c35 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:48:45 +0100 Subject: [PATCH 517/525] [misc] drop coffee-script imports --- server-ce/Gruntfile.js | 2 - server-ce/package-lock.json | 780 +++++++++++++++--------------------- server-ce/package.json | 2 - 3 files changed, 327 insertions(+), 457 deletions(-) diff --git a/server-ce/Gruntfile.js b/server-ce/Gruntfile.js index c38511386f..170ee5b353 100644 --- a/server-ce/Gruntfile.js +++ b/server-ce/Gruntfile.js @@ -16,7 +16,6 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const coffee = require('coffee-script') const fs = require('fs') const { spawn } = require('child_process') const { exec } = require('child_process') @@ -38,7 +37,6 @@ module.exports = function (grunt) { grunt.loadNpmTasks('grunt-execute') grunt.loadNpmTasks('grunt-available-tasks') grunt.loadNpmTasks('grunt-concurrent') - grunt.loadNpmTasks('grunt-contrib-coffee') grunt.loadNpmTasks('grunt-shell') grunt.task.loadTasks('./tasks') diff --git a/server-ce/package-lock.json b/server-ce/package-lock.json index 2f074b3a51..3331f87502 100644 --- a/server-ce/package-lock.json +++ b/server-ce/package-lock.json @@ -30,31 +30,10 @@ "js-tokens": "^4.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" } } }, @@ -205,10 +184,13 @@ "dev": true }, "ansi-styles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", - "dev": true + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } }, "argparse": { "version": "0.1.16", @@ -234,6 +216,11 @@ } } }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" + }, "array-includes": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", @@ -247,6 +234,19 @@ "is-string": "^1.0.5" } }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, "array.prototype.flat": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", @@ -258,6 +258,11 @@ "es-abstract": "^1.18.0-next.1" } }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -317,14 +322,13 @@ "dev": true }, "chalk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "~1.0.0", - "has-color": "~0.1.0", - "strip-ansi": "~0.1.0" + "ansi-styles": "^3.2.1", + "supports-color": "^5.3.0" } }, "coffee-script": { @@ -353,6 +357,14 @@ "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", "dev": true }, + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -387,6 +399,26 @@ } } }, + "cson": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/cson/-/cson-3.0.2.tgz", + "integrity": "sha1-g+6Qids8JUvsHpjkmNmqzxGtzFQ=", + "requires": { + "coffee-script": "^1.9.0", + "cson-parser": "^1.0.6", + "extract-opts": "^3.0.1", + "requirefresh": "^2.0.0", + "safefs": "^4.0.0" + } + }, + "cson-parser": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz", + "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=", + "requires": { + "coffee-script": "^1.10.0" + } + }, "dateformat": { "version": "1.0.2-1.2.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz", @@ -423,6 +455,11 @@ "esutils": "^2.0.2" } }, + "double-ended-queue": { + "version": "2.1.0-0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" + }, "dtrace-provider": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", @@ -430,6 +467,20 @@ "dev": true, "optional": true }, + "each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", + "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" + }, + "eachr": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eachr/-/eachr-3.2.0.tgz", + "integrity": "sha1-LDXkPqCGUW95l8+At6pk1VpKRIQ=", + "requires": { + "editions": "^1.1.1", + "typechecker": "^4.3.0" + } + }, "east": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/east/-/east-0.5.7.tgz", @@ -441,35 +492,10 @@ "twostep": "0.4.2" }, "dependencies": { - "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "requires": { - "graceful-readlink": ">= 1.0.0" - }, - "dependencies": { - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" - } - } - }, - "expressionify": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/expressionify/-/expressionify-0.9.3.tgz", - "integrity": "sha1-/iJnx+hpRXfxP02oML/DyNgXf5I=" - }, "progress": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" - }, - "twostep": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/twostep/-/twostep-0.4.2.tgz", - "integrity": "sha1-hLxQh6hxV00ev3vjB54D4SLUFbY=" } } }, @@ -478,6 +504,11 @@ "resolved": "https://registry.npmjs.org/east-mongo/-/east-mongo-0.3.3.tgz", "integrity": "sha1-WKtCdGaRy+ITtBweiG8EttyCq8A=" }, + "editions": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", + "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -537,6 +568,11 @@ "is-symbol": "^1.0.2" } }, + "es6-promise": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -692,15 +728,6 @@ "lru-cache": "^6.0.0" } }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1027,6 +1054,21 @@ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, + "expressionify": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/expressionify/-/expressionify-0.9.3.tgz", + "integrity": "sha1-/iJnx+hpRXfxP02oML/DyNgXf5I=" + }, + "extract-opts": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/extract-opts/-/extract-opts-3.3.1.tgz", + "integrity": "sha1-WrvtyYwNUgLjJ4cn+Rktfghsa+E=", + "requires": { + "eachr": "^3.2.0", + "editions": "^1.1.1", + "typechecker": "^4.3.0" + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1229,6 +1271,11 @@ "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", "dev": true }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, "grunt": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz", @@ -1336,40 +1383,6 @@ } } }, - "grunt-contrib-coffee": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/grunt-contrib-coffee/-/grunt-contrib-coffee-0.10.1.tgz", - "integrity": "sha1-7SLGgp9FiqjqR/hnaEM+mBMUAYY=", - "dev": true, - "requires": { - "chalk": "~0.4.0", - "coffee-script": "~1.7.0", - "lodash": "~2.4.1" - }, - "dependencies": { - "coffee-script": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz", - "integrity": "sha1-YplqhheAx15tUGnROCJyO3NAS/w=", - "dev": true, - "requires": { - "mkdirp": "~0.3.5" - } - }, - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - }, - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "dev": true - } - } - }, "grunt-execute": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/grunt-execute/-/grunt-execute-0.1.5.tgz", @@ -1525,26 +1538,6 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" } } - }, - "npm-run-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", - "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", - "requires": { - "path-key": "^1.0.0" - }, - "dependencies": { - "path-key": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", - "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=" - } - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" } } }, @@ -1563,12 +1556,6 @@ "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", "dev": true }, - "has-color": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", - "dev": true - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -1749,6 +1736,11 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "jit-grunt": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/jit-grunt/-/jit-grunt-0.10.0.tgz", + "integrity": "sha1-AIw6f+Hpa9DYTiYOofoXg0V/ecI=" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -1827,98 +1819,6 @@ "lodash": "~3.10.1" }, "dependencies": { - "cson": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/cson/-/cson-3.0.2.tgz", - "integrity": "sha1-g+6Qids8JUvsHpjkmNmqzxGtzFQ=", - "requires": { - "coffee-script": "^1.9.0", - "cson-parser": "^1.0.6", - "extract-opts": "^3.0.1", - "requirefresh": "^2.0.0", - "safefs": "^4.0.0" - }, - "dependencies": { - "cson-parser": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz", - "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=", - "requires": { - "coffee-script": "^1.10.0" - } - }, - "extract-opts": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/extract-opts/-/extract-opts-3.3.1.tgz", - "integrity": "sha1-WrvtyYwNUgLjJ4cn+Rktfghsa+E=", - "requires": { - "eachr": "^3.2.0", - "editions": "^1.1.1", - "typechecker": "^4.3.0" - }, - "dependencies": { - "eachr": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eachr/-/eachr-3.2.0.tgz", - "integrity": "sha1-LDXkPqCGUW95l8+At6pk1VpKRIQ=", - "requires": { - "editions": "^1.1.1", - "typechecker": "^4.3.0" - } - }, - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" - }, - "typechecker": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-4.4.1.tgz", - "integrity": "sha1-+XuV9RsDhBchLWd9RaNz7nvO1+Y=", - "requires": { - "editions": "^1.3.3" - } - } - } - }, - "requirefresh": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/requirefresh/-/requirefresh-2.1.0.tgz", - "integrity": "sha1-dC3Mwg86lpGNZsbxWX3I/+vE9vU=", - "requires": { - "editions": "^1.1.1" - }, - "dependencies": { - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" - } - } - }, - "safefs": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/safefs/-/safefs-4.1.0.tgz", - "integrity": "sha1-+CrrS9165R9lPrIPZyizBYyNZEU=", - "requires": { - "editions": "^1.1.1", - "graceful-fs": "^4.1.4" - }, - "dependencies": { - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - } - } - } - } - }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", @@ -2005,11 +1905,6 @@ } } }, - "jit-grunt": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/jit-grunt/-/jit-grunt-0.10.0.tgz", - "integrity": "sha1-AIw6f+Hpa9DYTiYOofoXg0V/ecI=" - }, "js-yaml": { "version": "3.4.6", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz", @@ -2046,125 +1941,56 @@ "integrity": "sha1-8WFLBshUToEo5CKchjR9tzrZeI0=" } } - }, - "load-grunt-tasks": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.3.0.tgz", - "integrity": "sha1-vliSkJRY2T3fdp60vGhRAggMYyE=", + } + } + }, + "load-grunt-tasks": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.3.0.tgz", + "integrity": "sha1-vliSkJRY2T3fdp60vGhRAggMYyE=", + "requires": { + "arrify": "^1.0.0", + "multimatch": "^2.0.0", + "pkg-up": "^1.0.0" + }, + "dependencies": { + "pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", "requires": { - "arrify": "^1.0.0", - "multimatch": "^2.0.0", - "pkg-up": "^1.0.0" + "find-up": "^1.0.0" }, "dependencies": { - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "multimatch": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "requires": { - "array-differ": "^1.0.0", - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "minimatch": "^3.0.0" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" }, "dependencies": { - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "requires": { - "array-uniq": "^1.0.1" - }, - "dependencies": { - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - } - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - } - } - } - } - } - } - }, - "pkg-up": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", - "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", - "requires": { - "find-up": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" + } + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" }, "dependencies": { - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - }, - "dependencies": { - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - } - } + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" } } } @@ -2281,43 +2107,6 @@ "readable-stream": "2.2.7" }, "dependencies": { - "es6-promise": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", - "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" - }, - "mongodb-core": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", - "integrity": "sha1-TEYTm986HwMt7ZHbSfOO7AFlkFA=", - "requires": { - "bson": "~1.0.4", - "require_optional": "~1.0.0" - }, - "dependencies": { - "require_optional": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", - "requires": { - "resolve-from": "^2.0.0", - "semver": "^5.1.0" - }, - "dependencies": { - "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" - } - } - } - } - }, "readable-stream": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", @@ -2381,6 +2170,15 @@ } } }, + "mongodb-core": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", + "integrity": "sha1-TEYTm986HwMt7ZHbSfOO7AFlkFA=", + "requires": { + "bson": "~1.0.4", + "require_optional": "~1.0.0" + } + }, "mongojs": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", @@ -2396,31 +2194,6 @@ "xtend": "^4.0.0" }, "dependencies": { - "each-series": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", - "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - }, - "dependencies": { - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } - }, - "parse-mongo-url": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", - "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" - }, "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", @@ -2474,21 +2247,6 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" } } - }, - "thunky": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", - "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" - }, - "to-mongodb-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", - "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" } } }, @@ -2498,6 +2256,50 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "requires": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + } + } + } + } + } + } + }, "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", @@ -2580,6 +2382,26 @@ "validate-npm-package-license": "^3.0.1" } }, + "npm-run-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", + "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", + "requires": { + "path-key": "^1.0.0" + }, + "dependencies": { + "path-key": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", + "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=" + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, "object-inspect": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", @@ -2619,7 +2441,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -2681,6 +2502,11 @@ "json-parse-better-errors": "^1.0.1" } }, + "parse-mongo-url": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", + "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -2809,25 +2635,18 @@ "double-ended-queue": "^2.1.0-0", "redis-commands": "^1.2.0", "redis-parser": "^2.6.0" - }, - "dependencies": { - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, - "redis-commands": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz", - "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=" - }, - "redis-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", - "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" - } } }, + "redis-commands": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz", + "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=" + }, + "redis-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", + "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -2840,6 +2659,35 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + }, + "dependencies": { + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + } + } + }, + "requirefresh": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/requirefresh/-/requirefresh-2.1.0.tgz", + "integrity": "sha1-dC3Mwg86lpGNZsbxWX3I/+vE9vU=", + "requires": { + "editions": "^1.1.1" + } + }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -2861,6 +2709,22 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" }, + "safefs": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/safefs/-/safefs-4.1.0.tgz", + "integrity": "sha1-+CrrS9165R9lPrIPZyizBYyNZEU=", + "requires": { + "editions": "^1.1.1", + "graceful-fs": "^4.1.4" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + } + } + }, "sax": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", @@ -2987,17 +2851,6 @@ "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "string.prototype.trimend": { @@ -3027,10 +2880,13 @@ "dev": true }, "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", - "dev": true + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } }, "strip-bom": { "version": "3.0.0", @@ -3084,15 +2940,6 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } } } }, @@ -3102,6 +2949,16 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "thunky": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", + "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" + }, + "to-mongodb-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", + "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" + }, "tsconfig-paths": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", @@ -3113,6 +2970,11 @@ "strip-bom": "^3.0.0" } }, + "twostep": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/twostep/-/twostep-0.4.2.tgz", + "integrity": "sha1-hLxQh6hxV00ev3vjB54D4SLUFbY=" + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3128,6 +2990,14 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "typechecker": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-4.4.1.tgz", + "integrity": "sha1-+XuV9RsDhBchLWd9RaNz7nvO1+Y=", + "requires": { + "editions": "^1.3.3" + } + }, "unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -3204,8 +3074,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "xml2js": { "version": "0.2.8", @@ -3216,6 +3085,11 @@ "sax": "0.5.x" } }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/server-ce/package.json b/server-ce/package.json index c46ac96be4..f7ef5fd095 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -12,7 +12,6 @@ "@overleaf/settings": "^2.1.1", "async": "^0.9.0", "bson": "^1.0.4", - "coffee-script": "^1.11.1", "east": "0.5.7", "east-mongo": "0.3.3", "grunt-shell": "^1.1.1", @@ -41,7 +40,6 @@ "grunt-execute": "~0.1.5", "grunt-available-tasks": "~0.4.1", "grunt-concurrent": "~0.4.3", - "grunt-contrib-coffee": "~0.10.1", "prettier": "^2.2.1", "semver": "~2.2.1", "knox": "~0.8.9" From a8ca0a896fc9d9f377e0ba5c73f167f62b915987 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 13:04:19 +0100 Subject: [PATCH 518/525] [misc] fix listing of services for bin/ scripts --- server-ce/bin/compile-services | 7 +++---- server-ce/bin/install-services | 3 +-- server-ce/services.js | 6 ++++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index 4045a49a4c..2ebde44826 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -2,19 +2,18 @@ set -e -grep 'name:' config/services.js | \ - sed 's/.*name: "\(.*\)",/\1/' | \ +node ./config/services.js | \ while read service do pushd $service echo "Compiling Service $service" - case $service in + case $service in web) npm run webpack:production ;; *) echo "$service doesn't require a compilation" ;; - esac + esac popd done diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services index becf174cc1..591fb3354b 100755 --- a/server-ce/bin/install-services +++ b/server-ce/bin/install-services @@ -2,8 +2,7 @@ set -e -grep 'name:' config/services.js | \ - sed 's/.*name: "\(.*\)",/\1/' | \ +node ./config/services.js | \ while read service do pushd $service diff --git a/server-ce/services.js b/server-ce/services.js index 4fc6365f6b..c47186a159 100644 --- a/server-ce/services.js +++ b/server-ce/services.js @@ -55,3 +55,9 @@ module.exports = [ version: 'master', }, ] + +if (require.main === module) { + for (const service of module.exports) { + console.log(service.name) + } +} From adf3420c91c873fd0c2ad492f0ea7270797f3ced Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Fri, 9 Jul 2021 16:52:26 +0200 Subject: [PATCH 519/525] Renamed SAML setting `privateCert` -> `privateKey` Required by `passport-saml` update to 3.x --- server-ce/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/settings.js b/server-ce/settings.js index 25de871789..eb5a5f015e 100644 --- a/server-ce/settings.js +++ b/server-ce/settings.js @@ -680,7 +680,7 @@ if (process.env.SHARELATEX_SAML_ENTRYPOINT) { // https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 if (process.env.SHARELATEX_SAML_CERT) { settings.saml.server.cert = process.env.SHARELATEX_SAML_CERT - settings.saml.server.privateCert = process.env.SHARELATEX_SAML_PRIVATE_CERT + settings.saml.server.privateKey = process.env.SHARELATEX_SAML_PRIVATE_CERT } } From ac1eb8fb503adc6c88b2fdf91a5833d72a4058d5 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Mon, 12 Jul 2021 17:24:29 +0100 Subject: [PATCH 520/525] [misc] goodbye grunt --- server-ce/Dockerfile | 52 +- server-ce/Dockerfile-base | 6 - server-ce/Gruntfile.js | 355 -- server-ce/README.md | 2 +- server-ce/bin/compile-services | 19 - server-ce/bin/grunt | 33 + server-ce/bin/install-services | 21 - server-ce/genScript.js | 60 + server-ce/git-revision.sh | 6 - server-ce/init_scripts/98_check_db_access.sh | 5 +- server-ce/package-lock.json | 3100 ------------------ server-ce/package.json | 47 - server-ce/tasks/CreateAndDestroyUsers.js | 116 - 13 files changed, 114 insertions(+), 3708 deletions(-) delete mode 100644 server-ce/Gruntfile.js delete mode 100755 server-ce/bin/compile-services create mode 100644 server-ce/bin/grunt delete mode 100755 server-ce/bin/install-services create mode 100644 server-ce/genScript.js delete mode 100755 server-ce/git-revision.sh delete mode 100644 server-ce/package-lock.json delete mode 100644 server-ce/package.json delete mode 100644 server-ce/tasks/CreateAndDestroyUsers.js diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index 33f2e0baab..e967cef81c 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -5,57 +5,32 @@ ARG SHARELATEX_BASE_TAG=sharelatex/sharelatex-base:latest FROM $SHARELATEX_BASE_TAG -ENV SHARELATEX_CONFIG /etc/sharelatex/settings.js - +WORKDIR /var/www/sharelatex # Add required source files # ------------------------- -ADD ${baseDir}/bin /var/www/sharelatex/bin -ADD ${baseDir}/doc /var/www/sharelatex/doc -ADD ${baseDir}/tasks /var/www/sharelatex/tasks -ADD ${baseDir}/Gruntfile.js /var/www/sharelatex/Gruntfile.js -ADD ${baseDir}/package.json /var/www/sharelatex/package.json -ADD ${baseDir}/package-lock.json /var/www/sharelatex/package-lock.json -ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js - - -# Copy build dependencies -# ----------------------- -ADD ${baseDir}/git-revision.sh /var/www/git-revision.sh -ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js - +ADD ${baseDir}/genScript.js /var/www/sharelatex/genScript.js +ADD ${baseDir}/services.js /var/www/sharelatex/services.js # Checkout services # ----------------- -RUN cd /var/www/sharelatex \ -&& npm ci \ -&& grunt install \ +RUN node genScript checkout | bash \ \ -# Cleanup not needed artifacts -# ---------------------------- -&& rm -rf /root/.cache /root/.npm $(find /tmp/ -mindepth 1 -maxdepth 1) \ -# Stores the version installed for each service +# Store the revision for each service # --------------------------------------------- -&& cd /var/www \ -&& ./git-revision.sh > revisions.txt \ +&& node genScript revisions | bash > revisions.txt \ \ # Cleanup the git history # ------------------- -&& rm -rf $(find /var/www/sharelatex -name .git) +&& node genScript cleanup-git | bash # Install npm dependencies # ------------------------ -RUN cd /var/www/sharelatex \ -&& bash ./bin/install-services \ - \ -# Cleanup not needed artifacts -# ---------------------------- -&& rm -rf /root/.cache /root/.npm $(find /tmp/ -mindepth 1 -maxdepth 1) +RUN node genScript install | bash -# Compile CoffeeScript +# Compile # -------------------- -RUN cd /var/www/sharelatex \ -&& bash ./bin/compile-services +RUN node genScript compile | bash # Links CLSI synctex to its default location # ------------------------------------------ @@ -87,8 +62,15 @@ COPY ${baseDir}/init_scripts/ /etc/my_init.d/ # ----------------------- COPY ${baseDir}/settings.js /etc/sharelatex/settings.js +# Copy grunt thin wrapper +# ----------------------- +ADD ${baseDir}/bin/grunt /usr/local/bin/grunt +RUN chmod +x /usr/local/bin/grunt + # Set Environment Variables # -------------------------------- +ENV SHARELATEX_CONFIG /etc/sharelatex/settings.js + ENV WEB_API_USER "sharelatex" ENV SHARELATEX_APP_NAME "Overleaf Community Edition" diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index ff86658ce6..0878d4a8e1 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -35,12 +35,6 @@ RUN apt-get update \ ADD ./vendor/envsubst /usr/bin/envsubst RUN chmod +x /usr/bin/envsubst -# Install Grunt -# ------------ -RUN npm install -g \ - grunt-cli \ -&& rm -rf /root/.npm - # Install TexLive # --------------- # CTAN mirrors occasionally fail, in that case install TexLive against an diff --git a/server-ce/Gruntfile.js b/server-ce/Gruntfile.js deleted file mode 100644 index 170ee5b353..0000000000 --- a/server-ce/Gruntfile.js +++ /dev/null @@ -1,355 +0,0 @@ -/* eslint-disable - camelcase, - no-return-assign, - no-unreachable, - no-unused-vars, - node/handle-callback-err, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS101: Remove unnecessary use of Array.from - * DS102: Remove unnecessary code created because of implicit returns - * DS103: Rewrite code to no longer use __guard__, or convert again using --optional-chaining - * DS205: Consider reworking code to avoid use of IIFEs - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -const fs = require('fs') -const { spawn } = require('child_process') -const { exec } = require('child_process') -const rimraf = require('rimraf') -const Path = require('path') -const semver = require('semver') -const knox = require('knox') -const crypto = require('crypto') -const async = require('async') -const settings = require('@overleaf/settings') -const _ = require('underscore') - -const SERVICES = require('./config/services') - -module.exports = function (grunt) { - let Helpers - let service - grunt.loadNpmTasks('grunt-bunyan') - grunt.loadNpmTasks('grunt-execute') - grunt.loadNpmTasks('grunt-available-tasks') - grunt.loadNpmTasks('grunt-concurrent') - grunt.loadNpmTasks('grunt-shell') - - grunt.task.loadTasks('./tasks') - - const execute = {} - for (service of Array.from(SERVICES)) { - execute[service.name] = { src: `${service.name}/app.js` } - } - - grunt.initConfig({ - execute, - - concurrent: { - all: { - tasks: (() => { - const result = [] - for (service of Array.from(SERVICES)) { - result.push(`run:${service.name}`) - } - return result - })(), - options: { - limit: SERVICES.length, - logConcurrentOutput: true, - }, - }, - }, - - availabletasks: { - tasks: { - options: { - filter: 'exclude', - tasks: ['concurrent', 'execute', 'bunyan', 'availabletasks'], - groups: { - 'Run tasks': ['run', 'run:all', 'default'].concat( - (() => { - const result1 = [] - for (service of Array.from(SERVICES)) { - result1.push(`run:${service.name}`) - } - return result1 - })() - ), - Misc: ['help'], - 'Install tasks': (() => { - const result2 = [] - for (service of Array.from(SERVICES)) { - result2.push(`install:${service.name}`) - } - return result2 - })().concat(['install:all', 'install']), - 'Update tasks': (() => { - const result3 = [] - for (service of Array.from(SERVICES)) { - result3.push(`update:${service.name}`) - } - return result3 - })().concat(['update:all', 'update']), - Checks: [ - 'check', - 'check:redis', - 'check:latexmk', - 'check:s3', - 'check:make', - 'check:mongo', - ], - }, - }, - }, - }, - }) - - for (service of Array.from(SERVICES)) { - ;(service => - grunt.registerTask( - `install:${service.name}`, - `Download and set up the ${service.name} service`, - function () { - const done = this.async() - return Helpers.installService(service, done) - } - ))(service) - } - - grunt.registerTask( - 'install:all', - 'Download and set up all ShareLaTeX services', - [] - .concat( - (() => { - const result4 = [] - for (service of Array.from(SERVICES)) { - result4.push(`install:${service.name}`) - } - return result4 - })() - ) - .concat(['postinstall']) - ) - - grunt.registerTask('install', 'install:all') - grunt.registerTask('postinstall', 'Explain postinstall steps', function () { - return Helpers.postinstallMessage(this.async()) - }) - - grunt.registerTask( - 'update:all', - 'Checkout and update all ShareLaTeX services', - ['check:make'].concat( - (() => { - const result5 = [] - for (service of Array.from(SERVICES)) { - result5.push(`update:${service.name}`) - } - return result5 - })() - ) - ) - grunt.registerTask('update', 'update:all') - grunt.registerTask('run', 'Run all of the sharelatex processes', [ - 'concurrent:all', - ]) - grunt.registerTask('run:all', 'run') - - grunt.registerTask('help', 'Display this help list', 'availabletasks') - grunt.registerTask('default', 'run') - - grunt.registerTask( - 'check:redis', - 'Check that redis is installed and running', - function () { - return Helpers.checkRedisConnect(this.async()) - } - ) - - grunt.registerTask( - 'check:mongo', - 'Check that mongo is installed', - function () { - return Helpers.checkMongoConnect(this.async()) - } - ) - - grunt.registerTask( - 'check', - 'Check that you have the required dependencies installed', - ['check:redis', 'check:mongo', 'check:make'] - ) - - grunt.registerTask('check:make', 'Check that make is installed', function () { - return Helpers.checkMake(this.async()) - }) - - return (Helpers = { - installService(service, callback) { - if (callback == null) { - callback = function (error) {} - } - console.log(`Installing ${service.name}`) - return Helpers.cloneGitRepo(service, function (error) { - if (error != null) { - return callback(error) - } else { - return callback() - } - }) - }, - - cloneGitRepo(service, callback) { - if (callback == null) { - callback = function (error) {} - } - const repo_src = service.repo - const dir = service.name - if (!fs.existsSync(dir)) { - const proc = spawn('git', ['clone', repo_src, dir], { - stdio: 'inherit', - }) - return proc.on('close', () => - Helpers.checkoutVersion(service, callback) - ) - } else { - console.log(`${dir} already installed, skipping.`) - return callback() - } - }, - - checkoutVersion(service, callback) { - if (callback == null) { - callback = function (error) {} - } - const dir = service.name - grunt.log.write(`checking out ${service.name} ${service.version}`) - const proc = spawn('git', ['checkout', service.version], { - stdio: 'inherit', - cwd: dir, - }) - return proc.on('close', () => callback()) - }, - - postinstallMessage(callback) { - if (callback == null) { - callback = function (error) {} - } - grunt.log.write(`\ -Services cloned: - ${(() => { - const result6 = [] - for (service of Array.from(SERVICES)) { - result6.push(service.name) - } - return result6 - })()} -To install services run: - $ source bin/install-services -This will install the required node versions and run \`npm install\` for each service. -See https://github.com/sharelatex/sharelatex/pull/549 for more info.\ -`) - return callback() - }, - - checkMake(callback) { - if (callback == null) { - callback = function (error) {} - } - grunt.log.write('Checking make is installed... ') - return exec('make --version', function (error, stdout, stderr) { - if (error != null && error.message.match('not found')) { - grunt.log.error('FAIL.') - grunt.log.errorlns(`\ -Either make is not installed or is not in your path. - -On Ubuntu you can install make with: - - sudo apt-get install build-essential -\ -`) - return callback(error) - } else if (error != null) { - return callback(error) - } else { - grunt.log.write('OK.') - return callback() - } - }) - }, - checkMongoConnect(callback) { - if (callback == null) { - callback = function (error) {} - } - grunt.log.write('Checking can connect to mongo') - const mongojs = require('mongojs') - const db = mongojs(settings.mongo.url, ['tags']) - db.runCommand({ ping: 1 }, function (err, res) { - if (!err && res.ok) { - grunt.log.write('OK.') - } - return callback() - }) - return db.on('error', function (err) { - err = 'Can not connect to mongodb' - grunt.log.error('FAIL.') - grunt.log.errorlns(`\ -!!!!!!!!!!!!!! MONGO ERROR !!!!!!!!!!!!!! - -ShareLaTeX can not talk to the mongodb instance - -Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\ -`) - throw new Error('Can not connect to Mongodb') - return callback(err) - }) - }, - - checkRedisConnect(callback) { - if (callback == null) { - callback = function (error) {} - } - grunt.log.write('Checking can connect to redis\n') - const rclient = require('redis').createClient(settings.redis.web) - - rclient.ping(function (err, res) { - if (err == null) { - grunt.log.write('OK.') - } else { - throw new Error('Can not connect to redis') - } - return callback() - }) - const errorHandler = _.once(function (err) { - err = 'Can not connect to redis' - grunt.log.error('FAIL.') - grunt.log.errorlns(`\ -!!!!!!!!!!!!!! REDIS ERROR !!!!!!!!!!!!!! - -ShareLaTeX can not talk to the redis instance - -Check the redis instance is running and accessible on env var SHARELATEX_REDIS_HOST - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\ -`) - throw new Error('Can not connect to redis') - return callback(err) - }) - return rclient.on('error', errorHandler) - }, - }) -} - -function __guard__(value, transform) { - return typeof value !== 'undefined' && value !== null - ? transform(value) - : undefined -} diff --git a/server-ce/README.md b/server-ce/README.md index 8ed22e0e41..1d7737608c 100644 --- a/server-ce/README.md +++ b/server-ce/README.md @@ -42,7 +42,7 @@ If you are upgrading from a previous version of Overleaf, please see the [Releas ## Other repositories -This repository does not contain any code. It acts a wrapper and toolkit for managing the many different Overleaf services. These each run as their own Node.js process and have their own GitHub repository. These are all downloaded and set up when you run `grunt install` +This repository does not contain any code. It acts a wrapper and toolkit for managing the many different Overleaf services. These each run as their own Node.js process and have their own GitHub repository. | Service | Description | | ------- | ----------- | diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services deleted file mode 100755 index 2ebde44826..0000000000 --- a/server-ce/bin/compile-services +++ /dev/null @@ -1,19 +0,0 @@ -#! env bash - -set -e - -node ./config/services.js | \ - while read service - do - pushd $service - echo "Compiling Service $service" - case $service in - web) - npm run webpack:production - ;; - *) - echo "$service doesn't require a compilation" - ;; - esac - popd - done diff --git a/server-ce/bin/grunt b/server-ce/bin/grunt new file mode 100644 index 0000000000..cabc7b8fd6 --- /dev/null +++ b/server-ce/bin/grunt @@ -0,0 +1,33 @@ +#!/bin/bash +# Thin wrapper on old grunt tasks to ease migrating. + +set -e +TASK="$1" +shift 1 + +case "$TASK" in + user:create-admin) + cd /var/www/sharelatex/web + node scripts/server-ce/create-admin "$@" + ;; + + user:delete) + cd /var/www/sharelatex/web + node scripts/server-ce/delete-user "$@" + ;; + + check:mongo) + cd /var/www/sharelatex/web + node scripts/server-ce/check-mongodb + ;; + + check:redis) + cd /var/www/sharelatex/web + node scripts/server-ce/check-redis + ;; + + *) + echo "Unknown task $TASK" + exit 1 + ;; +esac diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services deleted file mode 100755 index 591fb3354b..0000000000 --- a/server-ce/bin/install-services +++ /dev/null @@ -1,21 +0,0 @@ -#! env bash - -set -e - -node ./config/services.js | \ - while read service - do - pushd $service - echo "Installing service $service" - case $service in - web) - # install webpack and friends from dev-dependencies. - npm ci - ;; - *) - npm ci --only=production - ;; - esac - popd - done - diff --git a/server-ce/genScript.js b/server-ce/genScript.js new file mode 100644 index 0000000000..6049b2dbe8 --- /dev/null +++ b/server-ce/genScript.js @@ -0,0 +1,60 @@ +const services = require('./services') + +console.log('#!/bin/bash') +console.log('set -ex') + +switch (process.argv.pop()) { + case 'checkout': + for (const service of services) { + console.log(`git clone ${service.repo} ${service.name}`) + console.log(`git -C ${service.name} checkout ${service.version}`) + } + break + case 'revisions': + for (const service of services) { + console.log(`git -C ${service.name} rev-parse HEAD`) + } + break + case 'cleanup-git': + for (const service of services) { + console.log(`rm -rf ${service.name}/.git`) + } + break + case 'install': + for (const service of services) { + console.log('pushd', service.name) + switch (service.name) { + case 'web': + console.log('npm ci') + break + default: + console.log('npm ci --only=production') + } + console.log('popd') + } + break + case 'compile': + for (const service of services) { + console.log('pushd', service.name) + switch (service.name) { + case 'web': + console.log('npm run webpack:production') + // drop webpack/babel cache + console.log('rm -rf node_modules/.cache') + break + default: + console.log(`echo ${service.name} does not require a compilation`) + } + console.log('popd') + } + break + default: + console.error('unknown command') + console.log('exit 101') + process.exit(101) +} + +console.log('set +x') +console.log( + 'rm -rf /root/.cache /root/.npm $(find /tmp/ -mindepth 1 -maxdepth 1)' +) diff --git a/server-ce/git-revision.sh b/server-ce/git-revision.sh deleted file mode 100755 index e26f75bfd4..0000000000 --- a/server-ce/git-revision.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -for gitDir in $(find "$PWD" -name .git); do - echo -n "$(dirname ${gitDir})," - git --git-dir="$gitDir" rev-parse HEAD -done diff --git a/server-ce/init_scripts/98_check_db_access.sh b/server-ce/init_scripts/98_check_db_access.sh index f8507f582f..dd8aa76058 100755 --- a/server-ce/init_scripts/98_check_db_access.sh +++ b/server-ce/init_scripts/98_check_db_access.sh @@ -2,6 +2,7 @@ set -e echo "Checking can connect to mongo and redis" -cd /var/www/sharelatex && grunt check:redis -cd /var/www/sharelatex && grunt check:mongo +cd /var/www/sharelatex/web +node scripts/server-ce/check-mongodb +node scripts/server-ce/check-redis echo "All checks passed" diff --git a/server-ce/package-lock.json b/server-ce/package-lock.json deleted file mode 100644 index 3331f87502..0000000000 --- a/server-ce/package-lock.json +++ /dev/null @@ -1,3100 +0,0 @@ -{ - "name": "sharelatex", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - } - } - }, - "@eslint/eslintrc": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", - "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, - "@overleaf/settings": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@overleaf/settings/-/settings-2.1.1.tgz", - "integrity": "sha512-vcJwqCGFKmQxTP/syUqCeMaSRjHmBcQgKOACR9He2uJcErg2GZPa1go+nGvszMbkElM4HfRKm/MfxvqHhoN4TQ==" - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", - "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=", - "dev": true, - "requires": { - "underscore": "~1.7.0", - "underscore.string": "~2.4.0" - }, - "dependencies": { - "underscore": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", - "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", - "dev": true - }, - "underscore.string": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz", - "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=", - "dev": true - } - } - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" - }, - "array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "bson": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz", - "integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw=" - }, - "bunyan": { - "version": "0.22.3", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.22.3.tgz", - "integrity": "sha1-ehncG0yMZF90AkGnQPIkUUfGfsI=", - "dev": true, - "requires": { - "dtrace-provider": "0.2.8", - "mv": "~2" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "supports-color": "^5.3.0" - } - }, - "coffee-script": { - "version": "1.12.7", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", - "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colors": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", - "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", - "dev": true - }, - "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "requires": { - "graceful-readlink": ">= 1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "cson": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/cson/-/cson-3.0.2.tgz", - "integrity": "sha1-g+6Qids8JUvsHpjkmNmqzxGtzFQ=", - "requires": { - "coffee-script": "^1.9.0", - "cson-parser": "^1.0.6", - "extract-opts": "^3.0.1", - "requirefresh": "^2.0.0", - "safefs": "^4.0.0" - } - }, - "cson-parser": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz", - "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=", - "requires": { - "coffee-script": "^1.10.0" - } - }, - "dateformat": { - "version": "1.0.2-1.2.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz", - "integrity": "sha1-sCIMAt6YYXQztyhRz0fePfLNvuk=", - "dev": true - }, - "debug": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", - "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, - "dtrace-provider": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", - "integrity": "sha1-4kPxkhmqlfvw2PL/sH9b1k6U/iA=", - "dev": true, - "optional": true - }, - "each-series": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", - "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" - }, - "eachr": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eachr/-/eachr-3.2.0.tgz", - "integrity": "sha1-LDXkPqCGUW95l8+At6pk1VpKRIQ=", - "requires": { - "editions": "^1.1.1", - "typechecker": "^4.3.0" - } - }, - "east": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/east/-/east-0.5.7.tgz", - "integrity": "sha1-CCt+o8KzV5wEFlltDXCKznC0HLg=", - "requires": { - "commander": "2.9.0", - "expressionify": "0.9.3", - "progress": "1.1.8", - "twostep": "0.4.2" - }, - "dependencies": { - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" - } - } - }, - "east-mongo": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/east-mongo/-/east-mongo-0.3.3.tgz", - "integrity": "sha1-WKtCdGaRy+ITtBweiG8EttyCq8A=" - }, - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", - "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.10.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", - "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "7.30.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", - "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "eslint-config-prettier": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", - "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", - "dev": true - }, - "eslint-config-standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", - "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true - }, - "eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-module-utils": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", - "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-chai-expect": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-2.2.0.tgz", - "integrity": "sha512-ExTJKhgeYMfY8wDj3UiZmgpMKJOUHGNHmWMlxT49JUDB1vTnw0sSNfXJSxnX+LcebyBD/gudXzjzD136WqPJrQ==", - "dev": true - }, - "eslint-plugin-chai-friendly": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.6.0.tgz", - "integrity": "sha512-Uvvv1gkbRGp/qfN15B0kQyQWg+oFA8buDSqrwmW3egNSk/FpqH2MjQqKOuKwmEL6w4QIQrIjDp+gg6kGGmD3oQ==", - "dev": true - }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.23.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz", - "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==", - "dev": true, - "requires": { - "array-includes": "^3.1.3", - "array.prototype.flat": "^1.2.4", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.1", - "find-up": "^2.0.0", - "has": "^1.0.3", - "is-core-module": "^2.4.0", - "minimatch": "^3.0.4", - "object.values": "^1.1.3", - "pkg-up": "^2.0.0", - "read-pkg-up": "^3.0.0", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.9.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-mocha": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-8.2.0.tgz", - "integrity": "sha512-8oOR47Ejt+YJPNQzedbiklDqS1zurEaNrxXpRs+Uk4DMDPVmKNagShFeUaYsfvWP55AhI+P1non5QZAHV6K78A==", - "dev": true, - "requires": { - "eslint-utils": "^2.1.0", - "ramda": "^0.27.1" - } - }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-plugin-promise": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", - "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", - "dev": true - }, - "eslint-plugin-standard": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-5.0.0.tgz", - "integrity": "sha512-eSIXPc9wBM4BrniMzJRBm2uoVuXz2EPa+NXPk2+itrVt+r5SbKFERx/IgrK/HmfjddyKVz2f+j+7gBRvu19xLg==", - "dev": true - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", - "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "eventemitter2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", - "dev": true - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expressionify": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/expressionify/-/expressionify-0.9.3.tgz", - "integrity": "sha1-/iJnx+hpRXfxP02oML/DyNgXf5I=" - }, - "extract-opts": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/extract-opts/-/extract-opts-3.3.1.tgz", - "integrity": "sha1-WrvtyYwNUgLjJ4cn+Rktfghsa+E=", - "requires": { - "eachr": "^3.2.0", - "editions": "^1.1.1", - "typechecker": "^4.3.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "findup-sync": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz", - "integrity": "sha1-fz56l7gjksZTvwZYm9hRkOk8NoM=", - "dev": true, - "requires": { - "glob": "~3.2.9", - "lodash": "~2.4.1" - }, - "dependencies": { - "glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", - "dev": true, - "requires": { - "inherits": "2", - "minimatch": "0.3" - } - }, - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - }, - "minimatch": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", - "dev": true, - "requires": { - "lru-cache": "2", - "sigmund": "~1.0.0" - } - } - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "dependencies": { - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatted": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.0.tgz", - "integrity": "sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "getobject": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", - "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", - "dev": true - }, - "glob": { - "version": "3.1.21", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", - "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", - "dev": true, - "requires": { - "graceful-fs": "~1.2.0", - "inherits": "1", - "minimatch": "~0.2.11" - }, - "dependencies": { - "inherits": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", - "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", - "dev": true - } - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "13.10.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", - "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "graceful-fs": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", - "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", - "dev": true - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" - }, - "grunt": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz", - "integrity": "sha1-VpN81RlDJK3/bSB2MYMqnWuk5/A=", - "dev": true, - "requires": { - "async": "~0.1.22", - "coffee-script": "~1.3.3", - "colors": "~0.6.2", - "dateformat": "1.0.2-1.2.3", - "eventemitter2": "~0.4.13", - "exit": "~0.1.1", - "findup-sync": "~0.1.2", - "getobject": "~0.1.0", - "glob": "~3.1.21", - "grunt-legacy-log": "~0.1.0", - "grunt-legacy-util": "~0.2.0", - "hooker": "~0.2.3", - "iconv-lite": "~0.2.11", - "js-yaml": "~2.0.5", - "lodash": "~0.9.2", - "minimatch": "~0.2.12", - "nopt": "~1.0.10", - "rimraf": "~2.2.8", - "underscore.string": "~2.2.1", - "which": "~1.0.5" - }, - "dependencies": { - "async": { - "version": "0.1.22", - "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", - "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=", - "dev": true - }, - "coffee-script": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz", - "integrity": "sha1-FQ1rTLUiiUNp7+1qIQHCC8f0pPQ=", - "dev": true - }, - "lodash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz", - "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=", - "dev": true - } - } - }, - "grunt-available-tasks": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/grunt-available-tasks/-/grunt-available-tasks-0.4.5.tgz", - "integrity": "sha1-a99ifacQJ7pD6ypjaIansUVh5dE=", - "dev": true, - "requires": { - "lodash": "~2.4.0", - "underscore.string": "~2.3.3" - }, - "dependencies": { - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - }, - "underscore.string": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", - "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", - "dev": true - } - } - }, - "grunt-bunyan": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/grunt-bunyan/-/grunt-bunyan-0.5.0.tgz", - "integrity": "sha1-aCnXbgGZQ9owQTk2MaNuKsgpsWw=", - "dev": true, - "requires": { - "lodash": "~2.4.1" - }, - "dependencies": { - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - } - } - }, - "grunt-concurrent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/grunt-concurrent/-/grunt-concurrent-0.4.3.tgz", - "integrity": "sha1-JFNJAYVZTInYOZ87GENHb2hp5J0=", - "dev": true, - "requires": { - "async": "~0.2.9", - "lpad": "~0.1.0" - }, - "dependencies": { - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", - "dev": true - } - } - }, - "grunt-execute": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/grunt-execute/-/grunt-execute-0.1.5.tgz", - "integrity": "sha1-yX64lDYS/vu3L749Mu+VIzxfouk=", - "dev": true - }, - "grunt-legacy-log": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz", - "integrity": "sha1-7ClCboAwIa9ZAp+H0vnNczWgVTE=", - "dev": true, - "requires": { - "colors": "~0.6.2", - "grunt-legacy-log-utils": "~0.1.1", - "hooker": "~0.2.3", - "lodash": "~2.4.1", - "underscore.string": "~2.3.3" - }, - "dependencies": { - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - }, - "underscore.string": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", - "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", - "dev": true - } - } - }, - "grunt-legacy-log-utils": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz", - "integrity": "sha1-wHBrndkGThFvNvI/5OawSGcsD34=", - "dev": true, - "requires": { - "colors": "~0.6.2", - "lodash": "~2.4.1", - "underscore.string": "~2.3.3" - }, - "dependencies": { - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - }, - "underscore.string": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", - "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", - "dev": true - } - } - }, - "grunt-legacy-util": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz", - "integrity": "sha1-kzJIhNv343qf98Am3/RR2UqeVUs=", - "dev": true, - "requires": { - "async": "~0.1.22", - "exit": "~0.1.1", - "getobject": "~0.1.0", - "hooker": "~0.2.3", - "lodash": "~0.9.2", - "underscore.string": "~2.2.1", - "which": "~1.0.5" - }, - "dependencies": { - "async": { - "version": "0.1.22", - "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", - "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=", - "dev": true - }, - "lodash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz", - "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=", - "dev": true - } - } - }, - "grunt-shell": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-1.3.1.tgz", - "integrity": "sha1-XivuzQXV03h/pAECjVcz1dQ7m9E=", - "requires": { - "chalk": "^1.0.0", - "npm-run-path": "^1.0.0", - "object-assign": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - } - } - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "hooker": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", - "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", - "dev": true - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "iconv-lite": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz", - "integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=", - "dev": true - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", - "dev": true - }, - "is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "dev": true - }, - "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", - "dev": true - }, - "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - } - }, - "is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", - "dev": true - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "jit-grunt": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/jit-grunt/-/jit-grunt-0.10.0.tgz", - "integrity": "sha1-AIw6f+Hpa9DYTiYOofoXg0V/ecI=" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz", - "integrity": "sha1-olrmUJmZ6X3yeMZxnaEb0Gh3Q6g=", - "dev": true, - "requires": { - "argparse": "~ 0.1.11", - "esprima": "~ 1.0.2" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "knox": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/knox/-/knox-0.8.10.tgz", - "integrity": "sha1-ai7c2sHSrjedHhmU1Vm5XCg7JYg=", - "dev": true, - "requires": { - "debug": "~0.7.0", - "mime": "*", - "stream-counter": "~0.1.0", - "xml2js": "0.2.x" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "load-grunt-config": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/load-grunt-config/-/load-grunt-config-0.19.2.tgz", - "integrity": "sha1-UgkNSiDG5j90p2SPJJsZ57f87CQ=", - "requires": { - "cson": "~3.0.2", - "glob": "~5.0.15", - "jit-grunt": "~0.10.0", - "js-yaml": "~3.4.3", - "load-grunt-tasks": "~3.3.0", - "lodash": "~3.10.1" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - }, - "dependencies": { - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - } - } - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - }, - "dependencies": { - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - } - } - }, - "js-yaml": { - "version": "3.4.6", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz", - "integrity": "sha1-a+GyP2JJ9T0pM3D9TRqqY84bTrA=", - "requires": { - "argparse": "^1.0.2", - "esprima": "^2.6.0", - "inherit": "^2.2.2" - }, - "dependencies": { - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "requires": { - "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - } - } - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" - }, - "inherit": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/inherit/-/inherit-2.2.6.tgz", - "integrity": "sha1-8WFLBshUToEo5CKchjR9tzrZeI0=" - } - } - } - } - }, - "load-grunt-tasks": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.3.0.tgz", - "integrity": "sha1-vliSkJRY2T3fdp60vGhRAggMYyE=", - "requires": { - "arrify": "^1.0.0", - "multimatch": "^2.0.0", - "pkg-up": "^1.0.0" - }, - "dependencies": { - "pkg-up": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", - "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", - "requires": { - "find-up": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - }, - "dependencies": { - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - } - } - } - } - } - } - } - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true - } - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "lpad": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lpad/-/lpad-0.1.0.tgz", - "integrity": "sha1-5MYMKROTIcWXDeSTtJauDXdM0qc=", - "dev": true - }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true - }, - "mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "dev": true - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "dev": true, - "requires": { - "lru-cache": "2", - "sigmund": "~1.0.0" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "optional": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mongodb": { - "version": "2.2.34", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.34.tgz", - "integrity": "sha1-o09Zu+thdUrsQy3nLD/iFSakTBo=", - "requires": { - "es6-promise": "3.2.1", - "mongodb-core": "2.1.18", - "readable-stream": "2.2.7" - }, - "dependencies": { - "readable-stream": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", - "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", - "requires": { - "buffer-shims": "~1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "buffer-shims": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - } - } - } - } - }, - "mongodb-core": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", - "integrity": "sha1-TEYTm986HwMt7ZHbSfOO7AFlkFA=", - "requires": { - "bson": "~1.0.4", - "require_optional": "~1.0.0" - } - }, - "mongojs": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", - "integrity": "sha1-8of7/UV/7fWItakBHmhRPZ3TK/s=", - "requires": { - "each-series": "^1.0.0", - "mongodb": "^2.0.45", - "once": "^1.3.2", - "parse-mongo-url": "^1.1.0", - "readable-stream": "^2.0.2", - "thunky": "^0.1.0", - "to-mongodb-core": "^2.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.0.3", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - } - } - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "multimatch": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", - "requires": { - "array-differ": "^1.0.0", - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "minimatch": "^3.0.0" - }, - "dependencies": { - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - } - } - } - } - } - } - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "optional": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "optional": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "optional": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true, - "optional": true - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "npm-run-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", - "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", - "requires": { - "path-key": "^1.0.0" - }, - "dependencies": { - "path-key": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", - "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=" - } - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.values": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse-mongo-url": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", - "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "ramda": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", - "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "redis": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", - "requires": { - "double-ended-queue": "^2.1.0-0", - "redis-commands": "^1.2.0", - "redis-parser": "^2.6.0" - } - }, - "redis-commands": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz", - "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=" - }, - "redis-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", - "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "require_optional": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", - "requires": { - "resolve-from": "^2.0.0", - "semver": "^5.1.0" - }, - "dependencies": { - "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" - } - } - }, - "requirefresh": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/requirefresh/-/requirefresh-2.1.0.tgz", - "integrity": "sha1-dC3Mwg86lpGNZsbxWX3I/+vE9vU=", - "requires": { - "editions": "^1.1.1" - } - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" - }, - "safefs": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/safefs/-/safefs-4.1.0.tgz", - "integrity": "sha1-+CrrS9165R9lPrIPZyizBYyNZEU=", - "requires": { - "editions": "^1.1.1", - "graceful-fs": "^4.1.4" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - } - } - }, - "sax": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", - "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", - "dev": true - }, - "semver": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-2.2.1.tgz", - "integrity": "sha1-eUEYKz/8xYC/8cF5QqzfeVHA0hM=", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", - "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "stream-counter": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-0.1.0.tgz", - "integrity": "sha1-oDXkKTYftX82Fgbhf82Ki5Z3Mns=", - "dev": true, - "requires": { - "readable-stream": "~1.0.2" - } - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", - "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", - "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "thunky": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", - "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" - }, - "to-mongodb-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", - "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" - }, - "tsconfig-paths": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", - "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", - "dev": true, - "requires": { - "json5": "^2.2.0", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "twostep": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/twostep/-/twostep-0.4.2.tgz", - "integrity": "sha1-hLxQh6hxV00ev3vjB54D4SLUFbY=" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typechecker": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-4.4.1.tgz", - "integrity": "sha1-+XuV9RsDhBchLWd9RaNz7nvO1+Y=", - "requires": { - "editions": "^1.3.3" - } - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - }, - "underscore.string": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz", - "integrity": "sha1-18D6KvXVoaZ/QlPa7pgTLnM/Dxk=", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "which": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", - "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=", - "dev": true - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xml2js": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.8.tgz", - "integrity": "sha1-m4FpCTFjH/CdGVdUn69U9PmAs8I=", - "dev": true, - "requires": { - "sax": "0.5.x" - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } -} diff --git a/server-ce/package.json b/server-ce/package.json deleted file mode 100644 index f7ef5fd095..0000000000 --- a/server-ce/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "sharelatex", - "version": "0.0.1", - "description": "An online collaborative LaTeX editor", - "scripts": { - "lint": "eslint --max-warnings 0 --format unix .", - "lint:fix": "eslint --fix .", - "format": "prettier --list-different $PWD/'**/*.js'", - "format:fix": "prettier --write $PWD/'**/*.js'" - }, - "dependencies": { - "@overleaf/settings": "^2.1.1", - "async": "^0.9.0", - "bson": "^1.0.4", - "east": "0.5.7", - "east-mongo": "0.3.3", - "grunt-shell": "^1.1.1", - "load-grunt-config": "^0.19.2", - "lodash": "^3.0.0", - "mongodb": "^2.2.34", - "mongojs": "2.4.0", - "redis": "^2.6.2", - "rimraf": "~2.2.6", - "underscore": "^1.7.0" - }, - "devDependencies": { - "grunt": "~0.4.2", - "bunyan": "~0.22.1", - "eslint": "^7.21.0", - "eslint-config-prettier": "^8.1.0", - "eslint-config-standard": "^16.0.2", - "eslint-plugin-chai-expect": "^2.2.0", - "eslint-plugin-chai-friendly": "^0.6.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-mocha": "^8.0.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-standard": "^5.0.0", - "grunt-bunyan": "~0.5.0", - "grunt-execute": "~0.1.5", - "grunt-available-tasks": "~0.4.1", - "grunt-concurrent": "~0.4.3", - "prettier": "^2.2.1", - "semver": "~2.2.1", - "knox": "~0.8.9" - } -} diff --git a/server-ce/tasks/CreateAndDestroyUsers.js b/server-ce/tasks/CreateAndDestroyUsers.js deleted file mode 100644 index b7d519cc6c..0000000000 --- a/server-ce/tasks/CreateAndDestroyUsers.js +++ /dev/null @@ -1,116 +0,0 @@ -/* eslint-disable - no-undef, - no-unused-vars, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ - -module.exports = function (grunt) { - grunt.registerTask( - 'user:create-admin', - 'Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt user:create-admin --email joe@example.com', - function () { - const done = this.async() - const email = grunt.option('email') - if (email == null) { - console.error('Usage: grunt user:create-admin --email=joe@example.com') - process.exit(1) - } - - const settings = require('@overleaf/settings') - const mongodb = require('../web/app/src/infrastructure/mongodb') - const UserRegistrationHandler = require('../web/app/src/Features/User/UserRegistrationHandler') - const OneTimeTokenHandler = require('../web/app/src/Features/Security/OneTimeTokenHandler') - return mongodb.waitForDb().then(() => - UserRegistrationHandler.registerNewUser( - { - email, - password: require('crypto').randomBytes(32).toString('hex'), - }, - function (error, user) { - if ( - error != null && - (error != null ? error.message : undefined) !== - 'EmailAlreadyRegistered' - ) { - throw error - } - user.isAdmin = true - return user.save(function (error) { - if (error != null) { - throw error - } - const ONE_WEEK = 7 * 24 * 60 * 60 // seconds - return OneTimeTokenHandler.getNewToken( - 'password', - { - expiresIn: ONE_WEEK, - email: user.email, - user_id: user._id.toString(), - }, - function (err, token) { - if (err != null) { - return next(err) - } - - console.log('') - console.log(`\ -Successfully created ${email} as an admin user. - -Please visit the following URL to set a password for ${email} and log in: - -${settings.siteUrl}/user/password/set?passwordResetToken=${token} -\ -`) - return done() - } - ) - }) - } - ) - ) - } - ) - - return grunt.registerTask( - 'user:delete', - 'deletes a user and all their data, Usage: grunt user:delete --email joe@example.com', - function () { - const done = this.async() - const email = grunt.option('email') - if (email == null) { - console.error('Usage: grunt user:delete --email=joe@example.com') - process.exit(1) - } - const settings = require('@overleaf/settings') - const mongodb = require('../web/app/src/infrastructure/mongodb') - const UserGetter = require('../web/app/src/Features/User/UserGetter') - const UserDeleter = require('../web/app/src/Features/User/UserDeleter') - return mongodb.waitForDb().then(() => - UserGetter.getUser({ email }, function (error, user) { - if (error != null) { - throw error - } - if (user == null) { - console.log( - `user ${email} not in database, potentially already deleted` - ) - return done() - } - return UserDeleter.deleteUser(user._id, function (err) { - if (err != null) { - throw err - } - return done() - }) - }) - ) - } - ) -} From afe2c9934da7667d324e96b3563b6fa37b7a27a8 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Tue, 13 Jul 2021 09:13:04 +0100 Subject: [PATCH 521/525] [misc] work around broken 'npm ci --only=production' --- server-ce/genScript.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server-ce/genScript.js b/server-ce/genScript.js index 6049b2dbe8..54e946bdeb 100644 --- a/server-ce/genScript.js +++ b/server-ce/genScript.js @@ -28,7 +28,8 @@ switch (process.argv.pop()) { console.log('npm ci') break default: - console.log('npm ci --only=production') + // TODO(das7pad): revert back to npm ci --only=production (https://github.com/overleaf/issues/issues/4544) + console.log('npm ci') } console.log('popd') } From 77cd7690fb52747417a7bcea1187defcbcc1ebcc Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Tue, 13 Jul 2021 17:03:14 +0100 Subject: [PATCH 522/525] [misc] move server-ce scripts into a module in web --- server-ce/bin/grunt | 14 ++++++-------- server-ce/init_scripts/98_check_db_access.sh | 6 +++--- 2 files changed, 9 insertions(+), 11 deletions(-) mode change 100644 => 100755 server-ce/bin/grunt diff --git a/server-ce/bin/grunt b/server-ce/bin/grunt old mode 100644 new mode 100755 index cabc7b8fd6..c84a2c0e57 --- a/server-ce/bin/grunt +++ b/server-ce/bin/grunt @@ -5,25 +5,23 @@ set -e TASK="$1" shift 1 +cd /var/www/sharelatex/web/modules/server-ce-scripts/scripts + case "$TASK" in user:create-admin) - cd /var/www/sharelatex/web - node scripts/server-ce/create-admin "$@" + node create-admin "$@" ;; user:delete) - cd /var/www/sharelatex/web - node scripts/server-ce/delete-user "$@" + node delete-user "$@" ;; check:mongo) - cd /var/www/sharelatex/web - node scripts/server-ce/check-mongodb + node check-mongodb ;; check:redis) - cd /var/www/sharelatex/web - node scripts/server-ce/check-redis + node check-redis ;; *) diff --git a/server-ce/init_scripts/98_check_db_access.sh b/server-ce/init_scripts/98_check_db_access.sh index dd8aa76058..aab69e24fe 100755 --- a/server-ce/init_scripts/98_check_db_access.sh +++ b/server-ce/init_scripts/98_check_db_access.sh @@ -2,7 +2,7 @@ set -e echo "Checking can connect to mongo and redis" -cd /var/www/sharelatex/web -node scripts/server-ce/check-mongodb -node scripts/server-ce/check-redis +cd /var/www/sharelatex/web/modules/server-ce-scripts/scripts +node check-mongodb +node check-redis echo "All checks passed" From 510b678dc6851de85e166e940475fb749daf7076 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 15 Jul 2021 10:16:17 +0100 Subject: [PATCH 523/525] Add init script to run migrations from web --- server-ce/init_scripts/99_run_web_migrations.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100755 server-ce/init_scripts/99_run_web_migrations.sh diff --git a/server-ce/init_scripts/99_run_web_migrations.sh b/server-ce/init_scripts/99_run_web_migrations.sh new file mode 100755 index 0000000000..a94ce18602 --- /dev/null +++ b/server-ce/init_scripts/99_run_web_migrations.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ "${SHARELATEX_IS_SERVER_PRO:-null}" == "true" ]]; then + environment="server-pro" +else + environment="server-ce" +fi + +echo "Running migrations for $environment" +cd /var/www/sharelatex/web +npm run migrations -- migrate -t "$environment" +echo "Finished migrations" From 90610acb5992f4439f7c1befec85ee6cb10dd907 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Thu, 15 Jul 2021 15:09:54 +0100 Subject: [PATCH 524/525] [misc] bin/grunt: keep up with changes to create-admin script --- server-ce/bin/grunt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-ce/bin/grunt b/server-ce/bin/grunt index c84a2c0e57..03f89b52c7 100755 --- a/server-ce/bin/grunt +++ b/server-ce/bin/grunt @@ -9,7 +9,7 @@ cd /var/www/sharelatex/web/modules/server-ce-scripts/scripts case "$TASK" in user:create-admin) - node create-admin "$@" + node create-user --admin "$@" ;; user:delete) From f0bd9941ddd06c0848d4f3323fc04630bf513bf2 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Fri, 16 Jul 2021 15:31:53 +0100 Subject: [PATCH 525/525] [misc] bring back old schema of revision.txt - store in /var/www/revision.txt - prefix each line with the services directory --- server-ce/Dockerfile | 2 +- server-ce/genScript.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index e967cef81c..c5ce81ef24 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -18,7 +18,7 @@ RUN node genScript checkout | bash \ \ # Store the revision for each service # --------------------------------------------- -&& node genScript revisions | bash > revisions.txt \ +&& node genScript revisions | bash > /var/www/revisions.txt \ \ # Cleanup the git history # ------------------- diff --git a/server-ce/genScript.js b/server-ce/genScript.js index 54e946bdeb..e8f61f2ba2 100644 --- a/server-ce/genScript.js +++ b/server-ce/genScript.js @@ -12,6 +12,7 @@ switch (process.argv.pop()) { break case 'revisions': for (const service of services) { + console.log(`echo -n /var/www/sharelatex/${service.name},`) console.log(`git -C ${service.name} rev-parse HEAD`) } break

}m6SCId)FFKi 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�Sf$G@+)^1-T|MSWpFs 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

Key FeaturesWiki • - Server Pro • + Server ProContributing • - Mailing List • + Mailing ListAuthorsLicense