@schibsted/account-sdk-browser 4.8.7 → 5.0.0-beta.1
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 +14 -10
- package/es5/global.js +719 -619
- package/es5/global.js.map +1 -1
- package/es5/global.min.js +1 -1
- package/es5/global.min.js.map +1 -1
- package/es5/identity.js +692 -592
- package/es5/identity.js.map +1 -1
- package/es5/identity.min.js +1 -1
- package/es5/identity.min.js.map +1 -1
- package/es5/index.js +724 -624
- package/es5/index.js.map +1 -1
- package/es5/index.min.js +1 -1
- package/es5/index.min.js.map +1 -1
- package/es5/monetization.js +1 -1
- package/es5/monetization.js.map +1 -1
- package/es5/monetization.min.js +1 -1
- package/es5/monetization.min.js.map +1 -1
- package/package.json +1 -1
- package/src/identity.d.ts +4 -1
- package/src/identity.js +117 -13
- package/src/version.js +1 -1
package/package.json
CHANGED
package/src/identity.d.ts
CHANGED
|
@@ -13,15 +13,17 @@ export class Identity extends TinyEmitter {
|
|
|
13
13
|
* @param {function} [options.log] - A function that receives debug log information. If not set,
|
|
14
14
|
* no logging will be done
|
|
15
15
|
* @param {object} [options.window] - window object
|
|
16
|
+
* @param {function} [options.callbackBeforeRedirect] - callback triggered before session refresh redirect happen
|
|
16
17
|
* @throws {SDKError} - If any of options are invalid
|
|
17
18
|
*/
|
|
18
|
-
constructor({ clientId, redirectUri, sessionDomain, env, log, window }: {
|
|
19
|
+
constructor({ clientId, redirectUri, sessionDomain, env, log, window, callbackBeforeRedirect }: {
|
|
19
20
|
clientId: string;
|
|
20
21
|
sessionDomain: string;
|
|
21
22
|
redirectUri: string;
|
|
22
23
|
env?: string;
|
|
23
24
|
log?: Function;
|
|
24
25
|
window?: any;
|
|
26
|
+
callbackBeforeRedirect?: Function;
|
|
25
27
|
});
|
|
26
28
|
_sessionInitiatedSent: boolean;
|
|
27
29
|
window: any;
|
|
@@ -30,6 +32,7 @@ export class Identity extends TinyEmitter {
|
|
|
30
32
|
redirectUri: string;
|
|
31
33
|
env: string;
|
|
32
34
|
log: Function;
|
|
35
|
+
callbackBeforeRedirect: Function;
|
|
33
36
|
_sessionDomain: string;
|
|
34
37
|
_enableSessionCaching: boolean;
|
|
35
38
|
_session: {};
|
package/src/identity.js
CHANGED
|
@@ -145,6 +145,13 @@ import version from './version.js';
|
|
|
145
145
|
*/
|
|
146
146
|
|
|
147
147
|
const HAS_SESSION_CACHE_KEY = 'hasSession-cache';
|
|
148
|
+
const SESSION_CALL_BLOCKED_CACHE_KEY = 'sessionCallBlocked-cache';
|
|
149
|
+
const SESSION_CALL_BLOCKED_TTL = 1000 * 60 * 5;
|
|
150
|
+
|
|
151
|
+
const TAB_ID_KEY = 'tab-id-cache';
|
|
152
|
+
const TAB_ID = Math.floor(Math.random() * 100000)
|
|
153
|
+
const TAB_ID_TTL = 1000 * 60 * 60 * 24 * 30;
|
|
154
|
+
|
|
148
155
|
const globalWindow = () => window;
|
|
149
156
|
|
|
150
157
|
/**
|
|
@@ -160,9 +167,18 @@ export class Identity extends EventEmitter {
|
|
|
160
167
|
* @param {function} [options.log] - A function that receives debug log information. If not set,
|
|
161
168
|
* no logging will be done
|
|
162
169
|
* @param {object} [options.window] - window object
|
|
170
|
+
* @param {function} [options.callbackBeforeRedirect] - callback triggered before session refresh redirect happen
|
|
163
171
|
* @throws {SDKError} - If any of options are invalid
|
|
164
172
|
*/
|
|
165
|
-
constructor({
|
|
173
|
+
constructor({
|
|
174
|
+
clientId,
|
|
175
|
+
redirectUri,
|
|
176
|
+
sessionDomain,
|
|
177
|
+
env = 'PRE',
|
|
178
|
+
log,
|
|
179
|
+
window = globalWindow(),
|
|
180
|
+
callbackBeforeRedirect = ()=>{}
|
|
181
|
+
}) {
|
|
166
182
|
super();
|
|
167
183
|
assert(isNonEmptyString(clientId), 'clientId parameter is required');
|
|
168
184
|
assert(isObject(window), 'The reference to window is missing');
|
|
@@ -173,10 +189,12 @@ export class Identity extends EventEmitter {
|
|
|
173
189
|
this._sessionInitiatedSent = false;
|
|
174
190
|
this.window = window;
|
|
175
191
|
this.clientId = clientId;
|
|
176
|
-
this.
|
|
192
|
+
this.sessionStorageCache = new Cache(() => this.window && this.window.sessionStorage);
|
|
193
|
+
this.localStorageCache = new Cache(() => this.window && this.window.localStorage);
|
|
177
194
|
this.redirectUri = redirectUri;
|
|
178
195
|
this.env = env;
|
|
179
196
|
this.log = log;
|
|
197
|
+
this.callbackBeforeRedirect = callbackBeforeRedirect;
|
|
180
198
|
this._sessionDomain = sessionDomain;
|
|
181
199
|
|
|
182
200
|
// Internal hack: set to false to always refresh from hassession
|
|
@@ -190,6 +208,61 @@ export class Identity extends EventEmitter {
|
|
|
190
208
|
this._setBffServerUrl(env);
|
|
191
209
|
this._setOauthServerUrl(env);
|
|
192
210
|
this._setGlobalSessionServiceUrl(env);
|
|
211
|
+
|
|
212
|
+
this._unblockSessionCall();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Read tabId from session storage
|
|
217
|
+
* @returns {number}
|
|
218
|
+
* @private
|
|
219
|
+
*/
|
|
220
|
+
_getTabId() {
|
|
221
|
+
if (this._enableSessionCaching) {
|
|
222
|
+
const tabId = this.cache.get(TAB_ID_KEY);
|
|
223
|
+
if (!tabId) {
|
|
224
|
+
this.cache.set(TAB_ID_KEY, TAB_ID, TAB_ID_TTL);
|
|
225
|
+
return TAB_ID;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return tabId;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Checks if getting session is blocked
|
|
234
|
+
* @private
|
|
235
|
+
*
|
|
236
|
+
* @returns {boolean|void}
|
|
237
|
+
*/
|
|
238
|
+
_isSessionCallBlocked(){
|
|
239
|
+
return this.localStorageCache.get(SESSION_CALL_BLOCKED_CACHE_KEY);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Block calls to get session
|
|
244
|
+
* @private
|
|
245
|
+
*
|
|
246
|
+
* @returns {void}
|
|
247
|
+
*/
|
|
248
|
+
_blockSessionCall(){
|
|
249
|
+
const SESSION_CALL_BLOCKED = true;
|
|
250
|
+
|
|
251
|
+
this.localStorageCache.set(
|
|
252
|
+
SESSION_CALL_BLOCKED_CACHE_KEY,
|
|
253
|
+
SESSION_CALL_BLOCKED,
|
|
254
|
+
SESSION_CALL_BLOCKED_TTL
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Unblocks calls to get session
|
|
260
|
+
* @private
|
|
261
|
+
*
|
|
262
|
+
* @returns {void}
|
|
263
|
+
*/
|
|
264
|
+
_unblockSessionCall(){
|
|
265
|
+
this.localStorageCache.delete(SESSION_CALL_BLOCKED_CACHE_KEY);
|
|
193
266
|
}
|
|
194
267
|
|
|
195
268
|
/**
|
|
@@ -480,9 +553,15 @@ export class Identity extends EventEmitter {
|
|
|
480
553
|
* @return {Promise<HasSessionSuccessResponse|HasSessionFailureResponse>}
|
|
481
554
|
*/
|
|
482
555
|
hasSession() {
|
|
556
|
+
const isSessionCallBlocked = this._isSessionCallBlocked()
|
|
557
|
+
if (isSessionCallBlocked) {
|
|
558
|
+
return this._session;
|
|
559
|
+
}
|
|
560
|
+
|
|
483
561
|
if (this._hasSessionInProgress) {
|
|
484
562
|
return this._hasSessionInProgress;
|
|
485
563
|
}
|
|
564
|
+
|
|
486
565
|
const _postProcess = (sessionData) => {
|
|
487
566
|
if (sessionData.error) {
|
|
488
567
|
throw new SDKError('HasSession failed', sessionData.error);
|
|
@@ -492,35 +571,60 @@ export class Identity extends EventEmitter {
|
|
|
492
571
|
this._session = sessionData;
|
|
493
572
|
return sessionData;
|
|
494
573
|
};
|
|
574
|
+
|
|
575
|
+
const _checkRedirectionNeed = (sessionData={})=>{
|
|
576
|
+
const sessionDataKeys = Object.keys(sessionData);
|
|
577
|
+
|
|
578
|
+
return sessionDataKeys.length === 1 &&
|
|
579
|
+
sessionDataKeys[0] === 'redirectURL';
|
|
580
|
+
}
|
|
581
|
+
|
|
495
582
|
const _getSession = async () => {
|
|
496
583
|
if (this._enableSessionCaching) {
|
|
497
584
|
// Try to resolve from cache (it has a TTL)
|
|
498
|
-
let cachedSession = this.
|
|
585
|
+
let cachedSession = this.sessionStorageCache.get(HAS_SESSION_CACHE_KEY);
|
|
499
586
|
if (cachedSession) {
|
|
500
587
|
return _postProcess(cachedSession);
|
|
501
588
|
}
|
|
502
589
|
}
|
|
503
590
|
let sessionData = null;
|
|
504
591
|
try {
|
|
505
|
-
sessionData = await this._sessionService.get('/session');
|
|
592
|
+
sessionData = await this._sessionService.get('/v2/session');
|
|
506
593
|
} catch (err) {
|
|
507
594
|
if (err && err.code === 400 && this._enableSessionCaching) {
|
|
508
595
|
const expiresIn = 1000 * (err.expiresIn || 300);
|
|
509
|
-
this.
|
|
596
|
+
this.sessionStorageCache.set(HAS_SESSION_CACHE_KEY, { error: err }, expiresIn);
|
|
510
597
|
}
|
|
511
598
|
throw err;
|
|
512
599
|
}
|
|
513
600
|
|
|
514
|
-
if (sessionData
|
|
515
|
-
|
|
516
|
-
|
|
601
|
+
if (sessionData){
|
|
602
|
+
// for expiring session and safari browser do full page redirect to gain new session
|
|
603
|
+
if(_checkRedirectionNeed(sessionData)){
|
|
604
|
+
this._blockSessionCall();
|
|
605
|
+
|
|
606
|
+
await this.callbackBeforeRedirect();
|
|
607
|
+
|
|
608
|
+
return this._sessionService.makeUrl(sessionData.redirectURL, {tabId: this._getTabId()});
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
if (this._enableSessionCaching) {
|
|
612
|
+
const expiresIn = 1000 * (sessionData.expiresIn || 300);
|
|
613
|
+
this.sessionStorageCache.set(HAS_SESSION_CACHE_KEY, sessionData, expiresIn);
|
|
614
|
+
}
|
|
517
615
|
}
|
|
616
|
+
|
|
518
617
|
return _postProcess(sessionData);
|
|
519
618
|
};
|
|
520
619
|
this._hasSessionInProgress = _getSession()
|
|
521
620
|
.then(
|
|
522
621
|
sessionData => {
|
|
523
622
|
this._hasSessionInProgress = false;
|
|
623
|
+
|
|
624
|
+
if (isUrl(sessionData)) {
|
|
625
|
+
return this.window.location.href = sessionData;
|
|
626
|
+
}
|
|
627
|
+
|
|
524
628
|
return sessionData;
|
|
525
629
|
},
|
|
526
630
|
err => {
|
|
@@ -554,7 +658,7 @@ export class Identity extends EventEmitter {
|
|
|
554
658
|
* @returns {void}
|
|
555
659
|
*/
|
|
556
660
|
clearCachedUserSession() {
|
|
557
|
-
this.
|
|
661
|
+
this.sessionStorageCache.delete(HAS_SESSION_CACHE_KEY);
|
|
558
662
|
}
|
|
559
663
|
|
|
560
664
|
/**
|
|
@@ -632,10 +736,10 @@ export class Identity extends EventEmitter {
|
|
|
632
736
|
* meaning the same user's ID will differ between merchants.
|
|
633
737
|
* Additionally, this identifier is bound to the external party provided as argument.
|
|
634
738
|
*
|
|
635
|
-
* @description This function calls {@link Identity#hasSession} internally and thus has the side
|
|
636
|
-
* effect that it might perform an auto-login on the user
|
|
637
739
|
* @param {string} externalParty
|
|
638
740
|
* @param {string|null} optionalSuffix
|
|
741
|
+
* @description This function calls {@link Identity#hasSession} internally and thus has the side
|
|
742
|
+
* effect that it might perform an auto-login on the user
|
|
639
743
|
* @throws {SDKError} If the `pairId` is missing in user session.
|
|
640
744
|
* @throws {SDKError} If the `externalParty` is not defined
|
|
641
745
|
* @return {Promise<string>} The merchant- and 3rd-party-specific `externalId`
|
|
@@ -765,7 +869,7 @@ export class Identity extends EventEmitter {
|
|
|
765
869
|
prompt = 'select_account'
|
|
766
870
|
}) {
|
|
767
871
|
this._closePopup();
|
|
768
|
-
this.
|
|
872
|
+
this.sessionStorageCache.delete(HAS_SESSION_CACHE_KEY);
|
|
769
873
|
const url = this.loginUrl({
|
|
770
874
|
state,
|
|
771
875
|
acrValues,
|
|
@@ -814,7 +918,7 @@ export class Identity extends EventEmitter {
|
|
|
814
918
|
* @return {void}
|
|
815
919
|
*/
|
|
816
920
|
logout(redirectUri = this.redirectUri) {
|
|
817
|
-
this.
|
|
921
|
+
this.sessionStorageCache.delete(HAS_SESSION_CACHE_KEY);
|
|
818
922
|
this._maybeClearVarnishCookie();
|
|
819
923
|
this.emit('logout');
|
|
820
924
|
this.window.location.href = this.logoutUrl(redirectUri);
|
package/src/version.js
CHANGED