@adobe/acc-js-sdk 1.1.33 → 1.1.35

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.
@@ -64,6 +64,8 @@
64
64
  link: messageCenter.html
65
65
  - name: Reports Data API
66
66
  link: reportData.html
67
+ - name: AEM asset upload API
68
+ link: uploadAemAsset.html
67
69
  - name: --
68
70
  - name: Advanced Topics
69
71
  children:
@@ -3,6 +3,20 @@ layout: page
3
3
  title: Change Log
4
4
  ---
5
5
 
6
+ <section class="changelog"><h1>Version 1.1.35</h1>
7
+ <h2>2023/07/25</h2>
8
+ <li>
9
+ Added `sessionInfo` parameter to `ofImsBearerToken` function. When this parameter is used, the logon call will make sure user and server informations are returned. See <a href="https://opensource.adobe.com/acc-js-sdk/connecting.html"></a> for more information.
10
+ </li>
11
+ </section>
12
+
13
+ <section class="changelog"><h1>Version 1.1.34</h1>
14
+ <h2>2023/07/25</h2>
15
+ <li>
16
+ Added `uploadAemAsset` method which downloads an asset from AEM and uploads it to Campaign. See <a href="https://opensource.adobe.com/acc-js-sdk/uploadAemAsset.html"></a> for more information.
17
+ </li>
18
+ </section>
19
+
6
20
  <section class="changelog"><h1>Version 1.1.33</h1>
7
21
  <h2>2023/07/08</h2>
8
22
  <li>
@@ -140,6 +140,23 @@ const connectionParameters = sdk.ConnectionParameters.ofBearerToken(
140
140
  "ims_bearer_token");
141
141
  </pre>
142
142
 
143
+ <p>
144
+ One caveat with ofImsBearerToken mechanism is that logon will not actually call any SOAP logon APIs. The bearer token is just stored in memory and will be passed along with subsequent calls.
145
+ </p>
146
+ <p>
147
+ This can be a concern because "xtk:session#Logon" and "xtk:session#BearerTokenLogon" return a session info object containing information about the server and the logged user.
148
+ This includes the server version and build number, the list of active packages, etc. This information is not available when using ofImsBearerToken.
149
+ </p>
150
+ <p>
151
+ In Version 1.1.35 of the SDK, it is possible to get this information consistently with other Logon method by passing the "sessionInfo" option to the ofImsBearerToken call.
152
+ </p>
153
+ <pre class="code">
154
+ const connectionParameters = sdk.ConnectionParameters.ofImsBearerToken(
155
+ "https://myInstance.campaign.adobe.com",
156
+ "ims_bearer_token",
157
+ { sessionInfo: true });
158
+ </pre>
159
+
143
160
 
144
161
  <h2>Login with Session token</h2>
145
162
  <p>
@@ -0,0 +1,45 @@
1
+ ---
2
+ layout: page
3
+ title: AEM asset upload API
4
+ ---
5
+
6
+ <p>Campaign API for downloading & uploading(publishing) AEM cloud asset on campaign publication server. Just like all APIs in the SDK, it's been wrapped into a function and will return a JSON object containing publishedUrl.</p>
7
+ <p class="warning">Note: This API can be used only with assetInfo url of AEM asset. AssetInfo url returns signed download url when called with GET API.
8
+ </p>
9
+ <h1>/nms/aemAssetDownload.jssp</h1>
10
+ <p>This API is authenticated only using ims user token and run directly on the Apache front server.</p>
11
+ <pre class="code">
12
+ const version = sdk.getSDKVersion();
13
+ console.log(`${version.description} version ${version.version}`);
14
+
15
+ <span class="comment">// Logon to a Campaign instance with ImsBearerToken</span>
16
+ const connectionParameters = sdk.ConnectionParameters.ofImsBearerToken("http://acc-sdk:8080", "ey...", options);
17
+ console.log(connectionParameters);
18
+
19
+ const client = await sdk.init(connectionParameters);
20
+ await client.logon();
21
+
22
+ const url = "https://abcd.adobexyzcloud.domain.com/asset/xyz.png";
23
+ const response = await client.fileUploader.uploadAemAsset(url);
24
+ console.log(response);
25
+ </pre>
26
+
27
+ <p>will return in this format</p>
28
+ <pre class="code">
29
+ {
30
+ "publishedURL": "http://trk-my-instance.my.domain.com/res/trk-inst/12f6710969d74ad965a333d31cf8c06d.jpeg"
31
+ }
32
+ </pre>
33
+
34
+ <p class="warning">Note: This API can only be authenticated using ImsBearerToken because the same Ims user token
35
+ is used to authenticate AEM asset GET call.
36
+ </p>
37
+ <pre class="code">
38
+ const connectionParameters = sdk.ConnectionParameters.ofImsBearerToken("http://acc-sdk:8080", "ey...", options);
39
+ console.log(connectionParameters);
40
+ </pre>
41
+
42
+ <p class="info">The API returns error with error code whenever it fails.<br>
43
+ The sdk error is "SDK-000017 Failed to upload AEM asset". It will also include specific reason for failure
44
+ and error code.
45
+ </p>
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@adobe/acc-js-sdk",
3
- "version": "1.1.33",
3
+ "version": "1.1.35",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@adobe/acc-js-sdk",
9
- "version": "1.1.33",
9
+ "version": "1.1.35",
10
10
  "license": "ISC",
11
11
  "dependencies": {
12
12
  "axios": "^1.2.1",
@@ -3041,9 +3041,10 @@
3041
3041
  }
3042
3042
  },
3043
3043
  "node_modules/jest-snapshot/node_modules/semver": {
3044
- "version": "7.3.8",
3044
+ "version": "7.5.4",
3045
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
3046
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
3045
3047
  "dev": true,
3046
- "license": "ISC",
3047
3048
  "dependencies": {
3048
3049
  "lru-cache": "^6.0.0"
3049
3050
  },
@@ -3357,26 +3358,6 @@
3357
3358
  "node": ">=v12.22.7"
3358
3359
  }
3359
3360
  },
3360
- "node_modules/jsdom/node_modules/tough-cookie": {
3361
- "version": "4.1.2",
3362
- "license": "BSD-3-Clause",
3363
- "dependencies": {
3364
- "psl": "^1.1.33",
3365
- "punycode": "^2.1.1",
3366
- "universalify": "^0.2.0",
3367
- "url-parse": "^1.5.3"
3368
- },
3369
- "engines": {
3370
- "node": ">=6"
3371
- }
3372
- },
3373
- "node_modules/jsdom/node_modules/universalify": {
3374
- "version": "0.2.0",
3375
- "license": "MIT",
3376
- "engines": {
3377
- "node": ">= 4.0.0"
3378
- }
3379
- },
3380
3361
  "node_modules/jsesc": {
3381
3362
  "version": "2.5.2",
3382
3363
  "dev": true,
@@ -4053,9 +4034,10 @@
4053
4034
  "license": "MIT"
4054
4035
  },
4055
4036
  "node_modules/semver": {
4056
- "version": "6.3.0",
4037
+ "version": "6.3.1",
4038
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
4039
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
4057
4040
  "dev": true,
4058
- "license": "ISC",
4059
4041
  "bin": {
4060
4042
  "semver": "bin/semver.js"
4061
4043
  }
@@ -4274,6 +4256,20 @@
4274
4256
  "node": ">=8.0"
4275
4257
  }
4276
4258
  },
4259
+ "node_modules/tough-cookie": {
4260
+ "version": "4.1.3",
4261
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
4262
+ "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
4263
+ "dependencies": {
4264
+ "psl": "^1.1.33",
4265
+ "punycode": "^2.1.1",
4266
+ "universalify": "^0.2.0",
4267
+ "url-parse": "^1.5.3"
4268
+ },
4269
+ "engines": {
4270
+ "node": ">=6"
4271
+ }
4272
+ },
4277
4273
  "node_modules/tr46": {
4278
4274
  "version": "3.0.0",
4279
4275
  "license": "MIT",
@@ -4324,6 +4320,14 @@
4324
4320
  "dev": true,
4325
4321
  "license": "MIT"
4326
4322
  },
4323
+ "node_modules/universalify": {
4324
+ "version": "0.2.0",
4325
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
4326
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
4327
+ "engines": {
4328
+ "node": ">= 4.0.0"
4329
+ }
4330
+ },
4327
4331
  "node_modules/update-browserslist-db": {
4328
4332
  "version": "1.0.10",
4329
4333
  "dev": true,
@@ -4464,8 +4468,9 @@
4464
4468
  }
4465
4469
  },
4466
4470
  "node_modules/word-wrap": {
4467
- "version": "1.2.3",
4468
- "license": "MIT",
4471
+ "version": "1.2.5",
4472
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
4473
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
4469
4474
  "engines": {
4470
4475
  "node": ">=0.10.0"
4471
4476
  }
@@ -6618,7 +6623,9 @@
6618
6623
  },
6619
6624
  "dependencies": {
6620
6625
  "semver": {
6621
- "version": "7.3.8",
6626
+ "version": "7.5.4",
6627
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
6628
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
6622
6629
  "dev": true,
6623
6630
  "requires": {
6624
6631
  "lru-cache": "^6.0.0"
@@ -6808,18 +6815,6 @@
6808
6815
  "requires": {
6809
6816
  "xmlchars": "^2.2.0"
6810
6817
  }
6811
- },
6812
- "tough-cookie": {
6813
- "version": "4.1.2",
6814
- "requires": {
6815
- "psl": "^1.1.33",
6816
- "punycode": "^2.1.1",
6817
- "universalify": "^0.2.0",
6818
- "url-parse": "^1.5.3"
6819
- }
6820
- },
6821
- "universalify": {
6822
- "version": "0.2.0"
6823
6818
  }
6824
6819
  }
6825
6820
  },
@@ -7242,7 +7237,9 @@
7242
7237
  "version": "2.1.2"
7243
7238
  },
7244
7239
  "semver": {
7245
- "version": "6.3.0",
7240
+ "version": "6.3.1",
7241
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
7242
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
7246
7243
  "dev": true
7247
7244
  },
7248
7245
  "shebang-command": {
@@ -7379,6 +7376,17 @@
7379
7376
  "is-number": "^7.0.0"
7380
7377
  }
7381
7378
  },
7379
+ "tough-cookie": {
7380
+ "version": "4.1.3",
7381
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
7382
+ "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
7383
+ "requires": {
7384
+ "psl": "^1.1.33",
7385
+ "punycode": "^2.1.1",
7386
+ "universalify": "^0.2.0",
7387
+ "url-parse": "^1.5.3"
7388
+ }
7389
+ },
7382
7390
  "tr46": {
7383
7391
  "version": "3.0.0",
7384
7392
  "requires": {
@@ -7408,6 +7416,11 @@
7408
7416
  "version": "1.13.6",
7409
7417
  "dev": true
7410
7418
  },
7419
+ "universalify": {
7420
+ "version": "0.2.0",
7421
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
7422
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg=="
7423
+ },
7411
7424
  "update-browserslist-db": {
7412
7425
  "version": "1.0.10",
7413
7426
  "dev": true,
@@ -7493,7 +7506,9 @@
7493
7506
  }
7494
7507
  },
7495
7508
  "word-wrap": {
7496
- "version": "1.2.3"
7509
+ "version": "1.2.5",
7510
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
7511
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="
7497
7512
  },
7498
7513
  "wrap-ansi": {
7499
7514
  "version": "7.0.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/acc-js-sdk",
3
- "version": "1.1.33",
3
+ "version": "1.1.35",
4
4
  "description": "ACC Javascript SDK",
5
5
  "main": "src/index.js",
6
6
  "homepage": "https://github.com/adobe/acc-js-sdk#readme",
@@ -1365,9 +1365,11 @@ class Application {
1365
1365
  * The server version, formatted as major.minor.servicePack (ex: 8.2.10)
1366
1366
  * @type {string}
1367
1367
  */
1368
- this.version = EntityAccessor.getAttributeAsString(serverInfo, "majNumber") + "." +
1369
- EntityAccessor.getAttributeAsString(serverInfo, "minNumber") + "." +
1370
- EntityAccessor.getAttributeAsString(serverInfo, "servicePack");
1368
+ const majNumber = EntityAccessor.getAttributeAsString(serverInfo, "majNumber");
1369
+ const minNumber = EntityAccessor.getAttributeAsString(serverInfo, "minNumber");
1370
+ const servicePack = EntityAccessor.getAttributeAsString(serverInfo, "servicePack");
1371
+ if (majNumber && minNumber && servicePack)
1372
+ this.version = majNumber + "." + minNumber + "." + servicePack;
1371
1373
  /**
1372
1374
  * The Campaign instance name
1373
1375
  * @type {string}
package/src/campaign.js CHANGED
@@ -42,6 +42,7 @@ const { Util } = require("./util.js");
42
42
  static REPORT_FETCH_FAILED(name, details) { return new CampaignException(undefined, 500, 16384, `SDK-000014 Failed to fetch report ${name}`, details); }
43
43
  static FEATURE_NOT_SUPPORTED(name) { return new CampaignException(undefined, 500, 16384, `SDK-000015 ${name} feature is not supported by the ACC instance`); }
44
44
  static REQUEST_ABORTED( ) { return new CampaignException(undefined, 500, -53, `SDK-000016 Request was aborted by the client`); }
45
+ static AEM_ASSET_UPLOAD_FAILED(details, statusCode=500) { return new CampaignException(undefined, statusCode, 16384, `SDK-000017 Failed to upload AEM asset`, details); }
45
46
 
46
47
 
47
48
  /**
@@ -226,13 +227,14 @@ function makeCampaignException(call, err) {
226
227
 
227
228
  if (err.statusCode && ctor && ctor.name == "HttpError") {
228
229
  var faultString = err.statusText;
229
- var details = err.data;
230
+ var details = typeof err.data == 'object' ? JSON.stringify(err.data) : err.data;
230
231
  if (!faultString) {
231
- faultString = err.data;
232
+ faultString = typeof err.data == 'object' ? JSON.stringify(err.data) : err.data;
232
233
  details = undefined;
233
234
  }
235
+
234
236
  // Session expiration case must return a 401
235
- if (err.data && err.data.indexOf(`XSV-350008`) != -1)
237
+ if (err.data && typeof err.data == 'string' && err.data.indexOf(`XSV-350008`) != -1)
236
238
  return CampaignException.SESSION_EXPIRED();
237
239
  return new CampaignException(call, err.statusCode, "", faultString, details, err);
238
240
  }
package/src/client.js CHANGED
@@ -639,6 +639,41 @@ const fileUploader = (client) => {
639
639
  reject(CampaignException.FILE_UPLOAD_FAILED(file.name, ex));
640
640
  }
641
641
  });
642
+ },
643
+
644
+ /**
645
+ * Exposed method to call aemAssetDownload.jssp which will
646
+ * download the asset from AEM and upload it to Campaign.
647
+ */
648
+ uploadAemAsset: async (assetDownloadUrl) => {
649
+ const url = `${client._connectionParameters._endpoint}/nms/aemAssetDownload.jssp`;
650
+ const headers = client._getAuthHeaders(false);
651
+ headers['Content-Type'] = 'application/json';
652
+
653
+ try {
654
+ // We need to pass the Authorization header to AEM to download the asset from AEM
655
+ // as well as authenticating campaign server.
656
+ // A user token having access to campaign as well as AEM is required
657
+ if(headers['Authorization'] === undefined || headers['Authorization'] === '' || headers['Authorization'] === 'null') {
658
+ throw 'Bearer token is missing';
659
+ }
660
+
661
+ const response = await client._makeHttpCall({
662
+ url: url,
663
+ method: 'POST',
664
+ data: {assetDownloadUrl: assetDownloadUrl},
665
+ headers: headers
666
+ });
667
+ if(response.publishedURL)
668
+ return response;
669
+ else
670
+ throw 'Publishing failed';
671
+ } catch (ex) {
672
+ if(ex instanceof CampaignException)
673
+ throw CampaignException.AEM_ASSET_UPLOAD_FAILED(ex.faultString, ex.statusCode);
674
+ else
675
+ throw CampaignException.AEM_ASSET_UPLOAD_FAILED(ex, ex.statusCode);
676
+ }
642
677
  }
643
678
  };
644
679
  };
@@ -1377,6 +1412,52 @@ class Client {
1377
1412
  delete this._observabilityContext.session;
1378
1413
  }
1379
1414
 
1415
+ _updateSessionInfo(sessionInfo, soapCall) {
1416
+ this._sessionInfo = sessionInfo;
1417
+ this._installedPackages = {};
1418
+ const userInfo = DomUtil.findElement(sessionInfo, "userInfo");
1419
+ if (!userInfo)
1420
+ throw CampaignException.UNEXPECTED_SOAP_RESPONSE(soapCall, `userInfo structure missing`);
1421
+ let pack = DomUtil.getFirstChildElement(userInfo, "installed-package");
1422
+ while (pack) {
1423
+ const name = `${DomUtil.getAttributeAsString(pack, "namespace")}:${DomUtil.getAttributeAsString(pack, "name")}`;
1424
+ this._installedPackages[name] = name;
1425
+ pack = DomUtil.getNextSiblingElement(pack);
1426
+ }
1427
+ }
1428
+
1429
+ async _fetchSessionInfo() {
1430
+ const userInfoPromise = this.NLWS.xml.xtkSession.getUserInfo();
1431
+ const testPromise = this.test();
1432
+ const all = Promise.all([userInfoPromise, testPromise]);
1433
+ const values = await all;
1434
+
1435
+ const sessionInfo = DomUtil.newDocument("sessionInfo");
1436
+ const sessionInfoRoot = sessionInfo.documentElement;
1437
+ const userInfo = sessionInfo.importNode(values[0], true);
1438
+ sessionInfoRoot.appendChild(userInfo);
1439
+ const serverInfo = sessionInfo.createElement('serverInfo');
1440
+ sessionInfoRoot.appendChild(serverInfo);
1441
+ const test = values[1];
1442
+ if (test["date"])
1443
+ serverInfo.setAttribute("serverDate", new Date(Date.parse(test["date"])).toISOString());
1444
+ serverInfo.setAttribute("instanceName", test["instance"]);
1445
+ if (test["version"]) {
1446
+ const versionParts = test["version"].split(".");
1447
+ serverInfo.setAttribute("majNumber", versionParts[0]);
1448
+ serverInfo.setAttribute("minNumber", versionParts[1]);
1449
+ serverInfo.setAttribute("servicePack", versionParts[2]);
1450
+ }
1451
+ let buildNumber = test["build"];
1452
+ // Alternative method to get the build number (not available unless server has been upgraded at least once)
1453
+ if (!buildNumber)
1454
+ buildNumber = await this.getOption("NmsServer_LastPostUpgrade", false);
1455
+ if (!buildNumber)
1456
+ throw CampaignException.UNEXPECTED_SOAP_RESPONSE(undefined, `buildNumber structure missing for both /r/test and NmsServer_LastPostUpgrade option`);
1457
+ serverInfo.setAttribute("buildNumber", buildNumber);
1458
+ return sessionInfoRoot;
1459
+ }
1460
+
1380
1461
  /**
1381
1462
  * Login to an instance
1382
1463
  */
@@ -1431,8 +1512,18 @@ class Client {
1431
1512
  that._sessionToken = "";
1432
1513
  that._securityToken = "";
1433
1514
  that._bearerToken = credentials._bearerToken;
1434
- that._onLogon();
1435
- return Promise.resolve();
1515
+
1516
+ // With IMS Bearer token, we do not call the Logon or BearerTokenLogon method any more. As a consequence,
1517
+ // we do not have the user and server information returned by those methods, so we need to get the corresponding
1518
+ // information by other means
1519
+ if (!this._connectionParameters._options.sessionInfo) {
1520
+ that._onLogon();
1521
+ return Promise.resolve();
1522
+ }
1523
+ return that._fetchSessionInfo().then((sessionInfo) => {
1524
+ that._updateSessionInfo(sessionInfo, undefined);
1525
+ that._onLogon();
1526
+ });
1436
1527
  }
1437
1528
  else if (credentials._type == "UserPassword" || credentials._type == "BearerToken") {
1438
1529
  const soapCall = that._prepareSoapCall("xtk:session", credentials._type === "UserPassword" ? "Logon" : "BearerTokenLogon", true, false, this._connectionParameters._options.extraHttpHeaders);
@@ -1458,19 +1549,8 @@ class Client {
1458
1549
  }
1459
1550
  return this._makeSoapCall(soapCall).then(function() {
1460
1551
  const sessionToken = soapCall.getNextString();
1461
-
1462
- that._sessionInfo = soapCall.getNextDocument();
1463
- that._installedPackages = {};
1464
- const userInfo = DomUtil.findElement(that._sessionInfo, "userInfo");
1465
- if (!userInfo)
1466
- throw CampaignException.UNEXPECTED_SOAP_RESPONSE(soapCall, `userInfo structure missing`);
1467
- var pack = DomUtil.getFirstChildElement(userInfo, "installed-package");
1468
- while (pack) {
1469
- const name = `${DomUtil.getAttributeAsString(pack, "namespace")}:${DomUtil.getAttributeAsString(pack, "name")}`;
1470
- that._installedPackages[name] = name;
1471
- pack = DomUtil.getNextSiblingElement(pack);
1472
- }
1473
-
1552
+ const sessionInfo = soapCall.getNextDocument();
1553
+ that._updateSessionInfo(sessionInfo, soapCall);
1474
1554
  const securityToken = soapCall.getNextString();
1475
1555
  soapCall.checkNoMoreArgs();
1476
1556
  // Sanity check: we should have both a session token and a security token.
@@ -2002,7 +2082,7 @@ class Client {
2002
2082
  if (this._traceAPICalls)
2003
2083
  console.log("HTTP//failure", err);
2004
2084
  this._notifyObservers((observer) => observer.onHTTPCallFailure && observer.onHTTPCallFailure(request, err) );
2005
- const ex = makeCampaignException({ request:request, reqponse:err.response }, err);
2085
+ const ex = makeCampaignException({ request:request, response:err.response }, err);
2006
2086
  this._trackEvent('HTTP//failure', event, { }, ex);
2007
2087
  throw ex;
2008
2088
  }
@@ -26,6 +26,7 @@ const { Cipher } = require('../src/crypto.js');
26
26
  const { EntityAccessor } = require('../src/entityAccessor.js');
27
27
  const { JSDOM } = require('jsdom');
28
28
  const dom = new JSDOM();
29
+ const { CampaignException } = require('../src/campaign.js');
29
30
 
30
31
  describe('ACC Client', function () {
31
32
 
@@ -1746,6 +1747,83 @@ describe('ACC Client', function () {
1746
1747
  });
1747
1748
  });
1748
1749
 
1750
+ // write unit test for client.fileUploader.uploadAemAsset method
1751
+ describe("Tests for client.fileUploader.uploadAemAsset method", () => {
1752
+ // Case 1: uploadAemAsset method should return a valid response
1753
+ it("Should return correct response", async () => {
1754
+ const client = await Mock.makeClient();
1755
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1756
+ await client.NLWS.xtkSession.logon();
1757
+
1758
+ const mockResponse = {
1759
+ "publishedURL" : "http://trk-inst-xyz.campaign.adobe.com/res/trk-inst/409afb8798180a36591456e152b6c406.jpeg"
1760
+ };
1761
+ client._bearerToken = 'Bearer 1234567890';
1762
+ client._transport.mockReturnValueOnce(mockResponse);
1763
+ const response = await client.fileUploader.uploadAemAsset("https://author-p74953-e183988-cmstg.adobeaemcloud.com/adobe/repository/content/dam/projects/children-kids-group-eating-ice-cream-funny-party-72701973%20%281%29%20%2812%29%20%282%29%20%283%29.jpg;api=block_download");
1764
+ expect(response).toBe(mockResponse);
1765
+
1766
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
1767
+ await client.NLWS.xtkSession.logoff();
1768
+ });
1769
+
1770
+ // Case 2: Bearertoken is not provided, but the client is already authenticated with session token
1771
+ it("Should throw error for missing authentication token", async () => {
1772
+ const client = await Mock.makeClient();
1773
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1774
+ await client.NLWS.xtkSession.logon();
1775
+
1776
+ await (client.fileUploader.uploadAemAsset("https://author-p74953-e183988-cmstg.adobeaemcloud.com/adobe/repository/content/dam/projects/children-kids-group-eating-ice-cream-funny-party-72701973%20%281%29%20%2812%29%20%282%29%20%283%29.jpg;api=block_download"))
1777
+ .catch( e => { expect(e).toMatchObject(CampaignException.AEM_ASSET_UPLOAD_FAILED('Bearer token is missing'))});
1778
+
1779
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
1780
+ await client.NLWS.xtkSession.logoff();
1781
+ });
1782
+
1783
+ // Case 3: 200 response but publishedURL is not returned
1784
+ // It shouldn't occur as API also checks non-emptiness of publishedURL before returning the response.
1785
+ it("Should throw error for missing publishedURL", async () => {
1786
+ const client = await Mock.makeClient();
1787
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1788
+ await client.NLWS.xtkSession.logon();
1789
+
1790
+ const mockResponse = {};
1791
+ client._transport.mockReturnValueOnce(mockResponse);
1792
+ client._bearerToken = 'Bearer 1234567890';
1793
+
1794
+ await (client.fileUploader.uploadAemAsset("https://author-p74953-e183988-cmstg.adobeaemcloud.com/adobe/repository/content/dam/projects/children-kids-group-eating-ice-cream-funny-party-72701973%20%281%29%20%2812%29%20%282%29%20%283%29.jpg;api=block_download"))
1795
+ .catch( e => { console.log(e); expect(e).toMatchObject(CampaignException.AEM_ASSET_UPLOAD_FAILED('Publishing failed'))});
1796
+
1797
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
1798
+ await client.NLWS.xtkSession.logoff();
1799
+ });
1800
+
1801
+ // Case 4: AEM Asset upload failed (reason maybe aem not reachable, assetlink not reachable, etc)
1802
+ it("Should throw error when AEM Asset upload failed", async () => {
1803
+ const client = await Mock.makeClient();
1804
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1805
+ await client.NLWS.xtkSession.logon();
1806
+
1807
+ //const mockResponse = {};
1808
+ client._transport.mockImplementation(() => {
1809
+ var ex = CampaignException.AEM_ASSET_UPLOAD_FAILED('The requested content does not exist', 400);
1810
+ ex.faultString = 'The requested content does not exist';
1811
+ ex.detail = 'Failed to upload AEM asset';
1812
+ throw ex;
1813
+ });
1814
+ client._bearerToken = 'Bearer 1234567890';
1815
+
1816
+ var ex = CampaignException.AEM_ASSET_UPLOAD_FAILED('The requested content does not exist', 400);
1817
+ await (client.fileUploader.uploadAemAsset("https://author-p74953-e183988-cmstg.adobeaemcloud.com/adobe/repository/content/dam/projects/children-kids-group-eating-ice-cream-funny-party-72701973%20%281%29%20%2812%29%20%282%29%20%283%29.jpg;api=block_download"))
1818
+ .catch( e => { console.log(e); expect(e).toMatchObject(ex)});
1819
+
1820
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
1821
+ await client.NLWS.xtkSession.logoff();
1822
+ });
1823
+
1824
+ });
1825
+
1826
+
1749
1827
  describe("Observers", () => {
1750
1828
 
1751
1829
  it("Should observe SOAP api Call (getOption)", async () => {
@@ -171,4 +171,65 @@ describe('IMS Bearer Toekn', function () {
171
171
  // when using one of the Logon methods (Logno or BearertokenLogon)
172
172
  expect(application.packages).toBeUndefined();
173
173
  });
174
+
175
+ it('Should logon with IMS Bearer Token and return session info. No version string or date', async () => {
176
+ const client = await makeImsClient({ sessionInfo: true });
177
+ // As session info is asked, GetUserInfo and /r/test will be called
178
+ client._transport.mockReturnValueOnce(Promise.resolve(`<redir status='OK' build='9236' sha1='cc45440' instance='xxx_mkt_prod1' sourceIP='193.104.215.11' host='xxxol.campaign.adobe.com' localHost='xxxol-mkt-prod1-1'/>`));
179
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
180
+ client._transport.mockReturnValueOnce(Mock.GET_USER_INFO_RESPONSE);
181
+ await client.NLWS.xtkSession.logon();
182
+ expect(client.isLogged()).toBe(true);
183
+ expect(client.application.buildNumber).toBe("9236");
184
+ expect(client.application.version).toBe(undefined);
185
+ expect(client.application.instanceName).toBe("xxx_mkt_prod1");
186
+ expect(client.application.operator.login).toBe("admin");
187
+ });
188
+
189
+ it('Should logon with IMS Bearer Token and return session info', async () => {
190
+ const client = await makeImsClient({ sessionInfo: true });
191
+ // As session info is asked, GetUserInfo and /r/test will be called
192
+ client._transport.mockReturnValueOnce(Promise.resolve(`<redir status='OK' date='2021-08-27 08:02:07.963-07' version='8.5.1' build='9236' sha1='cc45440' instance='xxx_mkt_prod1' sourceIP='193.104.215.11' host='xxxol.campaign.adobe.com' localHost='xxxol-mkt-prod1-1'/>`));
193
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
194
+ client._transport.mockReturnValueOnce(Mock.GET_USER_INFO_RESPONSE);
195
+ await client.NLWS.xtkSession.logon();
196
+ expect(client.isLogged()).toBe(true);
197
+ expect(client.application.buildNumber).toBe("9236");
198
+ expect(client.application.version).toBe("8.5.1");
199
+ });
200
+
201
+ it('Should logon with IMS Bearer Token and return session info. Build number is missing from /r/test', async () => {
202
+ const client = await makeImsClient({ sessionInfo: true });
203
+ // As session info is asked, GetUserInfo and /r/test will be called
204
+ client._transport.mockReturnValueOnce(Promise.resolve(`<redir status='OK' date='2021-08-27 08:02:07.963-07'/>`));
205
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
206
+ client._transport.mockReturnValueOnce(Mock.GET_USER_INFO_RESPONSE);
207
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
208
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:session' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
209
+ <SOAP-ENV:Body>
210
+ <GetOptionResponse xmlns='urn:xtk:session' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
211
+ <pstrValue xsi:type='xsd:string'>9999</pstrValue>
212
+ <pbtType xsi:type='xsd:byte'>6</pbtType>
213
+ </GetOptionResponse>
214
+ </SOAP-ENV:Body>
215
+ </SOAP-ENV:Envelope>`));
216
+ // As build number is missing getOption will be called
217
+ await client.NLWS.xtkSession.logon();
218
+ expect(client.isLogged()).toBe(true);
219
+ expect(client.application.buildNumber).toBe("9999");
220
+ });
221
+
222
+ it('Should fail to logon with IMS Bearer Token because build number is missing', async () => {
223
+ const client = await makeImsClient({ sessionInfo: true });
224
+ // As session info is asked, GetUserInfo and /r/test will be called
225
+ client._transport.mockReturnValueOnce(Promise.resolve(`<redir status='OK' date='2021-08-27 08:02:07.963-07'/>`));
226
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
227
+ client._transport.mockReturnValueOnce(Mock.GET_USER_INFO_RESPONSE);
228
+ client._transport.mockReturnValueOnce(Mock.GET_OPTION_NOTFOUND_RESPONSE);
229
+ // As build number is missing getOption will be called
230
+ await expect(async() => {
231
+ await client.NLWS.xtkSession.logon();
232
+ }).rejects.toMatchObject({ errorCode: "SDK-000007" });
233
+ });
234
+
174
235
  });