json-object-editor 0.10.437 → 0.10.439
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.
- package/CHANGELOG.md +2 -0
- package/js/JsonObjectEditor.jquery.craydent.js +11 -2
- package/js/joe-full.js +11 -2
- package/js/joe.js +11 -2
- package/package.json +3 -1
- package/server/modules/Sites.js +8 -3
- package/server/modules/UniversalShorthand.js +1 -0
- package/server/plugins/notifier.js +127 -60
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
## CHANGELOG
|
|
2
2
|
|
|
3
3
|
### 0.10.400
|
|
4
|
+
439 - Enhanced route handling in Sites.js to support paths with and without leading slashes.
|
|
5
|
+
438 - enhance get function with itemtype parameter, and improve notifier functionality
|
|
4
6
|
437 - tagsList optimized using cache
|
|
5
7
|
436 - tags listRender
|
|
6
8
|
435 - and add user-select property to capp-menu-label
|
|
@@ -7340,13 +7340,18 @@ Field Rendering Helpers
|
|
|
7340
7340
|
}
|
|
7341
7341
|
window.$J = window.$J || {
|
|
7342
7342
|
_usages:{get:0,schema:0,search:0},
|
|
7343
|
-
get : function(itemID,callback){
|
|
7343
|
+
get : function(itemID,callback,itemtype){
|
|
7344
|
+
if(typeof callback == 'string' && !itemtype){
|
|
7345
|
+
itemtype = callback;
|
|
7346
|
+
callback = null;
|
|
7347
|
+
}
|
|
7344
7348
|
$J._usages.get++;
|
|
7345
|
-
var item = self.getDataItem(itemID) || $J.search({_id:itemID})[0] ;
|
|
7349
|
+
var item = self.getDataItem(itemID,itemtype) || $J.search({_id:itemID})[0] ;
|
|
7346
7350
|
if(item){
|
|
7347
7351
|
callback && callback(item);
|
|
7348
7352
|
return item;
|
|
7349
7353
|
}
|
|
7354
|
+
return false;
|
|
7350
7355
|
},
|
|
7351
7356
|
|
|
7352
7357
|
schema : function(schemaname,callback){
|
|
@@ -7831,6 +7836,10 @@ Field Rendering Helpers
|
|
|
7831
7836
|
oldObj:$.extend({},self.current.object),
|
|
7832
7837
|
callback:function(data){
|
|
7833
7838
|
self.showMessage(data.name +' updated successfully');
|
|
7839
|
+
//update the cache version
|
|
7840
|
+
if(self.Cache.lookup[data._id]){
|
|
7841
|
+
self.Cache.lookup[data._id] = data;
|
|
7842
|
+
}
|
|
7834
7843
|
},
|
|
7835
7844
|
ajaxObj: self.constructObjectFromFields(self.joe_index),
|
|
7836
7845
|
overwrites:{},
|
package/js/joe-full.js
CHANGED
|
@@ -18645,13 +18645,18 @@ Field Rendering Helpers
|
|
|
18645
18645
|
}
|
|
18646
18646
|
window.$J = window.$J || {
|
|
18647
18647
|
_usages:{get:0,schema:0,search:0},
|
|
18648
|
-
get : function(itemID,callback){
|
|
18648
|
+
get : function(itemID,callback,itemtype){
|
|
18649
|
+
if(typeof callback == 'string' && !itemtype){
|
|
18650
|
+
itemtype = callback;
|
|
18651
|
+
callback = null;
|
|
18652
|
+
}
|
|
18649
18653
|
$J._usages.get++;
|
|
18650
|
-
var item = self.getDataItem(itemID) || $J.search({_id:itemID})[0] ;
|
|
18654
|
+
var item = self.getDataItem(itemID,itemtype) || $J.search({_id:itemID})[0] ;
|
|
18651
18655
|
if(item){
|
|
18652
18656
|
callback && callback(item);
|
|
18653
18657
|
return item;
|
|
18654
18658
|
}
|
|
18659
|
+
return false;
|
|
18655
18660
|
},
|
|
18656
18661
|
|
|
18657
18662
|
schema : function(schemaname,callback){
|
|
@@ -19136,6 +19141,10 @@ Field Rendering Helpers
|
|
|
19136
19141
|
oldObj:$.extend({},self.current.object),
|
|
19137
19142
|
callback:function(data){
|
|
19138
19143
|
self.showMessage(data.name +' updated successfully');
|
|
19144
|
+
//update the cache version
|
|
19145
|
+
if(self.Cache.lookup[data._id]){
|
|
19146
|
+
self.Cache.lookup[data._id] = data;
|
|
19147
|
+
}
|
|
19139
19148
|
},
|
|
19140
19149
|
ajaxObj: self.constructObjectFromFields(self.joe_index),
|
|
19141
19150
|
overwrites:{},
|
package/js/joe.js
CHANGED
|
@@ -7346,13 +7346,18 @@ Field Rendering Helpers
|
|
|
7346
7346
|
}
|
|
7347
7347
|
window.$J = window.$J || {
|
|
7348
7348
|
_usages:{get:0,schema:0,search:0},
|
|
7349
|
-
get : function(itemID,callback){
|
|
7349
|
+
get : function(itemID,callback,itemtype){
|
|
7350
|
+
if(typeof callback == 'string' && !itemtype){
|
|
7351
|
+
itemtype = callback;
|
|
7352
|
+
callback = null;
|
|
7353
|
+
}
|
|
7350
7354
|
$J._usages.get++;
|
|
7351
|
-
var item = self.getDataItem(itemID) || $J.search({_id:itemID})[0] ;
|
|
7355
|
+
var item = self.getDataItem(itemID,itemtype) || $J.search({_id:itemID})[0] ;
|
|
7352
7356
|
if(item){
|
|
7353
7357
|
callback && callback(item);
|
|
7354
7358
|
return item;
|
|
7355
7359
|
}
|
|
7360
|
+
return false;
|
|
7356
7361
|
},
|
|
7357
7362
|
|
|
7358
7363
|
schema : function(schemaname,callback){
|
|
@@ -7837,6 +7842,10 @@ Field Rendering Helpers
|
|
|
7837
7842
|
oldObj:$.extend({},self.current.object),
|
|
7838
7843
|
callback:function(data){
|
|
7839
7844
|
self.showMessage(data.name +' updated successfully');
|
|
7845
|
+
//update the cache version
|
|
7846
|
+
if(self.Cache.lookup[data._id]){
|
|
7847
|
+
self.Cache.lookup[data._id] = data;
|
|
7848
|
+
}
|
|
7840
7849
|
},
|
|
7841
7850
|
ajaxObj: self.constructObjectFromFields(self.joe_index),
|
|
7842
7851
|
overwrites:{},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-object-editor",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.439",
|
|
4
4
|
"description": "JOE the Json Object Editor | Platform Edition",
|
|
5
5
|
"main": "app.js",
|
|
6
6
|
"scripts": {
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"cookie-parser": "^1.4.1",
|
|
37
37
|
"craydent": "^0.8.9",
|
|
38
38
|
"express": "^4.16.4",
|
|
39
|
+
"googleapis": "^149.0.0",
|
|
39
40
|
"got": "^12.6.0",
|
|
40
41
|
"jwt-decode": "^2.2.0",
|
|
41
42
|
"mailgun": "^0.5.0",
|
|
@@ -43,6 +44,7 @@
|
|
|
43
44
|
"mysql": "^2.16.0",
|
|
44
45
|
"nodemailer": "^2.7.2",
|
|
45
46
|
"nodemailer-ses-transport": "^1.4.0",
|
|
47
|
+
"openai": "^5.0.1",
|
|
46
48
|
"opener": "^1.4.3",
|
|
47
49
|
"pem": "^1.13.2",
|
|
48
50
|
"plaid": "^13.1.0",
|
package/server/modules/Sites.js
CHANGED
|
@@ -321,6 +321,7 @@ var Blocks = {
|
|
|
321
321
|
|
|
322
322
|
|
|
323
323
|
SitesServer.parseRoute = function(req,res,next){
|
|
324
|
+
const origin = req?.headers?.referer && new URL(req.headers.referer).origin;
|
|
324
325
|
var routeStartTimer = new Date().getTime();
|
|
325
326
|
var mixins = {};
|
|
326
327
|
var DYNAMIC={};
|
|
@@ -371,8 +372,10 @@ logit('\n\r'+modulename+new Date()+' siteurl: '+siteurl+' site: '+(site && site.
|
|
|
371
372
|
datasets[ds] = JOE.Data[ds];
|
|
372
373
|
});
|
|
373
374
|
|
|
374
|
-
|
|
375
|
-
var
|
|
375
|
+
var route = payload.siteRoute || '';
|
|
376
|
+
var routeWithSlash = route.startsWith('/') ? route : '/' + route;
|
|
377
|
+
var routeWithoutSlash = route.startsWith('/') ? route.slice(1) : route;
|
|
378
|
+
var page = JOE.Data.page.where({$and:[{site:site._id},{path:{$in:[routeWithSlash,routeWithoutSlash]}}]})[0]
|
|
376
379
|
|| findDynamicPage(payload.originalURL,site,req);
|
|
377
380
|
|
|
378
381
|
if(!page){
|
|
@@ -516,7 +519,9 @@ logit('\n\r'+modulename+new Date()+' siteurl: '+siteurl+' site: '+(site && site.
|
|
|
516
519
|
DATA:datasets,
|
|
517
520
|
PLUGIN:{str:pluginstr},
|
|
518
521
|
WEBCONFIG:JOE.webconfig,
|
|
519
|
-
SECTION:section_content||{}
|
|
522
|
+
SECTION:section_content||{},
|
|
523
|
+
REQUEST:req,
|
|
524
|
+
ORIGIN:origin
|
|
520
525
|
};
|
|
521
526
|
if (pluginstr){
|
|
522
527
|
content.PAGE.content = pluginstr;
|
|
@@ -1,62 +1,62 @@
|
|
|
1
1
|
var nodemailer = require('nodemailer');
|
|
2
2
|
var ses = require('nodemailer-ses-transport');
|
|
3
|
-
|
|
4
|
-
function Notifier(){
|
|
3
|
+
|
|
4
|
+
function Notifier() {
|
|
5
5
|
var self = this;
|
|
6
6
|
this.info = {
|
|
7
|
-
info:"This plugin sends notifications via email",
|
|
8
|
-
specs:['notification','recipient']
|
|
9
|
-
|
|
7
|
+
info: "This plugin sends notifications via email",
|
|
8
|
+
specs: ['notification', 'recipient']
|
|
9
|
+
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
this.default = function(data,req,res){
|
|
12
|
+
this.default = function (data, req, res) {
|
|
13
13
|
var payload = {};
|
|
14
14
|
//get NOTIFICATION
|
|
15
|
-
var notificationID = data.notification||'';
|
|
16
|
-
|
|
17
|
-
var notification = JOE.Cache.findByID('notification',notificationID);
|
|
18
|
-
if(!data.notification || !notification){
|
|
19
|
-
return {error:'notification not found'};
|
|
15
|
+
var notificationID = data.notification || '';
|
|
16
|
+
|
|
17
|
+
var notification = JOE.Cache.findByID('notification', notificationID);
|
|
18
|
+
if (!data.notification || !notification) {
|
|
19
|
+
return { error: 'notification not found' };
|
|
20
20
|
}
|
|
21
21
|
payload.NOTIFICATION = notification;
|
|
22
22
|
//GET recipient
|
|
23
|
-
var recipientID = data.recipient||(data._recipient && data._recipient._id) || '';
|
|
24
|
-
var recipient = data._recipient || JOE.Cache.findByID(notification.dataset,recipientID);
|
|
25
|
-
if(!recipient){
|
|
26
|
-
return {error:'recipient not found'};
|
|
23
|
+
var recipientID = data.recipient || (data._recipient && data._recipient._id) || '';
|
|
24
|
+
var recipient = data._recipient || JOE.Cache.findByID(notification.dataset, recipientID);
|
|
25
|
+
if (!recipient) {
|
|
26
|
+
return { error: 'recipient not found' };
|
|
27
27
|
}
|
|
28
28
|
payload.RECIPIENT = recipient;
|
|
29
29
|
// console.log(notificationID);
|
|
30
30
|
// var notification = JOE.Cache.findByID('notification',data.recipient||'');
|
|
31
31
|
|
|
32
|
-
var ses_config = tryEval(JOE.Cache.settings.AWS_SESCONFIG)||{};
|
|
33
|
-
ses_config.correctClockSkew =true;
|
|
32
|
+
var ses_config = tryEval(JOE.Cache.settings.AWS_SESCONFIG) || {};
|
|
33
|
+
ses_config.correctClockSkew = true;
|
|
34
34
|
var transporter = nodemailer.createTransport(ses(ses_config));
|
|
35
35
|
var mailOptions = {
|
|
36
36
|
from: notification.from, // sender address
|
|
37
|
-
to: fillTemplate(notification.to,payload), // list of receivers
|
|
38
|
-
subject: fillTemplate(notification.subject,payload), // Subject line
|
|
39
|
-
text: fillTemplate(notification.text,payload), // plaintext body
|
|
40
|
-
html: fillTemplate(notification.content,payload) // html body
|
|
37
|
+
to: fillTemplate(notification.to, payload), // list of receivers
|
|
38
|
+
subject: fillTemplate(notification.subject, payload), // Subject line
|
|
39
|
+
text: fillTemplate(notification.text, payload), // plaintext body
|
|
40
|
+
html: fillTemplate(notification.content, payload) // html body
|
|
41
41
|
};
|
|
42
|
-
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
|
|
44
|
+
transporter.sendMail(mailOptions, function (error, info) {
|
|
45
|
+
if (error) {
|
|
46
46
|
res && res.send(error);
|
|
47
47
|
return console.log(error);
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
res && res.send({ status: 'success', info: info });
|
|
50
50
|
return;
|
|
51
51
|
});
|
|
52
|
-
|
|
53
|
-
if(res){
|
|
54
|
-
return {use_callback:true};
|
|
55
|
-
}else{
|
|
56
|
-
return {data:data};
|
|
52
|
+
|
|
53
|
+
if (res) {
|
|
54
|
+
return { use_callback: true };
|
|
55
|
+
} else {
|
|
56
|
+
return { data: data };
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
this.sendNotification = function(notificationIDs,payload,callback){
|
|
59
|
+
this.sendNotification = function (notificationIDs, payload, callback) {
|
|
60
60
|
// var notificationID = 'e9761fed-7a50-4c0f-9f59-663a2a955a2a';
|
|
61
61
|
// var payload ={MEMBER:{
|
|
62
62
|
// first_name:'Corey',
|
|
@@ -64,29 +64,29 @@ function Notifier(){
|
|
|
64
64
|
// name:'craql'
|
|
65
65
|
// }}
|
|
66
66
|
//console.log(typeof notificationIDs);
|
|
67
|
-
if(typeof notificationIDs == "string"){
|
|
67
|
+
if (typeof notificationIDs == "string") {
|
|
68
68
|
notificationIDs = [notificationIDs];
|
|
69
69
|
}
|
|
70
|
-
(notificationIDs ||[]).map(function(notificationID){
|
|
71
|
-
if($c.isCuid(notificationID)){
|
|
72
|
-
var notification = JOE.Cache.findByID('notification',notificationID);
|
|
73
|
-
}else{
|
|
74
|
-
var notification = JOE.Cache.findByID('notification',notificationID,{idprop:'notification_code'});
|
|
70
|
+
(notificationIDs || []).map(function (notificationID) {
|
|
71
|
+
if ($c.isCuid(notificationID)) {
|
|
72
|
+
var notification = JOE.Cache.findByID('notification', notificationID);
|
|
73
|
+
} else {
|
|
74
|
+
var notification = JOE.Cache.findByID('notification', notificationID, { idprop: 'notification_code' });
|
|
75
75
|
}
|
|
76
|
-
if(!notification){
|
|
77
|
-
console.log(JOE.Utils.color('[plugin]','error')+' error: notification not found sendNotification('+notificationID+') ');
|
|
78
|
-
return {error:'notification not found'};
|
|
76
|
+
if (!notification) {
|
|
77
|
+
console.log(JOE.Utils.color('[plugin]', 'error') + ' error: notification not found sendNotification(' + notificationID + ') ');
|
|
78
|
+
return { error: 'notification not found' };
|
|
79
79
|
}
|
|
80
|
-
if(!notification.from){
|
|
81
|
-
return {error:'no sender for notification: '+notification.name};
|
|
80
|
+
if (!notification.from) {
|
|
81
|
+
return { error: 'no sender for notification: ' + notification.name };
|
|
82
82
|
}
|
|
83
|
-
if(!notification.to || !notification.to.length){
|
|
84
|
-
return {error:'no recipient for notification: '+notification.name};
|
|
83
|
+
if (!notification.to || !notification.to.length) {
|
|
84
|
+
return { error: 'no recipient for notification: ' + notification.name };
|
|
85
85
|
}
|
|
86
|
-
if(notification.notification_type == "email"){
|
|
86
|
+
if (notification.notification_type == "email") {
|
|
87
87
|
self.sendEmail(
|
|
88
88
|
notification.subject,
|
|
89
|
-
{html:notification.content,text:notification.content},
|
|
89
|
+
{ html: notification.content, text: notification.content },
|
|
90
90
|
notification.from,
|
|
91
91
|
notification.to,
|
|
92
92
|
payload,
|
|
@@ -94,32 +94,99 @@ function Notifier(){
|
|
|
94
94
|
)
|
|
95
95
|
}
|
|
96
96
|
})
|
|
97
|
-
|
|
97
|
+
|
|
98
98
|
}
|
|
99
|
-
this.sendEmail = function(subject,content, from, recipient,payload,callback){
|
|
99
|
+
this.sendEmail = function (subject, content, from, recipient, payload, callback) {
|
|
100
100
|
var payload = payload || {};
|
|
101
|
-
var ses_config = tryEval(JOE.Cache.settings.AWS_SESCONFIG)||{};
|
|
102
|
-
ses_config.correctClockSkew =true;
|
|
101
|
+
var ses_config = tryEval(JOE.Cache.settings.AWS_SESCONFIG) || {};
|
|
102
|
+
ses_config.correctClockSkew = true;
|
|
103
103
|
var transporter = nodemailer.createTransport(ses(ses_config));
|
|
104
104
|
var mailOptions = {
|
|
105
105
|
from: from, // sender address
|
|
106
|
-
to: fillTemplate(recipient,payload), // list of receivers
|
|
107
|
-
subject: fillTemplate(subject,payload), // Subject line
|
|
108
|
-
text: fillTemplate((content.text || content),payload), // plaintext body
|
|
109
|
-
html: fillTemplate((content.html || content),payload) // html body
|
|
106
|
+
to: fillTemplate(recipient, payload), // list of receivers
|
|
107
|
+
subject: fillTemplate(subject, payload), // Subject line
|
|
108
|
+
text: fillTemplate((content.text || content), payload), // plaintext body
|
|
109
|
+
html: fillTemplate((content.html || content), payload) // html body
|
|
110
110
|
};
|
|
111
|
-
transporter.sendMail(mailOptions, function(error, info){
|
|
112
|
-
if(error){
|
|
113
|
-
|
|
111
|
+
transporter.sendMail(mailOptions, function (error, info) {
|
|
112
|
+
if (error) {
|
|
113
|
+
|
|
114
114
|
callback && callback(error);
|
|
115
115
|
return console.log(error);
|
|
116
116
|
}
|
|
117
|
-
|
|
117
|
+
callback && callback(null, { status: 'success' });
|
|
118
118
|
return;
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
|
+
this.sendRawEmail = function (data, req, res) {
|
|
122
|
+
const payload = data.payload || {};
|
|
123
|
+
let recipients = data.to;
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
// If `to` is a stringified JSON array, parse it (for GET or form cases)
|
|
127
|
+
if (typeof recipients === 'string' && recipients.startsWith('[')) {
|
|
128
|
+
recipients = JSON.parse(recipients);
|
|
129
|
+
}
|
|
130
|
+
} catch (e) {
|
|
131
|
+
return res?.send?.({ error: 'Invalid "to" field: array parsing failed' });
|
|
132
|
+
}
|
|
133
|
+
self.sendMultiTransportEmail(
|
|
134
|
+
fillTemplate(data.subject, payload),
|
|
135
|
+
{
|
|
136
|
+
text: data.text,
|
|
137
|
+
html: data.html
|
|
138
|
+
},
|
|
139
|
+
fillTemplate(data.from, payload),
|
|
140
|
+
recipients,
|
|
141
|
+
payload,
|
|
142
|
+
function (err, result) {
|
|
143
|
+
if (err) {
|
|
144
|
+
console.error('[notifier] sendRawEmail error:', err);
|
|
145
|
+
res?.send?.({error:err});
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
res?.send?.(result);
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
return res ? { use_callback: true } : { status: 'queued' };
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
this.sendMultiTransportEmail = function (subject, content, from, recipients, payload, callback) {
|
|
156
|
+
const smtpConfig = tryEval(JOE.Cache.settings.SMTP_CONFIG);
|
|
157
|
+
const sesConfig = tryEval(JOE.Cache.settings.AWS_SESCONFIG);
|
|
158
|
+
|
|
159
|
+
let transporter;
|
|
160
|
+
if (smtpConfig && smtpConfig.auth?.user) {
|
|
161
|
+
transporter = nodemailer.createTransport(smtpConfig);
|
|
162
|
+
} else if (sesConfig?.accessKeyId) {
|
|
163
|
+
sesConfig.correctClockSkew = true;
|
|
164
|
+
transporter = nodemailer.createTransport(ses(sesConfig));
|
|
165
|
+
} else {
|
|
166
|
+
const err = new Error('No valid SMTP or SES configuration found.');
|
|
167
|
+
callback?.(err);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const resolvedTo = Array.isArray(recipients)
|
|
171
|
+
? recipients.map(r => fillTemplate(r, payload)).join(', ')
|
|
172
|
+
: fillTemplate(recipients, payload);
|
|
173
|
+
const mailOptions = {
|
|
174
|
+
from,
|
|
175
|
+
to: resolvedTo,
|
|
176
|
+
subject: fillTemplate(subject, payload),
|
|
177
|
+
text: fillTemplate(content.text || content, payload),
|
|
178
|
+
html: fillTemplate(content.html || content, payload)
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
transporter.sendMail(mailOptions, (err, info) => {
|
|
182
|
+
if (err) return callback?.(err);
|
|
183
|
+
callback?.(null, { status: 'success', info });
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
|
|
121
188
|
|
|
122
|
-
this.protected = ['sendEmail','sendNotification'];
|
|
123
|
-
return self;
|
|
189
|
+
this.protected = ['sendEmail', 'sendDynamicEmail', 'sendNotification'];
|
|
190
|
+
return self;
|
|
124
191
|
}
|
|
125
192
|
module.exports = new Notifier();
|