@adobe/acc-js-sdk 1.0.3 → 1.0.7
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/.github/workflows/codeql-analysis.yml +70 -0
- package/.vscode/launch.json +0 -1
- package/CHANGELOG.md +37 -1
- package/README.md +63 -3
- package/compile.js +2 -0
- package/package-lock.json +2438 -3367
- package/package.json +10 -7
- package/samples/002 - basics - schemas.js +3 -3
- package/samples/020 - encryption.js +5 -5
- package/src/application.js +66 -5
- package/src/cache.js +275 -0
- package/src/campaign.js +35 -22
- package/src/client.js +246 -125
- package/src/crypto.js +5 -2
- package/src/domUtil.js +53 -20
- package/src/entityAccessor.js +4 -2
- package/src/index.js +107 -105
- package/src/methodCache.js +55 -46
- package/src/optionCache.js +40 -28
- package/src/soap.js +53 -23
- package/src/transport.js +11 -7
- package/src/util.js +103 -64
- package/src/xtkCaster.js +66 -11
- package/src/xtkEntityCache.js +42 -24
- package/test/application.test.js +40 -1
- package/test/caches.test.js +214 -14
- package/test/client.test.js +485 -30
- package/test/crypto.test.js +16 -12
- package/test/domUtil.test.js +23 -0
- package/test/mock.js +52 -10
- package/test/soap.test.js +13 -6
- package/test/util.test.js +151 -1
- package/test/xtkCaster.test.js +97 -0
package/src/optionCache.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/*
|
|
3
2
|
Copyright 2020 Adobe. All rights reserved.
|
|
4
3
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -10,7 +9,8 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
|
|
|
10
9
|
OF ANY KIND, either express or implied. See the License for the specific language
|
|
11
10
|
governing permissions and limitations under the License.
|
|
12
11
|
*/
|
|
13
|
-
|
|
12
|
+
(function() {
|
|
13
|
+
"use strict";
|
|
14
14
|
|
|
15
15
|
/**********************************************************************************
|
|
16
16
|
*
|
|
@@ -18,6 +18,8 @@ governing permissions and limitations under the License.
|
|
|
18
18
|
*
|
|
19
19
|
*********************************************************************************/
|
|
20
20
|
const XtkCaster = require('./xtkCaster.js').XtkCaster;
|
|
21
|
+
const { Cache } = require('./cache.js');
|
|
22
|
+
|
|
21
23
|
|
|
22
24
|
/**
|
|
23
25
|
* @namespace Campaign
|
|
@@ -31,23 +33,40 @@ const XtkCaster = require('./xtkCaster.js').XtkCaster;
|
|
|
31
33
|
|
|
32
34
|
|
|
33
35
|
/**
|
|
34
|
-
* A in-memory cache for xtk option values. Not intended to be used directly,
|
|
35
|
-
* but an internal cache for the Campaign.Client object
|
|
36
|
-
*
|
|
37
36
|
* @private
|
|
38
37
|
* @class
|
|
39
38
|
* @constructor
|
|
40
39
|
* @memberof Campaign
|
|
41
40
|
*/
|
|
42
|
-
class OptionCache {
|
|
41
|
+
class OptionCache extends Cache {
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
/**
|
|
44
|
+
* A in-memory cache for xtk option values. Not intended to be used directly,
|
|
45
|
+
* but an internal cache for the Campaign.Client object
|
|
46
|
+
*
|
|
47
|
+
* Cached object are made of
|
|
48
|
+
* - the key is the option name
|
|
49
|
+
* - the value is the option, a JSON object made of value, type, and rawValue properties
|
|
50
|
+
*
|
|
51
|
+
* @param {Storage} storage is an optional Storage object, such as localStorage or sessionStorage
|
|
52
|
+
* @param {string} rootKey is an optional root key to use for the storage object
|
|
53
|
+
* @param {number} ttl is the TTL for objects in ms. Defaults to 5 mins
|
|
54
|
+
*/
|
|
55
|
+
constructor(storage, rootKey, ttl) {
|
|
56
|
+
super(storage, rootKey, ttl);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Cache an option and its value
|
|
61
|
+
* For backward compatibility purpose. Use "put" instead
|
|
62
|
+
*
|
|
63
|
+
* @deprecated
|
|
64
|
+
* @param {string} name is the option name
|
|
65
|
+
* @param {Array} rawValueAndtype a 2 elements array, whose first element is the raw option value (text serialized) and the second element
|
|
66
|
+
* is the data type of the option. Such an array is returned by the xtk:session#GetOption method
|
|
67
|
+
*/
|
|
68
|
+
cache(schemaId, methodName) {
|
|
69
|
+
return this.put(schemaId, methodName);
|
|
51
70
|
}
|
|
52
71
|
|
|
53
72
|
/**
|
|
@@ -57,16 +76,16 @@ class OptionCache {
|
|
|
57
76
|
* @param {Array} rawValueAndtype a 2 elements array, whose first element is the raw option value (text serialized) and the second element
|
|
58
77
|
* is the data type of the option. Such an array is returned by the xtk:session#GetOption method
|
|
59
78
|
*/
|
|
60
|
-
|
|
79
|
+
put(name, rawValueAndtype) {
|
|
61
80
|
var value = null;
|
|
62
81
|
var type = 0;
|
|
63
|
-
var rawValue
|
|
82
|
+
var rawValue;
|
|
64
83
|
if (rawValueAndtype && rawValueAndtype[1] != 0) {
|
|
65
84
|
rawValue = rawValueAndtype[0];
|
|
66
85
|
type = rawValueAndtype[1];
|
|
67
86
|
value = XtkCaster.as(rawValue, type);
|
|
68
87
|
}
|
|
69
|
-
|
|
88
|
+
super.put(name, { value:value, type:type, rawValue:rawValue });
|
|
70
89
|
return value;
|
|
71
90
|
}
|
|
72
91
|
|
|
@@ -77,7 +96,7 @@ class OptionCache {
|
|
|
77
96
|
* @returns {*} the option value
|
|
78
97
|
*/
|
|
79
98
|
get(name) {
|
|
80
|
-
const option =
|
|
99
|
+
const option = super.get(name);
|
|
81
100
|
return option ? option.value : undefined;
|
|
82
101
|
}
|
|
83
102
|
|
|
@@ -88,19 +107,12 @@ class OptionCache {
|
|
|
88
107
|
* @returns {Campaign.XtkOption} the option
|
|
89
108
|
*/
|
|
90
109
|
getOption(name) {
|
|
91
|
-
|
|
92
|
-
return option;
|
|
110
|
+
return super.get(name);
|
|
93
111
|
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Clears the cache
|
|
97
|
-
*/
|
|
98
|
-
clear() {
|
|
99
|
-
this._optionsByName = {};
|
|
100
|
-
}
|
|
101
|
-
|
|
102
112
|
}
|
|
103
113
|
|
|
104
114
|
|
|
105
115
|
// Public exports
|
|
106
|
-
exports.OptionCache = OptionCache;
|
|
116
|
+
exports.OptionCache = OptionCache;
|
|
117
|
+
|
|
118
|
+
})();
|
package/src/soap.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/*
|
|
3
2
|
Copyright 2020 Adobe. All rights reserved.
|
|
4
3
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -10,7 +9,9 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
|
|
|
10
9
|
OF ANY KIND, either express or implied. See the License for the specific language
|
|
11
10
|
governing permissions and limitations under the License.
|
|
12
11
|
*/
|
|
13
|
-
|
|
12
|
+
(function() {
|
|
13
|
+
"use strict";
|
|
14
|
+
|
|
14
15
|
|
|
15
16
|
/**********************************************************************************
|
|
16
17
|
*
|
|
@@ -92,6 +93,8 @@ class SoapMethodCall {
|
|
|
92
93
|
// Soap calls marked as internal are calls performed by the framework internally
|
|
93
94
|
// (such as GetEntityIfMoreRecent calls needed to lookup schemas)
|
|
94
95
|
this.internal = false;
|
|
96
|
+
// Enable soap retry
|
|
97
|
+
this.retry = true;
|
|
95
98
|
|
|
96
99
|
this._sessionToken = sessionToken || "";
|
|
97
100
|
this._securityToken = securityToken || "";
|
|
@@ -118,7 +121,8 @@ class SoapMethodCall {
|
|
|
118
121
|
* @returns {boolean} indicates if the call requires a Logon first
|
|
119
122
|
*/
|
|
120
123
|
requiresLogon() {
|
|
121
|
-
const requiresLogon = !(this.urn === "xtk:session" &&
|
|
124
|
+
const requiresLogon = !(this.urn === "xtk:session" &&
|
|
125
|
+
(this.methodName === "Logon" || this.methodName === "BearerTokenLogon") ) ;
|
|
122
126
|
return requiresLogon;
|
|
123
127
|
}
|
|
124
128
|
|
|
@@ -149,22 +153,6 @@ class SoapMethodCall {
|
|
|
149
153
|
this._method.setAttribute(`xmlns:m`, urnPath);
|
|
150
154
|
this._method.setAttribute(`SOAP-ENV:encodingStyle`, encoding);
|
|
151
155
|
this._data.appendChild(this._method);
|
|
152
|
-
|
|
153
|
-
if (this._sessionToken) {
|
|
154
|
-
const cookieHeader = this._doc.createElement("Cookie");
|
|
155
|
-
cookieHeader.textContent = `__sessiontoken=${this._sessionToken}`;
|
|
156
|
-
this._header.appendChild(cookieHeader);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const securityTokenHeader = this._doc.createElement("X-Security-Token");
|
|
160
|
-
securityTokenHeader.textContent = this._securityToken;
|
|
161
|
-
this._header.appendChild(securityTokenHeader);
|
|
162
|
-
|
|
163
|
-
// Always write a sessiontoken element as the first parameter. Even when using SecurityToken authentication
|
|
164
|
-
// and when the session token is actually passed implicitely as a cookie, one must write a sessiontoken
|
|
165
|
-
// element. If not, authentication will fail because the first parameter is interpreted as the "authentication mode"
|
|
166
|
-
// and eventually passed as the first parameter of CXtkLocalSessionPart::GetXtkSecurity
|
|
167
|
-
this.writeString("sessiontoken", this._sessionToken);
|
|
168
156
|
}
|
|
169
157
|
|
|
170
158
|
/**
|
|
@@ -514,7 +502,7 @@ class SoapMethodCall {
|
|
|
514
502
|
* @returns a boolean set to true if ther are no more response args to read
|
|
515
503
|
*/
|
|
516
504
|
checkNoMoreArgs() {
|
|
517
|
-
return !this.elemCurrent
|
|
505
|
+
return !this.elemCurrent;
|
|
518
506
|
}
|
|
519
507
|
|
|
520
508
|
/**
|
|
@@ -535,17 +523,55 @@ class SoapMethodCall {
|
|
|
535
523
|
data: DomUtil.toXMLString(this._doc)
|
|
536
524
|
};
|
|
537
525
|
if (this._sessionToken)
|
|
538
|
-
options.headers
|
|
526
|
+
options.headers.Cookie = '__sessiontoken=' + this._sessionToken;
|
|
539
527
|
if (this._userAgentString)
|
|
540
528
|
options.headers['User-Agent'] = this._userAgentString;
|
|
541
529
|
return options;
|
|
542
530
|
}
|
|
543
|
-
|
|
531
|
+
|
|
544
532
|
/**
|
|
545
533
|
* Finalize a SOAP call just before sending
|
|
546
534
|
* @param {string} url the endpoint (/nl/jsp/soaprouter.jsp)
|
|
535
|
+
* @param {client.Client} sdk client (optional)
|
|
547
536
|
*/
|
|
548
|
-
finalize(url) {
|
|
537
|
+
finalize(url, client) {
|
|
538
|
+
if (client) {
|
|
539
|
+
this._sessionToken = client._sessionToken;
|
|
540
|
+
this._securityToken = client._securityToken;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
var cookieHeader = DomUtil.findElement(this._header, "Cookie");
|
|
544
|
+
if (this._sessionToken) {
|
|
545
|
+
if (!cookieHeader) {
|
|
546
|
+
cookieHeader = this._doc.createElement("Cookie");
|
|
547
|
+
this._header.appendChild(cookieHeader);
|
|
548
|
+
}
|
|
549
|
+
cookieHeader.textContent = `__sessiontoken=${this._sessionToken}`;
|
|
550
|
+
} else if (cookieHeader) {
|
|
551
|
+
cookieHeader.remove();
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
var securityTokenHeader = DomUtil.findElement(this._header, "X-Security-Token");
|
|
555
|
+
if (!securityTokenHeader) {
|
|
556
|
+
securityTokenHeader = this._doc.createElement("X-Security-Token");
|
|
557
|
+
this._header.appendChild(securityTokenHeader);
|
|
558
|
+
}
|
|
559
|
+
securityTokenHeader.textContent = this._securityToken;
|
|
560
|
+
|
|
561
|
+
// Always write a sessiontoken element as the first parameter. Even when using SecurityToken authentication
|
|
562
|
+
// and when the session token is actually passed implicitely as a cookie, one must write a sessiontoken
|
|
563
|
+
// element. If not, authentication will fail because the first parameter is interpreted as the "authentication mode"
|
|
564
|
+
// and eventually passed as the first parameter of CXtkLocalSessionPart::GetXtkSecurity
|
|
565
|
+
var sessionTokenElem = DomUtil.findElement(this._method, "sessiontoken");
|
|
566
|
+
if (sessionTokenElem) {
|
|
567
|
+
sessionTokenElem.textContent = this._sessionToken;
|
|
568
|
+
} else {
|
|
569
|
+
sessionTokenElem = this._doc.createElement("sessiontoken");
|
|
570
|
+
sessionTokenElem.setAttribute("xsi:type", "xsd:string");
|
|
571
|
+
// sessionTokenElem.setAttribute("SOAP-ENV:encodingStyle", SOAP_ENCODING_NATIVE);
|
|
572
|
+
sessionTokenElem.textContent = this._sessionToken;
|
|
573
|
+
this._method.prepend(sessionTokenElem);
|
|
574
|
+
}
|
|
549
575
|
const options = this._createHTTPRequest(url);
|
|
550
576
|
// Prepare request and empty response objects
|
|
551
577
|
this.request = options;
|
|
@@ -563,6 +589,8 @@ class SoapMethodCall {
|
|
|
563
589
|
const that = this;
|
|
564
590
|
const promise = this._transport(this.request);
|
|
565
591
|
return promise.then(function(body) {
|
|
592
|
+
if (body.indexOf(`XSV-350008`) != -1)
|
|
593
|
+
throw CampaignException.SESSION_EXPIRED();
|
|
566
594
|
that.response = body;
|
|
567
595
|
// Response is a serialized XML document with the following structure
|
|
568
596
|
//
|
|
@@ -636,3 +664,5 @@ class SoapMethodCall {
|
|
|
636
664
|
|
|
637
665
|
// Public exports
|
|
638
666
|
exports.SoapMethodCall = SoapMethodCall;
|
|
667
|
+
|
|
668
|
+
})();
|
package/src/transport.js
CHANGED
|
@@ -9,6 +9,8 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
|
|
|
9
9
|
OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
10
|
governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
|
+
(function() {
|
|
13
|
+
"use strict";
|
|
12
14
|
|
|
13
15
|
const { Util } = require('./util.js');
|
|
14
16
|
|
|
@@ -70,9 +72,8 @@ if (!Util.isBrowser()) {
|
|
|
70
72
|
return Promise.reject(new HttpError(500, error ? error.toString() : undefined));
|
|
71
73
|
// HTTP errors (400, 404, 500, etc.) are returned here
|
|
72
74
|
return Promise.reject(new HttpError(response.status, response.statusText, response.data));
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
|
|
75
|
+
});
|
|
76
|
+
};
|
|
76
77
|
|
|
77
78
|
exports.request = request;
|
|
78
79
|
exports.HttpError = HttpError;
|
|
@@ -107,13 +108,16 @@ if (!Util.isBrowser()) {
|
|
|
107
108
|
return blob.text();
|
|
108
109
|
});
|
|
109
110
|
}).catch((ex) => {
|
|
110
|
-
|
|
111
|
+
const proto = Object.getPrototypeOf(ex);
|
|
112
|
+
if (proto.constructor.name == "HttpError")
|
|
111
113
|
throw ex;
|
|
112
114
|
throw new HttpError(ex.status, ex.statusText);
|
|
113
|
-
})
|
|
115
|
+
});
|
|
114
116
|
return p;
|
|
115
|
-
}
|
|
117
|
+
};
|
|
116
118
|
|
|
117
119
|
module.exports.request = request;
|
|
118
120
|
|
|
119
|
-
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
})();
|
package/src/util.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
1
|
/*
|
|
4
2
|
Copyright 2020 Adobe. All rights reserved.
|
|
5
3
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -11,7 +9,9 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
|
|
|
11
9
|
OF ANY KIND, either express or implied. See the License for the specific language
|
|
12
10
|
governing permissions and limitations under the License.
|
|
13
11
|
*/
|
|
14
|
-
|
|
12
|
+
(function() {
|
|
13
|
+
"use strict";
|
|
14
|
+
|
|
15
15
|
|
|
16
16
|
/**********************************************************************************
|
|
17
17
|
*
|
|
@@ -20,83 +20,122 @@ governing permissions and limitations under the License.
|
|
|
20
20
|
*********************************************************************************/
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* @namespace
|
|
23
|
+
* @namespace Utils
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
* @memberof Campaign
|
|
27
|
+
* @memberof Utils
|
|
29
28
|
* @class
|
|
30
29
|
* @constructor
|
|
31
30
|
*/
|
|
32
31
|
class Util {
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
static isArray(o) {
|
|
40
|
-
if (o === null || o === undefined) return false;
|
|
41
|
-
// JavaScript arrays are objects
|
|
42
|
-
if (typeof o != "object") return false;
|
|
43
|
-
// They also have a length property. But checking the length is not enough
|
|
44
|
-
// since, it can also be an object litteral with a "length" property. Campaign
|
|
45
|
-
// schema attributes typically have a "length" attribute and are not arrays
|
|
46
|
-
if (o.length === undefined || o.length === null) return false;
|
|
47
|
-
// So check for a "push" function
|
|
48
|
-
if (o.push === undefined || o.push === null) return false;
|
|
49
|
-
if (typeof o.push != "function")
|
|
50
|
-
return false;
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
33
|
+
/**
|
|
34
|
+
* Generic helper functions available everywhere in the SDK. Al functions are static, it is not necessary to create new instances of this object
|
|
35
|
+
*/
|
|
36
|
+
constructor() {
|
|
37
|
+
}
|
|
53
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Indicates whether the SDK is running in a browser or not
|
|
41
|
+
* @returns {boolean} a boolean indicating if the SDK is running in a browser or not
|
|
42
|
+
*/
|
|
43
|
+
static isBrowser() {
|
|
44
|
+
const browser = typeof window !== 'undefined';
|
|
45
|
+
return browser;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Tests if an object is a JavaScript array
|
|
50
|
+
* @param {*} obj the object to test, may be undefined
|
|
51
|
+
* @returns {boolean} true if the object is an array
|
|
52
|
+
*/
|
|
53
|
+
static isArray(obj) {
|
|
54
|
+
if (obj === null || obj === undefined) return false;
|
|
55
|
+
// JavaScript arrays are objects
|
|
56
|
+
if (typeof obj != "object") return false;
|
|
57
|
+
// They also have a length property. But checking the length is not enough
|
|
58
|
+
// since, it can also be an object litteral with a "length" property. Campaign
|
|
59
|
+
// schema attributes typically have a "length" attribute and are not arrays
|
|
60
|
+
if (obj.length === undefined || obj.length === null) return false;
|
|
61
|
+
// So check for a "push" function
|
|
62
|
+
if (obj.push === undefined || obj.push === null) return false;
|
|
63
|
+
if (typeof obj.push != "function")
|
|
64
|
+
return false;
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
54
67
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
text = text.substring(0, index + from.length) + '***' + text.substring(index2);
|
|
65
|
-
index = index2;
|
|
66
|
-
}
|
|
67
|
-
return text;
|
|
68
|
+
// Helper function for trim() to replace text between 2 indices
|
|
69
|
+
static _removeBetween(text, from, to) {
|
|
70
|
+
var index = 0;
|
|
71
|
+
while (index < text.length) {
|
|
72
|
+
index = text.indexOf(from, index);
|
|
73
|
+
if (index == -1) break;
|
|
74
|
+
const index2 = text.indexOf(to, index);
|
|
75
|
+
if (index2 == -1) {
|
|
76
|
+
break;
|
|
68
77
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
text = text.substring(0, index + from.length) + '***' + text.substring(index2);
|
|
79
|
+
index = index2;
|
|
80
|
+
}
|
|
81
|
+
return text;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Trims a text, an object or an array and remove sensitive information, such as session tokens, passwords, etc.
|
|
86
|
+
*
|
|
87
|
+
* @param {string|Object|Array} obj is the object to trim
|
|
88
|
+
* @returns {string|Object|Array} the trimmed object
|
|
89
|
+
*/
|
|
90
|
+
static trim(obj) {
|
|
91
|
+
if (obj == null || obj == undefined) return undefined;
|
|
92
|
+
if (Util.isArray(obj)) {
|
|
93
|
+
const a = [];
|
|
94
|
+
for (const p of obj) {
|
|
95
|
+
a.push(Util.trim(p));
|
|
96
|
+
}
|
|
97
|
+
return a;
|
|
98
|
+
}
|
|
99
|
+
if (typeof obj == "object") {
|
|
100
|
+
for (const p in obj) {
|
|
101
|
+
if (p.toLowerCase() === "x-security-token")
|
|
102
|
+
obj[p] = "***";
|
|
103
|
+
else if (p === "Cookie") {
|
|
104
|
+
var index = obj[p].toLowerCase().indexOf("__sessiontoken");
|
|
105
|
+
if (index !== -1) {
|
|
106
|
+
index = obj[p].indexOf("=", index);
|
|
107
|
+
if (index !== -1) {
|
|
108
|
+
index = index + 1;
|
|
109
|
+
const endIndex = obj[p].indexOf(";", index);
|
|
110
|
+
if (endIndex == -1)
|
|
111
|
+
obj[p] = obj[p].substring(0, index) + "***";
|
|
112
|
+
else
|
|
113
|
+
obj[p] = obj[p].substring(0, index) + "***" + obj[p].substring(endIndex);
|
|
114
|
+
}
|
|
82
115
|
}
|
|
83
116
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
while (text && (text.endsWith(' ') || text.endsWith('\n') || text.endsWith('\r') || text.endsWith('\t')))
|
|
87
|
-
text = text.substring(0, text.length - 1);
|
|
88
|
-
|
|
89
|
-
// Hide session tokens
|
|
90
|
-
text = this._removeBetween(text, "<Cookie>__sessiontoken=", "</Cookie>");
|
|
91
|
-
text = this._removeBetween(text, "<X-Security-Token>", "</X-Security-Token>");
|
|
92
|
-
text = this._removeBetween(text, '<sessiontoken xsi:type="xsd:string">', '</sessiontoken>');
|
|
93
|
-
text = this._removeBetween(text, "<pstrSessionToken xsi:type='xsd:string'>", "</pstrSessionToken>");
|
|
94
|
-
text = this._removeBetween(text, "<pstrSecurityToken xsi:type='xsd:string'>", "</pstrSecurityToken>");
|
|
95
|
-
}
|
|
96
|
-
return text;
|
|
117
|
+
else
|
|
118
|
+
obj[p] = Util.trim(obj[p]);
|
|
97
119
|
}
|
|
120
|
+
}
|
|
121
|
+
if (typeof obj == "string") {
|
|
122
|
+
// Remove trailing blanks
|
|
123
|
+
while (obj && (obj.endsWith(' ') || obj.endsWith('\n') || obj.endsWith('\r') || obj.endsWith('\t')))
|
|
124
|
+
obj = obj.substring(0, obj.length - 1);
|
|
98
125
|
|
|
126
|
+
// Hide session tokens
|
|
127
|
+
obj = this._removeBetween(obj, "<Cookie>__sessiontoken=", "</Cookie>");
|
|
128
|
+
obj = this._removeBetween(obj, "<X-Security-Token>", "</X-Security-Token>");
|
|
129
|
+
obj = this._removeBetween(obj, '<sessiontoken xsi:type="xsd:string">', '</sessiontoken>');
|
|
130
|
+
obj = this._removeBetween(obj, "<pstrSessionToken xsi:type='xsd:string'>", "</pstrSessionToken>");
|
|
131
|
+
obj = this._removeBetween(obj, "<pstrSecurityToken xsi:type='xsd:string'>", "</pstrSecurityToken>");
|
|
132
|
+
obj = this._removeBetween(obj, '<password xsi:type="xsd:string">', '</password>');
|
|
133
|
+
}
|
|
134
|
+
return obj;
|
|
135
|
+
}
|
|
99
136
|
}
|
|
100
137
|
|
|
101
138
|
// Public expots
|
|
102
139
|
exports.Util = Util;
|
|
140
|
+
|
|
141
|
+
})();
|
package/src/xtkCaster.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/*
|
|
3
2
|
Copyright 2020 Adobe. All rights reserved.
|
|
4
3
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -10,7 +9,10 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
|
|
|
10
9
|
OF ANY KIND, either express or implied. See the License for the specific language
|
|
11
10
|
governing permissions and limitations under the License.
|
|
12
11
|
*/
|
|
12
|
+
(function() {
|
|
13
|
+
"use strict";
|
|
13
14
|
|
|
15
|
+
const { Util } = require('./util.js');
|
|
14
16
|
|
|
15
17
|
/**********************************************************************************
|
|
16
18
|
*
|
|
@@ -37,11 +39,15 @@ governing permissions and limitations under the License.
|
|
|
37
39
|
| Xtk type | | JS type | Comment |
|
|
38
40
|
| ------------ |----|-------- | --- |
|
|
39
41
|
| string | 6 | string | never null, defaults to "" |
|
|
40
|
-
| memo | 12 | string |
|
|
41
|
-
| CDATA | 13 | string |
|
|
42
|
+
| memo | 12 | string | large strings. Never null, defaults to ""
|
|
43
|
+
| CDATA | 13 | string | string in the CDATA section of an XML document. Never null, defaults to ""
|
|
44
|
+
| uuid | | string |
|
|
45
|
+
| blob | | string |
|
|
46
|
+
| html | | string |
|
|
42
47
|
| byte | 1 | number | signed integer in the [-128, 128[ range. Never null, defaults to 0 |
|
|
43
48
|
| short | 2 | number | signed 16 bits integer in the [-32768, 32768[ range. Never null, defaults to 0 |
|
|
44
49
|
| long | 3 | number | signed 32 bits integer. Never null, defaults to 0 |
|
|
50
|
+
| int | | number | signed 32 bits integer. Never null, defaults to 0 |
|
|
45
51
|
| int64 | | string | signed 64 bits integer. As JavaScript handles all numbers as doubles, it's not possible to properly represent an int64 as a number, and it's therefore represented as a string.
|
|
46
52
|
| float | 4 | number | single-percision numeric value. Never null, defaults to 0 |
|
|
47
53
|
| double | 5 | number | single-percision numeric value. Never null, defaults to 0 |
|
|
@@ -49,22 +55,24 @@ governing permissions and limitations under the License.
|
|
|
49
55
|
| datetimetz | | | |
|
|
50
56
|
| datetimenotz | | | |
|
|
51
57
|
| date | 10 | Date | UTC timestamp with day precision. Can be null |
|
|
58
|
+
| timespan | 14 | number | A timespan, in seconds
|
|
52
59
|
| boolean | 15 | boolean | boolean value, defaultint to false. Cannot be null |
|
|
53
|
-
|
|
|
60
|
+
| array | | Array | a array or a collection
|
|
54
61
|
|
|
55
|
-
* @typedef {(0|''|6|'string'|'int64'|12|13|'memo'|'CDATA'|1|'byte'|2|'short'|3|'long'|15|'boolean'|4|5|'float'|'double'|7|'datetime'|'datetimetz'|'datetimenotz'|10|'date')} XtkType
|
|
62
|
+
* @typedef {(0|''|6|'string'|'int64'|12|13|'memo'|'CDATA'|1|'byte'|2|'short'|3|'long'|15|'boolean'|4|5|'float'|'double'|7|'datetime'|'datetimetz'|'datetimenotz'|10|'date'|14|'timespan'|'array')} XtkType
|
|
56
63
|
* @memberof Campaign
|
|
57
64
|
*/
|
|
58
65
|
|
|
59
|
-
/**
|
|
60
|
-
* Helpers to convert between JavaScript data types and Campaign XTK data types
|
|
61
|
-
*
|
|
66
|
+
/**
|
|
62
67
|
* @memberof Campaign
|
|
63
68
|
* @class
|
|
64
69
|
* @constructor
|
|
65
70
|
*/
|
|
66
71
|
class XtkCaster {
|
|
67
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Helpers to convert between JavaScript data types and Campaign XTK data types
|
|
75
|
+
*/
|
|
68
76
|
constructor() {
|
|
69
77
|
}
|
|
70
78
|
|
|
@@ -84,10 +92,13 @@ class XtkCaster {
|
|
|
84
92
|
return null;
|
|
85
93
|
case 6: // FIELD_SZ
|
|
86
94
|
case "string":
|
|
95
|
+
case "uuid":
|
|
87
96
|
case "int64":
|
|
88
97
|
return "stringValue";
|
|
89
98
|
case 12: // FIELD_MEMO
|
|
90
99
|
case 13: // FIELD_MEMOSHORT
|
|
100
|
+
case "blob":
|
|
101
|
+
case "html":
|
|
91
102
|
case "memo":
|
|
92
103
|
case "CDATA":
|
|
93
104
|
return "memoValue";
|
|
@@ -96,8 +107,10 @@ class XtkCaster {
|
|
|
96
107
|
case 2: // FIELD_SHORT
|
|
97
108
|
case "short":
|
|
98
109
|
case 3: // FIELD_LONG
|
|
110
|
+
case "int":
|
|
99
111
|
case "long":
|
|
100
|
-
case
|
|
112
|
+
case "timespan":
|
|
113
|
+
case 15: // FIELD_BOOLEAN
|
|
101
114
|
case "boolean":
|
|
102
115
|
return "longValue";
|
|
103
116
|
case 4: // FIELD_FLOAT
|
|
@@ -111,7 +124,7 @@ class XtkCaster {
|
|
|
111
124
|
case "datetimenotz":
|
|
112
125
|
case 10: // FIELD_DATE
|
|
113
126
|
case "date":
|
|
114
|
-
return "timeStampValue"
|
|
127
|
+
return "timeStampValue";
|
|
115
128
|
default: {
|
|
116
129
|
throw CampaignException.BAD_PARAMETER("type", type, `Cannot get variant storage attribute name for type '${type}'`);
|
|
117
130
|
}
|
|
@@ -136,6 +149,9 @@ class XtkCaster {
|
|
|
136
149
|
case 13: // FIELD_MEMOSHORT
|
|
137
150
|
case "string":
|
|
138
151
|
case "memo":
|
|
152
|
+
case "uuid":
|
|
153
|
+
case "blob":
|
|
154
|
+
case "html":
|
|
139
155
|
case "CDATA": {
|
|
140
156
|
return this.asString(value);
|
|
141
157
|
}
|
|
@@ -148,6 +164,7 @@ class XtkCaster {
|
|
|
148
164
|
return this.asShort(value);
|
|
149
165
|
}
|
|
150
166
|
case 3: // FIELD_LONG
|
|
167
|
+
case "int":
|
|
151
168
|
case "long": {
|
|
152
169
|
return this.asLong(value);
|
|
153
170
|
}
|
|
@@ -174,6 +191,13 @@ class XtkCaster {
|
|
|
174
191
|
case "date": {
|
|
175
192
|
return this.asDate(value);
|
|
176
193
|
}
|
|
194
|
+
case "array": {
|
|
195
|
+
return this.asArray(value);
|
|
196
|
+
}
|
|
197
|
+
case 14: // FIELD_TIMESPAN
|
|
198
|
+
case "timespan": {
|
|
199
|
+
return this.asTimespan(value);
|
|
200
|
+
}
|
|
177
201
|
default: {
|
|
178
202
|
throw CampaignException.BAD_PARAMETER("type", type, `Cannot convert value type='${type}', value='${value}'`);
|
|
179
203
|
}
|
|
@@ -353,7 +377,7 @@ class XtkCaster {
|
|
|
353
377
|
}
|
|
354
378
|
|
|
355
379
|
/**
|
|
356
|
-
* Convert a raw value into a
|
|
380
|
+
* Convert a raw value into a date. This is a UTC timestamp where time fields are 0
|
|
357
381
|
*
|
|
358
382
|
* @param {*} value is the raw value to convert
|
|
359
383
|
* @return {Date} a date
|
|
@@ -368,6 +392,37 @@ class XtkCaster {
|
|
|
368
392
|
}
|
|
369
393
|
return timestamp;
|
|
370
394
|
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Convert a raw value into an array (if it is not an array yet). Null and undefined will be
|
|
398
|
+
* converted into an empty array
|
|
399
|
+
*
|
|
400
|
+
* @param {*} value is the raw value to convert
|
|
401
|
+
* @return {Array} a array
|
|
402
|
+
*/
|
|
403
|
+
static asArray(value) {
|
|
404
|
+
if (value === null || value === undefined) return [];
|
|
405
|
+
if (Util.isArray(value)) return value;
|
|
406
|
+
return [value];
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Convert a raw value into a timespan, in seconds
|
|
411
|
+
* @param {*} value is the raw value to convert
|
|
412
|
+
* @returns is the time span, in seconds
|
|
413
|
+
*/
|
|
414
|
+
static asTimespan(value) {
|
|
415
|
+
if (value === null || value === undefined) return 0;
|
|
416
|
+
if ((typeof value) == "string") value = value.trim();
|
|
417
|
+
if (value === "" || value === true || value === false) return 0;
|
|
418
|
+
if (value !== value || value === Number.POSITIVE_INFINITY || value === Number.NEGATIVE_INFINITY) return 0;
|
|
419
|
+
// Number to timespan -> Consider as number of seconds
|
|
420
|
+
var timespan = XtkCaster.asLong(value);
|
|
421
|
+
return timespan;
|
|
422
|
+
}
|
|
423
|
+
|
|
371
424
|
}
|
|
372
425
|
|
|
373
426
|
exports.XtkCaster = XtkCaster;
|
|
427
|
+
|
|
428
|
+
})();
|