@openfin/cloud-interop-core-api 0.0.1-alpha.c7e246f → 0.0.1-alpha.c89de1a
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/README.md +2 -2
- package/bundle.d.ts +12 -11
- package/index.cjs +105 -14
- package/index.mjs +105 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# @openfin/cloud-interop-core-api
|
|
2
2
|
|
|
3
|
-
This package contains the core interop library that handles all interactions with the
|
|
3
|
+
This package contains the core interop library that handles all interactions with the HERE Cloud Interop Service.
|
|
4
4
|
|
|
5
5
|
It is callable via browser or node applications.
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
## Authentication
|
|
9
9
|
|
|
10
|
-
The library supports authentication with the
|
|
10
|
+
The library supports authentication with the HERE Cloud Interop Service using the following methods:
|
|
11
11
|
- Basic Authentication
|
|
12
12
|
- JWT Token Authentication
|
|
13
13
|
- Default Authentication i.e. Interactive session based authentication using cookies
|
package/bundle.d.ts
CHANGED
|
@@ -245,36 +245,36 @@ export declare class CloudInteropAPI {
|
|
|
245
245
|
/**
|
|
246
246
|
* Connects and creates a session on the Cloud Interop service
|
|
247
247
|
*
|
|
248
|
-
* @param
|
|
249
|
-
* @returns
|
|
248
|
+
* @param parameters - The parameters to use to connect
|
|
249
|
+
* @returns Promise that resolves when connection is established
|
|
250
250
|
* @memberof CloudInteropAPI
|
|
251
|
-
* @throws
|
|
252
|
-
* @throws
|
|
251
|
+
* @throws CloudInteropAPIError - If an error occurs during connection
|
|
252
|
+
* @throws AuthorizationError - If the connection is unauthorized
|
|
253
253
|
*/
|
|
254
254
|
connect(parameters: ConnectParameters): Promise<void>;
|
|
255
255
|
/**
|
|
256
256
|
* Disconnects from the Cloud Interop service
|
|
257
257
|
*
|
|
258
|
-
* @returns
|
|
258
|
+
* @returns Promise that resolves when disconnected
|
|
259
259
|
* @memberof CloudInteropAPI
|
|
260
|
-
* @throws
|
|
260
|
+
* @throws CloudInteropAPIError - If an error occurs during disconnection
|
|
261
261
|
*/
|
|
262
262
|
disconnect(): Promise<void>;
|
|
263
263
|
/**
|
|
264
264
|
* Publishes a new context for the given context group to the other connected sessions
|
|
265
265
|
*
|
|
266
|
-
* @param
|
|
267
|
-
* @param
|
|
268
|
-
* @returns
|
|
266
|
+
* @param contextGroup - The context group to publish to
|
|
267
|
+
* @param context - The context to publish
|
|
268
|
+
* @returns Promise that resolves when context is published
|
|
269
269
|
* @memberof CloudInteropAPI
|
|
270
270
|
*/
|
|
271
271
|
setContext(contextGroup: string, context: InferredContext): Promise<void>;
|
|
272
272
|
/**
|
|
273
273
|
* Starts an intent discovery operation
|
|
274
274
|
*
|
|
275
|
-
* @returns
|
|
275
|
+
* @returns Promise that resolves when intent discovery is started
|
|
276
276
|
* @memberof CloudInteropAPI
|
|
277
|
-
* @throws
|
|
277
|
+
* @throws CloudInteropAPIError - If an error occurs during intent discovery
|
|
278
278
|
*/
|
|
279
279
|
startIntentDiscovery(options: StartIntentDiscoveryOptions): Promise<void>;
|
|
280
280
|
raiseIntent(options: RaiseIntentAPIOptions): Promise<void>;
|
|
@@ -418,6 +418,7 @@ export declare type CreateSessionResponse = {
|
|
|
418
418
|
sub: string;
|
|
419
419
|
platformId: string;
|
|
420
420
|
sourceId: string;
|
|
421
|
+
localSessionExpiryHandling?: boolean;
|
|
421
422
|
};
|
|
422
423
|
|
|
423
424
|
declare const errorSchema: z.ZodObject<{
|
package/index.cjs
CHANGED
|
@@ -353,6 +353,7 @@ class CloudInteropAPI {
|
|
|
353
353
|
#attemptingToReconnect = false;
|
|
354
354
|
#events = new EventController();
|
|
355
355
|
#intents;
|
|
356
|
+
#sessionTimer;
|
|
356
357
|
constructor(cloudInteropSettings) {
|
|
357
358
|
this.#cloudInteropSettings = cloudInteropSettings;
|
|
358
359
|
}
|
|
@@ -365,11 +366,11 @@ class CloudInteropAPI {
|
|
|
365
366
|
/**
|
|
366
367
|
* Connects and creates a session on the Cloud Interop service
|
|
367
368
|
*
|
|
368
|
-
* @param
|
|
369
|
-
* @returns
|
|
369
|
+
* @param parameters - The parameters to use to connect
|
|
370
|
+
* @returns Promise that resolves when connection is established
|
|
370
371
|
* @memberof CloudInteropAPI
|
|
371
|
-
* @throws
|
|
372
|
-
* @throws
|
|
372
|
+
* @throws CloudInteropAPIError - If an error occurs during connection
|
|
373
|
+
* @throws AuthorizationError - If the connection is unauthorized
|
|
373
374
|
*/
|
|
374
375
|
async connect(parameters) {
|
|
375
376
|
this.#validateConnectParams(parameters);
|
|
@@ -393,6 +394,11 @@ class CloudInteropAPI {
|
|
|
393
394
|
throw new CloudInteropAPIError(`Failed to connect to the Cloud Interop service: ${this.#cloudInteropSettings.url}`, 'ERR_CONNECT', new Error(createSessionResponse.statusText));
|
|
394
395
|
}
|
|
395
396
|
this.#sessionDetails = (await createSessionResponse.json());
|
|
397
|
+
// If local session expiry handling is enabled, start the session timer
|
|
398
|
+
if (this.#sessionDetails.localSessionExpiryHandling) {
|
|
399
|
+
this.#logger('debug', `Local session expiry handling is enabled`);
|
|
400
|
+
this.#startSessionTimer();
|
|
401
|
+
}
|
|
396
402
|
const sessionRootTopic = this.#sessionDetails.sessionRootTopic;
|
|
397
403
|
const clientOptions = {
|
|
398
404
|
keepalive: this.#keepAliveIntervalSeconds,
|
|
@@ -422,9 +428,7 @@ class CloudInteropAPI {
|
|
|
422
428
|
if (error instanceof mqtt.ErrorWithReasonCode) {
|
|
423
429
|
switch (error.code) {
|
|
424
430
|
case BadUserNamePasswordError: {
|
|
425
|
-
|
|
426
|
-
this.#logger('warn', `Session expired`);
|
|
427
|
-
this.#events.emitEvent('session-expired');
|
|
431
|
+
this.#handleSessionExpiry();
|
|
428
432
|
return;
|
|
429
433
|
}
|
|
430
434
|
default: {
|
|
@@ -478,9 +482,9 @@ class CloudInteropAPI {
|
|
|
478
482
|
/**
|
|
479
483
|
* Disconnects from the Cloud Interop service
|
|
480
484
|
*
|
|
481
|
-
* @returns
|
|
485
|
+
* @returns Promise that resolves when disconnected
|
|
482
486
|
* @memberof CloudInteropAPI
|
|
483
|
-
* @throws
|
|
487
|
+
* @throws CloudInteropAPIError - If an error occurs during disconnection
|
|
484
488
|
*/
|
|
485
489
|
async disconnect() {
|
|
486
490
|
await this.#disconnect(true);
|
|
@@ -488,9 +492,9 @@ class CloudInteropAPI {
|
|
|
488
492
|
/**
|
|
489
493
|
* Publishes a new context for the given context group to the other connected sessions
|
|
490
494
|
*
|
|
491
|
-
* @param
|
|
492
|
-
* @param
|
|
493
|
-
* @returns
|
|
495
|
+
* @param contextGroup - The context group to publish to
|
|
496
|
+
* @param context - The context to publish
|
|
497
|
+
* @returns Promise that resolves when context is published
|
|
494
498
|
* @memberof CloudInteropAPI
|
|
495
499
|
*/
|
|
496
500
|
async setContext(contextGroup, context) {
|
|
@@ -517,9 +521,9 @@ class CloudInteropAPI {
|
|
|
517
521
|
/**
|
|
518
522
|
* Starts an intent discovery operation
|
|
519
523
|
*
|
|
520
|
-
* @returns
|
|
524
|
+
* @returns Promise that resolves when intent discovery is started
|
|
521
525
|
* @memberof CloudInteropAPI
|
|
522
|
-
* @throws
|
|
526
|
+
* @throws CloudInteropAPIError - If an error occurs during intent discovery
|
|
523
527
|
*/
|
|
524
528
|
async startIntentDiscovery(options) {
|
|
525
529
|
this.#throwIfNotConnected();
|
|
@@ -560,6 +564,11 @@ class CloudInteropAPI {
|
|
|
560
564
|
if (!this.#connectionParams) {
|
|
561
565
|
throw new Error('Connect parameters must be provided');
|
|
562
566
|
}
|
|
567
|
+
// Cancel session timer if it's running
|
|
568
|
+
if (this.#sessionTimer) {
|
|
569
|
+
clearTimeout(this.#sessionTimer);
|
|
570
|
+
this.#sessionTimer = undefined;
|
|
571
|
+
}
|
|
563
572
|
const disconnectResponse = await fetch(`${this.#cloudInteropSettings.url}/api/sessions/${this.#sessionDetails.sessionId}`, {
|
|
564
573
|
method: 'DELETE',
|
|
565
574
|
headers: getRequestHeaders(this.#connectionParams),
|
|
@@ -658,6 +667,88 @@ class CloudInteropAPI {
|
|
|
658
667
|
throw new Error('MQTT client not connected');
|
|
659
668
|
}
|
|
660
669
|
}
|
|
670
|
+
/**
|
|
671
|
+
* Extracts the expiration timestamp from a JWT token.
|
|
672
|
+
*
|
|
673
|
+
* @param token - The JWT token string
|
|
674
|
+
* @returns The expiration timestamp in seconds, or null if extraction fails
|
|
675
|
+
*/
|
|
676
|
+
#extractExpirationFromJwt(token) {
|
|
677
|
+
try {
|
|
678
|
+
// JWT tokens have three parts separated by dots: header.payload.signature
|
|
679
|
+
// The exp claim is in the payload
|
|
680
|
+
const parts = token.split('.');
|
|
681
|
+
if (parts.length < 2) {
|
|
682
|
+
this.#logger('warn', 'Invalid JWT token format: expected at least 2 parts');
|
|
683
|
+
return null;
|
|
684
|
+
}
|
|
685
|
+
const payload = parts[1];
|
|
686
|
+
// Decode base64url encoded payload
|
|
687
|
+
const decodedBytes = buffer.Buffer.from(payload, 'base64url');
|
|
688
|
+
const payloadJson = decodedBytes.toString('utf8');
|
|
689
|
+
// Parse JSON to get the exp claim
|
|
690
|
+
const claims = JSON.parse(payloadJson);
|
|
691
|
+
const exp = claims.exp;
|
|
692
|
+
if (exp === undefined || exp === null) {
|
|
693
|
+
this.#logger('warn', "JWT token does not contain 'exp' claim");
|
|
694
|
+
return null;
|
|
695
|
+
}
|
|
696
|
+
if (typeof exp !== 'number') {
|
|
697
|
+
this.#logger('warn', `JWT token 'exp' claim is not a number: ${exp}`);
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
return exp;
|
|
701
|
+
}
|
|
702
|
+
catch (error) {
|
|
703
|
+
this.#logger('error', `Failed to extract expiration from JWT token: ${error instanceof Error ? error.message : error}`);
|
|
704
|
+
return null;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Start a session timer that will expire at the time specified in the JWT token's exp claim.
|
|
709
|
+
* When the timer fires, it executes the same actions as the BadUserNamePasswordError case.
|
|
710
|
+
*/
|
|
711
|
+
#startSessionTimer() {
|
|
712
|
+
if (!this.#sessionDetails?.localSessionExpiryHandling) {
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
const token = this.#sessionDetails.token;
|
|
716
|
+
if (!token) {
|
|
717
|
+
this.#logger('warn', 'Cannot start session timer: token not available');
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
// Extract expiration time from JWT token
|
|
721
|
+
const expTimestamp = this.#extractExpirationFromJwt(token);
|
|
722
|
+
if (expTimestamp === null) {
|
|
723
|
+
this.#logger('warn', 'Cannot start session timer: could not extract expiration from JWT token');
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
const currentTimeSeconds = Math.floor(Date.now() / 1000);
|
|
727
|
+
const delaySeconds = expTimestamp - currentTimeSeconds;
|
|
728
|
+
if (delaySeconds <= 0) {
|
|
729
|
+
this.#logger('warn', 'JWT token has already expired or expires immediately');
|
|
730
|
+
// Execute the same actions as BadUserNamePasswordError case
|
|
731
|
+
this.#handleSessionExpiry();
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
// Clear any existing timer
|
|
735
|
+
if (this.#sessionTimer) {
|
|
736
|
+
clearTimeout(this.#sessionTimer);
|
|
737
|
+
}
|
|
738
|
+
const expirationTimeString = new Date(expTimestamp * 1000).toISOString();
|
|
739
|
+
this.#logger('debug', `Starting session timer to expire in ${delaySeconds} seconds (at ${expirationTimeString})`);
|
|
740
|
+
this.#sessionTimer = setTimeout(async () => {
|
|
741
|
+
this.#handleSessionExpiry();
|
|
742
|
+
}, delaySeconds * 1000);
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Handles session expiry by executing the same actions as the BadUserNamePasswordError case.
|
|
746
|
+
*/
|
|
747
|
+
async #handleSessionExpiry() {
|
|
748
|
+
await this.#disconnect(false);
|
|
749
|
+
this.#logger('warn', 'Session expired');
|
|
750
|
+
this.#events.emitEvent('session-expired');
|
|
751
|
+
}
|
|
661
752
|
}
|
|
662
753
|
|
|
663
754
|
exports.AuthorizationError = AuthorizationError;
|
package/index.mjs
CHANGED
|
@@ -351,6 +351,7 @@ class CloudInteropAPI {
|
|
|
351
351
|
#attemptingToReconnect = false;
|
|
352
352
|
#events = new EventController();
|
|
353
353
|
#intents;
|
|
354
|
+
#sessionTimer;
|
|
354
355
|
constructor(cloudInteropSettings) {
|
|
355
356
|
this.#cloudInteropSettings = cloudInteropSettings;
|
|
356
357
|
}
|
|
@@ -363,11 +364,11 @@ class CloudInteropAPI {
|
|
|
363
364
|
/**
|
|
364
365
|
* Connects and creates a session on the Cloud Interop service
|
|
365
366
|
*
|
|
366
|
-
* @param
|
|
367
|
-
* @returns
|
|
367
|
+
* @param parameters - The parameters to use to connect
|
|
368
|
+
* @returns Promise that resolves when connection is established
|
|
368
369
|
* @memberof CloudInteropAPI
|
|
369
|
-
* @throws
|
|
370
|
-
* @throws
|
|
370
|
+
* @throws CloudInteropAPIError - If an error occurs during connection
|
|
371
|
+
* @throws AuthorizationError - If the connection is unauthorized
|
|
371
372
|
*/
|
|
372
373
|
async connect(parameters) {
|
|
373
374
|
this.#validateConnectParams(parameters);
|
|
@@ -391,6 +392,11 @@ class CloudInteropAPI {
|
|
|
391
392
|
throw new CloudInteropAPIError(`Failed to connect to the Cloud Interop service: ${this.#cloudInteropSettings.url}`, 'ERR_CONNECT', new Error(createSessionResponse.statusText));
|
|
392
393
|
}
|
|
393
394
|
this.#sessionDetails = (await createSessionResponse.json());
|
|
395
|
+
// If local session expiry handling is enabled, start the session timer
|
|
396
|
+
if (this.#sessionDetails.localSessionExpiryHandling) {
|
|
397
|
+
this.#logger('debug', `Local session expiry handling is enabled`);
|
|
398
|
+
this.#startSessionTimer();
|
|
399
|
+
}
|
|
394
400
|
const sessionRootTopic = this.#sessionDetails.sessionRootTopic;
|
|
395
401
|
const clientOptions = {
|
|
396
402
|
keepalive: this.#keepAliveIntervalSeconds,
|
|
@@ -420,9 +426,7 @@ class CloudInteropAPI {
|
|
|
420
426
|
if (error instanceof mqtt.ErrorWithReasonCode) {
|
|
421
427
|
switch (error.code) {
|
|
422
428
|
case BadUserNamePasswordError: {
|
|
423
|
-
|
|
424
|
-
this.#logger('warn', `Session expired`);
|
|
425
|
-
this.#events.emitEvent('session-expired');
|
|
429
|
+
this.#handleSessionExpiry();
|
|
426
430
|
return;
|
|
427
431
|
}
|
|
428
432
|
default: {
|
|
@@ -476,9 +480,9 @@ class CloudInteropAPI {
|
|
|
476
480
|
/**
|
|
477
481
|
* Disconnects from the Cloud Interop service
|
|
478
482
|
*
|
|
479
|
-
* @returns
|
|
483
|
+
* @returns Promise that resolves when disconnected
|
|
480
484
|
* @memberof CloudInteropAPI
|
|
481
|
-
* @throws
|
|
485
|
+
* @throws CloudInteropAPIError - If an error occurs during disconnection
|
|
482
486
|
*/
|
|
483
487
|
async disconnect() {
|
|
484
488
|
await this.#disconnect(true);
|
|
@@ -486,9 +490,9 @@ class CloudInteropAPI {
|
|
|
486
490
|
/**
|
|
487
491
|
* Publishes a new context for the given context group to the other connected sessions
|
|
488
492
|
*
|
|
489
|
-
* @param
|
|
490
|
-
* @param
|
|
491
|
-
* @returns
|
|
493
|
+
* @param contextGroup - The context group to publish to
|
|
494
|
+
* @param context - The context to publish
|
|
495
|
+
* @returns Promise that resolves when context is published
|
|
492
496
|
* @memberof CloudInteropAPI
|
|
493
497
|
*/
|
|
494
498
|
async setContext(contextGroup, context) {
|
|
@@ -515,9 +519,9 @@ class CloudInteropAPI {
|
|
|
515
519
|
/**
|
|
516
520
|
* Starts an intent discovery operation
|
|
517
521
|
*
|
|
518
|
-
* @returns
|
|
522
|
+
* @returns Promise that resolves when intent discovery is started
|
|
519
523
|
* @memberof CloudInteropAPI
|
|
520
|
-
* @throws
|
|
524
|
+
* @throws CloudInteropAPIError - If an error occurs during intent discovery
|
|
521
525
|
*/
|
|
522
526
|
async startIntentDiscovery(options) {
|
|
523
527
|
this.#throwIfNotConnected();
|
|
@@ -558,6 +562,11 @@ class CloudInteropAPI {
|
|
|
558
562
|
if (!this.#connectionParams) {
|
|
559
563
|
throw new Error('Connect parameters must be provided');
|
|
560
564
|
}
|
|
565
|
+
// Cancel session timer if it's running
|
|
566
|
+
if (this.#sessionTimer) {
|
|
567
|
+
clearTimeout(this.#sessionTimer);
|
|
568
|
+
this.#sessionTimer = undefined;
|
|
569
|
+
}
|
|
561
570
|
const disconnectResponse = await fetch(`${this.#cloudInteropSettings.url}/api/sessions/${this.#sessionDetails.sessionId}`, {
|
|
562
571
|
method: 'DELETE',
|
|
563
572
|
headers: getRequestHeaders(this.#connectionParams),
|
|
@@ -656,6 +665,88 @@ class CloudInteropAPI {
|
|
|
656
665
|
throw new Error('MQTT client not connected');
|
|
657
666
|
}
|
|
658
667
|
}
|
|
668
|
+
/**
|
|
669
|
+
* Extracts the expiration timestamp from a JWT token.
|
|
670
|
+
*
|
|
671
|
+
* @param token - The JWT token string
|
|
672
|
+
* @returns The expiration timestamp in seconds, or null if extraction fails
|
|
673
|
+
*/
|
|
674
|
+
#extractExpirationFromJwt(token) {
|
|
675
|
+
try {
|
|
676
|
+
// JWT tokens have three parts separated by dots: header.payload.signature
|
|
677
|
+
// The exp claim is in the payload
|
|
678
|
+
const parts = token.split('.');
|
|
679
|
+
if (parts.length < 2) {
|
|
680
|
+
this.#logger('warn', 'Invalid JWT token format: expected at least 2 parts');
|
|
681
|
+
return null;
|
|
682
|
+
}
|
|
683
|
+
const payload = parts[1];
|
|
684
|
+
// Decode base64url encoded payload
|
|
685
|
+
const decodedBytes = Buffer.from(payload, 'base64url');
|
|
686
|
+
const payloadJson = decodedBytes.toString('utf8');
|
|
687
|
+
// Parse JSON to get the exp claim
|
|
688
|
+
const claims = JSON.parse(payloadJson);
|
|
689
|
+
const exp = claims.exp;
|
|
690
|
+
if (exp === undefined || exp === null) {
|
|
691
|
+
this.#logger('warn', "JWT token does not contain 'exp' claim");
|
|
692
|
+
return null;
|
|
693
|
+
}
|
|
694
|
+
if (typeof exp !== 'number') {
|
|
695
|
+
this.#logger('warn', `JWT token 'exp' claim is not a number: ${exp}`);
|
|
696
|
+
return null;
|
|
697
|
+
}
|
|
698
|
+
return exp;
|
|
699
|
+
}
|
|
700
|
+
catch (error) {
|
|
701
|
+
this.#logger('error', `Failed to extract expiration from JWT token: ${error instanceof Error ? error.message : error}`);
|
|
702
|
+
return null;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Start a session timer that will expire at the time specified in the JWT token's exp claim.
|
|
707
|
+
* When the timer fires, it executes the same actions as the BadUserNamePasswordError case.
|
|
708
|
+
*/
|
|
709
|
+
#startSessionTimer() {
|
|
710
|
+
if (!this.#sessionDetails?.localSessionExpiryHandling) {
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
const token = this.#sessionDetails.token;
|
|
714
|
+
if (!token) {
|
|
715
|
+
this.#logger('warn', 'Cannot start session timer: token not available');
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
// Extract expiration time from JWT token
|
|
719
|
+
const expTimestamp = this.#extractExpirationFromJwt(token);
|
|
720
|
+
if (expTimestamp === null) {
|
|
721
|
+
this.#logger('warn', 'Cannot start session timer: could not extract expiration from JWT token');
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
const currentTimeSeconds = Math.floor(Date.now() / 1000);
|
|
725
|
+
const delaySeconds = expTimestamp - currentTimeSeconds;
|
|
726
|
+
if (delaySeconds <= 0) {
|
|
727
|
+
this.#logger('warn', 'JWT token has already expired or expires immediately');
|
|
728
|
+
// Execute the same actions as BadUserNamePasswordError case
|
|
729
|
+
this.#handleSessionExpiry();
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
// Clear any existing timer
|
|
733
|
+
if (this.#sessionTimer) {
|
|
734
|
+
clearTimeout(this.#sessionTimer);
|
|
735
|
+
}
|
|
736
|
+
const expirationTimeString = new Date(expTimestamp * 1000).toISOString();
|
|
737
|
+
this.#logger('debug', `Starting session timer to expire in ${delaySeconds} seconds (at ${expirationTimeString})`);
|
|
738
|
+
this.#sessionTimer = setTimeout(async () => {
|
|
739
|
+
this.#handleSessionExpiry();
|
|
740
|
+
}, delaySeconds * 1000);
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Handles session expiry by executing the same actions as the BadUserNamePasswordError case.
|
|
744
|
+
*/
|
|
745
|
+
async #handleSessionExpiry() {
|
|
746
|
+
await this.#disconnect(false);
|
|
747
|
+
this.#logger('warn', 'Session expired');
|
|
748
|
+
this.#events.emitEvent('session-expired');
|
|
749
|
+
}
|
|
659
750
|
}
|
|
660
751
|
|
|
661
752
|
export { AuthorizationError, CloudInteropAPI, CloudInteropAPIError };
|