@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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/acc-js-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "ACC Javascript SDK",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"homepage": "https://github.com/adobe/acc-js-sdk#readme",
|
|
@@ -10,21 +10,24 @@
|
|
|
10
10
|
"test": "test"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"axios": "^0.
|
|
14
|
-
"jsdom": "^
|
|
13
|
+
"axios": "^0.25.0",
|
|
14
|
+
"jsdom": "^19.0.0"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"docdash": "^1.2.0",
|
|
18
|
-
"eslint": "^7.
|
|
19
|
-
"jest": "^27.
|
|
20
|
-
"jest-junit": "^
|
|
18
|
+
"eslint": "^8.7.0",
|
|
19
|
+
"jest": "^27.4.7",
|
|
20
|
+
"jest-junit": "^13.0.0",
|
|
21
21
|
"jsdoc": "^3.6.7",
|
|
22
|
-
"
|
|
22
|
+
"jshint": "^2.13.3"
|
|
23
23
|
},
|
|
24
24
|
"author": "",
|
|
25
25
|
"scripts": {
|
|
26
26
|
"publish:npm": "npm publish --access public",
|
|
27
27
|
"unit-tests": "jest --config test/jest.config.js --maxWorkers=2",
|
|
28
28
|
"jsdoc": "jsdoc -a all -c jsdoc.json -r -R README.md src/*.js -d docs/jsdoc"
|
|
29
|
+
},
|
|
30
|
+
"jshintConfig": {
|
|
31
|
+
"esversion": 8
|
|
29
32
|
}
|
|
30
33
|
}
|
|
@@ -25,7 +25,7 @@ const utils = require("./utils.js");
|
|
|
25
25
|
code: async() => {
|
|
26
26
|
return await utils.logon(async (client, NLWS) => {
|
|
27
27
|
const schema = await client.getSchema("xtk:option");
|
|
28
|
-
console.log(`>> client.getSchema (current representation)
|
|
28
|
+
console.log(`>> client.getSchema (current representation) : ${JSON.stringify(schema)}`);
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
});
|
|
@@ -38,7 +38,7 @@ const utils = require("./utils.js");
|
|
|
38
38
|
code: async() => {
|
|
39
39
|
return await utils.logon(async (client, NLWS) => {
|
|
40
40
|
const schema = await client.getSchema("xtk:option", "xml");
|
|
41
|
-
console.log(`>> client.getSchema (xml)
|
|
41
|
+
console.log(`>> client.getSchema (xml) : ${client.DomUtil.toXMLString(schema)}`);
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
});
|
|
@@ -52,7 +52,7 @@ const utils = require("./utils.js");
|
|
|
52
52
|
code: async() => {
|
|
53
53
|
return await utils.logon(async (client, NLWS) => {
|
|
54
54
|
const schema = await client.getEntityIfMoreRecent("xtk:srcSchema", "nms:rtEvent");
|
|
55
|
-
console.log(`>> client.getEntityIfMoreRecent
|
|
55
|
+
console.log(`>> client.getEntityIfMoreRecent : ${JSON.stringify(schema)}`);
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
});
|
|
@@ -31,11 +31,11 @@ const utils = require("./utils.js");
|
|
|
31
31
|
code: async() => {
|
|
32
32
|
return await utils.logon(async (client, NLWS) => {
|
|
33
33
|
const password = "Hello, World";
|
|
34
|
-
console.log(`xtk:session#Encrypt
|
|
35
|
-
console.log(`xtk:session#EncryptPassword
|
|
36
|
-
console.log(`xtk:session#EncryptServerPassword
|
|
37
|
-
console.log(`xtk:session#HashPassword
|
|
38
|
-
console.log(`xtk:session#ReEncryptPassword
|
|
34
|
+
console.log(`xtk:session#Encrypt : ${await NLWS.xtkSession.encrypt(password)}`);
|
|
35
|
+
console.log(`xtk:session#EncryptPassword : ${await NLWS.xtkSession.encryptPassword(password)}`);
|
|
36
|
+
console.log(`xtk:session#EncryptServerPassword : ${await NLWS.xtkSession.encryptServerPassword(password)}`);
|
|
37
|
+
console.log(`xtk:session#HashPassword : ${await NLWS.xtkSession.hashPassword(password)}`);
|
|
38
|
+
console.log(`xtk:session#ReEncryptPassword : ${await NLWS.xtkSession.reEncryptPassword(await NLWS.xtkSession.encryptPassword(password))}`);
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
});
|
package/src/application.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,6 +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
|
*/
|
|
12
|
+
(function() {
|
|
13
|
+
"use strict";
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
/**********************************************************************************
|
|
@@ -31,7 +32,7 @@ const EntityAccessor = require('./entityAccessor.js').EntityAccessor;
|
|
|
31
32
|
// ========================================================================================
|
|
32
33
|
|
|
33
34
|
// Determine if a name is an attribute name, i.e. if it starts with the "@" character
|
|
34
|
-
const isAttributeName = function(name) { return name.length > 0 && name[0] == '@'; }
|
|
35
|
+
const isAttributeName = function(name) { return name.length > 0 && name[0] == '@'; };
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
/**
|
|
@@ -87,6 +88,22 @@ class XtkSchemaKey {
|
|
|
87
88
|
|
|
88
89
|
}
|
|
89
90
|
|
|
91
|
+
/**
|
|
92
|
+
* A join in a XtkSchemaNode link type
|
|
93
|
+
*
|
|
94
|
+
* @private
|
|
95
|
+
* @class
|
|
96
|
+
* @constructor
|
|
97
|
+
* @param {} xml
|
|
98
|
+
* @memberof Campaign
|
|
99
|
+
*/
|
|
100
|
+
class XtkJoin {
|
|
101
|
+
|
|
102
|
+
constructor(xml) {
|
|
103
|
+
this.src = EntityAccessor.getAttributeAsString(xml, "xpath-src");
|
|
104
|
+
this.dst = EntityAccessor.getAttributeAsString(xml, "xpath-dst");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
90
107
|
// ========================================================================================
|
|
91
108
|
// Schema nodes
|
|
92
109
|
// ========================================================================================
|
|
@@ -156,16 +173,37 @@ class XtkSchemaNode {
|
|
|
156
173
|
* @type {string}
|
|
157
174
|
*/
|
|
158
175
|
this.type = EntityAccessor.getAttributeAsString(xml, "type");
|
|
176
|
+
/**
|
|
177
|
+
* The node target
|
|
178
|
+
* @type {string}
|
|
179
|
+
*/
|
|
180
|
+
this.target = EntityAccessor.getAttributeAsString(xml, "target");
|
|
181
|
+
/**
|
|
182
|
+
* The node integrity
|
|
183
|
+
* @type {string}
|
|
184
|
+
*/
|
|
185
|
+
this.integrity = EntityAccessor.getAttributeAsString(xml, "integrity");
|
|
159
186
|
/**
|
|
160
187
|
* The node data length (applicable for string-types only)
|
|
161
188
|
* @type {number}
|
|
162
189
|
*/
|
|
163
190
|
this.length = EntityAccessor.getAttributeAsLong(xml, "length");
|
|
191
|
+
/**
|
|
192
|
+
* The enum of the node
|
|
193
|
+
* @type {string}
|
|
194
|
+
*/
|
|
195
|
+
this.enum = EntityAccessor.getAttributeAsString(xml, "enum");
|
|
164
196
|
/**
|
|
165
197
|
* "ref" attribute of the node, which references another node
|
|
166
198
|
* @type {string}
|
|
167
199
|
*/
|
|
168
200
|
this.ref = EntityAccessor.getAttributeAsString(xml, "ref");
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Has an unlimited number of children of the same type
|
|
204
|
+
* @type {boolean}
|
|
205
|
+
*/
|
|
206
|
+
this.unbound = EntityAccessor.getAttributeAsBoolean(xml, "unbound");
|
|
169
207
|
/**
|
|
170
208
|
* Children of the node. This is a object whose key are the names of the children nodes (without the "@"
|
|
171
209
|
* character for attributes)
|
|
@@ -197,6 +235,15 @@ class XtkSchemaNode {
|
|
|
197
235
|
* @type {string}
|
|
198
236
|
*/
|
|
199
237
|
this.nodePath = this._getNodePath(true)._path;
|
|
238
|
+
/**
|
|
239
|
+
* Element of type "link" has an array of XtkJoin
|
|
240
|
+
* @type {@type {XtkJoin[]}}
|
|
241
|
+
*/
|
|
242
|
+
this.joins = [];
|
|
243
|
+
|
|
244
|
+
for (var child of EntityAccessor.getChildElements(xml, "join")) {
|
|
245
|
+
this.joins.push(new XtkJoin(child));
|
|
246
|
+
}
|
|
200
247
|
|
|
201
248
|
// Children (elements and attributes)
|
|
202
249
|
const childNodes = [];
|
|
@@ -241,6 +288,15 @@ class XtkSchemaNode {
|
|
|
241
288
|
return false;
|
|
242
289
|
}
|
|
243
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Indicates whether the current node has an unlimited number of children of the same type.
|
|
293
|
+
*
|
|
294
|
+
* @returns {boolean} a boolean indicating whether the node contains a child with the given name
|
|
295
|
+
*/
|
|
296
|
+
isUnbound() {
|
|
297
|
+
return this.unbound;
|
|
298
|
+
}
|
|
299
|
+
|
|
244
300
|
/**
|
|
245
301
|
* Computes the path of a node
|
|
246
302
|
*
|
|
@@ -325,7 +381,7 @@ class XtkSchemaNode {
|
|
|
325
381
|
else if (element.isParent())
|
|
326
382
|
childNode = node.parent;
|
|
327
383
|
else
|
|
328
|
-
childNode = node._getChildDefAutoExpand(name, mustExist)
|
|
384
|
+
childNode = node._getChildDefAutoExpand(name, mustExist);
|
|
329
385
|
node = childNode;
|
|
330
386
|
}
|
|
331
387
|
return node;
|
|
@@ -658,8 +714,6 @@ function newCurrentLogin(userInfo) {
|
|
|
658
714
|
// ========================================================================================
|
|
659
715
|
|
|
660
716
|
/**
|
|
661
|
-
* The Application object provides access to certain properties of the Campaign server.
|
|
662
|
-
*
|
|
663
717
|
* @class
|
|
664
718
|
* @constructor
|
|
665
719
|
* @param {Campaign.Client} client The Campaign Client from which this Application object is created
|
|
@@ -667,6 +721,12 @@ function newCurrentLogin(userInfo) {
|
|
|
667
721
|
*/
|
|
668
722
|
class Application {
|
|
669
723
|
|
|
724
|
+
/**
|
|
725
|
+
* The Application object provides access to certain properties of the Campaign server.
|
|
726
|
+
* Do not create this object directly, it's automatically created by the Campaign.Client at Logon time
|
|
727
|
+
* @private
|
|
728
|
+
* @param {Campaign.Client} client the Campaign client representing the Campaign instance
|
|
729
|
+
*/
|
|
670
730
|
constructor(client) {
|
|
671
731
|
this.client = client;
|
|
672
732
|
const info = this.client.getSessionInfo();
|
|
@@ -737,3 +797,4 @@ exports.Application = Application;
|
|
|
737
797
|
// For tests
|
|
738
798
|
exports.newSchema = newSchema;
|
|
739
799
|
exports.newCurrentLogin = newCurrentLogin;
|
|
800
|
+
})();
|
package/src/cache.js
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020 Adobe. All rights reserved.
|
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
|
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
(function() {
|
|
13
|
+
"use strict";
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/**********************************************************************************
|
|
17
|
+
*
|
|
18
|
+
* Cache utilities
|
|
19
|
+
*
|
|
20
|
+
*********************************************************************************/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @namespace Utils
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
/**********************************************************************************
|
|
28
|
+
*
|
|
29
|
+
* A simple cache for XtkEntities, options, etc.
|
|
30
|
+
*
|
|
31
|
+
*********************************************************************************/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @private
|
|
35
|
+
* @class
|
|
36
|
+
* @constructor
|
|
37
|
+
* @memberof Utils
|
|
38
|
+
*/
|
|
39
|
+
class SafeStorage {
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A wrapper to the Storage interface (LocalStorage, etc.) which is "safe", i.e.
|
|
43
|
+
*
|
|
44
|
+
* - it will never throw / support local stroage to be undefined or not accessible
|
|
45
|
+
* - Handle the notion of "root key", i.e. prefix
|
|
46
|
+
* - Set/get values as JSON only and not as strings
|
|
47
|
+
* - Silently caches all exceptions
|
|
48
|
+
* - Automatically remove from storage cached values which are not valid, expired, or cannot be parsed
|
|
49
|
+
*
|
|
50
|
+
* SafeStorage objects are created automatically by Caches
|
|
51
|
+
*
|
|
52
|
+
* @param {Storage} delegate an optional delegate options, confomring to the Storage interface (getItem, setItem, removeItem)
|
|
53
|
+
* @param {string} rootKey an optional prefix which will be prepend to all keys
|
|
54
|
+
* @param {function} serDeser serializarion & deserialization function. First parameter is the object or value to serialize
|
|
55
|
+
* or deserialize, and second parameter is true for serialization or false for deserialization
|
|
56
|
+
*/
|
|
57
|
+
constructor(delegate, rootKey, serDeser) {
|
|
58
|
+
if (!serDeser)
|
|
59
|
+
serDeser = (item, serDeser) => {
|
|
60
|
+
if (serDeser) {
|
|
61
|
+
if (!item) throw Error(`Cannot serialize falsy cached item`);
|
|
62
|
+
if (typeof item !== "object") throw Error(`Cannot serialize non-object`);
|
|
63
|
+
return JSON.stringify(item);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
if (!item) throw Error(`Cannot deserialize falsy cached item`);
|
|
67
|
+
return JSON.parse(item);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
this._delegate = delegate;
|
|
71
|
+
this._rootKey = rootKey ? `${rootKey}$` : "";
|
|
72
|
+
this._serDeser = serDeser;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get an item from storage
|
|
77
|
+
* @param {string} key the item key (relative to the root key)
|
|
78
|
+
* @returns {Utils.CachedObject} the cached object, or undefined if not found.
|
|
79
|
+
* The storage serDeser fucntion will be used to deserialize the cached value
|
|
80
|
+
*/
|
|
81
|
+
getItem(key) {
|
|
82
|
+
if (!this._delegate || this._rootKey === undefined || this._rootKey === null)
|
|
83
|
+
return;
|
|
84
|
+
const itemKey = `${this._rootKey}${key}`;
|
|
85
|
+
const raw = this._delegate.getItem(itemKey);
|
|
86
|
+
if (!raw)
|
|
87
|
+
return undefined;
|
|
88
|
+
try {
|
|
89
|
+
return this._serDeser(raw, false);
|
|
90
|
+
} catch(ex) {
|
|
91
|
+
this.removeItem(key);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Put an item into storage
|
|
97
|
+
* @param {string} key the item key (relative to the root key)
|
|
98
|
+
* @param {Utils.CachedObject} json the object to cache
|
|
99
|
+
* The storage serDeser fucntion will be used to serialize the cached value
|
|
100
|
+
*/
|
|
101
|
+
setItem(key, json) {
|
|
102
|
+
if (!this._delegate || this._rootKey === undefined || this._rootKey === null)
|
|
103
|
+
return;
|
|
104
|
+
try {
|
|
105
|
+
//if (json && typeof json === "object") {
|
|
106
|
+
const raw = this._serDeser(json, true);
|
|
107
|
+
this._delegate.setItem(`${this._rootKey}${key}`, raw);
|
|
108
|
+
return;
|
|
109
|
+
} catch(ex) { /* Ignore errors in safe class */
|
|
110
|
+
}
|
|
111
|
+
this.removeItem(key);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Removes an item from the storage
|
|
116
|
+
* @param {string} key the item key (relative to the root key)
|
|
117
|
+
*/
|
|
118
|
+
removeItem(key) {
|
|
119
|
+
if (!this._delegate || this._rootKey === undefined || this._rootKey === null)
|
|
120
|
+
return;
|
|
121
|
+
try {
|
|
122
|
+
this._delegate.removeItem(`${this._rootKey}${key}`);
|
|
123
|
+
} catch(ex) { /* Ignore errors in safe class */
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @private
|
|
130
|
+
* @class
|
|
131
|
+
* @constructor
|
|
132
|
+
* @memberof Utils
|
|
133
|
+
*/
|
|
134
|
+
class CachedObject {
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* An object in the cache, i.e. a wrapped to a cached value and additional metadata to manage the cache.
|
|
138
|
+
* Do not create such objects directly, they are 100% managed by the Cache object
|
|
139
|
+
*
|
|
140
|
+
* @param {*} value the cached value
|
|
141
|
+
* @param {number} cachedAt the timestamp at which the value was cached
|
|
142
|
+
* @param {number} expiresAt the timestamp at which the cached value expires
|
|
143
|
+
*/
|
|
144
|
+
constructor(value, cachedAt, expiresAt) {
|
|
145
|
+
this.value = value;
|
|
146
|
+
this.cachedAt = cachedAt;
|
|
147
|
+
this.expiresAt = expiresAt;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @private
|
|
153
|
+
* @class
|
|
154
|
+
* @constructor
|
|
155
|
+
* @memberof Utils
|
|
156
|
+
*/
|
|
157
|
+
class Cache {
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* A general purpose in-memory cache with TTL. In addition to caching in memory, the cache has the ability to delegate the caching
|
|
161
|
+
* to a persistent cache, such as the browser localStorage. The interface is 100% synchronous.
|
|
162
|
+
*
|
|
163
|
+
* By default, caches take a single parameter for the key. It is possible however to use a more complex scenario by setting a makeKeyFn.
|
|
164
|
+
* When set, such a function will take 1 or more arguments and will be responsible to create a primitive key (a string) from the arguments.
|
|
165
|
+
* The cache public APIs : get and put therefore can take a variable number of key arguments, which will be combined into the actual primitive key.
|
|
166
|
+
*
|
|
167
|
+
* @param {Storage} storage is an optional Storage object, such as localStorage or sessionStorage. This object will be wrapped into a SafeStorage object to ensure access is safe and will not throw any exceptions
|
|
168
|
+
* @param {string} rootKey is an optional root key to use for the storage object
|
|
169
|
+
* @param {number} ttl is the TTL for objects in ms. Defaults to 5 mins
|
|
170
|
+
* @param {function} makeKeyFn is an optional function which will generate a key for objects in the cache. It's passed the arguments of the cache 'get' function
|
|
171
|
+
* @param {function} serDeser serializarion & deserialization function. First parameter is the object or value to serialize
|
|
172
|
+
* or deserialize, and second parameter is true for serialization or false for deserialization
|
|
173
|
+
*/
|
|
174
|
+
constructor(storage, rootKey, ttl, makeKeyFn, serDeser) {
|
|
175
|
+
this._storage = new SafeStorage(storage, rootKey, serDeser);
|
|
176
|
+
this._ttl = ttl || 1000*300;
|
|
177
|
+
this._makeKeyFn = makeKeyFn || ((x) => x);
|
|
178
|
+
this._cache = {};
|
|
179
|
+
// timestamp at which the cache was last cleared
|
|
180
|
+
this._lastCleared = this._loadLastCleared();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Load timestamp at which the cache was last cleared
|
|
184
|
+
_loadLastCleared() {
|
|
185
|
+
const json = this._storage.getItem("lastCleared");
|
|
186
|
+
return json ? json.timestamp : undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
_saveLastCleared() {
|
|
190
|
+
const now = Date.now();
|
|
191
|
+
this._lastCleared = now;
|
|
192
|
+
this._storage.setItem("lastCleared", { timestamp: now});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Load from local storage
|
|
196
|
+
_load(key) {
|
|
197
|
+
const json = this._storage.getItem(key);
|
|
198
|
+
if (!json || !json.cachedAt || json.cachedAt <= this._lastCleared) {
|
|
199
|
+
this._storage.removeItem(key);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
return json;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Save to local storage
|
|
206
|
+
_save(key, cached) {
|
|
207
|
+
this._storage.setItem(key, cached);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Remove from local storage
|
|
211
|
+
_remove(key) {
|
|
212
|
+
this._storage.removeItem(key);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
_getIfActive(key) {
|
|
216
|
+
// In memory cache?
|
|
217
|
+
var cached = this._cache[key];
|
|
218
|
+
// Local storage ?
|
|
219
|
+
if (!cached) {
|
|
220
|
+
cached = this._load(key);
|
|
221
|
+
this._cache[key] = cached;
|
|
222
|
+
}
|
|
223
|
+
if (!cached)
|
|
224
|
+
return undefined;
|
|
225
|
+
if (cached.expiresAt <= Date.now()) {
|
|
226
|
+
delete this._cache[key];
|
|
227
|
+
this._remove(key);
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
return cached.value;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Get a value from the cache
|
|
235
|
+
* @param {*} key the key or keys of the value to retreive
|
|
236
|
+
* @returns {*} the cached value, or undefined if not found
|
|
237
|
+
*/
|
|
238
|
+
get() {
|
|
239
|
+
const key = this._makeKeyFn.apply(this, arguments);
|
|
240
|
+
const cached = this._getIfActive(key);
|
|
241
|
+
return cached;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Put a value from the cache
|
|
246
|
+
* @param {*} key the key or keys of the value to retreive
|
|
247
|
+
* @param {*} value the value to cache
|
|
248
|
+
* @returns {CachedObject} a cached object containing the cached value
|
|
249
|
+
*/
|
|
250
|
+
put() {
|
|
251
|
+
const value = arguments[arguments.length -1];
|
|
252
|
+
const key = this._makeKeyFn.apply(this, arguments);
|
|
253
|
+
const now = Date.now();
|
|
254
|
+
const expiresAt = now + this._ttl;
|
|
255
|
+
const cached = new CachedObject(value, now, expiresAt);
|
|
256
|
+
this._cache[key] = cached;
|
|
257
|
+
this._save(key, cached);
|
|
258
|
+
return cached;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Removes everything from the cache. It does not directly removes data from persistent storage if there is, but it marks the cache
|
|
263
|
+
* as cleared so that subsequent get operation will not actually return any data cached in persistent storage
|
|
264
|
+
*/
|
|
265
|
+
clear() {
|
|
266
|
+
this._cache = {};
|
|
267
|
+
this._saveLastCleared();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Public expots
|
|
272
|
+
exports.SafeStorage = SafeStorage;
|
|
273
|
+
exports.Cache = Cache;
|
|
274
|
+
|
|
275
|
+
})();
|
package/src/campaign.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const { Util } = require("./util.js");
|
|
4
|
-
|
|
5
|
-
|
|
6
1
|
/*
|
|
7
2
|
Copyright 2020 Adobe. All rights reserved.
|
|
8
3
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -14,25 +9,18 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
|
|
|
14
9
|
OF ANY KIND, either express or implied. See the License for the specific language
|
|
15
10
|
governing permissions and limitations under the License.
|
|
16
11
|
*/
|
|
12
|
+
(function() {
|
|
13
|
+
"use strict";
|
|
17
14
|
|
|
18
|
-
|
|
15
|
+
const { Util } = require("./util.js");
|
|
16
|
+
|
|
19
17
|
/**
|
|
20
18
|
* @namespace Campaign
|
|
21
19
|
*/
|
|
22
20
|
|
|
23
21
|
/**
|
|
24
|
-
* Represents a Campaign exception, i.e. any kind of error that can happen when calling Campaign APIs,
|
|
25
|
-
* ranging from HTTP errors, XML serialization errors, SOAP errors, authentication errors, etc.
|
|
26
|
-
*
|
|
27
|
-
* @todo does not really belong to soap.js. Move it to a better place
|
|
28
22
|
* @class
|
|
29
23
|
* @constructor
|
|
30
|
-
* @param {SoapMethodCall|request} call the call that triggered the error. It can be a SoapMethodCall object, a HTTP request object, or even be undefined if the exception is generated outside of the context of a call
|
|
31
|
-
* @param {number} statusCode the HTTP status code (200, 500, etc.)
|
|
32
|
-
* @param {string} faultCode the fault code, i.e. an error code
|
|
33
|
-
* @param {string} faultString a short description of the error
|
|
34
|
-
* @param {string} detail a more detailed description of the error
|
|
35
|
-
* @param {*} cause an optional error object representing the cause of the exception
|
|
36
24
|
* @memberof Campaign
|
|
37
25
|
*/
|
|
38
26
|
class CampaignException {
|
|
@@ -49,19 +37,38 @@ governing permissions and limitations under the License.
|
|
|
49
37
|
static SOAP_UNKNOWN_METHOD(schema, method, details) { return new CampaignException(undefined, 400, 16384, `SDK-000009 Unknown method '${method}' of schema '${schema}'`, details); }
|
|
50
38
|
static NOT_LOGGED_IN(call, details) { return new CampaignException( call, 400, 16384, `SDK-000010 Cannot call API because client is not logged in`, details); }
|
|
51
39
|
static DECRYPT_ERROR(details) { return new CampaignException(undefined, 400, 16384, `SDK-000011 "Cannot decrypt password: password marker is missing`, details); }
|
|
40
|
+
static SESSION_EXPIRED() { return new CampaignException(undefined, 401, 16384, `SDK-000012 "Session has expired or is invalid. Please reconnect.`); }
|
|
52
41
|
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Returns a short description of the exception
|
|
45
|
+
* @returns {string} a short description of the exception
|
|
46
|
+
*/
|
|
53
47
|
toString() {
|
|
54
48
|
return this.message;
|
|
55
49
|
}
|
|
56
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Represents a Campaign exception, i.e. any kind of error that can happen when calling Campaign APIs,
|
|
53
|
+
* ranging from HTTP errors, XML serialization errors, SOAP errors, authentication errors, etc.
|
|
54
|
+
*
|
|
55
|
+
* Members of this object are trimmed, and all session tokens, security tokens, passwords, etc. are replaced by "***"
|
|
56
|
+
*
|
|
57
|
+
* @param {SoapMethodCall|request} call the call that triggered the error. It can be a SoapMethodCall object, a HTTP request object, or even be undefined if the exception is generated outside of the context of a call
|
|
58
|
+
* @param {number} statusCode the HTTP status code (200, 500, etc.)
|
|
59
|
+
* @param {string} faultCode the fault code, i.e. an error code
|
|
60
|
+
* @param {string} faultString a short description of the error
|
|
61
|
+
* @param {string} detail a more detailed description of the error
|
|
62
|
+
* @param {Error|string} cause an optional error object representing the cause of the exception
|
|
63
|
+
*/
|
|
57
64
|
constructor(call, statusCode, faultCode, faultString, detail, cause) {
|
|
58
65
|
|
|
59
66
|
// Provides a shorter and more friendly description of the call and method name
|
|
60
67
|
// depending on whether the exception is thrown by a SOAP or HTTP call
|
|
61
|
-
var methodCall
|
|
62
|
-
var methodName
|
|
68
|
+
var methodCall;
|
|
69
|
+
var methodName;
|
|
63
70
|
if (call) {
|
|
64
|
-
const ctor = call.
|
|
71
|
+
const ctor = Object.getPrototypeOf(call).constructor;
|
|
65
72
|
if (ctor && ctor.name == "SoapMethodCall") {
|
|
66
73
|
methodCall = {
|
|
67
74
|
type: "SOAP",
|
|
@@ -192,6 +199,7 @@ governing permissions and limitations under the License.
|
|
|
192
199
|
|
|
193
200
|
/**
|
|
194
201
|
* Creates a CampaignException for a SOAP call and from a root exception
|
|
202
|
+
*
|
|
195
203
|
* @private
|
|
196
204
|
* @param {SoapMethodCall} call the SOAP call
|
|
197
205
|
* @param {*} err the exception causing the SOAP call.
|
|
@@ -204,7 +212,7 @@ function makeCampaignException(call, err) {
|
|
|
204
212
|
return err;
|
|
205
213
|
|
|
206
214
|
// Wraps DOM exceptions which can occur when dealing with malformed XML
|
|
207
|
-
const ctor = err.
|
|
215
|
+
const ctor = Object.getPrototypeOf(err).constructor;
|
|
208
216
|
if (ctor && ctor.name == "DOMException") {
|
|
209
217
|
return new CampaignException(call, 500, err.code, `DOMException (${err.name})`, err.message, err);
|
|
210
218
|
}
|
|
@@ -216,6 +224,9 @@ function makeCampaignException(call, err) {
|
|
|
216
224
|
faultString = err.data;
|
|
217
225
|
details = undefined;
|
|
218
226
|
}
|
|
227
|
+
// Session expiration case must return a 401
|
|
228
|
+
if (err.data && err.data.indexOf(`XSV-350008`) != -1)
|
|
229
|
+
return CampaignException.SESSION_EXPIRED();
|
|
219
230
|
return new CampaignException(call, err.statusCode, "", faultString, details, err);
|
|
220
231
|
}
|
|
221
232
|
|
|
@@ -516,7 +527,7 @@ exports.OPERATOR_TYPE_GROUP = 1;
|
|
|
516
527
|
exports.OPERATOR_TYPE_RIGHT = 2;
|
|
517
528
|
|
|
518
529
|
exports.WORKFLOWTASK_STATUS_PENDING = 0;
|
|
519
|
-
exports.WORKFLOWTASK_STATUS_COMPLETED = 1
|
|
530
|
+
exports.WORKFLOWTASK_STATUS_COMPLETED = 1;
|
|
520
531
|
|
|
521
532
|
exports.MOBILE_MSGTYPE_SMS = 0;
|
|
522
533
|
exports.MOBILE_MSGTYPE_WAPPUSH = 1;
|
|
@@ -661,4 +672,6 @@ exports.ACTION_TYPE_EXPIRED = 11;
|
|
|
661
672
|
|
|
662
673
|
exports.CONTENT_EDITING_MODE_DEFAULT = 0;
|
|
663
674
|
exports.CONTENT_EDITING_MODE_DCE = 1;
|
|
664
|
-
exports.CONTENT_EDITING_MODE_AEM = 2;
|
|
675
|
+
exports.CONTENT_EDITING_MODE_AEM = 2;
|
|
676
|
+
|
|
677
|
+
})();
|