jsharmony-cms 1.5.4 → 1.5.8

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.
@@ -91,7 +91,7 @@ exports = module.exports = function(jsh, cms){
91
91
  complete_cb();
92
92
  },
93
93
  error: function(xhr, status, err){
94
- complete_cb(error);
94
+ complete_cb(err);
95
95
  }
96
96
  });
97
97
  }
@@ -82,7 +82,7 @@
82
82
  //"ACL": "public-read",
83
83
  //More parameters can be found at:
84
84
  //https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property
85
- }
85
+ },
86
86
  },
87
87
 
88
88
  //Git deployment settings
@@ -111,7 +111,7 @@ function jsHarmonyCMSConfig(){
111
111
  //"ACL": "public-read",
112
112
  //More parameters can be found at:
113
113
  //https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property
114
- }
114
+ },
115
115
  },
116
116
 
117
117
  //Advanced options
@@ -21,7 +21,7 @@
21
21
  {"name":"site_id","control":"dropdown","caption":"Site","validate":["Required"],"readonly":true,
22
22
  "lov":{"sql":"select site_id code_val, site_name code_txt from {schema}.site where site_sts='ACTIVE' and site_id={schema}.my_current_site_id()"}},
23
23
  {"name":"deployment_target_id","control":"dropdown","caption":"Deployment Target","validate":["Required"],
24
- "lov":{"parent":"site_id" ,"sql2":"select site_id code_parent, deployment_target_id code_val, deployment_target_name code_txt from {schema}.v_my_deployment_target where deployment_target_can_publish = 1 and deployment_target_sts='ACTIVE' and site_id={schema}.my_current_site_id() order by site_id,deployment_target_name"}},
24
+ "lov":{"parent":"site_id" ,"sql2":"select site_id code_parent, deployment_target_id code_val, deployment_target_name code_txt from {schema}.v_my_deployment_target where ((deployment_target_can_publish = 1) or (deployment_target_can_publish_release = 1)) and deployment_target_sts='ACTIVE' and site_id={schema}.my_current_site_id() order by site_id,deployment_target_name"}},
25
25
  {"control":"html","value":[
26
26
  "<% if(jsh.globalparams.isWebmaster){ %>",
27
27
  "<a href='#' onclick='<%=jsh._instance%>.XExt.popupForm(\"{namespace}Site_Tabs\",\"update\",{site_id:<%=jsh._instance%>.globalparams.site_id}); return false;'>Configure Deployment Targets</a>",
@@ -11,7 +11,10 @@
11
11
  {"control":"subform","caption":"Preview / Editor","target":"Site_Deployment_Target_Role_Editor","bindings":{"deployment_target_id":"deployment_target_id","deployment_target_role_type":"'EDITOR'"},
12
12
  "controlstyle":"display:inline-block; margin-right:15px;"
13
13
  },
14
- {"control":"subform","caption":"Publish","target":"Site_Deployment_Target_Role_Publish","bindings":{"deployment_target_id":"deployment_target_id","deployment_target_role_type":"'PUBLISH'"},
14
+ {"control":"subform","caption":"Publish (Any Branch)","target":"Site_Deployment_Target_Role_Publish","bindings":{"deployment_target_id":"deployment_target_id","deployment_target_role_type":"'PUBLISH'"},
15
+ "controlstyle":"display:inline-block;"
16
+ },
17
+ {"control":"subform","caption":"Publish Release","target":"Site_Deployment_Target_Role_Publish_Release","bindings":{"deployment_target_id":"deployment_target_id","deployment_target_role_type":"'PUBLISH_RELEASE'"},
15
18
  "controlstyle":"display:inline-block;"
16
19
  },
17
20
  ]
@@ -23,4 +23,7 @@
23
23
  "Site_Deployment_Target_Role_Publish": {
24
24
  "inherits": "Site_Deployment_Target_Role_Base"
25
25
  },
26
+ "Site_Deployment_Target_Role_Publish_Release": {
27
+ "inherits": "Site_Deployment_Target_Role_Base"
28
+ },
26
29
  }
@@ -546,6 +546,19 @@ module.exports = exports = function(module, funcs){
546
546
 
547
547
  branchData.page_mapping = {};
548
548
 
549
+ //Sort folders first, then by path length
550
+ branchItems = (branchItems||[]).sort(function(a,b){
551
+ a = a || {};
552
+ b = b || {};
553
+ if(!(a.page_is_folder) && (b.page_is_folder)) return 1;
554
+ if((a.page_is_folder) && !(b.page_is_folder)) return -1;
555
+ var apath = (a.page_path||'').toString();
556
+ var bpath = (b.page_path||'').toString();
557
+ if(apath.length > bpath.length) return 1;
558
+ if(apath.length < bpath.length) return -1;
559
+ return 0;
560
+ });
561
+
549
562
  _.each(branchItems, function(item){
550
563
  //Create mapping
551
564
  branchData.page_mapping[item.page_key] = item;
@@ -680,6 +693,19 @@ module.exports = exports = function(module, funcs){
680
693
 
681
694
  branchData.media_mapping = {};
682
695
 
696
+ //Sort folders first, then by path length
697
+ branchItems = (branchItems||[]).sort(function(a,b){
698
+ a = a || {};
699
+ b = b || {};
700
+ if(!(a.media_is_folder) && (b.media_is_folder)) return 1;
701
+ if((a.media_is_folder) && !(b.media_is_folder)) return -1;
702
+ var apath = (a.media_path||'').toString();
703
+ var bpath = (b.media_path||'').toString();
704
+ if(apath.length > bpath.length) return 1;
705
+ if(apath.length < bpath.length) return -1;
706
+ return 0;
707
+ });
708
+
683
709
  async.waterfall([
684
710
  function(cb){
685
711
  //Get all media from current database
@@ -514,7 +514,10 @@ module.exports = exports = function(module, funcs){
514
514
  var cms = module;
515
515
  var git_path = cms.Config.git.bin_path || 'git';
516
516
  return funcs.shellExec(git_path, repo_path, params, function(err, rslt, stderr){
517
- if(err) return cb(new Error('Git Error: ' + err.toString() + ' ' + (stderr||'')), rslt);
517
+ if(err){
518
+ if(err && (err.code == 'ENOENT')) err = new Error('Git executable not found using command: "'+git_path+'". Please install git, or set the git.bin_path config parameter');
519
+ return cb(new Error('Git Error: ' + err.toString() + ' ' + (stderr||'')), rslt);
520
+ }
518
521
  return cb(err, rslt);
519
522
  }, exec_options);
520
523
  }
@@ -1801,7 +1804,7 @@ module.exports = exports = function(module, funcs){
1801
1804
  appsrv.ExecRecordset('deployment', sql, sql_ptypes, sql_params, function (err, rslt) {
1802
1805
  if (err != null) { err.sql = sql; return cb(err); }
1803
1806
  if(!rslt || !rslt.length || !rslt[0]){ return cb(new Error('Error loading deployment media')); }
1804
- async.eachSeries(rslt[0], function(media, item_cb){
1807
+ async.eachLimit(rslt[0], 10, function(media, item_cb){
1805
1808
  var srcpath = funcs.getMediaFilename(media.media_file_id, media.media_ext);
1806
1809
  var media_fpath = '';
1807
1810
  async.waterfall([
@@ -1833,7 +1836,7 @@ module.exports = exports = function(module, funcs){
1833
1836
  },
1834
1837
  //Export thumbnails
1835
1838
  function(generate_cb){
1836
- async.eachOfSeries(branchData.site_config.media_thumbnails, function(thumbnail_config, thumbnail_id, thumbnail_cb){
1839
+ async.eachOf(branchData.site_config.media_thumbnails, function(thumbnail_config, thumbnail_id, thumbnail_cb){
1837
1840
  if(!thumbnail_config || !thumbnail_config.export) return thumbnail_cb();
1838
1841
  if(!_.includes(['.jpg','.jpeg','.tif','.tiff','.png','.gif','.svg'], media.media_ext)) return thumbnail_cb();
1839
1842
 
@@ -2567,6 +2570,7 @@ module.exports = exports = function(module, funcs){
2567
2570
  if(bucket_prefix){
2568
2571
  if(!bucket_prefix || (bucket_prefix[bucket_prefix.length-1]!='/')) bucket_prefix += '/';
2569
2572
  }
2573
+ var S3_THREADS = 10;
2570
2574
 
2571
2575
  var s3_files = {};
2572
2576
  var s3_upload = [];
@@ -2616,7 +2620,7 @@ module.exports = exports = function(module, funcs){
2616
2620
 
2617
2621
  //Upload new files to S3
2618
2622
  function(s3_cb){
2619
- async.eachSeries(s3_upload, function(page_path, page_cb){
2623
+ async.eachLimit(s3_upload, S3_THREADS, function(page_path, page_cb){
2620
2624
  var page_bpath = bucket_prefix + page_path;
2621
2625
  var page_fpath = path.join(publish_path, page_path);
2622
2626
  var fstream = fs.createReadStream(page_fpath);
@@ -2626,7 +2630,6 @@ module.exports = exports = function(module, funcs){
2626
2630
  Bucket: bucket,
2627
2631
  Key: page_bpath,
2628
2632
  Body: fstream,
2629
- ACL: 'public-read'
2630
2633
  };
2631
2634
  var contentType = HelperFS.getMimeType(page_bpath);
2632
2635
  if(contentType) uploadParams.ContentType = contentType;
@@ -2639,7 +2642,7 @@ module.exports = exports = function(module, funcs){
2639
2642
 
2640
2643
  //Delete removed files from S3
2641
2644
  function(s3_cb){
2642
- async.eachSeries(s3_delete, function(page_path, page_cb){
2645
+ async.eachLimit(s3_delete, S3_THREADS, function(page_path, page_cb){
2643
2646
  var page_bpath = bucket_prefix + page_path;
2644
2647
  funcs.deploy_log_info(deployment_id, 'Deleting: '+page_path);
2645
2648
  funcs.deploy_log_change(deployment_id, 'Deleting file: '+page_path);
@@ -199,6 +199,28 @@
199
199
  "\")",
200
200
  ]
201
201
  },
202
+ "{schema}.can_publish":{
203
+ "params": ["BRANCH_ID","DEPLOYMENT_TARGET_ID"],
204
+ "sql": [
205
+ "(case when exists(",
206
+ " select * from {schema}.v_my_deployment_target where deployment_target_id=%%%DEPLOYMENT_TARGET_ID%%% and (",
207
+ " (deployment_target_can_publish=1) or",
208
+ " (deployment_target_can_publish_release=1 and exists(select branch_child.branch_id from {schema}.branch branch_child where branch_child.branch_id=%%%BRANCH_ID%%% and branch_child.branch_type='PUBLIC'))",
209
+ " )",
210
+ ") then 1 else 0 end)"
211
+ ]
212
+ },
213
+ "{schema}.could_have_published":{
214
+ "params": ["BRANCH_ID","DEPLOYMENT_TARGET_ID"],
215
+ "sql": [
216
+ "(case when exists(",
217
+ " select * from {schema}.v_my_deployment_target where deployment_target_id=%%%DEPLOYMENT_TARGET_ID%%% and (",
218
+ " (deployment_target_can_publish=1) or",
219
+ " (deployment_target_can_publish_release=1 and exists(select branch_child.branch_id from {schema}.branch branch_child inner join {schema}.branch branch_parent on branch_parent.branch_id = branch_child.branch_parent_id where branch_child.branch_id=%%%BRANCH_ID%%% and branch_parent.branch_type='PUBLIC'))",
220
+ " )",
221
+ ") then 1 else 0 end)"
222
+ ]
223
+ },
202
224
  "{schema}.insert_token": {
203
225
  "params": ["sys_user_token_hash","sys_user_token_ext","sys_user_token_keys"],
204
226
  "sql": [
@@ -4,7 +4,8 @@
4
4
  "caption": "Deployment Target Role Type",
5
5
  "init_data": [
6
6
  { "code_val": "PUBLISH", "code_txt": "Publish", "code_seq": 1 },
7
- { "code_val": "EDITOR", "code_txt": "Preview / Editor", "code_seq": 2 }
7
+ { "code_val": "PUBLISH_RELEASE", "code_txt": "Publish Release", "code_seq": 2 },
8
+ { "code_val": "EDITOR", "code_txt": "Preview / Editor", "code_seq": 3 }
8
9
  ]
9
10
  },
10
11
 
@@ -153,6 +154,16 @@
153
154
  " when exists(select * from deployment_target_role dtr inner join {schema}.sys_user_site r on r.sys_user_site_access = dtr.sys_role_name and r.sys_user_id = jsharmony.my_sys_user_id() and r.site_id = deployment_target.site_id and dtr.deployment_target_role_type='PUBLISH' and dtr.deployment_target_id = deployment_target.deployment_target_id) then 1",
154
155
  " else 0 end"
155
156
  ]
157
+ },
158
+ {
159
+ "name":"deployment_target_can_publish_release", "type": "int",
160
+ "sqlselect": [
161
+ "case ",
162
+ " when {schema}.my_user_is_publisher(deployment_target.site_id) = 0 then 0",
163
+ " when exists(select * from deployment_target_role dtr inner join jsharmony.sys_user_role r on r.sys_role_name = dtr.sys_role_name and r.sys_user_id = jsharmony.my_sys_user_id() and dtr.deployment_target_role_type='PUBLISH_RELEASE' and dtr.deployment_target_id = deployment_target.deployment_target_id) then 1",
164
+ " when exists(select * from deployment_target_role dtr inner join {schema}.sys_user_site r on r.sys_user_site_access = dtr.sys_role_name and r.sys_user_id = jsharmony.my_sys_user_id() and r.site_id = deployment_target.site_id and dtr.deployment_target_role_type='PUBLISH_RELEASE' and dtr.deployment_target_id = deployment_target.deployment_target_id) then 1",
165
+ " else 0 end"
166
+ ]
156
167
  }
157
168
  ]
158
169
  }
@@ -181,7 +192,7 @@
181
192
  "deployment_etstmp",
182
193
  "deployment_euser",
183
194
  "deployment_mtstmp",
184
- "deployment_muser"
195
+ "deployment_muser",
185
196
  ]
186
197
  },
187
198
  "v_my_deployment_target": {
@@ -191,14 +202,14 @@
191
202
  "join_type": "inner",
192
203
  "join_columns": {
193
204
  "deployment.deployment_target_id": "v_my_deployment_target.deployment_target_id",
194
- "deployment_target_can_publish": "1"
205
+ "case when deployment_target_can_publish = 1 then 1 else when deployment_target_can_publish_release = 1 then 1 else 0 end": "1"
195
206
  }
196
207
  }
197
208
  },
198
209
  "triggers": [
199
210
  {"on": ["insert"], "exec": [
200
211
  //Verify access
201
- "errorif(not exists(select 1 from {schema}.v_my_deployment_target where v_my_deployment_target.deployment_target_id=inserted(deployment_target_id) and deployment_target_can_publish=1),'No access to publish to this deployment target.');",
212
+ "errorif($ifnull({schema}.can_publish(inserted(branch_id), inserted(deployment_target_id)),0)<>1,'No access to publish to this deployment target.');",
202
213
  //Verify non-duplicate tag name
203
214
  "errorif(exists(select 1 from {schema}.deployment inner join {schema}.branch on {schema}.branch.branch_id={schema}.deployment.branch_id where deployment_tag=inserted(deployment_tag) and site_id=inserted(site_id)),'Deployment Tag must be unique for the site.');",
204
215
  "errorif(exists(select 1 from {schema}.deployment inner join {schema}.deployment_target on {schema}.deployment_target.deployment_target_id={schema}.deployment.deployment_target_id where deployment_tag=inserted(deployment_tag) and site_id=(select site_id from deployment_target where deployment_target_id=inserted(deployment_target_id))),'Deployment Tag must be unique for the site.');",
@@ -218,7 +229,7 @@
218
229
  },
219
230
  {"on": ["update"], "exec": [
220
231
  //Verify access
221
- "errorif(not exists(select 1 from {schema}.v_my_deployment_target where v_my_deployment_target.deployment_target_id=(select deployment_target_id from {schema}.deployment where deployment_id = deleted(deployment_id)) and deployment_target_can_publish=1),'No access to cancel to this deployment.');",
232
+ "errorif($ifnull({schema}.could_have_published((select branch_id from {schema}.deployment where deployment_id = deleted(deployment_id)), (select deployment_target_id from {schema}.deployment where deployment_id = deleted(deployment_id))),0)<>1,'No access to cancel this deployment.');",
222
233
  "update {schema}.deployment set deployment_sts = 'CANCEL' where deployment_id = deleted(deployment_id)"
223
234
  ]
224
235
  }
@@ -0,0 +1,3 @@
1
+ jsharmony.version_increment('jsHarmonyCMS',1,5,7,0);
2
+ update {schema}.code_deployment_target_role_type set code_seq=3 where code_val='EDITOR';
3
+ insert into {schema}.code_deployment_target_role_type(code_val, code_txt, code_seq) values ('PUBLISH_RELEASE','Publish Release',2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsharmony-cms",
3
- "version": "1.5.4",
3
+ "version": "1.5.8",
4
4
  "description": "jsHarmony CMS",
5
5
  "main": "index.js",
6
6
  "scripts": {