jsharmony 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/.eslintrc.js +10 -3
  2. package/.eslintrc_clientjs.js +46 -0
  3. package/.eslintrc_test.js +51 -0
  4. package/AppSrv.DB.js +2 -2
  5. package/AppSrv.File.js +1 -3
  6. package/AppSrv.Helper.js +9 -9
  7. package/AppSrv.ModelExec.js +6 -10
  8. package/AppSrv.ModelForm.js +25 -23
  9. package/AppSrv.ModelGrid.js +20 -21
  10. package/AppSrv.ModelMetadata.js +36 -39
  11. package/AppSrv.ModelMultisel.js +13 -16
  12. package/AppSrv.Queue.js +4 -4
  13. package/AppSrv.Report.js +16 -16
  14. package/AppSrv.js +20 -21
  15. package/AppSrvModel.js +40 -41
  16. package/AppSrvRpt.js +65 -81
  17. package/AppSrvTask.js +56 -57
  18. package/clientjs/JSHFind.js +10 -10
  19. package/clientjs/XAPI.Form.js +29 -28
  20. package/clientjs/XAPI.Grid.js +30 -30
  21. package/clientjs/XAPI.js +2 -2
  22. package/clientjs/XBarcode.js +6 -5
  23. package/clientjs/XDebugConsole.js +54 -55
  24. package/clientjs/XEditableGrid.js +35 -39
  25. package/clientjs/XExt.XModel.js +48 -57
  26. package/clientjs/XExt.js +421 -412
  27. package/clientjs/XForm.js +85 -85
  28. package/clientjs/XFormat.js +74 -75
  29. package/clientjs/XGrid.js +50 -39
  30. package/clientjs/XImageLoader.js +2 -1
  31. package/clientjs/XLoader.js +8 -5
  32. package/clientjs/XMenu.js +47 -46
  33. package/clientjs/XPayment.js +4 -5
  34. package/clientjs/XScanner.js +4 -3
  35. package/clientjs/XSearch.js +13 -12
  36. package/clientjs/jsHarmony.js +66 -67
  37. package/init/install.app.config.local.js +9 -7
  38. package/jsHarmony.Helper.js +85 -80
  39. package/jsHarmony.LoadModels.js +63 -63
  40. package/jsHarmony.LoadSQL.js +10 -18
  41. package/jsHarmony.LoadTasks.js +8 -13
  42. package/jsHarmony.LoadViews.js +2 -2
  43. package/jsHarmony.Render.js +7 -7
  44. package/jsHarmony.js +2 -2
  45. package/jsHarmonyConfig.js +3 -3
  46. package/jsHarmonyExtensions.js +16 -16
  47. package/jsHarmonyModule.js +5 -6
  48. package/jsHarmonyModuleTransform.js +13 -13
  49. package/jsHarmonyServer.js +23 -19
  50. package/jsHarmonySite.js +9 -9
  51. package/jsHarmonyTranslator.js +12 -12
  52. package/lib/Auth.js +25 -23
  53. package/lib/CLI.js +34 -28
  54. package/lib/CodeGen.Models.js +35 -38
  55. package/lib/CodeGen.SQLObjects.js +17 -20
  56. package/lib/CodeGen.Schema.js +2 -4
  57. package/lib/CodeGen.js +1 -1
  58. package/lib/Helper.js +169 -170
  59. package/lib/HelperFS.js +29 -31
  60. package/lib/HelperRender.js +6 -10
  61. package/lib/JSParser.js +72 -56
  62. package/lib/JSScanner.js +14 -14
  63. package/lib/JSToken.js +15 -15
  64. package/lib/Logger.js +40 -46
  65. package/lib/Mailer.js +3 -1
  66. package/lib/WebConnect.js +11 -11
  67. package/lib/ejsext.js +78 -78
  68. package/lint.cmd +7 -0
  69. package/package.json +1 -1
  70. package/public/js/jsHarmony.js +1 -1
  71. package/render/RenderLogin.js +5 -12
  72. package/render/RenderLoginForgotPassword.js +15 -17
  73. package/render/RenderLoginForgotPasswordReset.js +5 -7
  74. package/render/RenderTemplate.js +3 -4
  75. package/routes/jsHarmonyRouter.js +54 -53
  76. package/sql/datatypes.sqlite.json +2 -2
  77. package/test/ValidateSubnet.js +1 -1
  78. package/test/images.js +4 -4
  79. package/test/index.js +2 -2
  80. package/test/modelTransforms.js +39 -39
  81. package/test/parser.js +0 -1
  82. package/test/websocket.js +4 -3
  83. package/test/xformat.js +0 -1
package/.eslintrc.js CHANGED
@@ -1,13 +1,20 @@
1
1
  module.exports = {
2
2
  "env": {
3
3
  "browser": true,
4
- "node": true
4
+ "node": true,
5
+ "es6": true,
5
6
  },
6
- "extends": "eslint:recommended",
7
+ "extends": [
8
+ "eslint:recommended",
9
+ ],
7
10
  "parserOptions": {
8
- "ecmaVersion": 6
11
+ "ecmaVersion": 8
9
12
  },
10
13
  "rules": {
14
+ "no-trailing-spaces":[
15
+ "error",
16
+ { "skipBlankLines": true }
17
+ ],
11
18
  "indent": [
12
19
  "error",
13
20
  2,
@@ -0,0 +1,46 @@
1
+ module.exports = {
2
+ "env": {
3
+ "browser": true,
4
+ },
5
+ "plugins": [
6
+ "es5"
7
+ ],
8
+ "extends": [
9
+ "eslint:recommended",
10
+ "plugin:es5/no-es2015"
11
+ ],
12
+ "rules": {
13
+ "no-trailing-spaces":[
14
+ "error",
15
+ { "skipBlankLines": true }
16
+ ],
17
+ "indent": [
18
+ "error",
19
+ 2,
20
+ { "SwitchCase":1 }
21
+ ],
22
+ "linebreak-style": [
23
+ "error",
24
+ "windows"
25
+ ],
26
+ "quotes": [
27
+ "error",
28
+ "single",
29
+ { "avoidEscape": true }
30
+ ],
31
+ "semi": [
32
+ "error",
33
+ "always"
34
+ ],
35
+ "no-unused-vars": [
36
+ "error",
37
+ {
38
+ "args": "none"
39
+ }
40
+ ],
41
+ "no-cond-assign": [
42
+ "error",
43
+ "except-parens"
44
+ ]
45
+ }
46
+ };
@@ -0,0 +1,51 @@
1
+ module.exports = {
2
+ "env": {
3
+ "browser": true,
4
+ },
5
+ "plugins": [
6
+ "es5"
7
+ ],
8
+ "extends": [
9
+ "eslint:recommended"
10
+ ],
11
+ "globals": {
12
+ "it": "readonly",
13
+ "describe": "readonly",
14
+ "after": "readonly",
15
+ },
16
+ "rules": {
17
+ "no-trailing-spaces":[
18
+ "error",
19
+ { "skipBlankLines": true }
20
+ ],
21
+ "indent": [
22
+ "error",
23
+ 2,
24
+ { "SwitchCase":1 }
25
+ ],
26
+ "linebreak-style": [
27
+ "error",
28
+ "windows"
29
+ ],
30
+ "quotes": [
31
+ "error",
32
+ "single",
33
+ { "avoidEscape": true }
34
+ ],
35
+ "semi": [
36
+ "error",
37
+ "always"
38
+ ],
39
+ "no-console": "off",
40
+ "no-unused-vars": [
41
+ "error",
42
+ {
43
+ "args": "none"
44
+ }
45
+ ],
46
+ "no-cond-assign": [
47
+ "error",
48
+ "except-parens"
49
+ ]
50
+ }
51
+ };
package/AppSrv.DB.js CHANGED
@@ -60,7 +60,7 @@ exports.ExecScalar = function (context, sql, ptypes, params, callback, dbconfig,
60
60
 
61
61
  exports.GetDBErrorMessage = function(dberrors, errmsg){
62
62
  if(!dberrors) return null;
63
- var errmsg = (errmsg||'').toString().toLowerCase();
63
+ errmsg = (errmsg||'').toString().toLowerCase();
64
64
  for (var i = 0; i < dberrors.length; i++) {
65
65
  var dberr = dberrors[i];
66
66
  var erex = dberr[0].toString().toLowerCase();
@@ -72,7 +72,7 @@ exports.GetDBErrorMessage = function(dberrors, errmsg){
72
72
  else if (errmsg.indexOf(erex) >= 0) { return etxt; }
73
73
  }
74
74
  return null;
75
- }
75
+ };
76
76
 
77
77
  exports.AppDBError = function (req, res, err, stats, errorHandler) {
78
78
  if(err.stats) stats = err.stats;
package/AppSrv.File.js CHANGED
@@ -202,7 +202,7 @@ exports.Download = function (req, res, fullmodelid, keyid, fieldid, options) {
202
202
  var datalockqueries = [];
203
203
  var fields = _this.getFieldsByName(model.fields, fieldlist);
204
204
 
205
- //Add DataLock parameters to SQL
205
+ //Add DataLock parameters to SQL
206
206
  this.getDataLockSQL(req, model, model.fields, sql_ptypes, sql_params, verrors, function (datalockquery) { datalockqueries.push(datalockquery); });
207
207
  //Add keys as SQL parameters
208
208
  var keyfield = keys[0];
@@ -372,8 +372,6 @@ exports.ProcessFileOperations = function (keyval, fileops, rslt, stats, callback
372
372
  if (fileop.src) filesrc = Helper.ReplaceAll(fileop.src, '%%%KEY%%%', keyval);
373
373
  if (fileop.dest) filedest = Helper.ReplaceAll(fileop.dest, '%%%KEY%%%', keyval);
374
374
 
375
- var allfiles = [];
376
-
377
375
  async.waterfall([
378
376
  function(filehandlercb){
379
377
  //Get src file extension
package/AppSrv.Helper.js CHANGED
@@ -24,7 +24,7 @@ module.exports = exports = {};
24
24
 
25
25
  exports.getFieldNames = function (req, fields, perm, fcond) {
26
26
  return _.map(exports.getFields(req, fields, perm, fcond), 'name');
27
- }
27
+ };
28
28
 
29
29
  exports.getFields = function (req, fields, perm, fcond) {
30
30
  var rslt = [];
@@ -37,11 +37,11 @@ exports.getFields = function (req, fields, perm, fcond) {
37
37
  }
38
38
  });
39
39
  return rslt;
40
- }
40
+ };
41
41
 
42
42
  exports.getFieldNamesWithProp = function (fields, prop) {
43
43
  return _.map(exports.getFieldsWithProp(fields, prop), 'name');
44
- }
44
+ };
45
45
 
46
46
  exports.getFieldsWithProp = function (fields, prop) {
47
47
  var rslt = [];
@@ -52,7 +52,7 @@ exports.getFieldsWithProp = function (fields, prop) {
52
52
  }
53
53
  });
54
54
  return rslt;
55
- }
55
+ };
56
56
 
57
57
  exports.getFieldsByName = function (fields, fieldnames, fcond) {
58
58
  var rslt = [];
@@ -62,7 +62,7 @@ exports.getFieldsByName = function (fields, fieldnames, fcond) {
62
62
  var field = fields[i];
63
63
  if (_.includes(fieldnames, field.name)){
64
64
  for(var j=0;j<fieldnames_missing.length;j++){
65
- if(fieldnames_missing[j]==field.name){
65
+ if(fieldnames_missing[j]==field.name){
66
66
  fieldnames_missing.splice(j,1);
67
67
  j--;
68
68
  }
@@ -74,7 +74,7 @@ exports.getFieldsByName = function (fields, fieldnames, fcond) {
74
74
  if(fieldnames_missing.length > 0){ this.jsh.Log.warning('Fields not found: ' + fieldnames_missing.join(', ')); }
75
75
 
76
76
  return rslt;
77
- }
77
+ };
78
78
 
79
79
  //Static function
80
80
  exports.getFieldByName = function (fields, fieldname) {
@@ -82,18 +82,18 @@ exports.getFieldByName = function (fields, fieldname) {
82
82
  if (fields[i].name == fieldname) return fields[i];
83
83
  }
84
84
  return;
85
- }
85
+ };
86
86
 
87
87
  exports.getKeyNames = function (fields) {
88
88
  return _.map(exports.getKeys(fields), 'name');
89
- }
89
+ };
90
90
 
91
91
  exports.getKeys = function (fields) {
92
92
  return _.filter(fields, function (field) {
93
93
  if (field.key) return true;
94
94
  return false;
95
95
  });
96
- }
96
+ };
97
97
 
98
98
  exports.getEncryptedFields = function (req, fields, perm) {
99
99
  var rslt = [];
@@ -26,9 +26,6 @@ exports.getModelExec = function (req, res, fullmodelid, Q, P, form_m) {
26
26
  var _this = this;
27
27
  var model = this.jsh.getModel(req, fullmodelid);
28
28
  if (!Helper.hasModelAction(req, model, 'B')) { Helper.GenError(req, res, -11, _this._tP('Invalid Model Access for @fullmodelid', { fullmodelid })); return; }
29
- var fieldlist = this.getFieldNames(req, model.fields, 'B');
30
- var filelist = this.getFileFieldNames(req, model.fields, 'B');
31
- var keylist = this.getKeyNames(model.fields);
32
29
  var crumbfieldlist = this.getFieldNames(req, model.fields, 'C');
33
30
 
34
31
  if (!_this.ParamCheck('Q', Q, _.union(_.map(crumbfieldlist, function (field) { return '|' + field; }), ['|_action']), false)) {
@@ -36,7 +33,6 @@ exports.getModelExec = function (req, res, fullmodelid, Q, P, form_m) {
36
33
  }
37
34
  if (!_this.ParamCheck('P', P, [])) { Helper.GenError(req, res, -4, 'Invalid Parameters'); return; }
38
35
 
39
- var nokey = (('nokey' in model) && (model.nokey));
40
36
  var is_browse = (('_action' in Q) && (Q['_action'] == 'browse'));
41
37
 
42
38
  //Return applicable drop-down lists
@@ -53,12 +49,12 @@ exports.getModelExec = function (req, res, fullmodelid, Q, P, form_m) {
53
49
  if(_this.addLOVTasks(req, res, model, Q, dbtasks)===false) return;
54
50
  if (!_.isEmpty(verrors)) { Helper.GenError(req, res, -2, verrors[''].join('\n')); return; }
55
51
  return dbtasks;
56
- }
52
+ };
57
53
 
58
54
  exports.postModelExec = function (req, res, fullmodelid, Q, P, onComplete) {
59
55
  var _this = this;
60
56
  var jsh = this.jsh;
61
- if (!jsh.hasModel(req, fullmodelid)) throw new Error("Error: Model " + fullmodelid + " not found in collection.");
57
+ if (!jsh.hasModel(req, fullmodelid)) throw new Error('Error: Model ' + fullmodelid + ' not found in collection.');
62
58
  var model = jsh.getModel(req, fullmodelid);
63
59
  if (!Helper.hasModelAction(req, model, 'U')) { Helper.GenError(req, res, -11, _this._tP('Invalid Model Access for @fullmodelid', { fullmodelid })); return; }
64
60
  var db = jsh.getModelDB(req, fullmodelid);
@@ -69,14 +65,14 @@ exports.postModelExec = function (req, res, fullmodelid, Q, P, onComplete) {
69
65
  if (!_this.ParamCheck('Q', Q, [])) { Helper.GenError(req, res, -4, 'Invalid Parameters'); return; }
70
66
  if (!_this.ParamCheck('P', P, Pcheck)) { Helper.GenError(req, res, -4, 'Invalid Parameters'); return; }
71
67
 
72
- if (!('sqlexec' in model)) throw new Error("Error: Model " + fullmodelid + " missing sqlexec.");
68
+ if (!('sqlexec' in model)) throw new Error('Error: Model ' + fullmodelid + ' missing sqlexec.');
73
69
  var sql_ptypes = [];
74
70
  var sql_params = {};
75
71
  var verrors = {};
76
72
  var param_datalocks = [];
77
73
  var datalockqueries = [];
78
74
 
79
- //Add fields from post
75
+ //Add fields from post
80
76
  var fields = _this.getFieldsByName(model.fields, fieldlist);
81
77
  _.each(fields, function (field) {
82
78
  var fname = field.name;
@@ -96,7 +92,7 @@ exports.postModelExec = function (req, res, fullmodelid, Q, P, onComplete) {
96
92
  else throw new Error('Missing parameter ' + fname);
97
93
  });
98
94
 
99
- //Add DataLock parameters to SQL
95
+ //Add DataLock parameters to SQL
100
96
  _this.getDataLockSQL(req, model, model.fields, sql_ptypes, sql_params, verrors, function (datalockquery) { datalockqueries.push(datalockquery); });
101
97
 
102
98
  verrors = _.merge(verrors, model.xvalidate.Validate('UK', sql_params));
@@ -116,6 +112,6 @@ exports.postModelExec = function (req, res, fullmodelid, Q, P, onComplete) {
116
112
  });
117
113
  };
118
114
  return onComplete(null, dbtasks);
119
- }
115
+ };
120
116
 
121
117
  return module.exports;
@@ -42,6 +42,7 @@ exports.getModelForm = function (req, res, fullmodelid, Q, P, form_m) {
42
42
  if ((encryptedfields.length > 0) && !(req.secure) && (!_this.jsh.Config.system_settings.allow_insecure_http_encryption)) { Helper.GenError(req, res, -51, 'Encrypted fields require HTTPS connection'); return; }
43
43
 
44
44
 
45
+
45
46
  var is_insert = false;
46
47
  var is_browse = false;
47
48
  var selecttype = 'single';
@@ -54,11 +55,11 @@ exports.getModelForm = function (req, res, fullmodelid, Q, P, form_m) {
54
55
  else if (_this.ParamCheck('Q', Q, _.union(_.map(foreignkeylist, function (field) { return '|' + field; }), ['|_action']), false)) {
55
56
  selecttype = 'multiple';
56
57
  }
57
- else {
58
+ else {
58
59
  //Display missing keys
59
60
  _this.ParamCheck('Q', Q, _.map(keylist, function (key) { return '&' + key; }), true);
60
61
  Helper.GenError(req, res, -4, 'Invalid Parameters');
61
- return;
62
+ return;
62
63
  }
63
64
  }
64
65
  else {
@@ -124,7 +125,7 @@ exports.getModelForm = function (req, res, fullmodelid, Q, P, form_m) {
124
125
  var keys = [];
125
126
  if (is_insert && !Helper.hasModelAction(req, model, 'I')) { Helper.GenError(req, res, -11, _this._tP('Invalid Model Access for @fullmodelid', { fullmodelid })); return; }
126
127
  if (!is_insert && !nokey && !model.unbound) {
127
- //Add dynamic parameters from query string
128
+ //Add dynamic parameters from query string
128
129
  if (selecttype == 'single') keys = this.getKeys(model.fields);
129
130
  else if (selecttype == 'multiple') keys = this.getFields(req, model.fields, 'F');
130
131
  for (var i = 0; i < keys.length; i++) {
@@ -205,7 +206,7 @@ exports.getModelForm = function (req, res, fullmodelid, Q, P, form_m) {
205
206
  }
206
207
  callback(err, rslt, stats);
207
208
  });
208
- }
209
+ };
209
210
  else if (is_insert && (selecttype == 'multiple')) {
210
211
  dbtasks[0][fullmodelid] = function (dbtrans, callback) {
211
212
  var rslt = [];
@@ -232,7 +233,7 @@ exports.getModelForm = function (req, res, fullmodelid, Q, P, form_m) {
232
233
  if(_this.addLOVTasks(req, res, model, Q, dbtasks[1], { action: targetperm })===false) return;
233
234
  if (!_.isEmpty(verrors)) { Helper.GenError(req, res, -2, verrors[''].join('\n')); return; }
234
235
  return dbtasks;
235
- }
236
+ };
236
237
 
237
238
  exports.putModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
238
239
  var _this = this;
@@ -303,7 +304,7 @@ exports.putModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
303
304
  }
304
305
  else throw new Error('Missing parameter ' + fname);
305
306
  });
306
- //Add DataLock parameters to Encryption SQL
307
+ //Add DataLock parameters to Encryption SQL
307
308
  _this.getDataLockSQL(req, model, model.fields, enc_sql_ptypes, enc_sql_params, verrors, function (datalockquery) { enc_datalockqueries.push(datalockquery); });
308
309
  }
309
310
 
@@ -330,7 +331,7 @@ exports.putModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
330
331
  else throw new Error('Missing parameter ' + fname);
331
332
  });
332
333
 
333
- var ignore_subs = _.map(subs, function(val){ return '_obj.'+val });
334
+ var ignore_subs = _.map(subs, function(val){ return '_obj.'+val; });
334
335
  verrors = _.merge(verrors, model.xvalidate.Validate('I', _.merge(vfiles, enc_sql_params, sql_params), '', ignore_subs));
335
336
  if (!_.isEmpty(verrors)) { Helper.GenError(req, res, -2, verrors[''].join('\n')); return; }
336
337
 
@@ -392,14 +393,14 @@ exports.putModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
392
393
  }
393
394
  if (fileops.length > 0) dbtasks['_POSTPROCESS'] = function (callback) {
394
395
  _this.ProcessFileOperationsDone(fileops, callback);
395
- }
396
+ };
396
397
  return onComplete(null, dbtasks);
397
398
  });
398
- }
399
+ };
399
400
 
400
401
  exports.postModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
401
402
  var _this = this;
402
- if (!this.jsh.hasModel(req, fullmodelid)) throw new Error("Error: Model " + fullmodelid + " not found in collection.");
403
+ if (!this.jsh.hasModel(req, fullmodelid)) throw new Error('Error: Model ' + fullmodelid + ' not found in collection.');
403
404
  var model = this.jsh.getModel(req, fullmodelid);
404
405
  if (!Helper.hasModelAction(req, model, 'U')) { Helper.GenError(req, res, -11, _this._tP('Invalid Model Access for @fullmodelid', { fullmodelid })); return; }
405
406
 
@@ -434,14 +435,14 @@ exports.postModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
434
435
  _.each(encryptedfields, function (field) {
435
436
  if (field.type == 'encascii') {
436
437
  if ('hash' in field) {
437
- var hashfield = _.find(model.fields, function (xfield) { return xfield.name == field.hash; });
438
+ let hashfield = _.find(model.fields, function (xfield) { return xfield.name == field.hash; });
438
439
  if (typeof hashfield == 'undefined') throw new Error('Field ' + field.name + ' hash is not defined.');
439
440
  hashfields[field.name] = hashfield;
440
441
  }
441
442
  }
442
443
  });
443
444
 
444
- //Add key from query string
445
+ //Add key from query string
445
446
  var keys = _this.getKeys(model.fields);
446
447
  _.each(keys, function (field) {
447
448
  var fname = field.name;
@@ -485,7 +486,7 @@ exports.postModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
485
486
  else throw new Error('Missing parameter ' + fname);
486
487
  });
487
488
 
488
- //Add DataLock parameters to SQL
489
+ //Add DataLock parameters to SQL
489
490
  _this.getDataLockSQL(req, model, model.fields, sql_ptypes, sql_params, verrors, function (datalockquery) { datalockqueries.push(datalockquery); });
490
491
 
491
492
  verrors = _.merge(verrors, model.xvalidate.Validate('UK', _.merge(vfiles, sql_params), '', vignorefiles, req._roles));
@@ -501,7 +502,7 @@ exports.postModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
501
502
  if (clearval.length == 0) {
502
503
  sql_params[field.name] = null;
503
504
  if ('hash' in field) {
504
- var hashfield = hashfields[field.name];
505
+ let hashfield = hashfields[field.name];
505
506
  sql_ptypes.push(_this.getDBType(hashfield));
506
507
  sql_params[hashfield.name] = null;
507
508
  }
@@ -513,10 +514,10 @@ exports.postModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
513
514
  cipher.update(clearval, 'ascii');
514
515
  sql_params[field.name] = cipher.final();
515
516
  if ('hash' in field) {
516
- var hashfield = hashfields[field.name];
517
+ let hashfield = hashfields[field.name];
517
518
  if (!(hashfield.salt in _this.jsh.Config.salts)) throw new Error('Hash salt not defined.');
518
519
  sql_ptypes.push(_this.getDBType(hashfield));
519
- sql_params[hashfield.name] = crypto.createHash('sha1').update(clearval + _this.jsh.Config.salts[hashfield.salt]).digest();;
520
+ sql_params[hashfield.name] = crypto.createHash('sha1').update(clearval + _this.jsh.Config.salts[hashfield.salt]).digest();
520
521
  }
521
522
  }
522
523
  }
@@ -557,14 +558,14 @@ exports.postModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
557
558
 
558
559
  if (fileops.length > 0) dbtasks['_POSTPROCESS'] = function (callback) {
559
560
  _this.ProcessFileOperationsDone(fileops, callback);
560
- }
561
+ };
561
562
 
562
563
  return onComplete(null, dbtasks);
563
564
  });
564
- }
565
+ };
565
566
 
566
567
  exports.deleteModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
567
- if (!this.jsh.hasModel(req, fullmodelid)) throw new Error("Error: Model " + fullmodelid + " not found in collection.");
568
+ if (!this.jsh.hasModel(req, fullmodelid)) throw new Error('Error: Model ' + fullmodelid + ' not found in collection.');
568
569
  var _this = this;
569
570
  var model = this.jsh.getModel(req, fullmodelid);
570
571
  if (!Helper.hasModelAction(req, model, 'D')) { Helper.GenError(req, res, -11, _this._tP('Invalid Model Access for @fullmodelid', { fullmodelid })); return; }
@@ -595,7 +596,7 @@ exports.deleteModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
595
596
  else throw new Error('Missing parameter ' + fname);
596
597
  });
597
598
 
598
- //Add DataLock parameters to SQL
599
+ //Add DataLock parameters to SQL
599
600
  _this.getDataLockSQL(req, model, model.fields, sql_ptypes, sql_params, verrors, function (datalockquery) { datalockqueries.push(datalockquery); });
600
601
 
601
602
  verrors = _.merge(verrors, model.xvalidate.Validate('K', sql_params));
@@ -614,9 +615,10 @@ exports.deleteModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
614
615
  };
615
616
  //Add post-processing task to delete any files
616
617
  if (filelist.length > 0) {
618
+ var keyval = '';
617
619
  if (keys.length == 1) keyval = sql_params[keys[0].name];
618
620
  else throw new Error('File uploads require one key');
619
- if ((typeof keyval == 'undefined') || !keyval) return callback(Helper.NewError('Invalid file key', -13), null);
621
+ if ((typeof keyval == 'undefined') || !keyval) return Helper.GenError(req, res, -13, 'Invalid file key');
620
622
 
621
623
  var fileops = [];
622
624
  _.each(filelist, function (file) {
@@ -630,9 +632,9 @@ exports.deleteModelForm = function (req, res, fullmodelid, Q, P, onComplete) {
630
632
  });
631
633
  dbtasks['_POSTPROCESS'] = function (callback) {
632
634
  _this.ProcessFileOperationsDone(fileops, callback);
633
- }
635
+ };
634
636
  }
635
637
  return onComplete(null, dbtasks);
636
- }
638
+ };
637
639
 
638
640
  return module.exports;
@@ -40,7 +40,7 @@ exports.getModelRecordset = function (req, res, fullmodelid, Q, P, rowlimit, opt
40
40
  searchlist = _.union(keylist, searchlist);
41
41
  var encryptedfields = this.getFields(req, model.fields, '*', function(field){ return field.type=='encascii'; });
42
42
  if (encryptedfields.length > 0) throw new Error('Encrypted fields not supported on GRID (field.type=encascii)');
43
- var encryptedfields = this.getEncryptedFields(req, model.fields, 'S');
43
+ encryptedfields = this.getEncryptedFields(req, model.fields, 'S'); //Encrypted fields can be used for search
44
44
  if ((encryptedfields.length > 0) && !(req.secure) && (!_this.jsh.Config.system_settings.allow_insecure_http_encryption)) { Helper.GenError(req, res, -51, 'Encrypted / hash fields require HTTPS connection'); return; }
45
45
  var db = _this.jsh.getModelDB(req, fullmodelid);
46
46
  if ('d' in Q) P = JSON.parse(Q.d);
@@ -80,7 +80,7 @@ exports.getModelRecordset = function (req, res, fullmodelid, Q, P, rowlimit, opt
80
80
  var sortfield = val.substring(1);
81
81
  var lovtxtfield = '';
82
82
  if(sortfield.indexOf('__'+_this.jsh.map.code_txt+'__')==0){
83
- var lovtxtfield = sortfield;
83
+ lovtxtfield = sortfield;
84
84
  sortfield = sortfield.substr(_this.jsh.map.code_txt.length + 4);
85
85
  }
86
86
  var sortdir = val[0];
@@ -89,7 +89,7 @@ exports.getModelRecordset = function (req, res, fullmodelid, Q, P, rowlimit, opt
89
89
  else throw new Error('Invalid sort string');
90
90
  if (!_.includes(availablesortfieldslist, sortfield)) throw new Error('Invalid sort field ' + sortfield);
91
91
 
92
- var field = _this.getFieldByName(model.fields, sortfield);
92
+ let field = _this.getFieldByName(model.fields, sortfield);
93
93
  var sortfieldname = sortfield;
94
94
  if(lovtxtfield && field.lov && !field.lov.showcode) sortfieldname = lovtxtfield;
95
95
  sortfields.push({ 'field': sortfieldname, 'dir': sortdir, 'sql': (field.sqlsort || '') });
@@ -105,7 +105,7 @@ exports.getModelRecordset = function (req, res, fullmodelid, Q, P, rowlimit, opt
105
105
  var search_items = JSON.parse(Q.searchjson);
106
106
  var search_join = 'and';
107
107
  if (_.isArray(search_items) && (search_items.length > 0)) {
108
- for (var i = 0; i < search_items.length; i++) {
108
+ for (let i = 0; i < search_items.length; i++) {
109
109
  var search_column = search_items[i].Column;
110
110
  var search_value = search_items[i].Value;
111
111
  var search_comparison = 'contains';
@@ -129,7 +129,6 @@ exports.getModelRecordset = function (req, res, fullmodelid, Q, P, rowlimit, opt
129
129
  if (search_column == 'ALL') {
130
130
  if (searchlist.length == 0) continue;
131
131
  var searchall = [];
132
- var firstSearchItem = true;
133
132
  var searchlistfields = this.getFieldsByName(model.fields, searchlist);
134
133
  _.each(searchlistfields, function (field) {
135
134
  if(field.disable_search_all) return;
@@ -146,7 +145,7 @@ exports.getModelRecordset = function (req, res, fullmodelid, Q, P, rowlimit, opt
146
145
  }
147
146
  }
148
147
  else {
149
- var field = this.getFieldByName(model.fields, search_column);
148
+ let field = this.getFieldByName(model.fields, search_column);
150
149
  var searchtermsql = this.addSearchTerm(req, model, field, i, search_value, search_comparison, sql_ptypes, sql_params, verrors);
151
150
  if (searchtermsql) {
152
151
  if (searchparams.length) searchparams.push(search_join);
@@ -177,8 +176,8 @@ exports.getModelRecordset = function (req, res, fullmodelid, Q, P, rowlimit, opt
177
176
  }
178
177
 
179
178
  var keys = searchfields;
180
- for (var i = 0; i < keys.length; i++) {
181
- var field = keys[i];
179
+ for (let i = 0; i < keys.length; i++) {
180
+ let field = keys[i];
182
181
  var fname = field.name;
183
182
  if ((fname in P) && !(fname in sql_params)) {
184
183
  var dbtype = _this.getDBType(field);
@@ -186,15 +185,15 @@ exports.getModelRecordset = function (req, res, fullmodelid, Q, P, rowlimit, opt
186
185
  sql_params[fname] = _this.DeformatParam(field, P[fname], verrors);
187
186
  }
188
187
  }
189
- for (var i = 0; i < model.fields.length; i++){
190
- var field = model.fields[i];
188
+ for (let i = 0; i < model.fields.length; i++){
189
+ let field = model.fields[i];
191
190
  if(field.lov && field.lov.sqlselect && field.lov.sqlselect_params){
192
191
  for(var j = 0; j < field.lov.sqlselect_params.length; j++){
193
192
  if(!(field.lov.sqlselect_params[j] in P)){ Helper.GenError(req, res, -99999, model.id + ' > ' + field.name + ': Missing lov.sqlselect parameter @'+field.lov.sqlselect_params[j] + ' - grid parameters must be passed in the querystring or bindings. The lov.sqlselect is inserted into the grid select statement; if this is a per-record lookup, use the expression LOVSQLTABLE.FIELD = MODELTABLE.FIELD'); return; }
194
193
  }
195
194
  }
196
195
  }
197
- //Add DataLock parameters to SQL
196
+ //Add DataLock parameters to SQL
198
197
  this.getDataLockSQL(req, model, model.fields, sql_ptypes, sql_params, verrors, function (datalockquery) { datalockqueries.push(datalockquery); }, null, fullmodelid);
199
198
  verrors = _.merge(verrors, model.xvalidate.Validate('BFK', sql_params, undefined, undefined, undefined, { ignoreUndefined: true }));
200
199
  if (!_.isEmpty(verrors)) { Helper.GenError(req, res, -2, verrors[''].join('\n')); return; }
@@ -283,7 +282,7 @@ exports.getModelRecordset = function (req, res, fullmodelid, Q, P, rowlimit, opt
283
282
  if(_this.addTitleTasks(req, res, model, P, dbtasks, (is_browse?'B':'U'))===false) return;
284
283
  }
285
284
  return dbtasks;
286
- }
285
+ };
287
286
 
288
287
  exports.exportCSV = function (req, res, dbtasks, fullmodelid, options) {
289
288
  var _this = this;
@@ -315,17 +314,17 @@ exports.exportCSV = function (req, res, dbtasks, fullmodelid, options) {
315
314
  dbtasks = _.reduce(dbtasks, function (rslt, dbtask, key) { rslt[key] = async.apply(dbtask, undefined); return rslt; }, {});
316
315
  db.ExecTasks(dbtasks, function (err, rslt, stats) {
317
316
  if (err != null) { _this.AppDBError(req, res, err, stats); return; }
318
- if (!fullmodelid in rslt) throw new Error('DB result missing model.');
317
+ if (!(fullmodelid in rslt)) throw new Error('DB result missing model.');
319
318
  var eof = false;
320
319
  if (_.isArray(rslt[fullmodelid]) && (_.isObject(rslt[fullmodelid][rslt[fullmodelid].length - 1])) && ('_eof' in rslt[fullmodelid][rslt[fullmodelid].length - 1])) {
321
- var eof = rslt[fullmodelid].pop();
322
- eof = eof._eof;
320
+ var rslt_eof = rslt[fullmodelid].pop();
321
+ eof = rslt_eof._eof;
323
322
  }
324
323
  //Add header
325
324
  if (rslt[fullmodelid].length > 0) {
326
325
  var header = {};
327
326
  var frow = _.extend({}, rslt[fullmodelid][0]);
328
- for (var fcol in frow) {
327
+ for (let fcol in frow) {
329
328
  //Ignore columns that should not be exported
330
329
  if(!_.includes(exportColumns, fcol)){ delete frow[fcol]; continue; }
331
330
  var field = _this.getFieldByName(model.fields, fcol);
@@ -342,10 +341,10 @@ exports.exportCSV = function (req, res, dbtasks, fullmodelid, options) {
342
341
  //If data was truncated, add notification row
343
342
  if (!eof) {
344
343
  var eofrow = {};
345
- for (var fcol in frow) {
344
+ for (let fcol in frow) {
346
345
  eofrow[fcol] = '';
347
346
  }
348
- for (var fcol in frow) {
347
+ for (let fcol in frow) {
349
348
  eofrow[fcol] = 'Data exceeded limit of ' + _this.jsh.Config.export_rowlimit + ' rows, data has been truncated.';
350
349
  break;
351
350
  }
@@ -355,7 +354,7 @@ exports.exportCSV = function (req, res, dbtasks, fullmodelid, options) {
355
354
  //Process data
356
355
  for (var i = dataidx; i < rslt[fullmodelid].length; i++) {
357
356
  var crow = rslt[fullmodelid][i];
358
- for (ccol in crow) {
357
+ for (let ccol in crow) {
359
358
  if(!ccol) continue;
360
359
  //Overwrite code_val with code_txt
361
360
  if(Helper.beginsWith(ccol, '__'+jsh.map.code_txt+'__')){
@@ -367,7 +366,7 @@ exports.exportCSV = function (req, res, dbtasks, fullmodelid, options) {
367
366
  crow[ccol] = crow[ccol].toISOString();//.replace('T', ' ').replace('Z', '');
368
367
  }
369
368
  }
370
- for (ccol in crow) {
369
+ for (let ccol in crow) {
371
370
  if(!_.includes(exportColumns, ccol)){ delete crow[ccol]; continue; }
372
371
  }
373
372
  }
@@ -380,6 +379,6 @@ exports.exportCSV = function (req, res, dbtasks, fullmodelid, options) {
380
379
  });
381
380
  csv.stringify(rslt[fullmodelid], { quotedString: true }).pipe(res);
382
381
  });
383
- }
382
+ };
384
383
 
385
384
  return module.exports;