@adobe/acc-js-sdk 1.1.36 → 1.1.38

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.
@@ -107,6 +107,8 @@
107
107
  link: passwords.html
108
108
  - name: Differences between the SDK and Campaign
109
109
  link: differences.html
110
+ - name: Anonymous SOAP calls
111
+ link: anonymous.html
110
112
  - name: --
111
113
  - name: Contributing
112
114
  children:
@@ -0,0 +1,41 @@
1
+ ---
2
+ layout: page
3
+ title: Anonymous SOAP calls
4
+ ---
5
+
6
+ <p>
7
+ The ACC JS SDK uses schemas to dynamically discover available methods and their signature.
8
+ But fetching schemas requires an authenticated user.
9
+ This means it's not directly possible to call anonymous SOAP methods from the SDK.
10
+ </p>
11
+
12
+ <p>
13
+ Anonymous SOAP methods are declared with the <b>access</b> attribute set to <b>anonymous</b>
14
+ </p>
15
+
16
+ <pre class="code">
17
+ &lt;method name="GetServerTime" static="true" access="anonymous">
18
+ &lt;help>Returns the server date and time&lt;/help>
19
+ &lt;parameters>
20
+ &lt;param name="serverTime" type="datetime" inout="out"/>
21
+ &lt;/parameters>
22
+ &lt;/method>
23
+ </pre>
24
+
25
+ <p>
26
+ In order to call anonymous SOAP methods, one therefore needs a different mechanism and the <b>makeSoapCall</b> method can be used
27
+ </p>
28
+
29
+ <pre class="code">
30
+ const sdk = require('@adobe/acc-js-sdk');
31
+ const connectionParameters = sdk.ConnectionParameters.ofAnonymousUser("https://myInstance.campaign.adobe.com");
32
+ var client = await sdk.init(connectionParameters);
33
+
34
+ client.traceAPICalls(true);
35
+
36
+
37
+ var inputParams = [];
38
+ var outputParams = [{ name: "serverTime", type: "datetime" }];
39
+ var result = await client.makeSoapCall("xtk:session", "GetServerTime", true, inputParams, outputParams);
40
+ console.log(result);
41
+ </pre>
@@ -3,6 +3,21 @@ layout: page
3
3
  title: Change Log
4
4
  ---
5
5
 
6
+ <section class="changelog"><h1>Version 1.1.38</h1>
7
+ <h2>2023/09/06</h2>
8
+ <li>
9
+ Add support for anonymous SOAP calls. See <a href="https://opensource.adobe.com/acc-js-sdk/anonymous.html"></a> for more information.
10
+ </li>
11
+ </section>
12
+
13
+
14
+ <section class="changelog"><h1>Version 1.1.37</h1>
15
+ <h2>2023/08/07</h2>
16
+ <li>
17
+ Fix missing schema localisation for description id when description is empty in the source schema
18
+ </li>
19
+ </section>
20
+
6
21
  <section class="changelog"><h1>Version 1.1.36</h1>
7
22
  <h2>2023/07/28</h2>
8
23
  <li>
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@adobe/acc-js-sdk",
3
- "version": "1.1.36",
3
+ "version": "1.1.38",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@adobe/acc-js-sdk",
9
- "version": "1.1.36",
9
+ "version": "1.1.38",
10
10
  "license": "ISC",
11
11
  "dependencies": {
12
12
  "axios": "^1.2.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/acc-js-sdk",
3
- "version": "1.1.36",
3
+ "version": "1.1.38",
4
4
  "description": "ACC Javascript SDK",
5
5
  "main": "src/index.js",
6
6
  "homepage": "https://github.com/adobe/acc-js-sdk#readme",
@@ -62,7 +62,10 @@ function propagateImplicitValues(xtkDesc, labelOnly) {
62
62
  // Force first letter as uppercase
63
63
  xtkDesc.label = xtkDesc.label.substring(0, 1).toUpperCase() + xtkDesc.label.substring(1);
64
64
  }
65
- if (!labelOnly && !xtkDesc.description) xtkDesc.description = xtkDesc.label;
65
+ if (!labelOnly && !xtkDesc.description) {
66
+ xtkDesc.description = xtkDesc.label;
67
+ xtkDesc.descriptionLocalizationId = xtkDesc.labelLocalizationId;
68
+ }
66
69
  }
67
70
 
68
71
  // ========================================================================================
package/src/client.js CHANGED
@@ -243,7 +243,7 @@ class Credentials {
243
243
  * @param {string} securityToken the security token. Will use an empty token if not specified
244
244
  */
245
245
  constructor(type, sessionToken, securityToken) {
246
- if (type != "UserPassword" && type != "ImsServiceToken" && type != "SessionToken" &&
246
+ if (type != "UserPassword" && type != "ImsServiceToken" && type != "SessionToken" && type != "SessionAndSecurityToken" &&
247
247
  type != "AnonymousUser" && type != "SecurityToken" && type != "BearerToken" && type != "ImsBearerToken")
248
248
  throw CampaignException.INVALID_CREDENTIALS_TYPE(type);
249
249
  this._type = type;
@@ -458,6 +458,21 @@ class ConnectionParameters {
458
458
  return new ConnectionParameters(endpoint, credentials, options);
459
459
  }
460
460
 
461
+ /**
462
+ * Creates connection parameters for a Campaign instance, using a session token and a security token
463
+ *
464
+ * @static
465
+ * @param {string} endpoint The campaign endpoint (URL)
466
+ * @param {string} sessionToken The session token
467
+ * @param {string} securityToken The security token
468
+ * @param {Campaign.ConnectionOptions} options connection options
469
+ * @returns {ConnectionParameters} a ConnectionParameters object which can be used to create a Client
470
+ */
471
+ static ofSessionAndSecurityToken(endpoint, sessionToken, securityToken, options) {
472
+ const credentials = new Credentials("SessionAndSecurityToken", sessionToken, securityToken);
473
+ return new ConnectionParameters(endpoint, credentials, options);
474
+ }
475
+
461
476
  /**
462
477
  * Creates connection parameters for a Campaign instance, using a security token.
463
478
  * Typically, called when embedding the SDK in Campaign: the session token will be
@@ -466,7 +481,7 @@ class ConnectionParameters {
466
481
  *
467
482
  * @static
468
483
  * @param {string} endpoint The campaign endpoint (URL)
469
- * @param {string} securityToken The session token
484
+ * @param {string} securityToken The security token
470
485
  * @param {Campaign.ConnectionOptions} options connection options
471
486
  * @returns {ConnectionParameters} a ConnectionParameters object which can be used to create a Client
472
487
  */
@@ -1497,11 +1512,11 @@ class Client {
1497
1512
  if (credentials._type != "SecurityToken" && typeof document != "undefined") {
1498
1513
  document.cookie = '__sessiontoken=;path=/;';
1499
1514
  }
1500
- if (credentials._type == "SessionToken" || credentials._type == "AnonymousUser") {
1515
+ if (credentials._type == "SessionToken" || credentials._type == "AnonymousUser" || credentials._type == "SessionAndSecurityToken") {
1501
1516
  that._sessionInfo = undefined;
1502
1517
  that._installedPackages = {};
1503
1518
  that._sessionToken = credentials._sessionToken;
1504
- that._securityToken = "";
1519
+ that._securityToken = credentials._type == "SessionAndSecurityToken" ? credentials._securityToken : "";
1505
1520
  that._bearerToken = undefined;
1506
1521
  that._onLogon();
1507
1522
  return Promise.resolve();
@@ -2059,7 +2074,30 @@ class Client {
2059
2074
  result.push(outputParams[i].value);
2060
2075
  }
2061
2076
  return result;
2077
+ }
2062
2078
 
2079
+ /**
2080
+ * Public API to dynamically invoke SOAP calls. This API allows to call any SOAP calls, including anonyous
2081
+ * SOAP calls such as xtk:session#GetServerTime
2082
+ *
2083
+ * @param {string} urn is the schema id, such as "xtk:session"
2084
+ * @param {string} methodName is the name of the method to call, for example "GetServerTime"
2085
+ * @param {boolean} isStatic indicates if the method is static or not
2086
+ * @param {array} inputParams is an array of input parameters. Each element of the array is an object with the following properties: name, type, value
2087
+ * @param {array} outputParams is an array of output parameters. Each element of the array is an object with the following properties: name, type
2088
+ * @param {string} representation the expected representation ('xml', 'BadgerFish', or 'SimpleJson'). If not set, will use the current representation
2089
+ *
2090
+ * @returns {array} the method return values in the same order as was described in the outputParams array.
2091
+ * In addition, the outputParams array will be modified, and the "value" property of each output param will be set
2092
+ */
2093
+ async makeSoapCall(urn, methodName, isStatic, inputParams, outputParams, representation) {
2094
+ const soapCall = this._prepareSoapCall(urn, methodName, isStatic, false,
2095
+ this._connectionParameters._options.extraHttpHeaders);
2096
+ // To support anonymous SOAP calls, we need to disable the logon check
2097
+ soapCall.requiresLogon = () => false;
2098
+ await this._makeInterceptableSoapCall(urn, null, soapCall, inputParams, outputParams, representation);
2099
+ const results = outputParams.map((o)=> o.value);
2100
+ return results;
2063
2101
  }
2064
2102
 
2065
2103
  async _makeHttpCall(request) {
@@ -2400,7 +2400,15 @@ describe('Application', () => {
2400
2400
  expect(root.labelLocalizationId).toBe('nms__recipient__e____recipient__@label');
2401
2401
  expect(root.descriptionLocalizationId).toBe('nms__recipient__e____recipient__@desc');
2402
2402
  });
2403
-
2403
+
2404
+ it("root node should have the label localization id when label exist but description does not exist", () => {
2405
+ const xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='recipient' label='Recipients' /></schema>");
2406
+ const schema = newSchema(xml);
2407
+ const root = schema.root;
2408
+ expect(root.labelLocalizationId).toBe('nms__recipient__e____recipient__@label');
2409
+ expect(root.descriptionLocalizationId).toBe('nms__recipient__e____recipient__@label');
2410
+ });
2411
+
2404
2412
  it("child node should have a correct label localization id", () => {
2405
2413
  const xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='lib' label='library' desc='library'/><element name='recipient' label='Recipients'/></schema>");
2406
2414
  const schema = newSchema(xml);
@@ -1756,11 +1756,11 @@ describe('ACC Client', function () {
1756
1756
  await client.NLWS.xtkSession.logon();
1757
1757
 
1758
1758
  const mockResponse = {
1759
- "publishedURL" : "http://trk-inst-xyz.campaign.adobe.com/res/trk-inst/409afb8798180a36591456e152b6c406.jpeg"
1759
+ "publishedURL" : "http://trk-inst-xyz.camp.adobe.com/res/trk-inst/409afb8798180a36591456e152b6c406.jpeg"
1760
1760
  };
1761
1761
  client._bearerToken = 'Bearer 1234567890';
1762
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");
1763
+ const response = await client.fileUploader.uploadAemAsset("https://author-stg.aem.adobe.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
1764
  expect(response).toBe(mockResponse);
1765
1765
 
1766
1766
  client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
@@ -1773,7 +1773,7 @@ describe('ACC Client', function () {
1773
1773
  client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1774
1774
  await client.NLWS.xtkSession.logon();
1775
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"))
1776
+ await (client.fileUploader.uploadAemAsset("https://author-stg.aem.adobe.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
1777
  .catch( e => { expect(e).toMatchObject(CampaignException.AEM_ASSET_UPLOAD_FAILED('Bearer token is missing'))});
1778
1778
 
1779
1779
  client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
@@ -1791,7 +1791,7 @@ describe('ACC Client', function () {
1791
1791
  client._transport.mockReturnValueOnce(mockResponse);
1792
1792
  client._bearerToken = 'Bearer 1234567890';
1793
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"))
1794
+ await (client.fileUploader.uploadAemAsset("https://author-stg.aem.adobe.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
1795
  .catch( e => { console.log(e); expect(e).toMatchObject(CampaignException.AEM_ASSET_UPLOAD_FAILED('Publishing failed'))});
1796
1796
 
1797
1797
  client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
@@ -1814,13 +1814,32 @@ describe('ACC Client', function () {
1814
1814
  client._bearerToken = 'Bearer 1234567890';
1815
1815
 
1816
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"))
1817
+ await (client.fileUploader.uploadAemAsset("https://author-stg.aem.adobe.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
1818
  .catch( e => { console.log(e); expect(e).toMatchObject(ex)});
1819
1819
 
1820
1820
  client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
1821
1821
  await client.NLWS.xtkSession.logoff();
1822
1822
  });
1823
1823
 
1824
+ // Case 5: transport layer returns response as string instead of json when sdk
1825
+ // used as package inside browser(Fetch API is used in browser while axios in node).
1826
+ it("Should return correct response", async () => {
1827
+ const client = await Mock.makeClient();
1828
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1829
+ await client.NLWS.xtkSession.logon();
1830
+
1831
+ const mockResponse = {
1832
+ "publishedURL" : "http://trk-inst-xyz.camp.adobe.com/res/trk-inst/409afb8798180a36591456e152b6c406.jpeg"
1833
+ };
1834
+ const mockResponseString = JSON.stringify(mockResponse);
1835
+ client._bearerToken = 'Bearer 1234567890';
1836
+ client._transport.mockReturnValueOnce(mockResponseString);
1837
+ const response = await client.fileUploader.uploadAemAsset("https://author-stg.aem.adobe.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");
1838
+ expect(response).toMatchObject(mockResponse);
1839
+
1840
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
1841
+ await client.NLWS.xtkSession.logoff();
1842
+ });
1824
1843
  });
1825
1844
 
1826
1845
 
@@ -2184,8 +2203,24 @@ describe('ACC Client', function () {
2184
2203
  expect(client.isLogged()).toBeFalsy();
2185
2204
  // Ensure logoff has been called
2186
2205
  expect(logoff.mock.calls.length).toBe(1);
2187
- })
2188
- })
2206
+ });
2207
+ });
2208
+
2209
+ describe("Session and security tokens authentication", () => {
2210
+ it("Should create logged client", async() => {
2211
+ const connectionParameters = sdk.ConnectionParameters.ofSessionAndSecurityToken("http://acc-sdk:8080", "$session_token$", "$security_token$");
2212
+ const client = await sdk.init(connectionParameters);
2213
+ client._transport = jest.fn();
2214
+ expect(client.isLogged()).toBeFalsy();
2215
+ await client.logon();
2216
+ expect(client.isLogged()).toBeTruthy();
2217
+ const logoff = client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
2218
+ await client.logoff();
2219
+ expect(client.isLogged()).toBeFalsy();
2220
+ // Ensure logoff has been called
2221
+ expect(logoff.mock.calls.length).toBe(1);
2222
+ });
2223
+ });
2189
2224
 
2190
2225
  describe("Bearer token authentication", () => {
2191
2226
  // Bearer token authentication is used when embedding IMS for authentication
@@ -4123,4 +4158,55 @@ describe('ACC Client', function () {
4123
4158
  await expect(jobs.linkTarget()).rejects.toThrow(/Cannot read (.*getSchema.*of null)|(.*of null.*getSchema)/);
4124
4159
  });
4125
4160
  });
4161
+
4162
+ describe("Anonymous SOAP calls", () => {
4163
+ it("Should call xtk:session#GetServerTime", async () => {
4164
+ const connectionParameters = sdk.ConnectionParameters.ofAnonymousUser("http://acc-sdk:8080");
4165
+ const client = await sdk.init(connectionParameters);
4166
+ client._transport = jest.fn();
4167
+
4168
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
4169
+ <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/'>
4170
+ <SOAP-ENV:Body>
4171
+ <GetServerTimeResponse xmlns='urn:xtk:session' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
4172
+ <ptmServerTime xsi:type='xsd:dateTime'>2023-08-25T13:58:11.477Z</ptmServerTime>
4173
+ </GetServerTimeResponse>
4174
+ </SOAP-ENV:Body>
4175
+ </SOAP-ENV:Envelope>`));
4176
+
4177
+ const inputParams = [];
4178
+ const outputParams = [{ name: "serverTime", type: "datetime" }];
4179
+ const result = await client.makeSoapCall("xtk:session", "GetServerTime", true, inputParams, outputParams);
4180
+ expect(result.length).toBe(1);
4181
+ expect(result[0]).toEqual(new Date("2023-08-25T13:58:11.477Z"));
4182
+ expect(outputParams[0].value).toEqual(new Date("2023-08-25T13:58:11.477Z"));
4183
+ });
4184
+
4185
+ it("Should call xtk:session#Logon", async () => {
4186
+ const connectionParameters = sdk.ConnectionParameters.ofAnonymousUser("http://acc-sdk:8080");
4187
+ const client = await sdk.init(connectionParameters);
4188
+ client._transport = jest.fn();
4189
+
4190
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
4191
+
4192
+ inputParams = [
4193
+ { name: "login", type: "string", value: "admin" },
4194
+ { name: "password", type: "string", value: "admin" },
4195
+ { name: "parameters", type: "DOMElement", value: { rememberMe: true } },
4196
+
4197
+ ];
4198
+ outputParams = [
4199
+ { name: "sessionToken", type: "string" },
4200
+ { name: "session", type: "DOMElement" },
4201
+ { name: "securityToken", type: "string" },
4202
+ ];
4203
+ const result = await client.makeSoapCall("xtk:session", "Logon", true, inputParams, outputParams);
4204
+ expect(result.length).toBe(3);
4205
+ expect(result[0]).toEqual("___$session_token$");
4206
+ expect(outputParams[0].value).toEqual("___$session_token$");
4207
+ expect(result[2]).toEqual("@$security_token$==");
4208
+ expect(outputParams[2].value).toEqual("@$security_token$==");
4209
+ expect(result[1].serverInfo.buildNumber).toBe("9219");
4210
+ });
4211
+ });
4126
4212
  });