replace usage of _.extend with Object.assign

This commit is contained in:
Girish Ramakrishnan
2023-05-25 11:27:23 +02:00
parent 79dd50910c
commit e6ba2a6e7a
15 changed files with 62 additions and 71 deletions
+2 -3
View File
@@ -21,8 +21,7 @@ const assert = require('assert'),
promiseRetry = require('./promise-retry.js'),
superagent = require('superagent'),
safe = require('safetydance'),
users = require('./users.js'),
_ = require('underscore');
users = require('./users.js');
const CA_PROD_DIRECTORY_URL = 'https://acme-v02.api.letsencrypt.org/directory',
CA_STAGING_DIRECTORY_URL = 'https://acme-staging-v02.api.letsencrypt.org/directory';
@@ -114,7 +113,7 @@ Acme2.prototype.sendSignedRequest = async function (url, payload) {
debug(`sendSignedRequest: using nonce ${nonce} for url ${url}`);
const protected64 = b64(JSON.stringify(_.extend({ }, header, { nonce: nonce })));
const protected64 = b64(JSON.stringify(Object.assign({}, header, { nonce: nonce })));
const signer = crypto.createSign('RSA-SHA256');
signer.update(protected64 + '.' + payload64, 'utf8');
+15 -15
View File
@@ -1243,7 +1243,7 @@ async function addTask(appId, installationState, task, auditSource) {
const taskId = await tasks.add(tasks.TASK_APP, [ appId, args ]);
const [updateError] = await safe(setTask(appId, _.extend({ installationState, taskId, error: null }, values), { requiredState, requireNullTaskId }));
const [updateError] = await safe(setTask(appId, Object.assign({ installationState, taskId, error: null }, values), { requiredState, requireNullTaskId }));
if (updateError && updateError.reason === BoxError.NOT_FOUND) throw new BoxError(BoxError.BAD_STATE, 'Another task is scheduled for this app'); // could be because app went away OR a taskId exists
if (updateError) throw updateError;
@@ -1378,9 +1378,9 @@ async function install(data, auditSource) {
}
const locations = [{ subdomain, domain, type: exports.LOCATION_TYPE_PRIMARY }]
.concat(secondaryDomains.map(ad => _.extend(ad, { type: exports.LOCATION_TYPE_SECONDARY })))
.concat(redirectDomains.map(ad => _.extend(ad, { type: exports.LOCATION_TYPE_REDIRECT })))
.concat(aliasDomains.map(ad => _.extend(ad, { type: exports.LOCATION_TYPE_ALIAS })));
.concat(secondaryDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_SECONDARY })))
.concat(redirectDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_REDIRECT })))
.concat(aliasDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_ALIAS })));
error = await validateLocations(locations);
if (error) throw error;
@@ -1426,7 +1426,7 @@ async function install(data, auditSource) {
const taskId = await addTask(appId, app.installationState, task, auditSource);
const newApp = _.extend({}, _.omit(app, 'icon'), { appStoreId, manifest, subdomain, domain, portBindings });
const newApp = Object.assign({}, _.omit(app, 'icon'), { appStoreId, manifest, subdomain, domain, portBindings });
newApp.fqdn = dns.fqdn(newApp.subdomain, newApp.domain);
newApp.secondaryDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); });
newApp.redirectDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); });
@@ -1484,7 +1484,7 @@ async function setUpstreamUri(app, upstreamUri, auditSource) {
const error = validateUpstreamUri(upstreamUri);
if (error) throw error;
await reverseProxy.writeAppConfigs(_.extend({}, app, { upstreamUri }));
await reverseProxy.writeAppConfigs(Object.assign({}, app, { upstreamUri }));
await update(appId, { upstreamUri });
@@ -1755,7 +1755,7 @@ async function setReverseProxyConfig(app, reverseProxyConfig, auditSource) {
assert.strictEqual(typeof reverseProxyConfig, 'object');
assert.strictEqual(typeof auditSource, 'object');
reverseProxyConfig = _.extend({ robotsTxt: null, csp: null, hstsPreload: false }, reverseProxyConfig);
reverseProxyConfig = Object.assign({ robotsTxt: null, csp: null, hstsPreload: false }, reverseProxyConfig);
const appId = app.id;
let error = validateCsp(reverseProxyConfig.csp);
@@ -1764,7 +1764,7 @@ async function setReverseProxyConfig(app, reverseProxyConfig, auditSource) {
error = validateRobotsTxt(reverseProxyConfig.robotsTxt);
if (error) throw error;
await reverseProxy.writeAppConfigs(_.extend({}, app, { reverseProxyConfig }));
await reverseProxy.writeAppConfigs(Object.assign({}, app, { reverseProxyConfig }));
await update(appId, { reverseProxyConfig });
@@ -1852,9 +1852,9 @@ async function setLocation(app, data, auditSource) {
}
const locations = [{ subdomain: values.subdomain, domain: values.domain, type: exports.LOCATION_TYPE_PRIMARY }]
.concat(values.secondaryDomains.map(ad => _.extend(ad, { type: exports.LOCATION_TYPE_SECONDARY })))
.concat(values.redirectDomains.map(ad => _.extend(ad, { type: exports.LOCATION_TYPE_REDIRECT })))
.concat(values.aliasDomains.map(ad => _.extend(ad, { type: exports.LOCATION_TYPE_ALIAS })));
.concat(values.secondaryDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_SECONDARY })))
.concat(values.redirectDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_REDIRECT })))
.concat(values.aliasDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_ALIAS })));
error = await validateLocations(locations);
if (error) throw error;
@@ -1876,7 +1876,7 @@ async function setLocation(app, data, auditSource) {
values.redirectDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); });
values.aliasDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); });
await eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, _.extend({ appId, app, taskId }, values));
await eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, Object.assign({ appId, app, taskId }, values));
return { taskId };
}
@@ -2085,7 +2085,7 @@ async function repair(app, data, auditSource) {
} else {
errorState = exports.ISTATE_PENDING_CONFIGURE;
if (data.dockerImage) {
let newManifest = _.extend({}, app.manifest, { dockerImage: data.dockerImage });
let newManifest = Object.assign({}, app.manifest, { dockerImage: data.dockerImage });
task.values.manifest = newManifest;
}
}
@@ -2269,7 +2269,7 @@ async function clone(app, data, user, auditSource) {
const secondaryDomains = translateSecondaryDomains(data.secondaryDomains || {});
const locations = [{ subdomain, domain, type: exports.LOCATION_TYPE_PRIMARY }]
.concat(secondaryDomains.map(ad => _.extend(ad, { type: exports.LOCATION_TYPE_SECONDARY })));
.concat(secondaryDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_SECONDARY })));
error = await validateLocations(locations);
if (error) throw error;
@@ -2327,7 +2327,7 @@ async function clone(app, data, user, auditSource) {
};
const taskId = await addTask(newAppId, exports.ISTATE_PENDING_CLONE, task, auditSource);
const newApp = _.extend({}, _.omit(obj, 'icon'), { appStoreId, manifest, subdomain, domain, portBindings });
const newApp = Object.assign({}, _.omit(obj, 'icon'), { appStoreId, manifest, subdomain, domain, portBindings });
newApp.fqdn = dns.fqdn(newApp.subdomain, newApp.domain);
newApp.secondaryDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); });
newApp.redirectDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); });
+2 -2
View File
@@ -258,7 +258,7 @@ async function moveDataDir(app, targetVolumeId, targetVolumePrefix) {
assert(targetVolumePrefix === null || typeof targetVolumePrefix === 'string');
const resolvedSourceDir = await apps.getStorageDir(app);
const resolvedTargetDir = await apps.getStorageDir(_.extend({}, app, { storageVolumeId: targetVolumeId, storageVolumePrefix: targetVolumePrefix }));
const resolvedTargetDir = await apps.getStorageDir(Object.assign({}, app, { storageVolumeId: targetVolumeId, storageVolumePrefix: targetVolumePrefix }));
debug(`moveDataDir: migrating data from ${resolvedSourceDir} to ${resolvedTargetDir}`);
@@ -525,7 +525,7 @@ async function migrateDataDir(app, args, progressCallback) {
// re-setup addons since this creates the localStorage destination
await progressCallback({ percent: 50, message: 'Setting up addons' });
await services.setupAddons(_.extend({}, app, { storageVolumeId: newStorageVolumeId, storageVolumePrefix: newStorageVolumePrefix }), app.manifest.addons);
await services.setupAddons(Object.assign({}, app, { storageVolumeId: newStorageVolumeId, storageVolumePrefix: newStorageVolumePrefix }), app.manifest.addons);
await progressCallback({ percent: 60, message: 'Moving data dir' });
await moveDataDir(app, newStorageVolumeId, newStorageVolumePrefix);
+3 -4
View File
@@ -4,8 +4,7 @@
const assert = require('assert'),
HttpError = require('connect-lastmile').HttpError,
util = require('util'),
_ = require('underscore');
util = require('util');
exports = module.exports = BoxError;
@@ -28,7 +27,7 @@ function BoxError(reason, errorOrMessage, override) {
} else { // error object
this.message = errorOrMessage.message;
this.nestedError = errorOrMessage;
_.extend(this, override); // copy enumerable properies
Object.assign(this, override); // copy enumerable properies
}
}
util.inherits(BoxError, Error);
@@ -70,7 +69,7 @@ BoxError.TIMEOUT = 'Timeout';
BoxError.TRY_AGAIN = 'Try Again';
BoxError.prototype.toPlainObject = function () {
return _.extend({}, { message: this.message, reason: this.reason }, this.details);
return Object.assign({}, { message: this.message, reason: this.reason }, this.details);
};
// this is a class method for now in case error is not a BoxError
+2 -3
View File
@@ -7,8 +7,7 @@ exports = module.exports = {
const assert = require('assert'),
constants = require('./constants.js'),
dns = require('dns'),
safe = require('safetydance'),
_ = require('underscore');
safe = require('safetydance');
// a note on TXT records. It doesn't have quotes ("") at the DNS level. Those quotes
// are added for DNS server software to enclose spaces. Such quotes may also be returned
@@ -20,7 +19,7 @@ async function resolve(hostname, rrtype, options) {
const defaultOptions = { server: '127.0.0.1', timeout: 5000 }; // unbound runs on 127.0.0.1
const resolver = new dns.promises.Resolver();
options = _.extend({ }, defaultOptions, options);
options = Object.assign({}, defaultOptions, options);
// Only use unbound on a Cloudron
if (constants.CLOUDRON) resolver.setServers([ options.server ]);
+4 -5
View File
@@ -46,8 +46,7 @@ const apps = require('./apps.js'),
safe = require('safetydance'),
system = require('./system.js'),
timers = require('timers/promises'),
volumes = require('./volumes.js'),
_ = require('underscore');
volumes = require('./volumes.js');
const DOCKER_SOCKET_PATH = '/var/run/docker.sock';
const gConnection = new Docker({ socketPath: DOCKER_SOCKET_PATH });
@@ -318,7 +317,7 @@ async function createSubcontainer(app, name, cmd, options) {
app.manifest.runtimeDirs.forEach(dir => runtimeVolumes[dir] = {});
}
let containerOptions = {
const containerOptions = {
name: name, // for referencing containers
Tty: isAppContainer,
Image: app.manifest.dockerImage,
@@ -405,9 +404,9 @@ async function createSubcontainer(app, name, cmd, options) {
];
}
containerOptions = _.extend(containerOptions, options);
const mergedOptions = Object.assign({}, containerOptions, options);
const [createError, container] = await safe(gConnection.createContainer(containerOptions));
const [createError, container] = await safe(gConnection.createContainer(mergedOptions));
if (createError && createError.statusCode === 409) throw new BoxError(BoxError.ALREADY_EXISTS, createError);
if (createError) throw new BoxError(BoxError.DOCKER_ERROR, createError);
+2 -3
View File
@@ -17,8 +17,7 @@ const apps = require('./apps.js'),
path = require('path'),
paths = require('./paths.js'),
safe = require('safetydance'),
util = require('util'),
_ = require('underscore');
util = require('util');
let gHttpServer = null;
@@ -67,7 +66,7 @@ function attachDockerRequest(req, res, next) {
function containersCreate(req, res, next) {
safe.set(req.body, 'HostConfig.NetworkMode', 'cloudron'); // overwrite the network the container lives in
safe.set(req.body, 'NetworkingConfig', {}); // drop any custom network configs
safe.set(req.body, 'Labels', _.extend({ }, safe.query(req.body, 'Labels'), { appId: req.app.id, isCloudronManaged: String(false) })); // overwrite the app id to track containers of an app
safe.set(req.body, 'Labels', Object.assign({}, safe.query(req.body, 'Labels'), { appId: req.app.id, isCloudronManaged: String(false) })); // overwrite the app id to track containers of an app
safe.set(req.body, 'HostConfig.LogConfig', { Type: 'syslog', Config: { 'tag': req.app.id, 'syslog-address': 'udp://127.0.0.1:2514', 'syslog-format': 'rfc5424' }});
const appDataDir = path.join(paths.APPS_DATA_DIR, req.app.id, 'data');
+1 -1
View File
@@ -529,7 +529,7 @@ async function checkRblStatus(domain) {
debug(`checkRblStatus: ${domain} (flippedIp: ${flippedIp}) is in the blacklist of ${JSON.stringify(rblServer)}`);
const result = _.extend({ }, rblServer);
const result = Object.assign({}, rblServer);
const [error2, txtRecords] = await safe(dig.resolve(flippedIp + '.' + rblServer.dns, 'TXT', DNS_OPTIONS));
result.txtRecords = error2 || !txtRecords ? 'No txt record' : txtRecords.map(x => x.join(''));
+2 -3
View File
@@ -28,8 +28,7 @@ const assert = require('assert'),
paths = require('./paths.js'),
users = require('./users.js'),
tld = require('tldjs'),
tokens = require('./tokens.js'),
_ = require('underscore');
tokens = require('./tokens.js');
// we cannot use tasks since the tasks table gets overwritten when db is imported
const gProvisionStatus = {
@@ -245,7 +244,7 @@ async function getStatus() {
const allSettings = await settings.list();
return _.extend({
return Object.assign({
version: constants.VERSION,
apiServerOrigin: settings.apiServerOrigin(), // used by CaaS tool
webServerOrigin: settings.webServerOrigin(), // used by CaaS tool
+2 -3
View File
@@ -18,8 +18,7 @@ const appstore = require('../appstore.js'),
HttpSuccess = require('connect-lastmile').HttpSuccess,
safe = require('safetydance'),
settings = require('../settings.js'),
support = require('../support.js'),
_ = require('underscore');
support = require('../support.js');
async function canCreateTicket(req, res, next) {
const [error, supportConfig] = await safe(settings.getSupportConfig());
@@ -47,7 +46,7 @@ async function createTicket(req, res, next) {
if (error) return next(new HttpError(503, `Error getting support config: ${error.message}`));
if (supportConfig.email !== constants.SUPPORT_EMAIL) return next(new HttpError(503, 'Sending to non-cloudron email not implemented yet'));
const [ticketError, result] = await safe(appstore.createTicket(_.extend({ }, req.body, { email: req.user.email, displayName: req.user.displayName }), AuditSource.fromRequest(req)));
const [ticketError, result] = await safe(appstore.createTicket(Object.assign({ }, req.body, { email: req.user.email, displayName: req.user.displayName }), AuditSource.fromRequest(req)));
if (ticketError) return next(new HttpError(503, `Error contacting cloudron.io: ${ticketError.message}. Please email ${constants.SUPPORT_EMAIL}`));
next(new HttpSuccess(201, result));
+2 -2
View File
@@ -471,7 +471,7 @@ async function setBackupCredentials(credentials) {
// preserve these fields
const extra = _.pick(currentConfig, 'retentionPolicy', 'schedulePattern', 'copyConcurrency', 'syncConcurrency', 'memoryLimit', 'downloadConcurrency', 'deleteConcurrency', 'uploadPartSize');
const backupConfig = _.extend({}, credentials, extra);
const backupConfig = Object.assign({}, credentials, extra);
backups.cleanupCacheFilesSync();
@@ -734,7 +734,7 @@ async function setAppstoreWebToken(token) {
async function list() {
const settings = await database.query(`SELECT ${SETTINGS_FIELDS} FROM settings WHERE value IS NOT NULL ORDER BY name`);
const result = _.extend({ }, gDefaults);
const result = Object.assign({}, gDefaults);
settings.forEach(function (setting) { result[setting.name] = setting.value; });
// convert booleans
+1 -1
View File
@@ -135,7 +135,7 @@ async function setCompleted(id, task) {
debug(`setCompleted - ${id}: ${JSON.stringify(task)}`);
await update(id, _.extend({ percent: 100 }, task));
await update(id, Object.assign({ percent: 100 }, task));
}
async function setCompletedByType(type, task) {
+7 -8
View File
@@ -10,8 +10,7 @@ const apptask = require('../apptask.js'),
expect = require('expect.js'),
fs = require('fs'),
paths = require('../paths.js'),
safe = require('safetydance'),
_ = require('underscore');
safe = require('safetydance');
describe('apptask', function () {
const { setup, cleanup, app } = common;
@@ -37,7 +36,7 @@ describe('apptask', function () {
});
it('barfs on empty manifest', async function () {
const badApp = _.extend({ }, app);
const badApp = Object.assign({ }, app);
badApp.manifest = { };
const [error] = await safe(apptask._verifyManifest(badApp.manifest));
@@ -45,8 +44,8 @@ describe('apptask', function () {
});
it('fails on bad manifest', async function () {
const badApp = _.extend({ }, app);
badApp.manifest = _.extend({ }, app.manifest);
const badApp = Object.assign({ }, app);
badApp.manifest = Object.assign({ }, app.manifest);
delete badApp.manifest.httpPort;
const [error] = await safe(apptask._verifyManifest(badApp.manifest));
@@ -54,8 +53,8 @@ describe('apptask', function () {
});
it('barfs on incompatible manifest', async function () {
const badApp = _.extend({ }, app);
badApp.manifest = _.extend({ }, app.manifest);
const badApp = Object.assign({ }, app);
badApp.manifest = Object.assign({ }, app.manifest);
badApp.manifest.maxBoxVersion = '0.0.0'; // max box version is too small
const [error] = await safe(apptask._verifyManifest(badApp.manifest));
@@ -63,7 +62,7 @@ describe('apptask', function () {
});
it('verifies manifest', async function () {
const goodApp = _.extend({ }, app);
const goodApp = Object.assign({ }, app);
await apptask._verifyManifest(goodApp.manifest);
});
+16 -17
View File
@@ -16,8 +16,7 @@ const async = require('async'),
server = require('../server.js'),
settings = require('../settings.js'),
superagent = require('superagent'),
users = require('../users.js'),
_ = require('underscore');
users = require('../users.js');
let gLdapServer;
@@ -193,7 +192,7 @@ describe('External LDAP', function () {
describe('settings', function () {
it('enabling fails with missing url', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
delete conf.url;
const [error] = await safe(settings.setExternalLdapConfig(conf));
@@ -201,7 +200,7 @@ describe('External LDAP', function () {
});
it('enabling fails with empty url', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.url = '';
const [error] = await safe(settings.setExternalLdapConfig(conf));
@@ -209,7 +208,7 @@ describe('External LDAP', function () {
});
it('enabling fails with missing baseDn', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
delete conf.baseDn;
const [error] = await safe(settings.setExternalLdapConfig(conf));
@@ -217,7 +216,7 @@ describe('External LDAP', function () {
});
it('enabling fails with empty baseDn', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.baseDn = '';
const [error] = await safe(settings.setExternalLdapConfig(conf));
@@ -225,7 +224,7 @@ describe('External LDAP', function () {
});
it('enabling fails with missing filter', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
delete conf.filter;
const [error] = await safe(settings.setExternalLdapConfig(conf));
@@ -233,7 +232,7 @@ describe('External LDAP', function () {
});
it('enabling fails with empty filter', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.filter = '';
const [error] = await safe(settings.setExternalLdapConfig(conf));
@@ -250,7 +249,7 @@ describe('External LDAP', function () {
// now test with groups
it('enabling with groups fails with missing groupBaseDn', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.syncGroups = true;
delete conf.groupBaseDn;
@@ -259,7 +258,7 @@ describe('External LDAP', function () {
});
it('enabling with groups fails with empty groupBaseDn', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.syncGroups = true;
conf.groupBaseDn = '';
@@ -268,7 +267,7 @@ describe('External LDAP', function () {
});
it('enabling with groups fails with missing groupFilter', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.syncGroups = true;
delete conf.groupFilter;
@@ -277,7 +276,7 @@ describe('External LDAP', function () {
});
it('enabling with groups fails with empty groupFilter', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.syncGroups = true;
conf.groupFilter = '';
@@ -286,7 +285,7 @@ describe('External LDAP', function () {
});
it('enabling with groups fails with missing groupnameField', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.syncGroups = true;
delete conf.groupnameField;
@@ -295,7 +294,7 @@ describe('External LDAP', function () {
});
it('enabling with groups fails with empty groupnameField', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.syncGroups = true;
conf.groupnameField = '';
@@ -304,7 +303,7 @@ describe('External LDAP', function () {
});
it('enabling with groups succeeds', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.syncGroups = true;
await settings.setExternalLdapConfig(conf);
@@ -375,7 +374,7 @@ describe('External LDAP', function () {
});
it('enable with groupSync', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.syncGroups = true;
await settings.setExternalLdapConfig(conf);
});
@@ -498,7 +497,7 @@ describe('External LDAP', function () {
});
it('enable auto create', async function () {
let conf = _.extend({}, LDAP_CONFIG);
let conf = Object.assign({}, LDAP_CONFIG);
conf.autoCreate = true;
await settings.setExternalLdapConfig(conf);
});
+1 -1
View File
@@ -624,7 +624,7 @@ async function update(user, data, auditSource) {
if (error) throw new BoxError(BoxError.DATABASE_ERROR, error);
if (result.affectedRows !== 1) throw new BoxError(BoxError.NOT_FOUND, 'User not found');
const newUser = _.extend({}, user, data);
const newUser = Object.assign({}, user, data);
await eventlog.add(eventlog.ACTION_USER_UPDATE, auditSource, {
userId: user.id,