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/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/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);
}
});
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 27148d33f0..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([
@@ -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;
@@ -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();
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/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;
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);
}
}
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}}
+ {{/if}}
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);
},
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({
diff --git a/frontend/src/modules/user/templates/forgotPassword.hbs b/frontend/src/modules/user/templates/forgotPassword.hbs
index 5c72b1d44b..ee5ee90504 100644
--- a/frontend/src/modules/user/templates/forgotPassword.hbs
+++ b/frontend/src/modules/user/templates/forgotPassword.hbs
@@ -1,3 +1,5 @@
+{{importConstants}}
+
{{t 'app.resetpassword'}}
@@ -24,6 +26,11 @@
diff --git a/install.js b/install.js
index 25e3543f97..b49e3fcad3 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,46 @@ 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"
- },
+ tenantDelete: [
+ {
+ 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 +272,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 +285,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 +297,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 +338,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 +346,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 +362,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 +381,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 +408,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 +439,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 +483,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/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/lib/bowermanager.js b/lib/bowermanager.js
index 2c39e65c27..3da95de5bf 100644
--- a/lib/bowermanager.js
+++ b/lib/bowermanager.js
@@ -173,20 +173,43 @@ 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) &&
+ semver.satisfies(installedFrameworkVersion, installedPlugin.framework)) {
+ return callback('Skipping as no newer compatible version found');
+ }
+ self.installPlugin(pluginName, version, callback);
+ });
+ });
});
});
});
@@ -278,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) {
- // Don't add a duplicate.
- if (options.strict) {
- return callback("Can't add " + pluginString + ": verion already exists");
+ 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);
}
- return callback(null);
+ var keysToPersist = [ '_isAvailableInEditor', '_isAddedByDefault' ];
+
+ keysToPersist.forEach(key => package[key] = installedPlugin[key]);
}
// Add the new plugin.
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/lib/installHelpers.js b/lib/installHelpers.js
index 77e4339416..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) {
@@ -185,11 +179,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/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/package-lock.json b/package-lock.json
index aab5e7c0ce..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": {
@@ -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",
@@ -185,10 +190,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 +590,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",
@@ -738,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",
@@ -810,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",
@@ -1005,11 +1016,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"
}
},
@@ -1172,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",
@@ -1226,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",
@@ -1761,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",
@@ -1830,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",
@@ -1909,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": {
@@ -2554,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",
@@ -2626,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"
+ }
}
}
},
@@ -3190,9 +3243,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",
@@ -3209,6 +3262,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",
@@ -3565,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",
@@ -3575,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",
@@ -3583,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",
@@ -3593,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",
@@ -3923,12 +4072,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",
@@ -3966,15 +4115,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 +4132,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"
+ }
}
}
},
@@ -4127,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",
@@ -4398,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",
@@ -4543,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",
@@ -4614,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",
@@ -4825,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",
@@ -5034,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",
@@ -5056,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",
@@ -5739,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",
@@ -5824,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",
@@ -6006,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 d2f7e32d99..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": [
@@ -13,7 +13,7 @@
},
"main": "index",
"engines": {
- "node": "10 || 12"
+ "node": "12 || 14"
},
"scripts": {
"test": "grunt test",
@@ -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",
@@ -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",
@@ -61,7 +62,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",
@@ -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",
@@ -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"
}
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);
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);
});
};
diff --git a/plugins/output/adapt/importsource.js b/plugins/output/adapt/importsource.js
index 3c04022da3..c579bccb90 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,31 @@ 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 schemaGlobals = plugin.globals;
+ if (!schemaGlobals) return;
+ const schemaDefaults = {};
+ const typeKey = type === 'component' || type === 'extension' ?
+ `_${type}s` :
+ `_${type}`;
+ const pluginKey = `_${plugin[type]}`;
+ if (!courseGlobals[typeKey]) {
+ courseGlobals[typeKey] = {};
+ }
+ Object.entries(schemaGlobals).forEach(([ key, value ]) => {
+ schemaDefaults[key] = value.default;
+ });
+ courseGlobals[typeKey][pluginKey] = _.defaults(courseGlobals[typeKey][pluginKey], schemaDefaults);
+ }));
+ await dbUpdate('course', { _id: courseId }, { _globals: courseGlobals });
+ },
function checkDetachedContent(cb) {
const detachedIds = Object.keys(detachedElementsMap);
if (detachedIds.length === 0) return cb();
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();
diff --git a/routes/lang/en.json b/routes/lang/en.json
index 1a25d0706b..c2c7c81155 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.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",
diff --git a/upgrade.js b/upgrade.js
index d3d3eaec9d..297cd24468 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: '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: 'input',
+ 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.');