@schibsted/account-sdk-browser 6.0.0-alpha.1 → 6.0.0-alpha.3

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.
Files changed (89) hide show
  1. package/README.md +39 -64
  2. package/dist/account-sdk.d.ts +4 -0
  3. package/dist/account.d.ts +29 -0
  4. package/dist/cache.d.ts +65 -0
  5. package/dist/config.d.ts +86 -0
  6. package/dist/get-account-sdk.d.ts +3 -0
  7. package/dist/global-registry.d.ts +23 -0
  8. package/dist/globals.d.ts +15 -0
  9. package/dist/has-access-response.d.ts +2 -0
  10. package/dist/identity.d.ts +323 -0
  11. package/dist/index.d.ts +8 -0
  12. package/dist/index.js +859 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/monetization.d.ts +58 -0
  15. package/{src → dist}/object.d.ts +4 -9
  16. package/dist/popup.d.ts +9 -0
  17. package/dist/resolve-browser-window.d.ts +1 -0
  18. package/dist/rest-client.d.ts +102 -0
  19. package/dist/rest-clients.d.ts +10 -0
  20. package/dist/sdk-error.d.ts +27 -0
  21. package/dist/session-response.d.ts +30 -0
  22. package/{src/spidTalk.d.ts → dist/spid-talk.d.ts} +4 -6
  23. package/dist/types/account.d.ts +13 -0
  24. package/dist/types/common.d.ts +22 -0
  25. package/dist/types/identity.d.ts +41 -0
  26. package/dist/types/login.d.ts +120 -0
  27. package/dist/types/monetization-guards.d.ts +2 -0
  28. package/dist/types/monetization.d.ts +21 -0
  29. package/dist/types/session-guards.d.ts +36 -0
  30. package/dist/types/session.d.ts +124 -0
  31. package/dist/url.d.ts +8 -0
  32. package/dist/validate.d.ts +50 -0
  33. package/dist/version.d.ts +2 -0
  34. package/package.json +30 -22
  35. package/src/account-sdk.ts +74 -0
  36. package/src/account.ts +149 -0
  37. package/src/{cache.js → cache.ts} +53 -38
  38. package/src/{config.js → config.ts} +7 -32
  39. package/src/get-account-sdk.ts +94 -0
  40. package/src/global-registry.ts +39 -0
  41. package/src/globals.ts +12 -0
  42. package/src/has-access-response.ts +35 -0
  43. package/src/identity.ts +1102 -0
  44. package/src/index.ts +32 -0
  45. package/src/{monetization.js → monetization.ts} +65 -73
  46. package/src/{object.js → object.ts} +9 -16
  47. package/src/popup.ts +74 -0
  48. package/src/resolve-browser-window.ts +11 -0
  49. package/src/rest-client.ts +253 -0
  50. package/src/rest-clients.ts +30 -0
  51. package/src/sdk-error.ts +59 -0
  52. package/src/session-response.ts +85 -0
  53. package/src/{spidTalk.js → spid-talk.ts} +10 -12
  54. package/src/types/account.ts +27 -0
  55. package/src/types/common.ts +26 -0
  56. package/src/types/identity.ts +55 -0
  57. package/src/types/login.ts +145 -0
  58. package/src/types/monetization-guards.ts +35 -0
  59. package/src/types/monetization.ts +24 -0
  60. package/src/types/session-guards.ts +89 -0
  61. package/src/types/session.ts +147 -0
  62. package/src/{url.js → url.ts} +6 -10
  63. package/src/{validate.js → validate.ts} +27 -43
  64. package/src/{version.js → version.ts} +1 -2
  65. package/identity.d.ts +0 -1
  66. package/identity.js +0 -5
  67. package/index.d.ts +0 -4
  68. package/index.js +0 -9
  69. package/monetization.d.ts +0 -1
  70. package/monetization.js +0 -5
  71. package/payment.d.ts +0 -1
  72. package/payment.js +0 -5
  73. package/src/RESTClient.d.ts +0 -89
  74. package/src/RESTClient.js +0 -193
  75. package/src/SDKError.d.ts +0 -16
  76. package/src/SDKError.js +0 -55
  77. package/src/cache.d.ts +0 -64
  78. package/src/config.d.ts +0 -34
  79. package/src/global-registry.js +0 -20
  80. package/src/identity.d.ts +0 -679
  81. package/src/identity.js +0 -1154
  82. package/src/monetization.d.ts +0 -80
  83. package/src/payment.d.ts +0 -115
  84. package/src/payment.js +0 -211
  85. package/src/popup.d.ts +0 -10
  86. package/src/popup.js +0 -59
  87. package/src/url.d.ts +0 -10
  88. package/src/validate.d.ts +0 -64
  89. package/src/version.d.ts +0 -2
package/src/identity.js DELETED
@@ -1,1154 +0,0 @@
1
- /* Copyright 2024 Schibsted Products & Technology AS. Licensed under the terms of the MIT license.
2
- * See LICENSE.md in the project root.
3
- */
4
-
5
- 'use strict';
6
-
7
- import { assert, isStr, isNonEmptyString, isObject, isUrl, isStrIn } from './validate.js';
8
- import { cloneDeep } from './object.js';
9
- import { urlMapper } from './url.js';
10
- import { ENDPOINTS, NAMESPACE } from './config.js';
11
- import EventEmitter from 'tiny-emitter';
12
- import Cache from './cache.js';
13
- import * as popup from './popup.js';
14
- import RESTClient from './RESTClient.js';
15
- import SDKError from './SDKError.js';
16
- import * as spidTalk from './spidTalk.js';
17
- import version from './version.js';
18
- import { registerGlobal } from './global-registry.js';
19
-
20
- /**
21
- * @typedef {object} LoginOptions
22
- * @property {string} state - An opaque value used by the client to maintain state between
23
- * the request and callback. It's also recommended to prevent CSRF {@link https://tools.ietf.org/html/rfc6749#section-10.12}
24
- * @property {string} [acrValues] - Authentication Context Class Reference Values. If
25
- * omitted, the user will be asked to authenticate using username+password.
26
- * For 2FA (Two-Factor Authentication) possible values are `sms`, `otp` (one time password),
27
- * `password` (will force password confirmation, even if user is already logged in), `eid`. Those values might
28
- * be mixed as space-separated string. To make sure that user has authenticated with 2FA you need
29
- * to verify AMR (Authentication Methods References) claim in ID token.
30
- * Might also be used to ensure additional acr (sms, otp) for already logged-in users.
31
- * Supported value is also 'otp-email' means one time password using email.
32
- * @property {string} [scope] - The OAuth scopes for the tokens. This is a list of
33
- * scopes, separated by space. If the list of scopes contains `openid`, the generated tokens
34
- * includes the id token which can be useful for getting information about the user. Omitting
35
- * scope is allowed, while `invalid_scope` is returned when the client asks for a scope you
36
- * aren’t allowed to request. {@link https://tools.ietf.org/html/rfc6749#section-3.3}
37
- * @property {string} [redirectUri] - Redirect uri that will receive the
38
- * code. Must exactly match a redirectUri from your client in self-service
39
- * @property {boolean} [preferPopup] - Should we try to open a popup window?
40
- * @property {string} [loginHint] - User email or UUID hint
41
- * @property {string} [tag] - Pulse tag
42
- * @property {string} [teaser] - Teaser slug. Teaser with given slug will be displayed
43
- * in place of default teaser
44
- * @property {number|string} [maxAge] - Specifies the allowable elapsed time in seconds since
45
- * the last time the End-User was actively authenticated. If last authentication time is more
46
- * than maxAge seconds in the past, re-authentication will be required. See the OpenID Connect
47
- * spec section 3.1.2.1 for more information
48
- * @property {string} [locale] - Optional parameter to overwrite client locale setting.
49
- * New flows supports nb_NO, fi_FI, sv_SE, en_US
50
- * @property {boolean} [oneStepLogin] - Display username and password on one screen
51
- * @property {string} [prompt] - String that specifies whether the Authorization Server prompts the
52
- * End-User for re-authentication or confirm account screen. Supported values: `select_account` or `login`
53
- * @property {string} [xDomainId] - Identifier for cross-domain tracking in Pulse
54
- * @property {string} [xEnvironmentId] - Environment for cross-domain tracking in Pulse
55
- * @property {string} [originCampaign] - Campaign identifier for tracking in Pulse
56
- */
57
- /**
58
- * @typedef {object} SimplifiedLoginWidgetLoginOptions
59
- * @property {string|function(): (string|Promise<string>)} state - An opaque value used by the client to maintain state between
60
- * the request and callback. It's also recommended to prevent CSRF {@link https://tools.ietf.org/html/rfc6749#section-10.12}
61
- * @property {string} [acrValues] - Authentication Context Class Reference Values. If
62
- * omitted, the user will be asked to authenticate using username+password.
63
- * For 2FA (Two-Factor Authentication) possible values are `sms`, `otp` (one time password) and
64
- * `password` (will force password confirmation, even if user is already logged in). Those values might
65
- * be mixed as space-separated string. To make sure that user has authenticated with 2FA you need
66
- * to verify AMR (Authentication Methods References) claim in ID token.
67
- * Might also be used to ensure additional acr (sms, otp) for already logged-in users.
68
- * Supported value is also 'otp-email' means one time password using email.
69
- * @property {string} [scope] - The OAuth scopes for the tokens. This is a list of
70
- * scopes, separated by space. If the list of scopes contains `openid`, the generated tokens
71
- * includes the id token which can be useful for getting information about the user. Omitting
72
- * scope is allowed, while `invalid_scope` is returned when the client asks for a scope you
73
- * aren’t allowed to request. {@link https://tools.ietf.org/html/rfc6749#section-3.3}
74
- * @property {string} [redirectUri] - Redirect uri that will receive the
75
- * code. Must exactly match a redirectUri from your client in self-service
76
- * @property {boolean} [preferPopup] - Should we try to open a popup window?
77
- * @property {string} [loginHint] - User email or UUID hint
78
- * @property {string} [tag] - Pulse tag
79
- * @property {string} [teaser] - Teaser slug. Teaser with given slug will be displayed
80
- * in place of default teaser
81
- * @property {number|string} [maxAge] - Specifies the allowable elapsed time in seconds since
82
- * the last time the End-User was actively authenticated. If last authentication time is more
83
- * than maxAge seconds in the past, re-authentication will be required. See the OpenID Connect
84
- * spec section 3.1.2.1 for more information
85
- * @property {string} [locale] - Optional parameter to overwrite client locale setting.
86
- * New flows supports nb_NO, fi_FI, sv_SE, en_US
87
- * @property {boolean} [oneStepLogin] - Display username and password on one screen
88
- * @property {string} [prompt] - String that specifies whether the Authorization Server prompts the
89
- * End-User for reauthentication or confirm account screen. Supported values: `select_account` or `login`
90
- * @property {string} [xDomainId] - Identifier for cross-domain tracking in Pulse
91
- * @property {string} [xEnvironmentId] - Environment for cross-domain tracking in Pulse
92
- * @property {string} [originCampaign] - Campaign identifier for tracking in Pulse
93
- */
94
-
95
- /**
96
- * @typedef {object} HasSessionSuccessResponse
97
- * @property {boolean} result - Is the user connected to the merchant? (it means that the merchant
98
- * id is in the list of merchants listed of this user in the database)? Example: false
99
- * @property {string} userStatus - Example: 'notConnected' or 'connected'. Deprecated, use
100
- * `Identity.isConnected()`
101
- * @property {string} baseDomain - Example: 'localhost'
102
- * @property {string} id - Example: '58eca10fdbb9f6df72c3368f'. Obsolete
103
- * @property {number} userId - Example: 37162
104
- * @property {string} uuid - Example: 'b3b23aa7-34f2-5d02-a10e-5a3455c6ab2c'
105
- * @property {string} sp_id - Example: 'eyJjbGllbnRfaWQ...'
106
- * @property {number} expiresIn - Example: 30 * 60 * 1000 (for 30 minutes)
107
- * @property {number} serverTime - Example: 1506285759
108
- * @property {string} sig - Example: 'NCdzXaz4ZRb7...' The sig parameter is a concatenation of an
109
- * HMAC SHA-256 signature string, a dot (.) and a base64url encoded JSON object (session).
110
- * {@link http://techdocs.spid.no/sdks/js/response-signature-and-validation/}
111
- * @property {string} displayName - (Only for connected users) Example: 'batman'
112
- * @property {string} givenName - (Only for connected users) Example: 'Bruce'
113
- * @property {string} familyName - (Only for connected users) Example: 'Wayne'
114
- * @property {string} gender - (Only for connected users) Example: 'male', 'female', 'undisclosed'
115
- * @property {string} photo - (Only for connected users) Example:
116
- * 'http://www.srv.com/some/picture.jpg'
117
- * @property {boolean} tracking - (Only for connected users)
118
- * @property {boolean} clientAgreementAccepted - (Only for connected users)
119
- * @property {boolean} defaultAgreementAccepted - (Only for connected users)
120
- * @property {string} pairId
121
- * @property {string} sdrn
122
- */
123
-
124
- /**
125
- * Emitted when an error happens (useful for debugging)
126
- * @event Identity#error
127
- */
128
-
129
- /**
130
- * @typedef {object} HasSessionFailureResponse
131
- * @property {object} error
132
- * @property {number} error.code - Typically an HTTP response code. Example: 401
133
- * @property {string} error.description - Example: "No session found!"
134
- * @property {string} error.type - Example: "UserException"
135
- * @property {object} response
136
- * @property {string} response.baseDomain - Example: "localhost"
137
- * @property {number} response.expiresIn - Time span in milliseconds. Example: 30 * 60 * 1000 (for 30 minutes)
138
- * @property {boolean} response.result
139
- * @property {number} response.serverTime - Server time in seconds since the Unix Epoch. Example: 1506287788
140
- */
141
-
142
- /**
143
- * @typedef {object} SimplifiedLoginData
144
- * @property {string} identifier - Deprecated: User UUID, to be be used as `loginHint` for {@link Identity#login}
145
- * @property {string} display_text - Human-readable user identifier
146
- * @property {string} client_name - Client name
147
- */
148
-
149
- /**
150
- * @typedef {object} SimplifiedLoginWidgetOptions
151
- * @property {string} encoding - expected encoding of simplified login widget. Could be utf-8 (default), iso-8859-1 or iso-8859-15
152
- */
153
-
154
- const HAS_SESSION_CACHE_KEY = 'hasSession-cache';
155
- const SESSION_CALL_BLOCKED_CACHE_KEY = 'sessionCallBlocked-cache';
156
- const SESSION_CALL_BLOCKED_TTL = 1000 * 60 * 5;
157
-
158
- const TAB_ID_KEY = 'tab-id-cache';
159
- const TAB_ID = Math.floor(Math.random() * 100000)
160
- const TAB_ID_TTL = 1000 * 60 * 60 * 24 * 30;
161
-
162
- const globalWindow = () => window;
163
-
164
- /**
165
- * Provides Identity functionalty to a web page
166
- */
167
- export class Identity extends EventEmitter {
168
- /**
169
- * @param {object} options
170
- * @param {string} options.clientId - Example: "1234567890abcdef12345678"
171
- * @param {string} options.sessionDomain - Example: "https://id.site.com"
172
- * @param {string} options.redirectUri - Example: "https://site.com"
173
- * @param {string} [options.env=PRE] - Schibsted account environment: `PRE`, `PRO`, `PRO_NO`, `PRO_FI` or `PRO_DK`
174
- * @param {function} [options.log] - A function that receives debug log information. If not set,
175
- * no logging will be done
176
- * @param {object} [options.window] - window object
177
- * @param {function} [options.callbackBeforeRedirect] - callback triggered before session refresh redirect happen
178
- * @throws {SDKError} - If any of options are invalid
179
- */
180
- constructor({
181
- clientId,
182
- redirectUri,
183
- sessionDomain,
184
- env = 'PRE',
185
- log,
186
- window = globalWindow(),
187
- callbackBeforeRedirect = ()=>{}
188
- }) {
189
- super();
190
- assert(isNonEmptyString(clientId), 'clientId parameter is required');
191
- assert(isObject(window), 'The reference to window is missing');
192
- assert(!redirectUri || isUrl(redirectUri), 'redirectUri parameter is invalid');
193
- assert(sessionDomain && isUrl(sessionDomain), 'sessionDomain parameter is not a valid URL');
194
-
195
- spidTalk.emulate(window);
196
- this._sessionInitiatedSent = false;
197
- this.window = window;
198
- this.clientId = clientId;
199
- this.sessionStorageCache = new Cache(() => this.window && this.window.sessionStorage);
200
- this.localStorageCache = new Cache(() => this.window && this.window.localStorage);
201
- this.redirectUri = redirectUri;
202
- this.env = env;
203
- this.log = log;
204
- this.callbackBeforeRedirect = callbackBeforeRedirect;
205
- this._sessionDomain = sessionDomain;
206
-
207
- // Internal hack: set to false to always refresh from hassession
208
- this._enableSessionCaching = true;
209
-
210
- // Old session
211
- this._session = {};
212
-
213
- this._setSessionServiceUrl(sessionDomain);
214
- this._usedSessionServiceGetSessionEndpoint = this._sessionService.url.pathname && this._sessionService.url.pathname.length <= 1 ? 'v2/session' : 'session';
215
-
216
- this._setSpidServerUrl(env);
217
- this._setBffServerUrl(env);
218
- this._setOauthServerUrl(env);
219
- this._setGlobalSessionServiceUrl(env);
220
-
221
- this._unblockSessionCall();
222
-
223
- registerGlobal(window, 'Identity', this);
224
-
225
- }
226
-
227
- /**
228
- * Read tabId from session storage
229
- * @returns {number}
230
- * @private
231
- */
232
- _getTabId() {
233
- if (this._enableSessionCaching) {
234
- const tabId = this.sessionStorageCache.get(TAB_ID_KEY);
235
- if (!tabId) {
236
- this.sessionStorageCache.set(TAB_ID_KEY, TAB_ID, TAB_ID_TTL);
237
- return TAB_ID;
238
- }
239
-
240
- return tabId;
241
- }
242
- }
243
-
244
- /**
245
- * Checks if getting session is blocked
246
- * @private
247
- *
248
- * @returns {boolean|void}
249
- */
250
- _isSessionCallBlocked(){
251
- return this.localStorageCache.get(SESSION_CALL_BLOCKED_CACHE_KEY);
252
- }
253
-
254
- /**
255
- * Block calls to get session
256
- * @private
257
- *
258
- * @returns {void}
259
- */
260
- _blockSessionCall(){
261
- const SESSION_CALL_BLOCKED = true;
262
-
263
- this.localStorageCache.set(
264
- SESSION_CALL_BLOCKED_CACHE_KEY,
265
- SESSION_CALL_BLOCKED,
266
- SESSION_CALL_BLOCKED_TTL
267
- );
268
- }
269
-
270
- /**
271
- * Unblocks calls to get session
272
- * @private
273
- *
274
- * @returns {void}
275
- */
276
- _unblockSessionCall(){
277
- this.localStorageCache.delete(SESSION_CALL_BLOCKED_CACHE_KEY);
278
- }
279
-
280
- /**
281
- * Set SPiD server URL
282
- * @private
283
- * @param {string} url - real URL or 'PRE' style key
284
- * @returns {void}
285
- */
286
- _setSpidServerUrl(url) {
287
- assert(isStr(url), `url parameter is invalid: ${url}`);
288
- this._spid = new RESTClient({
289
- serverUrl: urlMapper(url, ENDPOINTS.SPiD),
290
- log: this.log,
291
- defaultParams: { client_id: this.clientId, redirect_uri: this.redirectUri },
292
- });
293
- }
294
-
295
- /**
296
- * Set OAuth server URL
297
- * @private
298
- * @param {string} url - real URL or 'PRE' style key
299
- * @returns {void}
300
- */
301
- _setOauthServerUrl(url) {
302
- assert(isStr(url), `url parameter is invalid: ${url}`);
303
- this._oauthService = new RESTClient({
304
- serverUrl: urlMapper(url, ENDPOINTS.SPiD),
305
- log: this.log,
306
- defaultParams: { client_id: this.clientId, redirect_uri: this.redirectUri },
307
- });
308
- }
309
-
310
- /**
311
- * Set BFF server URL
312
- * @private
313
- * @param {string} url - real URL or 'PRE' style key
314
- * @returns {void}
315
- */
316
- _setBffServerUrl(url) {
317
- assert(isStr(url), `url parameter is invalid: ${url}`);
318
- this._bffService = new RESTClient({
319
- serverUrl: urlMapper(url, ENDPOINTS.BFF),
320
- log: this.log,
321
- defaultParams: { client_id: this.clientId, redirect_uri: this.redirectUri },
322
- });
323
- }
324
-
325
- /**
326
- * Set site-specific session-service domain
327
- * @private
328
- * @param {string} domain - real URL — (**not** 'PRE' style env key)
329
- * @returns {void}
330
- */
331
- _setSessionServiceUrl(domain) {
332
- assert(isStr(domain), `domain parameter is invalid: ${domain}`);
333
- const client_sdrn = `sdrn:${NAMESPACE[this.env]}:client:${this.clientId}`;
334
- this._sessionService = new RESTClient({
335
- serverUrl: domain,
336
- log: this.log,
337
- defaultParams: { client_sdrn, redirect_uri: this.redirectUri, sdk_version: version },
338
- });
339
- }
340
-
341
- /**
342
- * Set global session-service server URL
343
- * @private
344
- * @param {string} url - real URL or 'PRE' style key
345
- * @returns {void}
346
- */
347
- _setGlobalSessionServiceUrl(url) {
348
- assert(isStr(url), `url parameter is invalid: ${url}`);
349
- const client_sdrn = `sdrn:${NAMESPACE[this.env]}:client:${this.clientId}`;
350
- this._globalSessionService = new RESTClient({
351
- serverUrl: urlMapper(url, ENDPOINTS.SESSION_SERVICE),
352
- log: this.log,
353
- defaultParams: { client_sdrn, sdk_version: version },
354
- });
355
- }
356
-
357
- /**
358
- * Emits the relevant events based on the previous and new reply from hassession
359
- * @private
360
- * @param {object} previous
361
- * @param {object} current
362
- * @returns {void}
363
- */
364
- _emitSessionEvent(previous, current) {
365
- /**
366
- * Emitted when the user is logged in (This happens as a result of calling
367
- * {@link Identity#hasSession}, so it is also emitted if the user was previously logged in)
368
- * @event Identity#login
369
- */
370
- if (current.userId) {
371
- this.emit('login', current);
372
- }
373
- /**
374
- * Emitted when the user logged out
375
- * @event Identity#logout
376
- */
377
- if (previous.userId && !current.userId) {
378
- this.emit('logout', current);
379
- }
380
- /**
381
- * Emitted when the user is changed. This happens as a result of calling
382
- * {@link Identity#hasSession}, and is emitted if there was a user both before and after
383
- * this invocation, and the userId has now changed
384
- * @event Identity#userChange
385
- */
386
- if (previous.userId && current.userId && previous.userId !== current.userId) {
387
- this.emit('userChange', current);
388
- }
389
- if (previous.userId || current.userId) {
390
- /**
391
- * Emitted when the session is changed. More accurately, this event is emitted if there
392
- * was a logged-in user either before or after {@link Identity#hasSession} was called.
393
- * In practice, this means the event is emitted a lot
394
- * @event Identity#sessionChange
395
- */
396
- this.emit('sessionChange', current);
397
- } else {
398
- /**
399
- * Emitted when there is no logged-in user. More specifically, it means that there was
400
- * no logged-in user neither before nor after {@link Identity#hasSession} was called
401
- * @event Identity#notLoggedin
402
- */
403
- this.emit('notLoggedin', current);
404
- }
405
- /**
406
- * Emitted when the session is first created
407
- * @event Identity#sessionInit
408
- */
409
- if (current.userId && !this._sessionInitiatedSent) {
410
- this._sessionInitiatedSent = true;
411
- this.emit('sessionInit', current);
412
- }
413
- /**
414
- * Emitted when the user status changes. This happens as a result of calling
415
- * {@link Identity#hasSession}
416
- * @event Identity#statusChange
417
- */
418
- if (previous.userStatus !== current.userStatus) {
419
- this.emit('statusChange', current);
420
- }
421
- }
422
-
423
- /**
424
- * Close this.popup if it exists and is open
425
- * @private
426
- * @returns {void}
427
- */
428
- _closePopup() {
429
- if (this.popup) {
430
- if (!this.popup.closed) {
431
- this.popup.close();
432
- }
433
- this.popup = null;
434
- }
435
- }
436
-
437
- /**
438
- * Set the Varnish cookie (`SP_ID`) when hasSession() is called. Note that most browsers require
439
- * that you are on a "real domain" for this to work — so, **not** `localhost`
440
- * @param {object} [options]
441
- * @param {number} [options.expiresIn] Override this to set number of seconds before the varnish
442
- * cookie expires. The default is to use the same time that hasSession responses are cached for
443
- * @param {string} [options.domain] Override cookie domain. E.g. «vg.no» instead of «www.vg.no»
444
- * @returns {void}
445
- */
446
- enableVarnishCookie(options) {
447
- let expiresIn = 0;
448
- let domain;
449
- if (Number.isInteger(options)) {
450
- expiresIn = options;
451
- }
452
- else if (typeof options == 'object') {
453
- expiresIn = options.expiresIn || expiresIn;
454
- domain = options.domain || domain;
455
- }
456
-
457
- assert(Number.isInteger(expiresIn), `'expiresIn' must be an integer`);
458
- assert(expiresIn >= 0, `'expiresIn' cannot be negative`);
459
- this.setVarnishCookie = true;
460
- this.varnishExpiresIn = expiresIn;
461
- this.varnishCookieDomain = domain;
462
- }
463
-
464
- /**
465
- * Set the Varnish cookie if configured
466
- * @private
467
- * @param {HasSessionSuccessResponse} sessionData
468
- * @returns {void}
469
- */
470
- _maybeSetVarnishCookie(sessionData) {
471
- if (!this.setVarnishCookie) {
472
- return;
473
- }
474
- const date = new Date();
475
- const validExpires = this.varnishExpiresIn
476
- || typeof sessionData.expiresIn === 'number' && sessionData.expiresIn > 0;
477
- if (validExpires) {
478
- const expires = this.varnishExpiresIn || sessionData.expiresIn;
479
- date.setTime(date.getTime() + (expires * 1000));
480
- } else {
481
- date.setTime(0);
482
- }
483
-
484
- // If the domain is missing or of the wrong type, we'll use document.domain
485
- let domain = this.varnishCookieDomain ||
486
- (typeof sessionData.baseDomain === 'string'
487
- ? sessionData.baseDomain
488
- : document.domain) ||
489
- '';
490
-
491
- const cookie = [
492
- `SP_ID=${sessionData.sp_id}`,
493
- `expires=${date.toUTCString()}`,
494
- `path=/`,
495
- `domain=.${domain}`
496
- ].join('; ');
497
- document.cookie = cookie;
498
- }
499
-
500
- /**
501
- * Clear the Varnish cookie if configured
502
- * @private
503
- * @returns {void}
504
- */
505
- _maybeClearVarnishCookie() {
506
- if (this.setVarnishCookie) {
507
- this._clearVarnishCookie();
508
- }
509
- }
510
-
511
- /**
512
- * Clear the Varnish cookie
513
- * @private
514
- * @returns {void}
515
- */
516
- _clearVarnishCookie() {
517
- const baseDomain = this._session && typeof this._session.baseDomain === 'string'
518
- ? this._session.baseDomain
519
- : document.domain;
520
-
521
- let domain = this.varnishCookieDomain ||
522
- baseDomain ||
523
- '';
524
-
525
- document.cookie = `SP_ID=nothing; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=.${domain}`;
526
- }
527
-
528
- /**
529
- * Log used settings and version
530
- * @throws {SDKError} - If log method is not provided
531
- * @return {void}
532
- */
533
- logSettings() {
534
- if (!this.log && !window.console) {
535
- throw new SDKError('You have to provide log method in constructor');
536
- }
537
-
538
- const log = this.log || console.log;
539
-
540
- const settings = {
541
- clientId: this.clientId,
542
- redirectUri: this.redirectUri,
543
- env: this.env,
544
- sessionDomain: this._sessionDomain,
545
- sdkVersion: version
546
- }
547
-
548
- log(`Schibsted account SDK for browsers settings: \n${JSON.stringify(settings, null, 2)}`);
549
- }
550
-
551
- /**
552
- * @summary Queries the hassession endpoint and returns information about the status of the user
553
- * @description When we send a request to this endpoint, cookies sent along with the request
554
- * determines the status of the user.
555
- * @throws {SDKError} - If the call to the hasSession service fails in any way (this will happen
556
- * if, say, the user is not logged in)
557
- * @fires Identity#login
558
- * @fires Identity#logout
559
- * @fires Identity#userChange
560
- * @fires Identity#sessionChange
561
- * @fires Identity#notLoggedin
562
- * @fires Identity#sessionInit
563
- * @fires Identity#statusChange
564
- * @fires Identity#error
565
- * @return {Promise<HasSessionSuccessResponse|HasSessionFailureResponse>}
566
- */
567
- hasSession() {
568
- const isSessionCallBlocked = this._isSessionCallBlocked()
569
- if (isSessionCallBlocked) {
570
- return this._session;
571
- }
572
-
573
- if (this._hasSessionInProgress) {
574
- return this._hasSessionInProgress;
575
- }
576
-
577
- const _postProcess = (sessionData) => {
578
- if (sessionData.error) {
579
- throw new SDKError('HasSession failed', sessionData.error);
580
- }
581
- this._maybeSetVarnishCookie(sessionData);
582
- this._emitSessionEvent(this._session, sessionData);
583
- this._session = sessionData;
584
- return sessionData;
585
- };
586
-
587
- const _checkRedirectionNeed = (sessionData={})=>{
588
- const sessionDataKeys = Object.keys(sessionData);
589
-
590
- return sessionDataKeys.length === 1 &&
591
- sessionDataKeys[0] === 'redirectURL';
592
- }
593
-
594
- const _getSession = async () => {
595
- if (this._enableSessionCaching) {
596
- // Try to resolve from cache (it has a TTL)
597
- let cachedSession = this.sessionStorageCache.get(HAS_SESSION_CACHE_KEY);
598
- if (cachedSession) {
599
- return _postProcess(cachedSession);
600
- }
601
- }
602
- let sessionData = null;
603
- try {
604
- sessionData = await this._sessionService.get(this._usedSessionServiceGetSessionEndpoint, {tabId: this._getTabId()});
605
- } catch (err) {
606
- if (err && err.code === 400 && this._enableSessionCaching) {
607
- const expiresIn = 1000 * (err.expiresIn || 300);
608
- this.sessionStorageCache.set(HAS_SESSION_CACHE_KEY, { error: err }, expiresIn);
609
- }
610
- throw err;
611
- }
612
-
613
- if (sessionData){
614
- // for expiring session and safari browser do full page redirect to gain new session
615
- if(_checkRedirectionNeed(sessionData)){
616
- this._blockSessionCall();
617
-
618
- await this.callbackBeforeRedirect();
619
-
620
- return this._sessionService.makeUrl(sessionData.redirectURL, {tabId: this._getTabId()});
621
- }
622
-
623
- if (this._enableSessionCaching) {
624
- const expiresIn = 1000 * (sessionData.expiresIn || 300);
625
- this.sessionStorageCache.set(HAS_SESSION_CACHE_KEY, sessionData, expiresIn);
626
- }
627
- }
628
-
629
- return _postProcess(sessionData);
630
- };
631
- this._hasSessionInProgress = _getSession()
632
- .then(
633
- sessionData => {
634
- this._hasSessionInProgress = false;
635
-
636
- if (isUrl(sessionData)) {
637
- return this.window.location.href = sessionData;
638
- }
639
-
640
- return sessionData;
641
- },
642
- err => {
643
- this.emit('error', err);
644
- this._hasSessionInProgress = false;
645
- throw new SDKError('HasSession failed', err);
646
- }
647
- );
648
-
649
- return this._hasSessionInProgress;
650
- }
651
-
652
- /**
653
- * @async
654
- * @summary Allows the client app to check if the user is logged in to Schibsted account
655
- * @description This function calls {@link Identity#hasSession} internally and thus has the side
656
- * effect that it might perform an auto-login on the user
657
- * @return {Promise<boolean>}
658
- */
659
- async isLoggedIn() {
660
- try {
661
- const data = await this.hasSession();
662
- return 'result' in data;
663
- } catch (_) {
664
- return false;
665
- }
666
- }
667
-
668
- /**
669
- * Removes the cached user session.
670
- * @returns {void}
671
- */
672
- clearCachedUserSession() {
673
- this.sessionStorageCache.delete(HAS_SESSION_CACHE_KEY);
674
- }
675
-
676
- /**
677
- * @async
678
- * @summary Allows the caller to check if the current user is connected to the client_id in
679
- * Schibsted account. Being connected means that the user has agreed for their account to be
680
- * used by your web app and have accepted the required terms
681
- * @description This function calls {@link Identity#hasSession} internally and thus has the side
682
- * effect that it might perform an auto-login on the user
683
- * @summary Check if the user is connected to the client_id
684
- * @return {Promise<boolean>}
685
- */
686
- async isConnected() {
687
- try {
688
- const data = await this.hasSession();
689
- // if data is not an object, the promise will fail.
690
- // if the result is present, it's boolean. But if it's not, it should be assumed false.
691
- return !!data.result;
692
- } catch (_) {
693
- return false;
694
- }
695
- }
696
-
697
- /**
698
- * @async
699
- * @summary Returns information about the user
700
- * @description This function calls {@link Identity#hasSession} internally and thus has the side
701
- * effect that it might perform an auto-login on the user
702
- * @throws {SDKError} If the user isn't connected to the merchant
703
- * @throws {SDKError} If we couldn't get the user
704
- * @return {Promise<HasSessionSuccessResponse>}
705
- */
706
- async getUser() {
707
- const user = await this.hasSession();
708
- if (!user.result) {
709
- throw new SDKError('The user is not connected to this merchant');
710
- }
711
- return cloneDeep(user);
712
- }
713
-
714
- /**
715
- * @async
716
- * @summary
717
- * In Schibsted account, there are multiple ways of identifying a user; the `userId`,
718
- * `uuid` and `externalId` used for identifying a user-merchant pair (see {@link Identity#getExternalId}).
719
- * There are reasons for them all to exist. The `userId` is a numeric identifier, but
720
- * since Schibsted account is deployed separately in Norway and Sweden, there are a lot of
721
- * duplicates. The `userId` was introduced early, so many sites still need to use them for
722
- * legacy reasons. The `uuid` is universally unique, and so — if we could disregard a lot of
723
- * Schibsted components depending on the numeric `userId` — it would be a good identifier to use
724
- * @description This function calls {@link Identity#hasSession} internally and thus has the side
725
- * effect that it might perform an auto-login on the user
726
- * @throws {SDKError} If the user isn't connected to the merchant
727
- * @return {Promise<string>} The `userId` field (not to be confused with the `uuid`)
728
- */
729
- async getUserId() {
730
- const user = await this.hasSession();
731
- if (user.userId && user.result) {
732
- return user.userId;
733
- }
734
- throw new SDKError('The user is not connected to this merchant');
735
- }
736
-
737
- /**
738
- * @async
739
- * @function
740
- * @summary
741
- * Retrieves the external identifier (`externalId`) for the authenticated user.
742
- *
743
- * In Schibsted Account there are multiple ways of identifying users, however for integrations with
744
- * third-parties it's recommended to use `externalId` as it does not disclose
745
- * any critical data whilst allowing for user identification.
746
- *
747
- * `externalId` is merchant-scoped using a pairwise identifier (`pairId`),
748
- * meaning the same user's ID will differ between merchants.
749
- * Additionally, this identifier is bound to the external party provided as argument.
750
- *
751
- * @param {string} externalParty
752
- * @param {string|null} optionalSuffix
753
- * @description This function calls {@link Identity#hasSession} internally and thus has the side
754
- * effect that it might perform an auto-login on the user
755
- * @throws {SDKError} If the `pairId` is missing in user session.
756
- * @throws {SDKError} If the `externalParty` is not defined
757
- * @return {Promise<string>} The merchant- and 3rd-party-specific `externalId`
758
- */
759
- async getExternalId(externalParty, optionalSuffix = "") {
760
- const { pairId } = await this.hasSession();
761
-
762
- if (!pairId)
763
- throw new SDKError('pairId missing in user session!');
764
-
765
- if(!externalParty || externalParty.length === 0) {
766
- throw new SDKError('externalParty cannot be empty');
767
- }
768
- const _toHexDigest = (hashBuffer) =>{
769
- // convert buffer to byte array
770
- const hashArray = Array.from(new Uint8Array(hashBuffer));
771
- // convert bytes to hex string
772
- return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
773
- }
774
-
775
- const _getSha256Digest = (data) => {
776
- return crypto.subtle.digest('SHA-256', data);
777
- }
778
-
779
- const _hashMessage = async (message) => {
780
- const msgUint8 = new TextEncoder().encode(message);
781
- return _getSha256Digest(msgUint8).then( (it) => _toHexDigest(it));
782
- }
783
-
784
- const _constructMessage = (pairId, externalParty, optionalSuffix) => {
785
- return optionalSuffix
786
- ? `${pairId}:${externalParty}:${optionalSuffix}`
787
- : `${pairId}:${externalParty}`;
788
- }
789
-
790
- return _hashMessage(_constructMessage(pairId, externalParty, optionalSuffix))
791
- }
792
-
793
- /**
794
- * @async
795
- * @summary Enables brands to programmatically get the current the SDRN based on the user's session.
796
- * @description This function calls {@link Identity#hasSession} internally and thus has the side
797
- * effect that it might perform an auto-login on the user
798
- * @throws {SDKError} If the SDRN is missing in user session object.
799
- * @returns {Promise<string>}
800
- */
801
- async getUserSDRN() {
802
- const { sdrn } = await this.hasSession();
803
- if (sdrn) {
804
- return sdrn;
805
- }
806
- throw new SDKError('Failed to get SDRN from user session');
807
- }
808
-
809
- /**
810
- * @async
811
- * @summary In Schibsted account, there are two ways of identifying a user; the `userId` and the
812
- * `uuid`. There are reasons for them both existing. The `userId` is a numeric identifier, but
813
- * since Schibsted account is deployed separately in Norway and Sweden, there are a lot of
814
- * duplicates. The `userId` was introduced early, so many sites still need to use them for
815
- * legacy reasons. The `uuid` is universally unique, and so — if we could disregard a lot of
816
- * Schibsted components depending on the numeric `userId` — it would be a good identifier to use
817
- * @description This function calls {@link Identity#hasSession} internally and thus has the side
818
- * effect that it might perform an auto-login on the user
819
- * @throws {SDKError} If the user isn't connected to the merchant
820
- * @return {Promise<string>} The `uuid` field (not to be confused with the `userId`)
821
- */
822
- async getUserUuid() {
823
- const user = await this.hasSession();
824
- if (user.uuid && user.result) {
825
- return user.uuid;
826
- }
827
- throw new SDKError('The user is not connected to this merchant');
828
- }
829
-
830
- /**
831
- * @async
832
- * @summary Get basic information about any user currently logged-in to their Schibsted account
833
- * in this browser. Can be used to provide context in a continue-as prompt.
834
- * @description This function relies on the global Schibsted account user session cookie, which
835
- * is a third-party cookie and hence might be blocked by the browser (for example due to ITP in
836
- * Safari). So there's no guarantee any data is returned, even though a user is logged-in in
837
- * the current browser.
838
- * @return {Promise<SimplifiedLoginData|null>}
839
- */
840
- async getUserContextData() {
841
- try {
842
- return await this._globalSessionService.get('user-context');
843
- } catch (_) {
844
- return null;
845
- }
846
- }
847
-
848
- /**
849
- * If a popup is desired, this function needs to be called in response to a user event (like
850
- * click or tap) in order to work correctly. Otherwise the popup will be blocked by the
851
- * browser's popup blockers and has to be explicitly authorized to be shown.
852
- * @summary Perform a login, either using a full-page redirect or a popup
853
- * @see https://tools.ietf.org/html/rfc6749#section-4.1.1
854
- *
855
- * @param {LoginOptions} options
856
- * @param {string} options.state
857
- * @param {string} [options.acrValues]
858
- * @param {string} [options.scope=openid]
859
- * @param {string} [options.redirectUri]
860
- * @param {boolean} [options.preferPopup=false]
861
- * @param {string} [options.loginHint]
862
- * @param {string} [options.tag]
863
- * @param {string} [options.teaser]
864
- * @param {number|string} [options.maxAge]
865
- * @param {string} [options.locale]
866
- * @param {boolean} [options.oneStepLogin=false]
867
- * @param {string} [options.prompt=select_account]
868
- * @param {string} [options.xDomainId]
869
- * @param {string} [options.xEnvironmentId]
870
- * @param {string} [options.originCampaign]
871
- * @return {Window|null} - Reference to popup window if created (or `null` otherwise)
872
- */
873
- login({
874
- state,
875
- acrValues = '',
876
- scope = 'openid',
877
- redirectUri = this.redirectUri,
878
- preferPopup = false,
879
- loginHint = '',
880
- tag = '',
881
- teaser = '',
882
- maxAge = '',
883
- locale = '',
884
- oneStepLogin = false,
885
- prompt = 'select_account',
886
- xDomainId = '',
887
- xEnvironmentId = '',
888
- originCampaign = ''
889
- }) {
890
- this._closePopup();
891
- this.sessionStorageCache.delete(HAS_SESSION_CACHE_KEY);
892
- const url = this.loginUrl({
893
- state,
894
- acrValues,
895
- scope,
896
- redirectUri,
897
- loginHint,
898
- tag,
899
- teaser,
900
- maxAge,
901
- locale,
902
- oneStepLogin,
903
- prompt,
904
- xDomainId,
905
- xEnvironmentId,
906
- originCampaign
907
- });
908
-
909
- if (preferPopup) {
910
- this.popup =
911
- popup.open(this.window, url, 'Schibsted account', { width: 360, height: 570 });
912
- if (this.popup) {
913
- return this.popup;
914
- }
915
- }
916
- this.window.location.href = url;
917
- return null;
918
- }
919
-
920
- /**
921
- * @async
922
- * @summary Retrieve the sp_id (Varnish ID)
923
- * @description This function calls {@link Identity#hasSession} internally and thus has the side
924
- * effect that it might perform an auto-login on the user
925
- * @return {Promise<string|null>} - The sp_id string or null (if the server didn't return it)
926
- */
927
- async getSpId() {
928
- try {
929
- const user = await this.hasSession();
930
- return user.sp_id || null;
931
- } catch (_) {
932
- return null;
933
- }
934
- }
935
-
936
- /**
937
- * @summary Logs the user out from the Identity platform
938
- * @param {string} redirectUri - Where to redirect the browser after logging out of Schibsted
939
- * account
940
- * @return {void}
941
- */
942
- logout(redirectUri = this.redirectUri) {
943
- this.sessionStorageCache.delete(HAS_SESSION_CACHE_KEY);
944
- this._maybeClearVarnishCookie();
945
- this.emit('logout');
946
- this.window.location.href = this.logoutUrl(redirectUri);
947
- }
948
-
949
- /**
950
- * Generates the link to the new login page that'll be used in the popup or redirect flow
951
- * @param {LoginOptions} options
952
- * @param {string} options.state
953
- * @param {string} [options.acrValues]
954
- * @param {string} [options.scope=openid]
955
- * @param {string} [options.redirectUri]
956
- * @param {string} [options.loginHint]
957
- * @param {string} [options.tag]
958
- * @param {string} [options.teaser]
959
- * @param {number|string} [options.maxAge]
960
- * @param {string} [options.locale]
961
- * @param {boolean} [options.oneStepLogin=false]
962
- * @param {string} [options.prompt=select_account]
963
- * @param {string} [options.xDomainId]
964
- * @param {string} [options.xEnvironmentId]
965
- * @param {string} [options.originCampaign]
966
- * @return {string} - The url
967
- */
968
- loginUrl({
969
- state,
970
- acrValues = '',
971
- scope = 'openid',
972
- redirectUri = this.redirectUri,
973
- loginHint = '',
974
- tag = '',
975
- teaser = '',
976
- maxAge = '',
977
- locale = '',
978
- oneStepLogin = false,
979
- prompt = 'select_account',
980
- xDomainId = '',
981
- xEnvironmentId = '',
982
- originCampaign = ''
983
- }) {
984
- if (typeof arguments[0] !== 'object') {
985
- // backward compatibility
986
- state = arguments[0];
987
- acrValues = arguments[1];
988
- scope = arguments[2] || scope;
989
- redirectUri = arguments[3] || redirectUri;
990
- loginHint = arguments[4] || loginHint;
991
- tag = arguments[5] || tag;
992
- teaser = arguments[6] || teaser;
993
- maxAge = isNaN(arguments[7]) ? maxAge : arguments[7];
994
- }
995
- const isValidAcrValue = (acrValue) => isStrIn(acrValue, ['password', 'otp', 'sms', 'eid-dk', 'eid-no', 'eid-se', 'eid-fi', 'eid'], true);
996
- assert(!acrValues || isStrIn(acrValues, ['', 'otp-email'], true) || acrValues.split(' ').every(isValidAcrValue),
997
- `The acrValues parameter is not acceptable: ${acrValues}`);
998
- assert(isUrl(redirectUri),
999
- `loginUrl(): redirectUri must be a valid url but is ${redirectUri}`);
1000
- assert(isNonEmptyString(state),
1001
- `the state parameter should be a non empty string but it is ${state}`);
1002
-
1003
- return this._oauthService.makeUrl('oauth/authorize', {
1004
- response_type: 'code',
1005
- redirect_uri: redirectUri,
1006
- scope,
1007
- state,
1008
- acr_values: acrValues,
1009
- login_hint: loginHint,
1010
- tag,
1011
- teaser,
1012
- max_age: maxAge,
1013
- locale,
1014
- one_step_login: oneStepLogin || '',
1015
- prompt: acrValues ? '' : prompt,
1016
- x_domain_id: xDomainId,
1017
- x_env_id: xEnvironmentId,
1018
- utm_campaign: originCampaign
1019
- });
1020
- }
1021
-
1022
- /**
1023
- * The url for logging the user out
1024
- * @param {string} [redirectUri=this.redirectUri]
1025
- * @return {string} url
1026
- */
1027
- logoutUrl(redirectUri = this.redirectUri) {
1028
- assert(isUrl(redirectUri), `logoutUrl(): redirectUri is invalid`);
1029
- const params = { redirect_uri: redirectUri };
1030
- return this._sessionService.makeUrl('logout', params);
1031
- }
1032
-
1033
- /**
1034
- * The account summary page url
1035
- * @param {string} [redirectUri=this.redirectUri]
1036
- * @return {string}
1037
- */
1038
- accountUrl(redirectUri = this.redirectUri) {
1039
- return this._spid.makeUrl('profile-pages', {
1040
- response_type: 'code',
1041
- redirect_uri: redirectUri
1042
- });
1043
- }
1044
-
1045
- /**
1046
- * The phone editing page url
1047
- * @param {string} [redirectUri=this.redirectUri]
1048
- * @return {string}
1049
- */
1050
- phonesUrl(redirectUri = this.redirectUri) {
1051
- return this._spid.makeUrl('profile-pages/about-you/phone', {
1052
- response_type: 'code',
1053
- redirect_uri: redirectUri
1054
- });
1055
- }
1056
-
1057
- /**
1058
- * Function responsible for loading and displaying simplified login widget. How often
1059
- * widget will be display is up to you. Preferred way would be to show it once per user,
1060
- * and store that info in localStorage. Widget will be display only if user is logged in to SSO.
1061
- *
1062
- * @async
1063
- * @param {SimplifiedLoginWidgetLoginOptions} loginParams - the same as `options` param for login function. Login will be called on user
1064
- * continue action. `state` might be string or async function.
1065
- * @param {SimplifiedLoginWidgetOptions} [options] - additional configuration of Simplified Login Widget
1066
- * @fires Identity#simplifiedLoginOpened
1067
- * @fires Identity#simplifiedLoginCancelled
1068
- * @return {Promise<boolean|SDKError>} - will resolve to true if widget will be display. Otherwise, will throw SDKError
1069
- */
1070
- async showSimplifiedLoginWidget(loginParams, options) {
1071
- // getUserContextData doesn't throw exception
1072
- const userData = await this.getUserContextData();
1073
-
1074
- const queryParams = { client_id: this.clientId };
1075
- if (options && options.encoding) {
1076
- queryParams.encoding = options.encoding;
1077
- }
1078
- const widgetUrl = this._bffService.makeUrl('simplified-login-widget', queryParams, false);
1079
-
1080
- const prepareLoginParams = async (loginPrams) => {
1081
- if (typeof loginPrams.state === 'function') {
1082
- loginPrams.state = await loginPrams.state();
1083
- }
1084
-
1085
- return loginPrams;
1086
- }
1087
-
1088
- return new Promise(
1089
- (resolve, reject) => {
1090
- if (!userData || !userData.display_text || !userData.identifier) {
1091
- return reject(new SDKError('Missing user data'));
1092
- }
1093
-
1094
- const initialParams = {
1095
- displayText: userData.display_text,
1096
- env: this.env,
1097
- clientName: userData.client_name,
1098
- clientId: this.clientId,
1099
- providerId: userData.provider_id,
1100
- windowWidth: () => window.innerWidth,
1101
- windowOnResize: (f) => {
1102
- window.onresize = f;
1103
- },
1104
- };
1105
-
1106
- if (options && options.locale) {
1107
- initialParams.locale = options.locale;
1108
- }
1109
-
1110
- const loginHandler = async () => {
1111
- this.login(Object.assign(await prepareLoginParams(loginParams), {loginHint: userData.identifier}));
1112
- };
1113
-
1114
- const loginNotYouHandler = async () => {
1115
- this.login(Object.assign(await prepareLoginParams(loginParams), {loginHint: userData.identifier, prompt: 'login'}));
1116
- };
1117
-
1118
- const initHandler = () => {
1119
- /**
1120
- * Emitted when the simplified login widget is displayed on the screen
1121
- * @event Identity#simplifiedLoginOpened
1122
- */
1123
- this.emit('simplifiedLoginOpened');
1124
- }
1125
-
1126
- const cancelLoginHandler = () => {
1127
- /**
1128
- * Emitted when the user closes the simplified login widget
1129
- * @event Identity#simplifiedLoginCancelled
1130
- */
1131
- this.emit('simplifiedLoginCancelled');
1132
- }
1133
-
1134
- if (window.openSimplifiedLoginWidget) {
1135
- window.openSimplifiedLoginWidget(initialParams, loginHandler, loginNotYouHandler, initHandler, cancelLoginHandler);
1136
- return resolve(true);
1137
- }
1138
-
1139
- const simplifiedLoginWidget = document.createElement("script");
1140
- simplifiedLoginWidget.type = "text/javascript";
1141
- simplifiedLoginWidget.src = widgetUrl;
1142
- simplifiedLoginWidget.onload = () => {
1143
- window.openSimplifiedLoginWidget(initialParams, loginHandler, loginNotYouHandler, initHandler, cancelLoginHandler);
1144
- resolve(true);
1145
- };
1146
- simplifiedLoginWidget.onerror = () => {
1147
- reject(new SDKError('Error when loading simplified login widget content'));
1148
- };
1149
- document.getElementsByTagName('body')[0].appendChild(simplifiedLoginWidget);
1150
- });
1151
- }
1152
- }
1153
-
1154
- export default Identity;