From 29968859d11bc7ee3692c8c1954951cdc1bef542 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Fri, 12 Jun 2020 11:13:58 +0100 Subject: [PATCH 01/28] Ensure process.domain is set --- lib/application.js | 8 +++++++ package-lock.json | 56 +++++++++++++++++++++++++++++++++++----------- package.json | 2 +- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/lib/application.js b/lib/application.js index c868c28073..40fe4c6c81 100644 --- a/lib/application.js +++ b/lib/application.js @@ -290,9 +290,17 @@ Origin.prototype.createServer = function (options, cb) { requestDomain.session = req.session; requestDomain.on('error', next); requestDomain.run(next); + req.domain = requestDomain; }); server.use(auth.initialize()); server.use(auth.session()); + server.use((req, res, next) => { + if (!process.domain) { + // set process.domain again, fixes adaptlearning/adapt_authoring#2504 + req.domain.enter(); + } + next(); + }); server.use(express.static(path.join(require('./configuration').serverRoot, 'frontend', 'build'))); server.use(express.static(path.join(require('./configuration').serverRoot, 'frontend', 'src', 'libraries'))); if(!app.configuration.getConfig('isProduction')) { diff --git a/package-lock.json b/package-lock.json index aab5e7c0ce..54ebfb778e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3966,15 +3966,15 @@ "integrity": "sha1-D3ca0W9IOuZfQoeWlCjp+8SqYYE=" }, "mongoose": { - "version": "5.8.13", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.8.13.tgz", - "integrity": "sha512-YUBykYbx8/PMR1N8xAxl81PU+JQuMx5pVp7eHelifUMazshQqIwvToUtIxlinEG3NYbbS9FTSzYBrbBLDfrADQ==", + "version": "5.9.18", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.9.18.tgz", + "integrity": "sha512-agZbIuQcN1gZ12BJn6KesA+bgsvoLVjCwhfPw88hggxX8O24SWK4EJwN35GEZKDej9AHUZKNAPgmdeXCVQxviA==", "requires": { - "bson": "~1.1.1", + "bson": "^1.1.4", "kareem": "2.3.1", - "mongodb": "3.4.1", + "mongodb": "3.5.8", "mongoose-legacy-pluralize": "1.0.2", - "mpath": "0.6.0", + "mpath": "0.7.0", "mquery": "3.2.2", "ms": "2.1.2", "regexp-clone": "1.0.0", @@ -3983,26 +3983,56 @@ "sliced": "1.0.1" }, "dependencies": { + "bl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz", + "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "bson": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz", + "integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q==" + }, "mongodb": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.4.1.tgz", - "integrity": "sha512-juqt5/Z42J4DcE7tG7UdVaTKmUC6zinF4yioPfpeOSNBieWSK6qCY+0tfGQcHLKrauWPDdMZVROHJOa8q2pWsA==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.8.tgz", + "integrity": "sha512-jz7mR58z66JKL8Px4ZY+FXbgB7d0a0hEGCT7kw8iye46/gsqPrOEpZOswwJ2BQlfzsrCLKdsF9UcaUfGVN2HrQ==", "requires": { - "bson": "^1.1.1", + "bl": "^2.2.0", + "bson": "^1.1.4", + "denque": "^1.4.1", "require_optional": "^1.0.1", "safe-buffer": "^5.1.2", "saslprep": "^1.0.0" } }, "mpath": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.6.0.tgz", - "integrity": "sha512-i75qh79MJ5Xo/sbhxrDrPSEG0H/mr1kcZXJ8dH6URU5jD/knFxCVqVC/gVSW7GIXL/9hHWlT9haLbCXWOll3qw==" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz", + "integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } } } }, diff --git a/package.json b/package.json index d2f7e32d99..d3c03f478e 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "mime": "^2.4.4", "moment": "^2.24.0", "mongodb-uri": "^0.9.7", - "mongoose": "^5.7.3", + "mongoose": "^5.9.18", "morgan": "^1.9.1", "multer": "^1.4.2", "needle": "^2.4.0", From 2b6a61aa976a5b5d598204747c1ed1a4c0676a39 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Fri, 26 Jun 2020 15:09:36 +0100 Subject: [PATCH 02/28] Switch to attribute blacklist --- frontend/src/core/models/blockModel.js | 30 ++++++---------------- frontend/src/core/models/componentModel.js | 30 ++++------------------ frontend/src/core/models/contentModel.js | 18 +++++-------- 3 files changed, 20 insertions(+), 58 deletions(-) diff --git a/frontend/src/core/models/blockModel.js b/frontend/src/core/models/blockModel.js index 4742ede83e..4efafbfe06 100644 --- a/frontend/src/core/models/blockModel.js +++ b/frontend/src/core/models/blockModel.js @@ -10,28 +10,14 @@ define(function(require) { // Block specific properties layoutOptions: null, dragLayoutOptions: null, - // These are the only attributes which should be permitted on a save - // TODO look into this... - whitelistAttributes: [ - '_id', - '_courseId', - '_parentId', - '_layoutOptions', - '_type', - '_sortOrder', - '_classes', - '_isOptional', - '_isAvailable', - 'body', - 'displayTitle', - 'title', - '_extensions', - 'themeSettings', - '_onScreen', - '_isVisible', - '_isHidden', - 'instruction', - '_colorLabel' + attributeBlacklist: [ + '_isDeleted', + '_tenantId', + '_trackingId', + 'createdBy', + 'createdAt', + 'layoutOptions', + 'updatedAt' ] }); diff --git a/frontend/src/core/models/componentModel.js b/frontend/src/core/models/componentModel.js index 31d6210ae2..7130112b00 100644 --- a/frontend/src/core/models/componentModel.js +++ b/frontend/src/core/models/componentModel.js @@ -6,31 +6,11 @@ define(function(require) { urlRoot: 'api/content/component', _parentType: 'block', _siblingTypes: 'component', - // These are the only attributes which should be permitted on a save - // TODO look into this... - whitelistAttributes: [ - '_id', - '_componentType', - '_courseId', - '_layout', - '_parentId', - '_type', - 'properties', - '_component', - '_extensions', - '_classes', - '_isOptional', - '_isAvailable', - 'body', - 'displayTitle', - 'title', - 'version', - 'themeSettings', - '_onScreen', - '_isVisible', - '_isHidden', - 'instruction', - '_colorLabel' + attributeBlacklist: [ + '_isDeleted', + 'createdBy', + 'createdAt', + 'updatedAt' ] }); diff --git a/frontend/src/core/models/contentModel.js b/frontend/src/core/models/contentModel.js index 59f81fe23e..c8ab282ee1 100644 --- a/frontend/src/core/models/contentModel.js +++ b/frontend/src/core/models/contentModel.js @@ -7,7 +7,7 @@ define(function(require) { var ContentModel = Backbone.Model.extend({ idAttribute: '_id', - whitelistAttributes: null, + attributeBlacklist: null, initialize: function(options) { this.on('sync', this.loadedData, this); @@ -89,17 +89,13 @@ define(function(require) { return JSON.stringify(this); }, - // Remove any attributes which are not on the whitelist (called before a save) pruneAttributes: function() { - var self = this; - // Ensure that only valid attributes are pushed back on the save - if (self.whitelistAttributes) { - _.each(_.keys(self.attributes), function(key) { - if (!_.contains(self.whitelistAttributes, key)) { - self.unset(key); - } - }); - } + if (!this.attributeBlacklist) return; + Object.keys(this.attributes).forEach(function(key) { + if (_.contains(this.attributeBlacklist, key)) { + this.unset(key); + } + }, this); } }); From d58ed35372960856fa6d66998f3c63f07bfcf551 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Tue, 7 Jul 2020 09:35:56 +0100 Subject: [PATCH 03/28] Upgrade MongoDB dependencies --- package-lock.json | 34 ++++++++++++++++++++-------------- package.json | 4 ++-- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 54ebfb778e..9e297911f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -185,10 +185,11 @@ "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" }, "archetype": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/archetype/-/archetype-0.10.0.tgz", - "integrity": "sha512-MlujZnqXyI/8xG8XdOXZ8d6t74Dy3YcOApwSj3/TliFz9OuhpMiwW6gj4Xqhv9FgP/NPf78XhklMEUXmQdVjng==", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/archetype/-/archetype-0.11.3.tgz", + "integrity": "sha512-dlZfyq5xke/qPz1l3I76HdeO3zku40wPkejUhqGpf6E7JnhUz9IgMJKPY7a7+LkOQ3/VKFJBbOGv4T+sK1vUoA==", "requires": { + "lodash.clonedeep": "4.x", "lodash.set": "4.x", "mpath": "0.5.1", "standard-error": "1.1.0" @@ -584,9 +585,9 @@ "dev": true }, "bson": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.3.tgz", - "integrity": "sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg==" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz", + "integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q==" }, "buffer": { "version": "5.4.3", @@ -1005,11 +1006,11 @@ } }, "connect-mongodb-session": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/connect-mongodb-session/-/connect-mongodb-session-2.3.1.tgz", - "integrity": "sha512-lVgJkdXwvxuFBqFGMinV7sCulHXBiP0Xiw4Q205R+V16EztMQ9jWmhP6p6MO+mr0BtR6XVgfAvCXvQlCxl97JQ==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/connect-mongodb-session/-/connect-mongodb-session-2.3.3.tgz", + "integrity": "sha512-IiefbqCCy1SjRmJqKew2ancTn5UsGkgVSeCinDmK+LC7UyL1a+6tKZ7RuTyV/Ec+2tH0/pYGvMursvEHYE35Dg==", "requires": { - "archetype": "0.10.x", + "archetype": "0.11.x", "mongodb": "3.5.x" } }, @@ -3209,6 +3210,11 @@ "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -3923,12 +3929,12 @@ "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, "mongodb": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.3.tgz", - "integrity": "sha512-II7P7A3XUdPiXRgcN96qIoRa1oesM6qLNZkzfPluNZjVkgQk3jnQwOT6/uDk4USRDTTLjNFw2vwfmbRGTA7msg==", + "version": "3.5.9", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.9.tgz", + "integrity": "sha512-vXHBY1CsGYcEPoVWhwgxIBeWqP3dSu9RuRDsoLRPTITrcrgm1f0Ubu1xqF9ozMwv53agmEiZm0YGo+7WL3Nbug==", "requires": { "bl": "^2.2.0", - "bson": "^1.1.1", + "bson": "^1.1.4", "denque": "^1.4.1", "require_optional": "^1.0.1", "safe-buffer": "^5.1.2", diff --git a/package.json b/package.json index d3c03f478e..d87e813d6a 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "bytes": "^3.1.0", "chalk": "^2.4.2", "compression": "^1.7.4", - "connect-mongodb-session": "^2.2.0", + "connect-mongodb-session": "^2.3.3", "consolidate": "^0.15.1", "cookie-parser": "^1.4.4", "email-templates": "^6.0.2", @@ -84,7 +84,7 @@ "mocha": "^6.2.1", "mocha-multi": "^1.1.3", "mocha-simple-html-reporter": "^1.1.0", - "mongodb": "^3.3.2", + "mongodb": "^3.5.9", "should": "^13.2.3", "supertest": "^4.0.2" } From c1152d5bf36412801b1ff290c3728046c9825d11 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Tue, 7 Jul 2020 09:44:00 +0100 Subject: [PATCH 04/28] Switch Node dependency; merge version warning --- lib/installHelpers.js | 5 +---- package.json | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/installHelpers.js b/lib/installHelpers.js index 77e4339416..abf8198e36 100644 --- a/lib/installHelpers.js +++ b/lib/installHelpers.js @@ -185,11 +185,8 @@ function checkDependencies(checks, callback) { function checkNodeVersion(callback) { const requiredVersion = pkg.engines.node; const installedVersion = process.versions.node; - if(semver.gtr(installedVersion, requiredVersion)) { - return callback(null, `You are using Node.js ${installedVersion} which is not yet supported by Adapt. If you encounter issues, please downgrade to ${requiredVersion}.`); - } if(!semver.satisfies(installedVersion, requiredVersion)) { - return callback(`The application requires Node.js ${requiredVersion} to run, found ${installedVersion}. Please make sure you have a compatible version.`); + return callback(null, chalk.yellow(`You are using Node.js ${installedVersion} which is not supported by Adapt. If you encounter issues, please change to version ${requiredVersion}.`)); } callback(); } diff --git a/package.json b/package.json index d87e813d6a..85e0a4b47c 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "main": "index", "engines": { - "node": "10 || 12" + "node": "12 || 14" }, "scripts": { "test": "grunt test", From 6729a1e3b63ea5f11ced3cdc5495bc8437d51783 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Thu, 9 Jul 2020 12:50:33 +0100 Subject: [PATCH 05/28] Switch to inquirer --- install.js | 236 ++++++++++++----------- lib/installHelpers.js | 36 ++-- package-lock.json | 435 +++++++++++++++++++++++++----------------- package.json | 2 +- upgrade.js | 69 ++++--- 5 files changed, 422 insertions(+), 356 deletions(-) diff --git a/install.js b/install.js index 25e3543f97..72dd748f07 100644 --- a/install.js +++ b/install.js @@ -3,7 +3,6 @@ var chalk = require('chalk'); var fs = require('fs-extra'); var optimist = require('optimist'); var path = require('path'); -var prompt = require('prompt'); var crypto = require('crypto'); var auth = require('./lib/auth'); @@ -24,6 +23,7 @@ var masterTenant = false; var superUser = false; // from user input var configResults = {}; +var configOverrides = {}; installHelpers.checkPrimaryDependencies(function(error) { if(error) return handleError(null, 1, error); @@ -33,57 +33,59 @@ installHelpers.checkPrimaryDependencies(function(error) { return handleError(error, 1, 'Failed to get the latest framework version. Check package.json.'); } inputData = { - useConfigJSON: { - name: 'useJSON', - description: 'Use existing config values? y/N', - type: 'string', - before: installHelpers.inputHelpers.toBoolean, - default: 'N' - }, - startInstall: { - name: 'install', - description: 'Continue? Y/n', - type: 'string', - before: installHelpers.inputHelpers.toBoolean, - default: 'Y' - }, + useConfigJSON: [ + { + name: 'useJSON', + message: 'Use existing config values?', + type: 'confirm', + default: false + } + ], + startInstall: [ + { + name: 'install', + message: 'Continue?', + type: 'confirm', + default: true + } + ], server: [ { name: 'serverPort', type: 'number', - description: 'Server port', - pattern: installHelpers.inputHelpers.numberValidator, + message: 'Server port', + validate: installHelpers.inputHelpers.numberValidator, default: 5000 }, { name: 'serverName', - type: 'string', - description: 'Server name', + type: 'input', + message: 'Server name', default: 'localhost' }, { name: 'dataRoot', - type: 'string', - description: 'Data directory path', - pattern: installHelpers.inputHelpers.alphanumValidator, + type: 'input', + message: 'Data directory path', + validate: installHelpers.inputHelpers.alphanumValidator, default: 'data' }, { name: 'authoringToolRepository', - type: 'string', - description: "Git repository URL to be used for the authoring tool source code", + type: 'input', + message: 'Git repository URL to be used for the authoring tool source code', default: 'https://github.com/adaptlearning/adapt_authoring.git' }, { name: 'frameworkRepository', - type: 'string', - description: "Git repository URL to be used for the framework source code", + type: 'input', + message: 'Git repository URL to be used for the framework source code', default: 'https://github.com/adaptlearning/adapt_framework.git' }, { name: 'frameworkRevision', - type: 'string', - description: 'Specific git revision to be used for the framework. Accepts any valid revision type (e.g. branch/tag/commit)', + type: 'input', + message: 'Specific git revision to be used for the framework. Accepts any valid revision type (e.g. branch/tag/commit)', default: 'tags/' + latestFrameworkTag } ], @@ -91,122 +93,122 @@ installHelpers.checkPrimaryDependencies(function(error) { dbConfig: [ { name: 'dbName', - type: 'string', - description: 'Master database name', - pattern: installHelpers.inputHelpers.alphanumValidator, + type: 'input', + message: 'Master database name', + validate: installHelpers.inputHelpers.alphanumValidator, default: 'adapt-tenant-master' }, { name: 'useConnectionUri', - type: 'string', - description: "Will you be using a full database connection URI? (all connection options in the URI) y/N", - before: installHelpers.inputHelpers.toBoolean, - default: 'N' + type: 'confirm', + message: 'Will you be using a full database connection URI? (all connection options in the URI)', + default: false } ], configureUri: [ { name: 'dbConnectionUri', - type: 'string', - description: 'Database connection URI', + type: 'input', + message: 'Database connection URI', default: '' } ], configureStandard: [ { name: 'dbHost', - type: 'string', - description: 'Database host', + type: 'input', + message: 'Database host', default: 'localhost' }, { name: 'dbPort', type: 'number', - description: 'Database server port', - pattern: installHelpers.inputHelpers.numberValidator, + message: 'Database server port', + validate: installHelpers.inputHelpers.numberValidator, default: 27017 }, { name: 'dbUser', - type: 'string', - description: 'Database server user (only specify if using database authentication)', - pattern: installHelpers.inputHelpers.alphanumValidator, + type: 'input', + message: 'Database server user (only specify if using database authentication)', + validate: installHelpers.inputHelpers.alphanumValidator, default: '' }, { name: 'dbPass', - type: 'string', - description: 'Database server password (only specify if using database authentication)', - pattern: installHelpers.inputHelpers.alphanumValidator, + type: 'password', + message: 'Database server password (only specify if using database authentication)', + mask: installHelpers.inputHelpers.passwordReplace, + validate: installHelpers.inputHelpers.alphanumValidator, default: '' }, { name: 'dbAuthSource', - type: 'string', - description: 'Database server authentication database (only specify if using database authentication)', - pattern: installHelpers.inputHelpers.alphanumValidator, + type: 'input', + message: 'Database server authentication database (only specify if using database authentication)', + validate: installHelpers.inputHelpers.alphanumValidator, default: '' }, ] }, features: { smtp: { - confirm: { - name: 'useSmtp', - type: 'string', - description: "Will you be using an SMTP server? (used for sending emails) y/N", - before: installHelpers.inputHelpers.toBoolean, - default: 'N' - }, - confirmConnectionUrl: { - name: 'useSmtpConnectionUrl', - type: 'string', - description: "Will you use a URL to connect to your smtp Server y/N", - before: installHelpers.inputHelpers.toBoolean, - default: 'N' - }, + confirm: [ + { + name: 'useSmtp', + type: 'confirm', + message: 'Will you be using an SMTP server? (used for sending emails)', + default: false + } + ], + confirmConnectionUrl: [ + { + name: 'useSmtpConnectionUrl', + type: 'confirm', + message: 'Will you use a URL to connect to your smtp Server', + default: false + } + ], configure: [ { name: 'fromAddress', - type: 'string', - description: "Sender email address", + type: 'input', + message: 'Sender email address', default: '', }, { name: 'rootUrl', - type: 'string', - description: "The url this install will be accessible from", + type: 'input', + message: 'The url this install will be accessible from', default: '' // set using default server options } ], configureService: [ { name: 'smtpService', - type: 'string', - description: "Which SMTP service (if any) will be used? (see https://github.com/andris9/nodemailer-wellknown#supported-services for a list of supported services.)", + type: 'input', + message: 'Which SMTP service (if any) will be used? (see https://github.com/andris9/nodemailer-wellknown#supported-services for a list of supported services.)', default: 'none', }, { name: 'smtpUsername', - type: 'string', - description: "SMTP username", + type: 'input', + message: 'SMTP username', default: '', }, { name: 'smtpPassword', - type: 'string', - description: "SMTP password", - hidden: true, - replace: installHelpers.inputHelpers.passwordReplace, - default: '', - before: installHelpers.inputHelpers.passwordBefore + type: 'password', + message: 'SMTP password', + mask: installHelpers.inputHelpers.passwordReplace, + default: '' } ], configureConnectionUrl: [ { name: 'smtpConnectionUrl', - type: 'string', - description: "Custom connection URL: smtps://user%40gmail.com:pass@smtp.gmail.com/?pool=true", + type: 'input', + message: 'Custom connection URL: smtps://user%40gmail.com:pass@smtp.gmail.com/?pool=true', default: 'none', } ] @@ -215,48 +217,44 @@ installHelpers.checkPrimaryDependencies(function(error) { tenant: [ { name: 'masterTenantName', - type: 'string', - description: "Set a unique name for your tenant", - pattern: installHelpers.inputHelpers.alphanumValidator, + type: 'input', + message: 'Set a unique name for your tenant', + validate: installHelpers.inputHelpers.alphanumValidator, default: 'master' }, { name: 'masterTenantDisplayName', - type: 'string', - description: 'Set the display name for your tenant', + type: 'input', + message: 'Set the display name for your tenant', default: 'Master' } ], tenantDelete: { - name: "confirm", - description: "Continue? (Y/n)", - before: installHelpers.inputHelpers.toBoolean, - default: "Y" + name: 'confirm', + type: 'confirm', + message: 'Continue?', + default: true }, superUser: [ { name: 'suEmail', - type: 'string', - description: "Email address", - required: true + type: 'input', + message: 'Email address', + validate: installHelpers.inputHelpers.requiredValidator }, { name: 'suPassword', - type: 'string', - description: "Password", - hidden: true, - replace: installHelpers.inputHelpers.passwordReplace, - required: true, - before: installHelpers.inputHelpers.passwordBefore + type: 'password', + message: 'Password', + mask: installHelpers.inputHelpers.passwordReplace, + validate: installHelpers.inputHelpers.requiredValidator }, { name: 'suRetypePassword', - type: 'string', - description: "Confirm Password", - hidden: true, - replace: installHelpers.inputHelpers.passwordReplace, - required: true, - before: installHelpers.inputHelpers.passwordBefore + type: 'password', + message: 'Confirm Password', + mask: installHelpers.inputHelpers.passwordReplace, + validate: installHelpers.inputHelpers.requiredValidator } ] }; @@ -272,7 +270,7 @@ installHelpers.checkPrimaryDependencies(function(error) { return start(); } console.log('Found an existing config.json file. Do you want to use the values in this file during install?'); - installHelpers.getInput(inputData.useConfigJSON, function(result) { + installHelpers.getInput(inputData.useConfigJSON, configOverrides, function(result) { console.log(''); USE_CONFIG = result.useJSON; start(); @@ -285,9 +283,9 @@ installHelpers.checkPrimaryDependencies(function(error) { function generatePromptOverrides() { if(USE_CONFIG) { var configJson = require('./conf/config.json'); - var configData = JSON.parse(JSON.stringify(configJson).replace(/:true/g, ':"y"').replace(/:false/g, ':"n"')); + var configData = JSON.parse(JSON.stringify(configJson)); addConfig(configData); - configData.install = 'y'; + configData.install = true; } const sessionSecret = USE_CONFIG && configData.sessionSecret || crypto.randomBytes(64).toString('hex'); addConfig({ sessionSecret: sessionSecret }); @@ -297,14 +295,14 @@ function generatePromptOverrides() { function start() { // set overrides from command line arguments and config.json - prompt.override = generatePromptOverrides(); + configOverrides = generatePromptOverrides(); // Prompt the user to begin the install if(!IS_INTERACTIVE || USE_CONFIG) { console.log('This script will install the application. Please wait ...'); } else { console.log('This script will install the application. \nWould you like to continue?'); } - installHelpers.getInput(inputData.startInstall, function(result) { + installHelpers.getInput(inputData.startInstall, configOverrides, function(result) { if(!result.install) { return handleError(null, 0, 'User cancelled the install'); } @@ -338,7 +336,7 @@ function configureServer(callback) { if(error) { return handleError(error, 1, 'Failed to get latest framework version'); } - installHelpers.getInput(inputData.server, function(result) { + installHelpers.getInput(inputData.server, configOverrides, function(result) { addConfig(result); callback(); }); @@ -346,13 +344,13 @@ function configureServer(callback) { } function configureDatabase(callback) { - installHelpers.getInput(inputData.database.dbConfig, function(result) { + installHelpers.getInput(inputData.database.dbConfig, configOverrides, function(result) { addConfig(result); var isStandard = !installHelpers.inputHelpers.toBoolean(result.useConnectionUri); var config = inputData.database[isStandard ? 'configureStandard' : 'configureUri']; - installHelpers.getInput(config, function(result) { + installHelpers.getInput(config, configOverrides, function(result) { addConfig(result); callback(); }); @@ -362,13 +360,13 @@ function configureDatabase(callback) { function configureFeatures(callback) { async.series([ function smtp(cb) { - installHelpers.getInput(inputData.features.smtp.confirm, function(result) { + installHelpers.getInput(inputData.features.smtp.confirm, configOverrides, function(result) { addConfig(result); if (!installHelpers.inputHelpers.toBoolean(result.useSmtp)) { return cb(); } // prompt user if custom connection url or well-known-service should be used - installHelpers.getInput(inputData.features.smtp.confirmConnectionUrl, function(result) { + installHelpers.getInput(inputData.features.smtp.confirmConnectionUrl, configOverrides, function(result) { addConfig(result); var smtpConfig; if (installHelpers.inputHelpers.toBoolean(result.useSmtpConnectionUrl)) { @@ -381,7 +379,7 @@ function configureFeatures(callback) { smtpConfig[i].default = `http://${configResults.serverName}:${configResults.serverPort}`; } } - installHelpers.getInput(smtpConfig, function(result) { + installHelpers.getInput(smtpConfig, configOverrides, function(result) { addConfig(result); cb(); }); @@ -408,14 +406,14 @@ function configureMasterTenant(callback) { app.run({ skipVersionCheck: true, skipDependencyCheck: true }); app.on('serverStarted', function() { - if(USE_CONFIG && prompt.override.masterTenantName) { + if(USE_CONFIG && configOverrides.masterTenantName) { /** * remove the masterTenantDisplayName, as we can use the existing value * (which isn't in config.json so can't be used as an auto override) */ inputData.tenant = inputData.tenant.filter(item => item.name !== 'masterTenantDisplayName'); } - installHelpers.getInput(inputData.tenant, function(result) { + installHelpers.getInput(inputData.tenant, configOverrides, function(result) { console.log(''); // add the input to our cached config addConfig({ @@ -439,7 +437,7 @@ function configureMasterTenant(callback) { configResults.masterTenant.displayName = tenant.displayName; } console.log(chalk.yellow(`Tenant '${tenant.name}' already exists. ${chalk.underline('It must be deleted for install to continue.')}`)); - installHelpers.getInput(inputData.tenantDelete, function(result) { + installHelpers.getInput(inputData.tenantDelete, configOverrides, function(result) { console.log(''); if(!result.confirm) { return exit(1, 'Exiting install.'); @@ -483,7 +481,7 @@ function createSuperUser(callback) { handleError(error, 1, 'Failed to create admin user account. Please check the console output.'); }; console.log(`\nNow we need to set up a 'Super Admin' account. This account can be used to manage everything on your authoring tool instance.`); - installHelpers.getInput(inputData.superUser, function(result) { + installHelpers.getInput(inputData.superUser, configOverrides, function(result) { console.log(''); app.usermanager.deleteUser({ email: result.suEmail }, function(error, userRec) { if(error) return onError(error); diff --git a/lib/installHelpers.js b/lib/installHelpers.js index abf8198e36..b1acd5d70f 100644 --- a/lib/installHelpers.js +++ b/lib/installHelpers.js @@ -5,11 +5,11 @@ var configuration = require('./configuration'); var database = require('./database'); var exec = require('child_process').exec; var fs = require('fs-extra'); +var inquirer = require('inquirer'); var logger = require('./logger'); var logUpdate = require('log-update'); var mailer = require('./mailer'); var path = require('path'); -var prompt = require('prompt'); var readline = require('readline'); var request = require('request'); var semver = require('semver'); @@ -27,21 +27,14 @@ var spinnerInt = -1; var inputHelpers = { passwordReplace: '*', - numberValidator: /^[0-9]+\W*$/, - alphanumValidator: /^[A-Za-z0-9_-]+\W*$/, + numberValidator: v => /^[0-9]*$/.test(v), + alphanumValidator: v => /^[\w-]*$/.test(v), + requiredValidator: v => v !== '', toBoolean: function(v) { if (typeof v === 'boolean') return v; if (/(Y|y)[es]*/.test(v)) return true; return false; }, - passwordBefore: function(v) { - /** - * HACK because read module used by prompt adds a blank line when - * hidden & replace attrs are set - */ - readline.moveCursor(process.stdout, 0, -1); - return v; - }, isFalsy: function(v) { if (typeof v !== 'string') return !v; switch (v.trim()) { @@ -121,17 +114,18 @@ function hideSpinner() { logUpdate.clear(); } -function getInput(items, callback) { - prompt.message = '> '; - prompt.delimiter = ''; - prompt.start(); - prompt.get(items, function(error, result) { - if(error) { - if(error.message === 'canceled') error = new Error('User cancelled the process'); - return exit(1, error); - } - callback(result); +function getInput(questions, overrides, callback) { + const prefilled = {}; + // only show question if no prefilled config + questions = questions.filter(({ name }) => { + const override = overrides[name]; + if (override === undefined) return true; + prefilled[name] = override; }); + if (!questions.length) { + return callback(prefilled); + } + inquirer.prompt(questions).then(answers => callback({ ...answers, ...prefilled })); } function checkAllDependencies(callback) { diff --git a/package-lock.json b/package-lock.json index 9e297911f3..e918bfc88e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,6 +81,11 @@ "@types/babel-types": "*" } }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -739,6 +744,11 @@ "is-regex": "^1.0.3" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "cheerio": { "version": "0.22.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", @@ -811,9 +821,9 @@ } }, "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" }, "cliui": { "version": "2.1.0", @@ -1173,11 +1183,6 @@ "array-find-index": "^1.0.1" } }, - "cycle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", - "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=" - }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -1227,11 +1232,6 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, - "deep-equal": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.2.2.tgz", - "integrity": "sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0=" - }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -1762,6 +1762,16 @@ } } }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -1831,11 +1841,6 @@ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, - "eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" - }, "fast-deep-equal": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", @@ -1910,12 +1915,11 @@ "integrity": "sha512-LZ1Sj4RHS95t/ReZtRbCmMEWDDl7cfIMwmhNgCZcdtOgRlAHaGGOupoc166Q9AV+T7lXnUvu5HYczcsn69c6fw==" }, "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "escape-string-regexp": "^1.0.5" } }, "file-sync-cmp": { @@ -2555,11 +2559,6 @@ "sshpk": "^1.7.0" } }, - "i": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz", - "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=" - }, "i18n": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.8.5.tgz", @@ -2627,91 +2626,144 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "requires": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.0.tgz", + "integrity": "sha512-K+LZp6L/6eE5swqIcVXrxl21aGDU4S50gKH0/d96OMQnSBCyGyZl/oZhbkVmdp5sBoINHd4xZvFSARh2dk6DWA==", + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", "through": "^2.3.6" }, "dependencies": { "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "requires": { + "type-fest": "^0.11.0" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } }, "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "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" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "requires": { - "restore-cursor": "^1.0.1" + "restore-cursor": "^3.1.0" } }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "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==", "requires": { - "number-is-nan": "^1.0.0" + "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==" + }, + "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==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "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==" + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "requires": { + "mimic-fn": "^2.1.0" + } }, "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" } }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^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==", + "requires": { + "ansi-regex": "^5.0.0" } }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } } } }, @@ -3571,6 +3623,41 @@ "yargs": "^4.8.1" }, "dependencies": { + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "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" + } + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "requires": { + "restore-cursor": "^1.0.1" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==" + }, "cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", @@ -3581,6 +3668,35 @@ "wrap-ansi": "^2.0.0" } }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "requires": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + } + }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -3589,6 +3705,28 @@ "number-is-nan": "^1.0.0" } }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "requires": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "requires": { + "once": "^1.3.0" + } + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -3599,6 +3737,11 @@ "strip-ansi": "^3.0.0" } }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, "window-size": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", @@ -4163,11 +4306,6 @@ "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=" }, - "ncp": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz", - "integrity": "sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=" - }, "needle": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", @@ -4434,6 +4572,11 @@ "lcid": "^1.0.0" } }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, "p-limit": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", @@ -4579,11 +4722,6 @@ "pinkie": "^2.0.0" } }, - "pkginfo": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz", - "integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=" - }, "plur": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", @@ -4650,52 +4788,6 @@ "asap": "~2.0.3" } }, - "prompt": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prompt/-/prompt-1.0.0.tgz", - "integrity": "sha1-jlcSPDlquYiJf7Mn/Trtw+c15P4=", - "requires": { - "colors": "^1.1.2", - "pkginfo": "0.x.x", - "read": "1.0.x", - "revalidator": "0.1.x", - "utile": "0.3.x", - "winston": "2.1.x" - }, - "dependencies": { - "async": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", - "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" - }, - "winston": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/winston/-/winston-2.1.1.tgz", - "integrity": "sha1-PJNJ0ZYgf9G9/51LxD73JRDjoS4=", - "requires": { - "async": "~1.0.0", - "colors": "1.0.x", - "cycle": "1.0.x", - "eyes": "0.1.x", - "isstream": "0.1.x", - "pkginfo": "0.3.x", - "stack-trace": "0.0.x" - }, - "dependencies": { - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" - }, - "pkginfo": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", - "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=" - } - } - } - } - }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -4861,14 +4953,6 @@ "unpipe": "1.0.0" } }, - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", - "requires": { - "mute-stream": "~0.0.4" - } - }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -5070,11 +5154,6 @@ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, - "revalidator": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz", - "integrity": "sha1-/s5hv6DBtSoga9axgZgYS91SOjs=" - }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -5092,18 +5171,23 @@ } }, "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "requires": { - "once": "^1.3.0" - } + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" }, "rx-lite": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=" }, + "rxjs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", + "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -5775,6 +5859,14 @@ "resolved": "https://registry.npmjs.org/titleize/-/titleize-2.1.0.tgz", "integrity": "sha512-m+apkYlfiQTKLW+sI4vqUkwMEzfgEUEYSqljx1voUE3Wz/z1ZsxyzSxvH2X8uKVrOp7QkByWt0rA6+gvhCKy6g==" }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -5860,6 +5952,11 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -6042,26 +6139,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "utile": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/utile/-/utile-0.3.0.tgz", - "integrity": "sha1-E1LDQOuCDk2N26A5pPv6oy7U7zo=", - "requires": { - "async": "~0.9.0", - "deep-equal": "~0.2.1", - "i": "0.3.x", - "mkdirp": "0.x.x", - "ncp": "1.0.x", - "rimraf": "2.x.x" - }, - "dependencies": { - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" - } - } - }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", diff --git a/package.json b/package.json index 85e0a4b47c..d65e5ec055 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "handlebars": "^4.4.0", "handlebars-form-helpers": "^0.1.4", "hbs": "^4.0.5", + "inquirer": "^7.3.0", "jshint-stylish": "^2.2.1", "json-schema-mapper": "0.0.2", "junk": "^3.1.0", @@ -69,7 +70,6 @@ "nodemailer": "^6.3.0", "optimist": "^0.6.1", "passport": "^0.4.0", - "prompt": "^1.0.0", "request": "^2.88.0", "semver": "^6.3.0", "serve-favicon": "^2.5.0", diff --git a/upgrade.js b/upgrade.js index d3d3eaec9d..5b635738a3 100644 --- a/upgrade.js +++ b/upgrade.js @@ -1,9 +1,9 @@ var _ = require('underscore'); var async = require('async'); +var { argv } = require('optimist'); var chalk = require('chalk'); var fs = require('fs-extra'); -var prompt = require('prompt'); -var optimist = require('optimist'); +var inquirer = require('inquirer'); var path = require('path'); var semver = require('semver'); var migrateMongoose = require('migrate-mongoose'); @@ -32,8 +32,6 @@ function start() { // don't show any logger messages in the console logger.level('console','error'); - prompt.override = optimist.argv; - // start the server first app.run({ skipVersionCheck: true, skipStartLog: true }); app.on('serverStarted', function() { @@ -56,45 +54,44 @@ function ensureRepoValues() { function getUserInput() { // properties for the prompts - var confirmProperties = { - name: 'continue', - description: 'Continue? Y/n', - type: 'string', - default: 'Y', - before: installHelpers.inputHelpers.toBoolean - }; - var upgradeProperties = { - properties: { - updateAutomatically: { - description: 'Update automatically? Y/n', - type: 'string', - default: 'Y', - before: installHelpers.inputHelpers.toBoolean - } + var confirmProperties = [ + { + name: 'continue', + message: 'Continue?', + type: 'confirm', + default: true } - }; - var tagProperties = { - properties: { - authoringToolGitTag: { - type: 'string', - description: 'Specific git revision to be used for the authoring tool. Accepts any valid revision type (e.g. branch/tag/commit)', - default: '' - }, - frameworkGitTag: { - type: 'string', - description: 'Specific git revision to be used for the framework. Accepts any valid revision type (e.g. branch/tag/commit)', - default: '' - } + ]; + var upgradeProperties = [ + { + name: 'updateAutomatically', + message: 'Update automatically?', + type: 'confirm', + default: true + } + ]; + var tagProperties = [ + { + name: 'authoringToolGitTag', + type: 'string', + message: 'Specific git revision to be used for the authoring tool. Accepts any valid revision type (e.g. branch/tag/commit)', + default: '' + }, + { + name: 'frameworkGitTag', + type: 'string', + message: 'Specific git revision to be used for the framework. Accepts any valid revision type (e.g. branch/tag/commit)', + default: '' } - }; + ]; if (IS_INTERACTIVE) { console.log(`\nThis script will update the ${app.polyglot.t('app.productname')} and/or Adapt Framework. Would you like to continue?`); } - installHelpers.getInput(confirmProperties, function(result) { + installHelpers.getInput(confirmProperties, argv, function(result) { if(!installHelpers.inputHelpers.toBoolean(result.continue)) { return installHelpers.exit(); } - installHelpers.getInput(upgradeProperties, function(result) { + installHelpers.getInput(upgradeProperties, argv, function(result) { console.log(''); if(installHelpers.inputHelpers.toBoolean(result.updateAutomatically)) { return checkForUpdates(function(error, updateData) { @@ -105,7 +102,7 @@ function getUserInput() { }); } // no automatic update, so get the intended versions - installHelpers.getInput(tagProperties, function(result) { + installHelpers.getInput(tagProperties, argv, function(result) { console.log(''); if(!result.authoringToolGitTag && !result.frameworkGitTag) { return installHelpers.exit(1, 'Cannot update sofware if no revisions are specified.'); From 29758b4301f28ac74daf337932d8435baa4f26a2 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Thu, 9 Jul 2020 12:54:20 +0100 Subject: [PATCH 06/28] Fix type --- upgrade.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/upgrade.js b/upgrade.js index 5b635738a3..297cd24468 100644 --- a/upgrade.js +++ b/upgrade.js @@ -73,13 +73,13 @@ function getUserInput() { var tagProperties = [ { name: 'authoringToolGitTag', - type: 'string', + type: 'input', message: 'Specific git revision to be used for the authoring tool. Accepts any valid revision type (e.g. branch/tag/commit)', default: '' }, { name: 'frameworkGitTag', - type: 'string', + type: 'input', message: 'Specific git revision to be used for the framework. Accepts any valid revision type (e.g. branch/tag/commit)', default: '' } From ab5af548e29194f8f12ac9b497ebdbe4aeb9a3eb Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Thu, 9 Jul 2020 15:42:16 +0100 Subject: [PATCH 07/28] Unset navigation inner div widths --- frontend/src/modules/navigation/less/navigation.less | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/modules/navigation/less/navigation.less b/frontend/src/modules/navigation/less/navigation.less index 4c7b3433b6..ce04056268 100644 --- a/frontend/src/modules/navigation/less/navigation.less +++ b/frontend/src/modules/navigation/less/navigation.less @@ -46,7 +46,6 @@ } .navigation-left { - width:50%; float:left; .navigation-product-name { .no-select; @@ -54,7 +53,6 @@ } .navigation-right { - width:47%; padding-right: 20px; float:right; text-align:right; From 3af017b3bac6ca4495607b3f8acac0d0167abc3b Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Fri, 10 Jul 2020 09:47:29 +0100 Subject: [PATCH 08/28] Improve tooltips Only show tooltip if help text; move key to title attribute; fix overflow --- frontend/src/modules/scaffold/less/forms.less | 16 +++------------- .../src/modules/scaffold/templates/field.hbs | 11 ++++------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/frontend/src/modules/scaffold/less/forms.less b/frontend/src/modules/scaffold/less/forms.less index 67a428408a..f9a8563ba5 100644 --- a/frontend/src/modules/scaffold/less/forms.less +++ b/frontend/src/modules/scaffold/less/forms.less @@ -53,6 +53,7 @@ form .error { } .field { + position: relative; padding: 10px 30px; &-object { padding: 8px 10px; @@ -84,32 +85,21 @@ form .error { } .field-help { - position: relative; display: inline-block; padding: 0 3px; .tooltip { position: absolute; z-index: 2; - top: 0; - left: 105%; + max-width: 300px; padding: 5px; border-radius: 6px; + margin: 10px 0; background-color: @tertiary-color; color: @white; opacity: 0; text-align: center; transition: opacity 0.3s, visibility 0s 0.3s; visibility: hidden; - .tooltip-key { - color: @primary-color; - font-family: monospace; - } - .tooltip-help { - width: 300px; - .scaffold-items-modal & { - width: 200px; - } - } } i:hover + .tooltip { opacity: 0.9; diff --git a/frontend/src/modules/scaffold/templates/field.hbs b/frontend/src/modules/scaffold/templates/field.hbs index d20eda2f8b..7426ccc727 100644 --- a/frontend/src/modules/scaffold/templates/field.hbs +++ b/frontend/src/modules/scaffold/templates/field.hbs @@ -1,15 +1,12 @@
{{#if title}} - + + {{#if help}}
-
-
{{key}}
- {{#if help}} -
{{help}}
- {{/if}} -
+
{{help}}
+ {{/if}} From bf2f74c2923de00f179644291b337f34464a9e96 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Fri, 10 Jul 2020 10:29:04 +0100 Subject: [PATCH 09/28] Fix question format --- install.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/install.js b/install.js index 72dd748f07..b49e3fcad3 100644 --- a/install.js +++ b/install.js @@ -229,12 +229,14 @@ installHelpers.checkPrimaryDependencies(function(error) { default: 'Master' } ], - tenantDelete: { - name: 'confirm', - type: 'confirm', - message: 'Continue?', - default: true - }, + tenantDelete: [ + { + name: 'confirm', + type: 'confirm', + message: 'Continue?', + default: true + } + ], superUser: [ { name: 'suEmail', From 6e61668a4dab8ddf4ccca256a0468ed0eae0632c Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Tue, 14 Jul 2020 11:26:02 +0100 Subject: [PATCH 10/28] Fix input width --- frontend/src/modules/scaffold/less/displayTitle.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/modules/scaffold/less/displayTitle.less b/frontend/src/modules/scaffold/less/displayTitle.less index b0f552748d..1b8709e2d1 100644 --- a/frontend/src/modules/scaffold/less/displayTitle.less +++ b/frontend/src/modules/scaffold/less/displayTitle.less @@ -4,7 +4,7 @@ display: none; } .field-editor input { - width: 81%; + width: calc(90% - 80px); } } From 7eda936f704c81aee3a5e98507a2238648712602 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Tue, 14 Jul 2020 11:27:25 +0100 Subject: [PATCH 11/28] Fix button state --- .../scaffold/views/scaffoldDisplayTitleView.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/frontend/src/modules/scaffold/views/scaffoldDisplayTitleView.js b/frontend/src/modules/scaffold/views/scaffoldDisplayTitleView.js index a0654f630e..4f2c30d626 100644 --- a/frontend/src/modules/scaffold/views/scaffoldDisplayTitleView.js +++ b/frontend/src/modules/scaffold/views/scaffoldDisplayTitleView.js @@ -6,7 +6,7 @@ define([ 'core/origin', 'backbone-forms' ], function(Origin, BackboneForms) { form: null, - isLocked: false, + isLocked: null, events: { 'change input': 'triggerChange', @@ -46,15 +46,16 @@ define([ 'core/origin', 'backbone-forms' ], function(Origin, BackboneForms) { render: function() { this.$el.append(Handlebars.templates[this.constructor.template]({ field: '' })); this.setValue(this.value); - - if (this.form.fields.title.editor.getValue() === this.getValue()) { - this.isLocked = true; - this.toggleLockButton(); - } + this.isLocked = this.form.fields.title.editor.getValue() === this.getValue(); + _.defer(this.postRender.bind(this)); return this; }, + postRender: function() { + this.toggleLockButton(); + }, + triggerChange: function() { this.trigger('change', this); }, From 3c034b5ff324ee646d87f25418bf071a728cce81 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Tue, 14 Jul 2020 14:53:52 +0100 Subject: [PATCH 12/28] Remove build includes after build --- lib/outputmanager.js | 15 ++++++++++++--- plugins/output/adapt/publish.js | 4 ++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/outputmanager.js b/lib/outputmanager.js index c879da9f94..3d0540ca89 100644 --- a/lib/outputmanager.js +++ b/lib/outputmanager.js @@ -266,9 +266,6 @@ OutputPlugin.prototype.sanitizeCourseJSON = function(mode, json, next) { async.waterfall([ function(callback) { - if (mode === Constants.Modes.Export) { - return callback(); - } self.generateIncludesForConfig(configJson, function(error, includes) { if (error) { return callback(error); @@ -926,6 +923,18 @@ OutputPlugin.prototype.applyMenu = function(tenantId, courseId, jsonObject, dest } }; +OutputPlugin.prototype.removeBuildIncludes = async (configPath, next) => { + try { + const config = await fs.readJson(configPath); + await fs.writeJson(configPath, config, { spaces: 2, replacer: (key, value) => { + if (key !== 'build') return value; + }}); + next(null); + } catch (err) { + next(err); + } +} + /** * extending plugins must implement this * diff --git a/plugins/output/adapt/publish.js b/plugins/output/adapt/publish.js index 57869cf860..f6fdfa3085 100644 --- a/plugins/output/adapt/publish.js +++ b/plugins/output/adapt/publish.js @@ -223,6 +223,10 @@ function publishCourse(courseId, mode, request, response, next) { callback(null); }); }, + function(callback) { + const configPath = path.join(BUILD_FOLDER, Constants.Folders.Course, Constants.CourseCollections.config.filename); + self.removeBuildIncludes(configPath, err => callback(err)); + }, function(callback) { if (mode === Constants.Modes.Preview) { // No download required -- skip this step return callback(); From 9d2ba060472140475a58a717b297173c530e7679 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Fri, 17 Jul 2020 10:05:00 +0100 Subject: [PATCH 13/28] Skip plugin update if no newer compatible release --- lib/bowermanager.js | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/lib/bowermanager.js b/lib/bowermanager.js index 2c39e65c27..676e3398fa 100644 --- a/lib/bowermanager.js +++ b/lib/bowermanager.js @@ -173,20 +173,41 @@ BowerManager.prototype.installLatestCompatibleVersion = function (pluginName, ca } var requiredFrameworkVersion; var index = -1; + var pluginType; async.doUntil(function iterator(cb) { bower.commands.info(bowerPackage.url + '#' + latestInfo.versions[++index]) .on('error', cb) .on('end', function (result) { requiredFrameworkVersion = result.framework; + pluginType = Object.keys(result).find(key => { + return [ 'component', 'extension', 'menu', 'theme' ].includes(key); + }); cb(); }); }, async function isCompatible() { return semver.satisfies(installedFrameworkVersion, requiredFrameworkVersion); - }, function(error, version) { + }, error => { if(error) { return callback(error); } - self.installPlugin(pluginName, latestInfo.versions[index], callback); + app.contentmanager.getContentPlugin(pluginType, (error, plugin) => { + if (error) { + return callback(error); + } + app.db.retrieve(plugin.getPluginType(), { + name: pluginName + }, (error, results) => { + if (error) { + return callback(error); + } + var installedPlugin = results[0]; + var version = latestInfo.versions[index]; + if (installedPlugin && semver.gte(installedPlugin.version, version)) { + return callback('Skipping as no newer compatible version found'); + } + self.installPlugin(pluginName, version, callback); + }); + }); }); }); }); @@ -285,12 +306,12 @@ BowerManager.prototype.importPackage = function (plugin, packageInfo, options, c } if (results && results.length !== 0) { - // Don't add a duplicate. - if (options.strict) { - return callback("Can't add " + pluginString + ": verion already exists"); - } + // Don't add a duplicate. + if (options.strict) { + return callback("Can't add " + pluginString + ": verion already exists"); + } - return callback(null); + return callback(null); } // Add the new plugin. From ebc1b8bcf5a5eb87a906b48f8b4c550ef04375fb Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Fri, 17 Jul 2020 10:37:23 +0100 Subject: [PATCH 14/28] Permit plugin downgrade if framework downgrade --- lib/bowermanager.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/bowermanager.js b/lib/bowermanager.js index 676e3398fa..322d23a9a7 100644 --- a/lib/bowermanager.js +++ b/lib/bowermanager.js @@ -202,12 +202,14 @@ BowerManager.prototype.installLatestCompatibleVersion = function (pluginName, ca } var installedPlugin = results[0]; var version = latestInfo.versions[index]; - if (installedPlugin && semver.gte(installedPlugin.version, version)) { + if (installedPlugin && + semver.gte(installedPlugin.version, version) && + semver.satisfies(installedFrameworkVersion, installedPlugin.framework)) { return callback('Skipping as no newer compatible version found'); } self.installPlugin(pluginName, version, callback); }); - }); + }); }); }); }); From e42342b5ffeee3bbe4e3fefbc56b1b52731359e4 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Fri, 17 Jul 2020 10:56:21 +0100 Subject: [PATCH 15/28] Persist plugin management settings during update --- lib/bowermanager.js | 12 +++++++++++- plugins/content/bower/index.js | 5 ++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/bowermanager.js b/lib/bowermanager.js index 322d23a9a7..fd9f340624 100644 --- a/lib/bowermanager.js +++ b/lib/bowermanager.js @@ -301,19 +301,29 @@ BowerManager.prototype.importPackage = function (plugin, packageInfo, options, c // Add the package to the collection. // Check if a plugin with this name and version already exists. - db.retrieve(plugin.getPluginType(), { name: package.name, version: package.version }, function (err, results) { + db.retrieve(plugin.getPluginType(), { + name: package.name + }, function (err, results) { if (err) { logger.log('error', err); return callback(err); } if (results && results.length !== 0) { + var installedPlugin = results[0]; + + if (installedPlugin.version === package.version) { // Don't add a duplicate. if (options.strict) { return callback("Can't add " + pluginString + ": verion already exists"); } return callback(null); + } + + var keysToPersist = [ '_isAvailableInEditor', '_isAddedByDefault' ]; + + keysToPersist.forEach(key => package[key] = installedPlugin[key]); } // Add the new plugin. diff --git a/plugins/content/bower/index.js b/plugins/content/bower/index.js index 40eb478637..48fda18443 100644 --- a/plugins/content/bower/index.js +++ b/plugins/content/bower/index.js @@ -879,7 +879,10 @@ function addPackage (plugin, packageInfo, options, cb) { }); // Persist the _isAvailableInEditor flag. - db.update(plugin.type, {_id: newPlugin._id}, {_isAvailableInEditor: oldPlugin._isAvailableInEditor}, function(err, results) { + db.update(plugin.type, {_id: newPlugin._id}, { + _isAvailableInEditor: oldPlugin._isAvailableInEditor, + _isAddedByDefault: oldPlugin._isAddedByDefault + }, function(err, results) { if (err) { logger.log('error', err); return addCb(err); From 410a091da0d5e89088540401d8c641f270797662 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Fri, 17 Jul 2020 11:04:36 +0100 Subject: [PATCH 16/28] Fix indentation --- lib/bowermanager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bowermanager.js b/lib/bowermanager.js index fd9f340624..3da95de5bf 100644 --- a/lib/bowermanager.js +++ b/lib/bowermanager.js @@ -209,7 +209,7 @@ BowerManager.prototype.installLatestCompatibleVersion = function (pluginName, ca } self.installPlugin(pluginName, version, callback); }); - }); + }); }); }); }); From 9a67448119505b8d503dd9b0531e47b34b645c35 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Fri, 17 Jul 2020 14:52:32 +0100 Subject: [PATCH 17/28] Add configurable support fields --- frontend/src/core/helpers.js | 5 +++++ frontend/src/modules/help/index.js | 7 ++++++- frontend/src/modules/user/templates/forgotPassword.hbs | 9 ++++++++- lib/configuration.js | 4 +++- routes/lang/en.json | 3 ++- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/frontend/src/core/helpers.js b/frontend/src/core/helpers.js index 032d33e839..a112193e22 100644 --- a/frontend/src/core/helpers.js +++ b/frontend/src/core/helpers.js @@ -326,6 +326,11 @@ define(function(require){ } } return flatProperties; + }, + + importConstants: function() { + this.constants = Origin.constants; + return ''; } }; diff --git a/frontend/src/modules/help/index.js b/frontend/src/modules/help/index.js index 0c3ff4b3d1..4c8b464977 100644 --- a/frontend/src/modules/help/index.js +++ b/frontend/src/modules/help/index.js @@ -2,7 +2,12 @@ define(function(require) { var Origin = require('core/origin'); Origin.on('navigation:help', function() { - openWikiLink(getLink()); + var override = Origin.constants.supportLink; + if (override) { + window.open(override); + } else { + openWikiLink(getLink()); + } }); function getLink() { diff --git a/frontend/src/modules/user/templates/forgotPassword.hbs b/frontend/src/modules/user/templates/forgotPassword.hbs index 5c72b1d44b..af9be88d57 100644 --- a/frontend/src/modules/user/templates/forgotPassword.hbs +++ b/frontend/src/modules/user/templates/forgotPassword.hbs @@ -1,3 +1,5 @@ +{{importConstants}} + @@ -24,6 +26,11 @@
diff --git a/lib/configuration.js b/lib/configuration.js index d04162486e..c4554b1258 100644 --- a/lib/configuration.js +++ b/lib/configuration.js @@ -34,7 +34,9 @@ var ALLOWED_CLIENT_SIDE_KEYS = [ 'maxLoginAttempts', 'ckEditorExtraAllowedContent', 'ckEditorEnterMode', - 'maxFileUploadSize' + 'maxFileUploadSize', + 'supportLink', + 'supportContact' ]; /** diff --git a/routes/lang/en.json b/routes/lang/en.json index 1a25d0706b..98a0f2ebeb 100644 --- a/routes/lang/en.json +++ b/routes/lang/en.json @@ -133,7 +133,8 @@ "app.confirmpassword": "Confirm password", "app.passwordtip": "Enter a new password below. The most secure passwords have a mix of numbers, letters (including capitals) and other characters.", "app.forgotpasswordblurb": "Enter the email address associated with your Adapt account, then click Continue.", - "app.forgotpasswordfooter": "Contact Support for help with restoring access to your account.", + "app.forgotpasswordfooter": "Contact %{supportContact} for help with restoring access to your account.", + "app.vendor": "your authoring tool vendor", "app.hasyouremailchanged": "Has your email address changed?", "app.forgotpasswordsuccess": "Your request is being processed. If the details you provided match our records, you will receive further instructions via email.", "app.returnto": "Return to", From ee3c13097e8839622e4fbc95b3b48c57969ec9dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 19 Jul 2020 16:02:27 +0000 Subject: [PATCH 18/28] Bump lodash from 4.17.15 to 4.17.19 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19) Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index aab5e7c0ce..5bdd851b29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3190,9 +3190,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, "lodash.assign": { "version": "4.2.0", From 50e4a522eae4dc30ea4d6bfb2d822e4e41b5a4b9 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Mon, 20 Jul 2020 09:50:36 +0100 Subject: [PATCH 19/28] Use an adminstrator as default contact --- frontend/src/modules/user/templates/forgotPassword.hbs | 2 +- routes/lang/en.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/modules/user/templates/forgotPassword.hbs b/frontend/src/modules/user/templates/forgotPassword.hbs index af9be88d57..ee5ee90504 100644 --- a/frontend/src/modules/user/templates/forgotPassword.hbs +++ b/frontend/src/modules/user/templates/forgotPassword.hbs @@ -30,7 +30,7 @@ {{#if constants.supportContact}} {{t 'app.forgotpasswordfooter' supportContact=constants.supportContact}} {{else}} - {{t 'app.forgotpasswordfooter' supportContact=(t 'app.vendor')}} + {{t 'app.forgotpasswordfooter' supportContact=(t 'app.anadmin')}} {{/if}} diff --git a/routes/lang/en.json b/routes/lang/en.json index 98a0f2ebeb..c2c7c81155 100644 --- a/routes/lang/en.json +++ b/routes/lang/en.json @@ -134,7 +134,7 @@ "app.passwordtip": "Enter a new password below. The most secure passwords have a mix of numbers, letters (including capitals) and other characters.", "app.forgotpasswordblurb": "Enter the email address associated with your Adapt account, then click Continue.", "app.forgotpasswordfooter": "Contact %{supportContact} for help with restoring access to your account.", - "app.vendor": "your authoring tool vendor", + "app.anadmin": "an administrator", "app.hasyouremailchanged": "Has your email address changed?", "app.forgotpasswordsuccess": "Your request is being processed. If the details you provided match our records, you will receive further instructions via email.", "app.returnto": "Return to", From 05733605ab8715008283bd32e095bd0c0d67c0d1 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Tue, 28 Jul 2020 12:06:37 +0100 Subject: [PATCH 20/28] Preserve sort order integers on pasted children --- plugins/content/contentobject/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/content/contentobject/index.js b/plugins/content/contentobject/index.js index 5b722c9e23..78f564fee2 100644 --- a/plugins/content/contentobject/index.js +++ b/plugins/content/contentobject/index.js @@ -146,6 +146,10 @@ ContentObject.prototype.create = function (data, next) { logger.log('error', 'Error creating ContentObject!', error); return next(error); } + // preserve sort order integers on pasted children + if (Number.isInteger(data._sortOrder)) { + return next(null, doc); + } self.updateSiblingSortOrder(doc, next); }); }; From 9d14781966ed80fb5f7b74b61e8972e7ff7bd727 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Wed, 29 Jul 2020 14:52:34 +0100 Subject: [PATCH 21/28] Fix paste zone sort order --- .../src/modules/editor/contentObject/views/editorPageView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/modules/editor/contentObject/views/editorPageView.js b/frontend/src/modules/editor/contentObject/views/editorPageView.js index 27148d33f0..96082be191 100644 --- a/frontend/src/modules/editor/contentObject/views/editorPageView.js +++ b/frontend/src/modules/editor/contentObject/views/editorPageView.js @@ -109,7 +109,7 @@ define(function(require){ $.scrollTo(newArticleView.$el, 200); } // Increment the 'sortOrder' property - articleModel.set('_pasteZoneSortOrder', sortOrder++); + articleModel.set('_pasteZoneSortOrder', sortOrder + 1); // Post-article paste zone - sort order of placeholder will be one greater this.$('.page-articles').append(new EditorPasteZoneView({ model: articleModel }).$el); return newArticleView; From 5ce1875de16759162fccbcc985d2461c01f519b4 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Wed, 29 Jul 2020 14:54:57 +0100 Subject: [PATCH 22/28] Re-render on paste to refresh paste zones --- .../contentObject/views/editorPageArticleView.js | 16 +--------------- .../editor/contentObject/views/editorPageView.js | 16 +--------------- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/frontend/src/modules/editor/contentObject/views/editorPageArticleView.js b/frontend/src/modules/editor/contentObject/views/editorPageArticleView.js index c80f6a2913..8e00742a5c 100644 --- a/frontend/src/modules/editor/contentObject/views/editorPageArticleView.js +++ b/frontend/src/modules/editor/contentObject/views/editorPageArticleView.js @@ -48,7 +48,7 @@ define(function(require){ var events = {}; events['editorView:moveBlock:' + id] = this.render; events['editorView:deleteArticle:' + id] = this.deletePageArticle; - events['editorView:pasted:' + id] = this.onPaste; + events['editorView:pasted:' + id] = this.render; this.listenTo(Origin, events); } @@ -282,20 +282,6 @@ define(function(require){ duration = 0; } this.$('.article-content').velocity(shouldCollapse ? 'slideUp' : 'slideDown', duration); - }, - - onPaste: function(data) { - (new BlockModel({ _id: data._id })).fetch({ - success: _.bind(function(model) { - this.addBlockView(model); - }, this), - error: function(data) { - Origin.Notify.alert({ - type: 'error', - text: 'app.errorfetchingdata' - }); - } - }); } }, { diff --git a/frontend/src/modules/editor/contentObject/views/editorPageView.js b/frontend/src/modules/editor/contentObject/views/editorPageView.js index 96082be191..2dc4478271 100644 --- a/frontend/src/modules/editor/contentObject/views/editorPageView.js +++ b/frontend/src/modules/editor/contentObject/views/editorPageView.js @@ -27,7 +27,7 @@ define(function(require){ 'pageView:itemAnimated': this.evaluateChildStatus }; originEvents['editorView:moveArticle:' + id] = this.render; - originEvents['editorView:pasted:' + id] = this.onPaste; + originEvents['editorView:pasted:' + id] = this.render; this.listenTo(Origin, originEvents); Origin.options.addItems([ @@ -159,20 +159,6 @@ define(function(require){ Origin.trigger('contextMenu:open', fakeView, event); }, - onPaste: function(data) { - (new ArticleModel({ _id: data._id })).fetch({ - success: _.bind(function(model) { - this.addArticleView(model); - }, this), - error: function(data) { - Origin.Notify.alert({ - type: 'error', - text: 'app.errorfetchingdata' - }); - } - }); - }, - onCutArticle: function(view) { this.once('pageView:postRender', view.showPasteZones); this.render(); From dcabdc405d9e829242e7aad5957b71fa5b47d550 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Thu, 6 Aug 2020 11:38:41 +0100 Subject: [PATCH 23/28] Switch to ContentManager.create --- plugins/output/adapt/importsource.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/plugins/output/adapt/importsource.js b/plugins/output/adapt/importsource.js index 3c04022da3..fabb2e43e4 100644 --- a/plugins/output/adapt/importsource.js +++ b/plugins/output/adapt/importsource.js @@ -372,7 +372,7 @@ function ImportSource(req, done) { delete data._latestTrackingId; data.createdBy = app.usermanager.getCurrentUser()._id; if(type !== 'course') { - data._courseId = courseId; + data._courseId = courseId.toString(); } if(data._component) { data._componentType = metadata.componentMap[data._component]._id; @@ -482,15 +482,12 @@ function ImportSource(req, done) { if (detachedElementsMap[originalData._id]) { // do not import detached elements return done(); } // now we're ready to create the content - app.contentmanager.getContentPlugin(type, function(error, plugin) { - if(error) return done(error); - plugin.create(data, function(error, record) { - if(error) { - logger.log('warn', 'Failed to import ' + type + ' ' + (originalData._id || '') + ' ' + error); - return done(); - } // Create a courseAssets record if needed - createCourseAssets(type, record, error => done(error, record)); - }); + app.contentmanager.create(type, data, function(error, record) { + if(error) { + logger.log('warn', 'Failed to import ' + type + ' ' + (originalData._id || '') + ' ' + error); + return done(); + } // Create a courseAssets record if needed + createCourseAssets(type, record, error => done(error, record)); }); }); } From b57edf0f6128af495beece46206517293a34167c Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Thu, 6 Aug 2020 11:49:52 +0100 Subject: [PATCH 24/28] Populate default globals on import --- plugins/output/adapt/importsource.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/plugins/output/adapt/importsource.js b/plugins/output/adapt/importsource.js index fabb2e43e4..92b3f2f693 100644 --- a/plugins/output/adapt/importsource.js +++ b/plugins/output/adapt/importsource.js @@ -11,6 +11,7 @@ const helpers = require('./outputHelpers'); const logger = require("../../../lib/logger"); const mime = require('mime'); const path = require("path"); +const { promisify } = require('util'); function ImportSource(req, done) { var dbInstance; @@ -340,6 +341,30 @@ function ImportSource(req, done) { }, cb2); }, cb); }, + async function populateGlobals() { + const dbRetrieve = promisify(dbInstance.retrieve.bind(dbInstance)); + const dbUpdate = promisify(dbInstance.update.bind(dbInstance)); + const courseQuery = await dbRetrieve('course', { _id: courseId }); + const courseGlobals = courseQuery[0]._doc._globals || {}; + await Promise.all(plugindata.pluginIncludes.map(async ({ type, name }) => { + const pluginQuery = await dbRetrieve(`${type}type`, { name }); + const plugin = pluginQuery[0]._doc; + const pluginGlobals = plugin.globals; + if (!pluginGlobals) return; + const typeKey = type === 'component' || type === 'extension' ? + `_${type}s` : + `_${type}`; + const pluginKey = `_${plugin[type]}`; + if (!courseGlobals[typeKey]) { + courseGlobals[typeKey] = {}; + } + Object.entries(pluginGlobals).forEach(([key, value]) => { + pluginGlobals[key] = value.default; + }); + courseGlobals[typeKey][pluginKey] = _.defaults(courseGlobals[typeKey][pluginKey], pluginGlobals); + })); + await dbUpdate('course', { _id: courseId }, { _globals: courseGlobals }); + }, function checkDetachedContent(cb) { const detachedIds = Object.keys(detachedElementsMap); if (detachedIds.length === 0) return cb(); From e6fcf8ec657d8d2d026e4f7ba9666cb572b19232 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Mon, 10 Aug 2020 12:54:42 +0100 Subject: [PATCH 25/28] Tweak for clarity --- plugins/output/adapt/importsource.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/output/adapt/importsource.js b/plugins/output/adapt/importsource.js index 92b3f2f693..b74665def9 100644 --- a/plugins/output/adapt/importsource.js +++ b/plugins/output/adapt/importsource.js @@ -349,8 +349,9 @@ function ImportSource(req, done) { await Promise.all(plugindata.pluginIncludes.map(async ({ type, name }) => { const pluginQuery = await dbRetrieve(`${type}type`, { name }); const plugin = pluginQuery[0]._doc; - const pluginGlobals = plugin.globals; - if (!pluginGlobals) return; + const schemaGlobals = plugin.globals; + if (!schemaGlobals) return; + const schemaDefaults = {}; const typeKey = type === 'component' || type === 'extension' ? `_${type}s` : `_${type}`; @@ -358,10 +359,10 @@ function ImportSource(req, done) { if (!courseGlobals[typeKey]) { courseGlobals[typeKey] = {}; } - Object.entries(pluginGlobals).forEach(([key, value]) => { - pluginGlobals[key] = value.default; + Object.entries(schemaGlobals).forEach(([ key, value ]) => { + schemaDefaults[key] = value.default; }); - courseGlobals[typeKey][pluginKey] = _.defaults(courseGlobals[typeKey][pluginKey], pluginGlobals); + courseGlobals[typeKey][pluginKey] = _.defaults(courseGlobals[typeKey][pluginKey], schemaDefaults); })); await dbUpdate('course', { _id: courseId }, { _globals: courseGlobals }); }, From ca53f3693fa1e12571a1e6ebd5a598dd39677d42 Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Wed, 12 Aug 2020 11:39:36 +0100 Subject: [PATCH 26/28] Revert to manual ContentPlugin.create without hooks --- plugins/output/adapt/importsource.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/plugins/output/adapt/importsource.js b/plugins/output/adapt/importsource.js index b74665def9..c579bccb90 100644 --- a/plugins/output/adapt/importsource.js +++ b/plugins/output/adapt/importsource.js @@ -398,7 +398,7 @@ function ImportSource(req, done) { delete data._latestTrackingId; data.createdBy = app.usermanager.getCurrentUser()._id; if(type !== 'course') { - data._courseId = courseId.toString(); + data._courseId = courseId; } if(data._component) { data._componentType = metadata.componentMap[data._component]._id; @@ -508,12 +508,15 @@ function ImportSource(req, done) { if (detachedElementsMap[originalData._id]) { // do not import detached elements return done(); } // now we're ready to create the content - app.contentmanager.create(type, data, function(error, record) { - if(error) { - logger.log('warn', 'Failed to import ' + type + ' ' + (originalData._id || '') + ' ' + error); - return done(); - } // Create a courseAssets record if needed - createCourseAssets(type, record, error => done(error, record)); + app.contentmanager.getContentPlugin(type, function(error, plugin) { + if(error) return done(error); + plugin.create(data, function(error, record) { + if(error) { + logger.log('warn', 'Failed to import ' + type + ' ' + (originalData._id || '') + ' ' + error); + return done(); + } // Create a courseAssets record if needed + createCourseAssets(type, record, error => done(error, record)); + }); }); }); } From 86dc58b3701067ad41ef2bef41c21c4e103069dc Mon Sep 17 00:00:00 2001 From: Dan Gray Date: Thu, 13 Aug 2020 14:55:48 +0100 Subject: [PATCH 27/28] Check if course on clone item, fixes #2534 --- frontend/src/modules/scaffold/views/scaffoldListView.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/modules/scaffold/views/scaffoldListView.js b/frontend/src/modules/scaffold/views/scaffoldListView.js index 7e3909d658..16d65584c1 100644 --- a/frontend/src/modules/scaffold/views/scaffoldListView.js +++ b/frontend/src/modules/scaffold/views/scaffoldListView.js @@ -97,6 +97,7 @@ define([ var flatItem = Helpers.flattenNestedProperties(this.editor.value); var itemValues = _.values(flatItem); var parentAttributes = Origin.scaffold.getCurrentModel().attributes; + var parentId = parentAttributes._type === 'course' ? parentAttributes._id : parentAttributes._parentId; itemValues.forEach(function(item) { if (typeof item !== 'string' || item.indexOf('course/assets') === -1) return; @@ -112,7 +113,7 @@ define([ _contentTypeId : parentAttributes._id, _fieldName : itemFileName, _assetId : result[0]._id, - _contentTypeParentId: parentAttributes._parentId + _contentTypeParentId: parentId }, { error: function(error) { Origin.Notify.alert({ From 6f3e06056e70d596a9e20ca7168e19f614aeb61c Mon Sep 17 00:00:00 2001 From: Tom Greenfield Date: Tue, 18 Aug 2020 10:55:01 +0100 Subject: [PATCH 28/28] Prep for release --- CHANGELOG.md | 25 +++++++++++++++++++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf4f72e381..20890b9d75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,30 @@ All notable changes to the Adapt authoring tool are documented in this file. **IMPORTANT**: For information on how to **correctly and safely** update your installation, please consult **INSTALL.md**.
_Note that we adhere to the [semantic versioning](http://semver.org/) scheme for release numbering._ +## [0.10.4] - 2020-08-21 + +Bugfix release. + +### Fixed +- Copied articles sometimes get pasted into the wrong place ([#1892](https://github.com/adaptlearning/adapt_authoring/issues/1892)) +- Install breaks if any config values contain true/false ([#2133](https://github.com/adaptlearning/adapt_authoring/issues/2133)) +- Upgrade script replaces all core-bundled plugins ([#2316](https://github.com/adaptlearning/adapt_authoring/issues/2316)) +- Copied and pasted pages have out of order articles ([#2404](https://github.com/adaptlearning/adapt_authoring/issues/2404)) +- Tooltip overflow in sidebar 'modal' ([#2414](https://github.com/adaptlearning/adapt_authoring/issues/2414)) +- Error: Failed to determine user's tenant! ([#2504](https://github.com/adaptlearning/adapt_authoring/issues/2504)) +- Export fails as it requires LESS variables for plugins that aren't in the project ([#2510](https://github.com/adaptlearning/adapt_authoring/issues/2510)) +- Top navigation obscures save button on small window sizes ([#2511](https://github.com/adaptlearning/adapt_authoring/issues/2511)) +- Support Node 14 ([#2514](https://github.com/adaptlearning/adapt_authoring/issues/2514)) +- Reset not working ([#2518](https://github.com/adaptlearning/adapt_authoring/issues/2518)) +- Wrong state for display title icon ([#2523](https://github.com/adaptlearning/adapt_authoring/issues/2523)) +- Get 500 error when copying items with assets in Project Settings. Can also break courseassets in other items. ([#2534](https://github.com/adaptlearning/adapt_authoring/issues/2534)) +- default FW -> AT import issues - PLP settings ([adaptlearning/adapt_framework#2841](https://github.com/adaptlearning/adapt_framework/issues/2841)) + +### Added +- Option to customise the 'contact support' message with details of who to contact ([#2477](https://github.com/adaptlearning/adapt_authoring/issues/2477)) +- Remove 'field-help' icon if there isn't any 'help' text ([#2509](https://github.com/adaptlearning/adapt_authoring/issues/2509)) +- Customise help link ([#2527](https://github.com/adaptlearning/adapt_authoring/issues/2527)) + ## [0.10.3] - 2020-02-21 Bugfix release. @@ -687,6 +711,7 @@ Initial release. - Loading screen of death - Session cookie security issues +[0.10.4]: https://github.com/adaptlearning/adapt_authoring/compare/v0.10.3...v0.10.4 [0.10.3]: https://github.com/adaptlearning/adapt_authoring/compare/v0.10.2...v0.10.3 [0.10.2]: https://github.com/adaptlearning/adapt_authoring/compare/v0.10.1...v0.10.2 [0.10.1]: https://github.com/adaptlearning/adapt_authoring/compare/v0.10.0...v0.10.1 diff --git a/package-lock.json b/package-lock.json index 453076ec30..0d0c9e683e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "adapt_authoring", - "version": "0.10.3", + "version": "0.10.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d65e5ec055..f5dc2a0df2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "adapt_authoring", - "version": "0.10.3", + "version": "0.10.4", "license": "GPL-3.0", "description": "A server-based user interface for authoring eLearning courses using the Adapt Framework.", "keywords": [