@schibsted/account-sdk-browser 5.0.0 → 5.0.1-beta.2

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/es5/identity.js CHANGED
@@ -982,7 +982,7 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
982
982
  * `password` (will force password confirmation, even if user is already logged in), `eid`. Those values might
983
983
  * be mixed as space-separated string. To make sure that user has authenticated with 2FA you need
984
984
  * to verify AMR (Authentication Methods References) claim in ID token.
985
- * Might also be used to ensure additional acr (sms, otp) for already logged in users.
985
+ * Might also be used to ensure additional acr (sms, otp) for already logged-in users.
986
986
  * Supported value is also 'otp-email' means one time password using email.
987
987
  * @property {string} [scope] - The OAuth scopes for the tokens. This is a list of
988
988
  * scopes, separated by space. If the list of scopes contains `openid`, the generated tokens
@@ -1016,7 +1016,7 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
1016
1016
  * `password` (will force password confirmation, even if user is already logged in). Those values might
1017
1017
  * be mixed as space-separated string. To make sure that user has authenticated with 2FA you need
1018
1018
  * to verify AMR (Authentication Methods References) claim in ID token.
1019
- * Might also be used to ensure additional acr (sms, otp) for already logged in users.
1019
+ * Might also be used to ensure additional acr (sms, otp) for already logged-in users.
1020
1020
  * Supported value is also 'otp-email' means one time password using email.
1021
1021
  * @property {string} [scope] - The OAuth scopes for the tokens. This is a list of
1022
1022
  * scopes, separated by space. If the list of scopes contains `openid`, the generated tokens
@@ -1090,7 +1090,7 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
1090
1090
 
1091
1091
  /**
1092
1092
  * @typedef {object} SimplifiedLoginData
1093
- * @property {string} identifier - Deprecated: User UUID, to be be used as `loginHint` for {@link Identity#login}
1093
+ * @property {string} identifier - Deprecated: User UUID, to be as `loginHint` for {@link Identity#login}
1094
1094
  * @property {string} display_text - Human-readable user identifier
1095
1095
  * @property {string} client_name - Client name
1096
1096
  */
@@ -1102,13 +1102,17 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
1102
1102
 
1103
1103
  var HAS_SESSION_CACHE_KEY = 'hasSession-cache';
1104
1104
  var SESSION_CALL_BLOCKED_CACHE_KEY = 'sessionCallBlocked-cache';
1105
- var SESSION_CALL_BLOCKED_TTL = 1000 * 60 * 5;
1105
+ var SESSION_CALL_BLOCKED_TTL = 1000 * 30; //set to 30s, the default period for a request timeout
1106
+
1107
+ var TAB_ID_KEY = 'tab-id-cache';
1108
+ var TAB_ID = Math.floor(Math.random() * 100000);
1109
+ var TAB_ID_TTL = 1000 * 60 * 60 * 24 * 30;
1106
1110
  var globalWindow = function globalWindow() {
1107
1111
  return window;
1108
1112
  };
1109
1113
 
1110
1114
  /**
1111
- * Provides Identity functionalty to a web page
1115
+ * Provides Identity functionality to a web page
1112
1116
  */
1113
1117
  var Identity = /*#__PURE__*/function (_EventEmitter) {
1114
1118
  _inherits(Identity, _EventEmitter);
@@ -1144,20 +1148,24 @@ var Identity = /*#__PURE__*/function (_EventEmitter) {
1144
1148
  Object(_validate_js__WEBPACK_IMPORTED_MODULE_55__["assert"])(!redirectUri || Object(_validate_js__WEBPACK_IMPORTED_MODULE_55__["isUrl"])(redirectUri), 'redirectUri parameter is invalid');
1145
1149
  Object(_validate_js__WEBPACK_IMPORTED_MODULE_55__["assert"])(sessionDomain && Object(_validate_js__WEBPACK_IMPORTED_MODULE_55__["isUrl"])(sessionDomain), 'sessionDomain parameter is not a valid URL');
1146
1150
  _spidTalk_js__WEBPACK_IMPORTED_MODULE_64__["emulate"](window);
1151
+
1152
+ // Internal hack: set as false to always refresh from hasSession
1153
+ _this._enableSessionCaching = true;
1147
1154
  _this._sessionInitiatedSent = false;
1148
1155
  _this.window = window;
1149
1156
  _this.clientId = clientId;
1150
- _this.cache = new _cache_js__WEBPACK_IMPORTED_MODULE_60__["default"](function () {
1157
+ _this.sessionStorageCache = new _cache_js__WEBPACK_IMPORTED_MODULE_60__["default"](function () {
1151
1158
  return _this.window && _this.window.sessionStorage;
1152
1159
  });
1160
+ _this.localStorageCache = new _cache_js__WEBPACK_IMPORTED_MODULE_60__["default"](function () {
1161
+ return _this.window && _this.window.localStorage;
1162
+ });
1153
1163
  _this.redirectUri = redirectUri;
1154
1164
  _this.env = env;
1155
1165
  _this.log = log;
1156
1166
  _this.callbackBeforeRedirect = callbackBeforeRedirect;
1157
1167
  _this._sessionDomain = sessionDomain;
1158
-
1159
- // Internal hack: set to false to always refresh from hassession
1160
- _this._enableSessionCaching = true;
1168
+ _this._tabId = _this._getTabId();
1161
1169
 
1162
1170
  // Old session
1163
1171
  _this._session = {};
@@ -1166,50 +1174,61 @@ var Identity = /*#__PURE__*/function (_EventEmitter) {
1166
1174
  _this._setBffServerUrl(env);
1167
1175
  _this._setOauthServerUrl(env);
1168
1176
  _this._setGlobalSessionServiceUrl(env);
1169
- _this._unblockSessionCall();
1177
+ _this._unblockSessionCallByTab();
1170
1178
  return _this;
1171
1179
  }
1172
1180
 
1173
1181
  /**
1174
- * Checks if getting session is blocked
1182
+ * Read tabId from session storage if possible, otherwise save tabId to session storage and return it
1183
+ * @returns {number}
1175
1184
  * @private
1176
- *
1177
- * @returns {boolean|void}
1178
1185
  */
1179
1186
  _createClass(Identity, [{
1180
- key: "_isSessionCallBlocked",
1181
- value: function _isSessionCallBlocked() {
1187
+ key: "_getTabId",
1188
+ value: function _getTabId() {
1182
1189
  if (this._enableSessionCaching) {
1183
- return this.cache.get(SESSION_CALL_BLOCKED_CACHE_KEY);
1190
+ var tabId = this.sessionStorageCache.get(TAB_ID_KEY);
1191
+ if (!tabId) {
1192
+ this.sessionStorageCache.set(TAB_ID_KEY, TAB_ID, TAB_ID_TTL);
1193
+ return TAB_ID;
1194
+ }
1195
+ return tabId;
1184
1196
  }
1197
+ return TAB_ID;
1185
1198
  }
1186
1199
 
1187
1200
  /**
1188
- * Block calls to get session
1201
+ * Checks if calling GET session is blocked
1202
+ * @private
1203
+ * @returns {number|null}
1204
+ */
1205
+ }, {
1206
+ key: "_isSessionCallBlocked",
1207
+ value: function _isSessionCallBlocked() {
1208
+ return this.localStorageCache.get(SESSION_CALL_BLOCKED_CACHE_KEY);
1209
+ }
1210
+
1211
+ /**
1212
+ * Block calls to get session. This is done to prevent concurrent calls which can log user out if session is refreshed by one of them
1189
1213
  * @private
1190
- *
1191
1214
  * @returns {void}
1192
1215
  */
1193
1216
  }, {
1194
1217
  key: "_blockSessionCall",
1195
1218
  value: function _blockSessionCall() {
1196
- if (this._enableSessionCaching) {
1197
- var SESSION_CALL_BLOCKED = true;
1198
- this.cache.set(SESSION_CALL_BLOCKED_CACHE_KEY, SESSION_CALL_BLOCKED, SESSION_CALL_BLOCKED_TTL);
1199
- }
1219
+ this.localStorageCache.set(SESSION_CALL_BLOCKED_CACHE_KEY, this._tabId, SESSION_CALL_BLOCKED_TTL);
1200
1220
  }
1201
1221
 
1202
1222
  /**
1203
- * Unblocks calls to get session
1223
+ * Unblocks calls to get session if the lock was put by the same tab
1204
1224
  * @private
1205
- *
1206
1225
  * @returns {void}
1207
1226
  */
1208
1227
  }, {
1209
- key: "_unblockSessionCall",
1210
- value: function _unblockSessionCall() {
1211
- if (this._enableSessionCaching) {
1212
- this.cache.delete(SESSION_CALL_BLOCKED_CACHE_KEY);
1228
+ key: "_unblockSessionCallByTab",
1229
+ value: function _unblockSessionCallByTab() {
1230
+ if (this._isSessionCallBlocked() === this._tabId) {
1231
+ this.localStorageCache.delete(SESSION_CALL_BLOCKED_CACHE_KEY);
1213
1232
  }
1214
1233
  }
1215
1234
 
@@ -1317,7 +1336,7 @@ var Identity = /*#__PURE__*/function (_EventEmitter) {
1317
1336
  }
1318
1337
 
1319
1338
  /**
1320
- * Emits the relevant events based on the previous and new reply from hassession
1339
+ * Emits the relevant events based on the previous and new reply from {@link Identity#hasSession}
1321
1340
  * @private
1322
1341
  * @param {object} previous
1323
1342
  * @param {object} current
@@ -1401,7 +1420,7 @@ var Identity = /*#__PURE__*/function (_EventEmitter) {
1401
1420
  }
1402
1421
 
1403
1422
  /**
1404
- * Set the Varnish cookie (`SP_ID`) when hasSession() is called. Note that most browsers require
1423
+ * Set the Varnish cookie (`SP_ID`) when {@link Identity#hasSession} is called. Note that most browsers require
1405
1424
  * that you are on a "real domain" for this to work — so, **not** `localhost`
1406
1425
  * @param {object} [options]
1407
1426
  * @param {number} [options.expiresIn] Override this to set number of seconds before the varnish
@@ -1522,10 +1541,6 @@ var Identity = /*#__PURE__*/function (_EventEmitter) {
1522
1541
  key: "hasSession",
1523
1542
  value: function hasSession() {
1524
1543
  var _this2 = this;
1525
- var isSessionCallBlocked = this._isSessionCallBlocked();
1526
- if (isSessionCallBlocked) {
1527
- return this._session;
1528
- }
1529
1544
  if (this._hasSessionInProgress) {
1530
1545
  return this._hasSessionInProgress;
1531
1546
  }
@@ -1554,57 +1569,67 @@ var Identity = /*#__PURE__*/function (_EventEmitter) {
1554
1569
  break;
1555
1570
  }
1556
1571
  // Try to resolve from cache (it has a TTL)
1557
- cachedSession = _this2.cache.get(HAS_SESSION_CACHE_KEY);
1572
+ cachedSession = _this2.sessionStorageCache.get(HAS_SESSION_CACHE_KEY);
1558
1573
  if (!cachedSession) {
1559
1574
  _context.next = 4;
1560
1575
  break;
1561
1576
  }
1562
1577
  return _context.abrupt("return", _postProcess(cachedSession));
1563
1578
  case 4:
1579
+ if (!_this2._isSessionCallBlocked()) {
1580
+ _context.next = 6;
1581
+ break;
1582
+ }
1583
+ return _context.abrupt("return", _this2._session);
1584
+ case 6:
1564
1585
  sessionData = null;
1565
- _context.prev = 5;
1566
- _context.next = 8;
1567
- return _this2._sessionService.get('/v2/session');
1568
- case 8:
1586
+ _context.prev = 7;
1587
+ _this2._blockSessionCall();
1588
+ _context.next = 11;
1589
+ return _this2._sessionService.get('/v2/session', {
1590
+ tabId: _this2._tabId
1591
+ });
1592
+ case 11:
1569
1593
  sessionData = _context.sent;
1570
- _context.next = 15;
1594
+ _context.next = 18;
1571
1595
  break;
1572
- case 11:
1573
- _context.prev = 11;
1574
- _context.t0 = _context["catch"](5);
1596
+ case 14:
1597
+ _context.prev = 14;
1598
+ _context.t0 = _context["catch"](7);
1575
1599
  if (_context.t0 && _context.t0.code === 400 && _this2._enableSessionCaching) {
1576
1600
  expiresIn = 1000 * (_context.t0.expiresIn || 300);
1577
- _this2.cache.set(HAS_SESSION_CACHE_KEY, {
1601
+ _this2.sessionStorageCache.set(HAS_SESSION_CACHE_KEY, {
1578
1602
  error: _context.t0
1579
1603
  }, expiresIn);
1580
1604
  }
1581
1605
  throw _context.t0;
1582
- case 15:
1606
+ case 18:
1583
1607
  if (!sessionData) {
1584
- _context.next = 22;
1608
+ _context.next = 24;
1585
1609
  break;
1586
1610
  }
1587
1611
  if (!_checkRedirectionNeed(sessionData)) {
1588
- _context.next = 21;
1612
+ _context.next = 23;
1589
1613
  break;
1590
1614
  }
1591
- _this2._blockSessionCall();
1592
- _context.next = 20;
1615
+ _context.next = 22;
1593
1616
  return _this2.callbackBeforeRedirect();
1594
- case 20:
1595
- return _context.abrupt("return", _this2._sessionService.makeUrl(sessionData.redirectURL));
1596
- case 21:
1617
+ case 22:
1618
+ _this2.window.location.href = _this2._sessionService.makeUrl(sessionData.redirectURL, {
1619
+ tabId: _this2._getTabId()
1620
+ });
1621
+ case 23:
1597
1622
  if (_this2._enableSessionCaching) {
1598
1623
  _expiresIn = 1000 * (sessionData.expiresIn || 300);
1599
- _this2.cache.set(HAS_SESSION_CACHE_KEY, sessionData, _expiresIn);
1624
+ _this2.sessionStorageCache.set(HAS_SESSION_CACHE_KEY, sessionData, _expiresIn);
1600
1625
  }
1601
- case 22:
1626
+ case 24:
1602
1627
  return _context.abrupt("return", _postProcess(sessionData));
1603
- case 23:
1628
+ case 25:
1604
1629
  case "end":
1605
1630
  return _context.stop();
1606
1631
  }
1607
- }, _callee, null, [[5, 11]]);
1632
+ }, _callee, null, [[7, 14]]);
1608
1633
  }));
1609
1634
  return function _getSession() {
1610
1635
  return _ref2.apply(this, arguments);
@@ -1612,15 +1637,13 @@ var Identity = /*#__PURE__*/function (_EventEmitter) {
1612
1637
  }();
1613
1638
  this._hasSessionInProgress = _getSession().then(function (sessionData) {
1614
1639
  _this2._hasSessionInProgress = false;
1615
- if (Object(_validate_js__WEBPACK_IMPORTED_MODULE_55__["isUrl"])(sessionData)) {
1616
- return _this2.window.location.href = sessionData;
1617
- }
1618
1640
  return sessionData;
1619
1641
  }, function (err) {
1620
1642
  _this2.emit('error', err);
1621
1643
  _this2._hasSessionInProgress = false;
1622
1644
  throw new _SDKError_js__WEBPACK_IMPORTED_MODULE_63__["default"]('HasSession failed', err);
1623
1645
  });
1646
+ this._unblockSessionCallByTab();
1624
1647
  return this._hasSessionInProgress;
1625
1648
  }
1626
1649
 
@@ -1667,7 +1690,7 @@ var Identity = /*#__PURE__*/function (_EventEmitter) {
1667
1690
  }, {
1668
1691
  key: "clearCachedUserSession",
1669
1692
  value: function clearCachedUserSession() {
1670
- this.cache.delete(HAS_SESSION_CACHE_KEY);
1693
+ this.sessionStorageCache.delete(HAS_SESSION_CACHE_KEY);
1671
1694
  }
1672
1695
 
1673
1696
  /**
@@ -1761,7 +1784,7 @@ var Identity = /*#__PURE__*/function (_EventEmitter) {
1761
1784
  * @description This function calls {@link Identity#hasSession} internally and thus has the side
1762
1785
  * effect that it might perform an auto-login on the user
1763
1786
  * @throws {SDKError} If the user isn't connected to the merchant
1764
- * @return {Promise<string>} The `userId` field (not to be confused with the `uuid`)
1787
+ * @return {number} The `userId` field (not to be confused with the `uuid`)
1765
1788
  */
1766
1789
  }, {
1767
1790
  key: "getUserId",
@@ -2062,7 +2085,7 @@ var Identity = /*#__PURE__*/function (_EventEmitter) {
2062
2085
  _ref4$prompt = _ref4.prompt,
2063
2086
  prompt = _ref4$prompt === void 0 ? 'select_account' : _ref4$prompt;
2064
2087
  this._closePopup();
2065
- this.cache.delete(HAS_SESSION_CACHE_KEY);
2088
+ this.sessionStorageCache.delete(HAS_SESSION_CACHE_KEY);
2066
2089
  var url = this.loginUrl({
2067
2090
  state: state,
2068
2091
  acrValues: acrValues,
@@ -2135,7 +2158,7 @@ var Identity = /*#__PURE__*/function (_EventEmitter) {
2135
2158
  key: "logout",
2136
2159
  value: function logout() {
2137
2160
  var redirectUri = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.redirectUri;
2138
- this.cache.delete(HAS_SESSION_CACHE_KEY);
2161
+ this.sessionStorageCache.delete(HAS_SESSION_CACHE_KEY);
2139
2162
  this._maybeClearVarnishCookie();
2140
2163
  this.emit('logout');
2141
2164
  this.window.location.href = this.logoutUrl(redirectUri);
@@ -10992,7 +11015,6 @@ var Cache = /*#__PURE__*/function () {
10992
11015
  /**
10993
11016
  * Get a value from cache (checks that the object has not expired)
10994
11017
  * @param {string} key
10995
- * @private
10996
11018
  * @returns {*} - The value if it exists, otherwise null
10997
11019
  */
10998
11020
  _createClass(Cache, [{
@@ -11028,7 +11050,6 @@ var Cache = /*#__PURE__*/function () {
11028
11050
  * @param {string} key
11029
11051
  * @param {*} value
11030
11052
  * @param {Number} expiresIn - Value in milliseconds until the entry expires
11031
- * @private
11032
11053
  * @returns {void}
11033
11054
  */
11034
11055
  }, {
@@ -11057,7 +11078,6 @@ var Cache = /*#__PURE__*/function () {
11057
11078
  /**
11058
11079
  * Delete a cache entry
11059
11080
  * @param {string} key
11060
- * @private
11061
11081
  * @returns {void}
11062
11082
  */
11063
11083
  }, {
@@ -11977,7 +11997,7 @@ __webpack_require__.r(__webpack_exports__);
11977
11997
 
11978
11998
 
11979
11999
 
11980
- var version = '5.0.0';
12000
+ var version = '5.0.1-beta.2';
11981
12001
  /* harmony default export */ __webpack_exports__["default"] = (version);
11982
12002
 
11983
12003
  /***/ })