@adobe/acc-js-sdk 1.1.58 → 1.1.59
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/docs/changeLog.html +8 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/client.js +10 -3
- package/src/util.js +18 -1
- package/test/client.test.js +62 -8
- package/test/util.test.js +99 -0
package/docs/changeLog.html
CHANGED
|
@@ -3,8 +3,15 @@ layout: page
|
|
|
3
3
|
title: Change Log
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
<section class="changelog"><h1>Version 1.1.59</h1>
|
|
7
|
+
<h2>2025/08/22</h2>
|
|
8
|
+
<li>
|
|
9
|
+
In previous commit, computing the UUID was not working in a browser context
|
|
10
|
+
</li>
|
|
11
|
+
</section>
|
|
12
|
+
|
|
6
13
|
<section class="changelog"><h1>Version 1.1.58</h1>
|
|
7
|
-
<h2>2025/
|
|
14
|
+
<h2>2025/08/20</h2>
|
|
8
15
|
<li>
|
|
9
16
|
Bumped dependencies version to fix vulnerabilities
|
|
10
17
|
</li>
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/acc-js-sdk",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.59",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@adobe/acc-js-sdk",
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.59",
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"axios": "^1.7.8",
|
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -38,7 +38,7 @@ const EntityAccessor = require('./entityAccessor.js').EntityAccessor;
|
|
|
38
38
|
const { Util } = require('./util.js');
|
|
39
39
|
const { XtkJobInterface } = require('./xtkJob.js');
|
|
40
40
|
const qsStringify = require('qs-stringify');
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
/**
|
|
43
43
|
* @namespace Campaign
|
|
44
44
|
*
|
|
@@ -636,9 +636,16 @@ const fileUploader = (client) => {
|
|
|
636
636
|
// If a prefix is provided, we use it with a UUID (i.e. 'customPrefix-123e4567-e89b-12d3-a456-426614174000')
|
|
637
637
|
const oldBehaviorPrefix = 'RES';
|
|
638
638
|
const prefix = Util.validateFileResPrefix(fileResPrefix, oldBehaviorPrefix);
|
|
639
|
-
|
|
639
|
+
const getUUIDOrFallback = async() => {
|
|
640
|
+
try {
|
|
641
|
+
return Util.getUUID();
|
|
642
|
+
} catch (error) {
|
|
643
|
+
// In case getUUID throws, fall back to increasing the counter
|
|
644
|
+
return await client.NLWS.xtkCounter.increaseValue({ name: 'xtkResource' });
|
|
645
|
+
}
|
|
646
|
+
};
|
|
640
647
|
const suffix = (prefix === oldBehaviorPrefix) ?
|
|
641
|
-
await client.NLWS.xtkCounter.increaseValue({ name: 'xtkResource' }) :
|
|
648
|
+
await client.NLWS.xtkCounter.increaseValue({ name: 'xtkResource' }) : await getUUIDOrFallback();
|
|
642
649
|
|
|
643
650
|
const internalName = (prefix === oldBehaviorPrefix) ? `${prefix}${suffix}` : `${prefix}_${suffix}`;
|
|
644
651
|
|
package/src/util.js
CHANGED
|
@@ -143,7 +143,7 @@ class Util {
|
|
|
143
143
|
return schemaId;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
static validateFileResPrefix(prefix, defaultPrefix =
|
|
146
|
+
static validateFileResPrefix(prefix, defaultPrefix = 'RES') {
|
|
147
147
|
const regex = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
148
148
|
|
|
149
149
|
if (typeof prefix !== "string" || !regex.test(prefix)) {
|
|
@@ -153,6 +153,23 @@ class Util {
|
|
|
153
153
|
return prefix;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
static getUUID() {
|
|
157
|
+
if (globalThis.crypto &&
|
|
158
|
+
globalThis.crypto.randomUUID &&
|
|
159
|
+
typeof globalThis.crypto.randomUUID === 'function') {
|
|
160
|
+
return globalThis.crypto.randomUUID(); // browser
|
|
161
|
+
}
|
|
162
|
+
const nodeCrypto = (() => {
|
|
163
|
+
return require("crypto");
|
|
164
|
+
})();
|
|
165
|
+
if (nodeCrypto && nodeCrypto.randomUUID) {
|
|
166
|
+
return nodeCrypto.randomUUID(); // Node
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
//Nothing worked
|
|
170
|
+
throw new Error('Unable to generate UUID');
|
|
171
|
+
}
|
|
172
|
+
|
|
156
173
|
/**
|
|
157
174
|
* Test if an object is a promise
|
|
158
175
|
* @param {*} object the object to test
|
package/test/client.test.js
CHANGED
|
@@ -3604,7 +3604,7 @@ describe('ACC Client', function () {
|
|
|
3604
3604
|
statusCode: 500,
|
|
3605
3605
|
});
|
|
3606
3606
|
});
|
|
3607
|
-
});
|
|
3607
|
+
}); // "File uploader - on server"
|
|
3608
3608
|
|
|
3609
3609
|
describe("File uploader - on browser", () => {
|
|
3610
3610
|
beforeEach(() => {
|
|
@@ -4218,8 +4218,6 @@ describe('ACC Client', function () {
|
|
|
4218
4218
|
statusCode: 400,
|
|
4219
4219
|
});
|
|
4220
4220
|
});
|
|
4221
|
-
});
|
|
4222
|
-
|
|
4223
4221
|
it("Test uploads by specifying a file prefix", async () => {
|
|
4224
4222
|
// Create a mock client and logon
|
|
4225
4223
|
const client = await Mock.makeClient();
|
|
@@ -4261,13 +4259,69 @@ describe('ACC Client', function () {
|
|
|
4261
4259
|
); // xtk:fileRes#GetURL
|
|
4262
4260
|
|
|
4263
4261
|
// Call upload
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4262
|
+
await client.fileUploader.upload({
|
|
4263
|
+
type: "text/html",
|
|
4264
|
+
size: 12345,
|
|
4265
|
+
}, undefined, 'PREFIX');
|
|
4268
4266
|
expect(Util.validateFileResPrefix).toHaveBeenLastCalledWith('PREFIX', 'RES');
|
|
4269
4267
|
});
|
|
4270
|
-
|
|
4268
|
+
|
|
4269
|
+
it("Test uploads by with a file prefix but getUUID throws", async () => {
|
|
4270
|
+
// Create a mock client and logon
|
|
4271
|
+
const client = await Mock.makeClient();
|
|
4272
|
+
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
4273
|
+
await client.NLWS.xtkSession.logon();
|
|
4274
|
+
|
|
4275
|
+
// Mock the upload protocol
|
|
4276
|
+
// - the upload.jsp (which returns the content of an iframe and JS to eval)
|
|
4277
|
+
// - call to xtk:session#Write
|
|
4278
|
+
// - call to xtk:fileRes#PublishIfNeeded
|
|
4279
|
+
// - call to xtk:fileRes#GetURL
|
|
4280
|
+
|
|
4281
|
+
client._transport.mockReturnValueOnce(
|
|
4282
|
+
Promise.resolve(`Ok
|
|
4283
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
4284
|
+
<head>
|
|
4285
|
+
<script type="text/javascript">if(window.parent&&window.parent.document.controller&&"function"==typeof window.parent.document.controller.uploadFileCallBack){var aFilesInfo=new Array;aFilesInfo.push({paramName:"file",fileName:"test.txt",newFileName:"d8e8fca2dc0f896fd7cb4cb0031ba249.txt",md5:"d8e8fca2dc0f896fd7cb4cb0031ba249"}),window.parent.document.controller.uploadFileCallBack(aFilesInfo)}</script>
|
|
4286
|
+
</head>
|
|
4287
|
+
<body></body>
|
|
4288
|
+
</html>`)
|
|
4289
|
+
); // upload.jsp
|
|
4290
|
+
|
|
4291
|
+
client._transport.mockReturnValueOnce(
|
|
4292
|
+
Promise.resolve(Mock.GET_XTK_COUNTER_RESPONSE)
|
|
4293
|
+
); // GetEntityIfMoreRecentResponse - counter
|
|
4294
|
+
client._transport.mockReturnValueOnce(
|
|
4295
|
+
Mock.INCREASE_VALUE_RESPONSE
|
|
4296
|
+
); // xtk:counter#IncreaseValue
|
|
4297
|
+
|
|
4298
|
+
client._transport.mockReturnValueOnce(
|
|
4299
|
+
Mock.GET_XTK_SESSION_SCHEMA_RESPONSE
|
|
4300
|
+
); // GetEntityIfMoreRecentResponse - session
|
|
4301
|
+
|
|
4302
|
+
client._transport.mockReturnValueOnce(Mock.FILE_RES_WRITE_RESPONSE); // xtk:session#Write
|
|
4303
|
+
jest.spyOn(Util, 'getUUID').mockImplementation(() => { throw new Error('UUID error'); });
|
|
4304
|
+
|
|
4305
|
+
client._transport.mockReturnValueOnce(
|
|
4306
|
+
Promise.resolve(Mock.GET_FILERES_QUERY_SCHEMA_RESPONSE)
|
|
4307
|
+
); // GetEntityIfMoreRecentResponse - fileRes
|
|
4308
|
+
client._transport.mockReturnValueOnce(
|
|
4309
|
+
Promise.resolve(Mock.PUBLISH_IF_NEEDED_RESPONSE)
|
|
4310
|
+
); // xtk:fileRes#PublishIfNeeded
|
|
4311
|
+
|
|
4312
|
+
client._transport.mockReturnValueOnce(
|
|
4313
|
+
Promise.resolve(Mock.GET_URL_RESPONSE)
|
|
4314
|
+
); // xtk:fileRes#GetURL
|
|
4315
|
+
|
|
4316
|
+
// Call upload
|
|
4317
|
+
await client.fileUploader.upload({
|
|
4318
|
+
type: "text/html",
|
|
4319
|
+
size: 12345,
|
|
4320
|
+
}, undefined, 'PREFIX');
|
|
4321
|
+
expect(Util.getUUID).toHaveBeenCalledTimes(1);
|
|
4322
|
+
});
|
|
4323
|
+
}); // "File uploader - on browser"
|
|
4324
|
+
}); // 'upload'
|
|
4271
4325
|
|
|
4272
4326
|
describe('uploadAemAsset', () => {
|
|
4273
4327
|
// write unit test for client.fileUploader.uploadAemAsset method
|
package/test/util.test.js
CHANGED
|
@@ -458,5 +458,104 @@ describe('Util', function() {
|
|
|
458
458
|
expect(Util.validateFileResPrefix("132Invalid", "customDefault")).toBe("customDefault");
|
|
459
459
|
});
|
|
460
460
|
});
|
|
461
|
+
|
|
462
|
+
describe("GetUUID", () => {
|
|
463
|
+
describe("UUID - on server node", () => {
|
|
464
|
+
describe("node <= 16", () => {
|
|
465
|
+
describe('code coverage: getUUID', () => {
|
|
466
|
+
let originalCrypto;
|
|
467
|
+
// on old Node versions, crypto may not be available
|
|
468
|
+
// deleting globalThis.crypto to simulate the environment on newer Node
|
|
469
|
+
beforeEach(() => {
|
|
470
|
+
// Save the original crypto
|
|
471
|
+
originalCrypto = globalThis.crypto;
|
|
472
|
+
delete globalThis.crypto;
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
afterEach(() => {
|
|
476
|
+
// Restore it after the test
|
|
477
|
+
globalThis.crypto = originalCrypto;
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
it('should handle require("crypto") throwing', () => {
|
|
481
|
+
// Force require("crypto") to throw
|
|
482
|
+
jest.mock('crypto', () => {
|
|
483
|
+
throw new Error('mock require failure');
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
// Re-require the module AFTER mocking
|
|
487
|
+
const UUIDHelper = require('../src/util.js').Util;
|
|
488
|
+
|
|
489
|
+
let exceptionCaught = false;
|
|
490
|
+
try{
|
|
491
|
+
UUIDHelper.getUUID();
|
|
492
|
+
} catch (e) {
|
|
493
|
+
exceptionCaught = true;
|
|
494
|
+
}
|
|
495
|
+
expect(exceptionCaught).toBe(true);
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
it('should handle require("crypto") throwing', () => {
|
|
499
|
+
// Force require("crypto") to not have randomUUID
|
|
500
|
+
jest.mock('crypto', () => ({}));
|
|
501
|
+
|
|
502
|
+
// Re-require the module AFTER mocking
|
|
503
|
+
const UUIDHelper = require('../src/util.js').Util;
|
|
504
|
+
|
|
505
|
+
let exceptionCaught = false;
|
|
506
|
+
try{
|
|
507
|
+
UUIDHelper.getUUID();
|
|
508
|
+
} catch (e) {
|
|
509
|
+
exceptionCaught = e.message === 'Unable to generate UUID';
|
|
510
|
+
}
|
|
511
|
+
expect(exceptionCaught).toBe(true);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
it('should fallback to node crypto when globalThis.crypto is not available', () => {
|
|
515
|
+
jest.unmock('crypto');
|
|
516
|
+
// Spy on require
|
|
517
|
+
const spy = jest.spyOn(require('crypto'), 'randomUUID').mockReturnValue('mock-uuid');
|
|
518
|
+
|
|
519
|
+
// Re-import the module if your getUUID function is from a module
|
|
520
|
+
const uuid = Util.getUUID(); // or just call getUUID() if it's in scope
|
|
521
|
+
|
|
522
|
+
expect(uuid).toBe('mock-uuid');
|
|
523
|
+
expect(spy).toHaveBeenCalled();
|
|
524
|
+
spy.mockRestore();
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
});
|
|
528
|
+
});
|
|
529
|
+
describe("node > 16", () => {
|
|
530
|
+
it('should return a correct UUID v4', () => {
|
|
531
|
+
// x is [0-9a-f], Y is 8, 9, a or b
|
|
532
|
+
// uuid format: xxxxxxxx-xxxx-4xxx-Yxxx-xxxxxxxxxxxx
|
|
533
|
+
const uuidV4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
534
|
+
expect(uuidV4Regex.test(Util.getUUID())).toBe(true);
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
describe("UUID - on browser", () => {
|
|
539
|
+
// code coverage test as we mock the browser return values
|
|
540
|
+
it('should return a correct UUID v4', () => {
|
|
541
|
+
if (!globalThis.crypto || !globalThis.crypto.randomUUID){
|
|
542
|
+
globalThis.crypto = {
|
|
543
|
+
...globalThis.crypto,
|
|
544
|
+
randomUUID: jest.fn(),
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// x is [0-9a-f], Y is 8, 9, a or b
|
|
549
|
+
// uuid v4 format: xxxxxxxx-xxxx-4xxx-Yxxx-xxxxxxxxxxxx
|
|
550
|
+
// Mocking crypto.randomUUID to return a specific valid v4 UUID
|
|
551
|
+
jest.spyOn(globalThis.crypto, 'randomUUID').mockReturnValue('123e4567-e89b-42d3-a456-426614174000');
|
|
552
|
+
const uuidV4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
553
|
+
expect(uuidV4Regex.test(Util.getUUID())).toBe(true);
|
|
554
|
+
// Mocking crypto.randomUUID to return a specific an invalid v4 UUID
|
|
555
|
+
jest.spyOn(globalThis.crypto, 'randomUUID').mockReturnValue('12345678-1234-0234-0567-426614174000');
|
|
556
|
+
expect(uuidV4Regex.test(Util.getUUID())).toBe(false);
|
|
557
|
+
});
|
|
558
|
+
});
|
|
559
|
+
});
|
|
461
560
|
});
|
|
462
561
|
|