Skip to content

Commit

Permalink
Reset RSA access state on connect.core.terminate() (#830)
Browse files Browse the repository at this point in the history
Co-authored-by: Andy Wang <[email protected]>
  • Loading branch information
andywang219 and Andy Wang authored Jan 16, 2024
1 parent 61344d9 commit 5b3e54c
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 39 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "amazon-connect-streams",
"version": "1.8.2",
"version": "1.8.3",
"description": "Amazon Connect Streams Library",
"engines": {
"node": ">=12.0.0"
Expand Down
2 changes: 1 addition & 1 deletion release/connect-streams-min.js

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion release/connect-streams.js
Original file line number Diff line number Diff line change
Expand Up @@ -5990,7 +5990,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
global.lily = connect;
connect.core = {};
connect.core.initialized = false;
connect.version = "1.8.2";
connect.version = "1.8.3";
connect.DEFAULT_BATCH_SIZE = 500;
var CCP_SYN_TIMEOUT = 1000; // 1 sec
var CCP_ACK_TIMEOUT = 3000; // 3 sec
Expand Down Expand Up @@ -6118,6 +6118,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
connect.core.softphoneManager = null;
connect.core.upstream = null;
connect.core.keepaliveManager = null;
connect.storageAccess.resetStorageAccessState();
connect.agent.initialized = false;
connect.core.initialized = false;
};
Expand Down Expand Up @@ -9502,6 +9503,7 @@ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input ==
storageParams = {};
originalCCPUrl = "";
rsaContainer = null;
onGrantCallbackInvoked = false;
};

/**
Expand Down Expand Up @@ -9753,6 +9755,9 @@ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input ==
getRequestStorageAccessUrl: getRequestStorageAccessUrl,
storageAccessEvents: storageAccessEvents,
resetStorageAccessState: resetStorageAccessState,
getOnGrantCallbackInvoked: function getOnGrantCallbackInvoked() {
return onGrantCallbackInvoked;
},
getStorageAccessParams: function getStorageAccessParams() {
return storageParams;
},
Expand Down
1 change: 1 addition & 0 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
connect.core.softphoneManager = null;
connect.core.upstream = null;
connect.core.keepaliveManager = null;
connect.storageAccess.resetStorageAccessState();
connect.agent.initialized = false;
connect.core.initialized = false;
};
Expand Down
2 changes: 2 additions & 0 deletions src/request-storage-access.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
storageParams = {};
originalCCPUrl = "";
rsaContainer = null;
onGrantCallbackInvoked = false;
};

/**
Expand Down Expand Up @@ -373,6 +374,7 @@
getRequestStorageAccessUrl,
storageAccessEvents,
resetStorageAccessState,
getOnGrantCallbackInvoked: () => onGrantCallbackInvoked,
getStorageAccessParams: () => storageParams,
onRequest: onRequestHandler,
request: () => {
Expand Down
128 changes: 94 additions & 34 deletions test/unit/core.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,37 @@ describe('Core', function () {

describe('#connect.core.initCCP()', function () {
jsdom({ url: "http://localhost" });
var clock
var clock;
function isCCPInitialized(containerDiv, params) {
try {
expect(params.ccpUrl).not.to.be.a("null");
expect(containerDiv).not.to.be.a("null");
assert.isTrue(document.createElement.calledOnce);
assert.isTrue(containerDiv.appendChild.calledOnce);
return true;
} catch(e) {
console.log("InitCCP initialization failed: ",e);
return false;
}
}
function isCCPTerminated() {
try {
assert.isEmpty(connect.core.client);
assert.isEmpty(connect.core.agentAppClient);
assert.isEmpty(connect.core.masterClient);
assert.isNull(connect.core.agentDataProvider);
assert.isNull(connect.core.softphoneManager);
assert.isNull(connect.core.upstream);
assert.isNull(connect.core.keepaliveManager);
assert.isFalse(connect.agent.initialized);
assert.isFalse(connect.core.initialized);
assert.isFalse(connect.core.eventBus.logEvents);
return true;
} catch(e) {
console.log("InitCCP Terminated failed: ",e);
return false;
}
}

before(function () {
clock = sinon.useFakeTimers();
Expand All @@ -366,46 +396,28 @@ describe('Core', function () {
sandbox.stub(connect, "ChatRingtoneEngine");
sandbox.spy(document, "createElement");
connect.numberOfConnectedCCPs = 0;
connect.core.initCCP(this.containerDiv, this.params);
});

after(function () {
sandbox.restore();
clock.restore();
});


afterEach(() => {
sandbox.resetHistory();
})

it("CCP initialization", function () {
connect.core.initCCP(this.containerDiv, this.params);
expect(this.params.ccpUrl).not.to.be.a("null");
expect(this.containerDiv).not.to.be.a("null");
assert.isTrue(connect.core.checkNotInitialized.called);
assert.isTrue(document.createElement.calledOnce);
assert.isTrue(this.containerDiv.appendChild.calledOnce);
});

it("Replicates logs received upstream while ignoring duplicates", function () {
var logger = connect.getLog();
var loggerId = logger.getLoggerId();
var originalLoggerLength = logger._logs.length;
var newLogs = [
new connect.LogEntry("test", connect.LogLevel.LOG, "some log", "some-logger-id"),
new connect.LogEntry("test", connect.LogLevel.LOG, "some log with no logger id", null),
new connect.LogEntry("test", connect.LogLevel.INFO, "some log info", "some-logger-id"),
new connect.LogEntry("test", connect.LogLevel.ERROR, "some log error", "some-logger-id")
];
var dupLogs = [
new connect.LogEntry("test", connect.LogLevel.LOG, "some dup log", loggerId),
new connect.LogEntry("test", connect.LogLevel.INFO, "some dup log info", loggerId),
new connect.LogEntry("test", connect.LogLevel.ERROR, "some dup log error", loggerId)
]
var allLogs = newLogs.concat(dupLogs);
for (var i = 0; i < allLogs.length; i++) {
connect.core.getUpstream().upstreamBus.trigger(connect.EventType.LOG, allLogs[i]);
}
clock.tick(2000);
assert.lengthOf(logger._logs, originalLoggerLength + newLogs.length);
});


it("sends initCCP ringtone params on ACK", function () {
connect.core.initCCP(this.containerDiv, this.params);
const spy = sinon.spy(connect.core.getUpstream(), "sendUpstream");
connect.core.getUpstream().upstreamBus.trigger(connect.EventType.ACKNOWLEDGE, { id: 'portId' });
assert.isTrue(connect.core.getUpstream().sendUpstream.calledWith(connect.EventType.CONFIGURE, {
Expand All @@ -415,8 +427,9 @@ describe('Core', function () {
}));
spy.restore();
});

it("sets up ringtone engines on CONFIGURE with initCCP params", function () {
connect.core.initCCP(this.containerDiv, this.params);
connect.core.initRingtoneEngines({ ringtone: this.extraRingtone });
connect.core.getEventBus().trigger(connect.EventType.CONFIGURE, {
softphone: this.params.softphone,
Expand All @@ -426,28 +439,75 @@ describe('Core', function () {
connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent());
connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent());
connect.ifMaster.callArg(1);

assert.isTrue(connect.VoiceRingtoneEngine.calledWithNew(this.params.softphone));
assert.isTrue(connect.QueueCallbackRingtoneEngine.calledWithNew(this.params.softphone));
assert.isTrue(connect.ChatRingtoneEngine.calledWithNew(this.params.chat));
});

it("should update the number of connected CCPs on UPDATE_CONNECTED_CCPS event", function () {
connect.core.initCCP(this.containerDiv, this.params);
expect(connect.numberOfConnectedCCPs).to.equal(0);
connect.core.getUpstream().upstreamBus.trigger(connect.EventType.UPDATE_CONNECTED_CCPS, { length: 1 });
expect(connect.numberOfConnectedCCPs).to.equal(1);
});


it("Replicates logs received upstream while ignoring duplicates", function () {
connect.core.initCCP(this.containerDiv, this.params);
var logger = connect.getLog();
var loggerId = logger.getLoggerId();
var originalLoggerLength = logger._logs.length;
var newLogs = [
new connect.LogEntry("test", connect.LogLevel.LOG, "some log", "some-logger-id"),
new connect.LogEntry("test", connect.LogLevel.LOG, "some log with no logger id", null),
new connect.LogEntry("test", connect.LogLevel.INFO, "some log info", "some-logger-id"),
new connect.LogEntry("test", connect.LogLevel.ERROR, "some log error", "some-logger-id")
];
var dupLogs = [
new connect.LogEntry("test", connect.LogLevel.LOG, "some dup log", loggerId),
new connect.LogEntry("test", connect.LogLevel.INFO, "some dup log info", loggerId),
new connect.LogEntry("test", connect.LogLevel.ERROR, "some dup log error", loggerId)
]
var allLogs = newLogs.concat(dupLogs);
for (var i = 0; i < allLogs.length; i++) {
connect.core.getUpstream().upstreamBus.trigger(connect.EventType.LOG, allLogs[i]);
}
clock.tick(2000);
assert.lengthOf(logger._logs, originalLoggerLength + newLogs.length);
});

it("Check if CCP is initialized after calling terminate function and re-calling initCCP", function () {
const storageAccessOriginal = connect.storageAccess;
connect.storageAccess = { ...connect.storageAccess, resetStorageAccessState: sinon.fake()};

expect(this.params.ccpUrl).not.to.be.a("null");
expect(this.containerDiv).not.to.be.a("null");
connect.core.initCCP(this.containerDiv, this.params);
expect(isCCPInitialized(this.containerDiv, this.params)).to.be.true;

connect.core.terminate();
expect(connect.storageAccess.resetStorageAccessState.calledOnce).to.be.true;

connect.core.terminate();
expect(connect.storageAccess.resetStorageAccessState.calledTwice).to.be.true;

expect(isCCPTerminated()).to.be.true;
sandbox.resetHistory();
connect.core.initCCP(this.containerDiv, this.params);
expect(isCCPInitialized(this.containerDiv, this.params)).to.be.true;
connect.storageAccess = storageAccessOriginal;
});

describe("on ACK", function () {
let fakeOnInitHandler;

before(function () {
fakeOnInitHandler = sinon.fake();
connect.core.onInitialized(fakeOnInitHandler);
sandbox.stub(connect.WindowIOStream.prototype, 'send').returns(null);
connect.core.getUpstream().upstreamBus.trigger(connect.EventType.ACKNOWLEDGE, { id: 'portId' });
});

it("should set portStreamId on ACK", function () {
connect.core.getUpstream().upstreamBus.trigger(connect.EventType.ACKNOWLEDGE, { id: 'portId' });
expect(connect.core.portStreamId).to.equal('portId');
Expand Down
5 changes: 5 additions & 0 deletions test/unit/request-storage-access.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ describe("Request Storage Access module", () => {
});

connect.storageAccess.init(ccpUrl, container);
expect(connect.storageAccess.getOnGrantCallbackInvoked()).to.be.false;
connect.storageAccess.setupRequestHandlers({ onGrant: onGrantSpy });
connect.storageAccess.request();

Expand All @@ -232,10 +233,14 @@ describe("Request Storage Access module", () => {
);

expect(onGrantSpy.called).to.be.true;
expect(connect.storageAccess.getOnGrantCallbackInvoked()).to.be.true;
connect.storageAccess.request();

/** Should be called only once */
expect(onGrantSpy.calledTwice).not.to.be.true;

connect.storageAccess.resetStorageAccessState();
expect(connect.storageAccess.getOnGrantCallbackInvoked()).to.be.false;
});

it('Should hide container if mode is custom after granting access', () => {
Expand Down

0 comments on commit 5b3e54c

Please sign in to comment.