@schibsted/account-sdk-browser 6.0.0-alpha.4 → 6.0.0-alpha.6

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/src/identity.ts CHANGED
@@ -2,10 +2,8 @@
2
2
  * See LICENSE.md in the project root.
3
3
  */
4
4
 
5
- import { TinyEmitter } from 'tiny-emitter';
6
5
  import Cache from './cache.js';
7
6
  import { ENDPOINTS } from './config.js';
8
- import { registerAndDispatchInGlobal } from './global-registry.js';
9
7
  import { cloneDeep } from './object.js';
10
8
  import * as popup from './popup.js';
11
9
  import type RESTClient from './rest-client.js';
@@ -20,6 +18,7 @@ import {
20
18
  normalizeSessionResponse,
21
19
  } from './session-response.js';
22
20
  import * as spidTalk from './spid-talk.js';
21
+ import type { AccountEventName } from './types/account.js';
23
22
  import type { LogFunction } from './types/common.js';
24
23
  import type {
25
24
  IdentityBeforeRedirectCallback,
@@ -45,16 +44,6 @@ import { urlMapper } from './url.js';
45
44
  import { assert, isNonEmptyString, isObject, isStr, isStrIn, isUrl } from './validate.js';
46
45
  import version from './version.js';
47
46
 
48
- export { isConnectedSessionResponse, isSessionSuccessResponse } from './session-response.js';
49
- export type {
50
- ConnectedSessionResponse,
51
- SessionFailureResponse,
52
- SessionObjectResponse,
53
- SessionResponse,
54
- SessionSuccessResponse,
55
- SessionUserId,
56
- } from './types/session.js';
57
-
58
47
  declare global {
59
48
  interface Window {
60
49
  openSimplifiedLoginWidget?: OpenSimplifiedLoginWidget;
@@ -74,34 +63,44 @@ const globalWindow = () => window;
74
63
  /**
75
64
  * Provides Identity functionalty to a web page
76
65
  */
77
- export class Identity extends TinyEmitter {
78
- _sessionInitiatedSent: boolean;
79
- window: Window;
80
- clientId: string;
81
- sessionStorageCache: Cache;
82
- localStorageCache: Cache;
83
- redirectUri: string;
84
- env: string;
85
- log?: LogFunction;
86
- callbackBeforeRedirect: IdentityBeforeRedirectCallback;
87
- _sessionDomain: string;
88
- _enableSessionCaching: boolean;
66
+ export class Identity {
67
+ // Event bus
68
+ private readonly eventTarget = new EventTarget();
69
+
70
+ // Configuration
71
+ private readonly window: Window;
72
+ private readonly clientId: string;
73
+ private readonly redirectUri: string;
74
+ private readonly env: string;
75
+ private readonly log?: LogFunction;
76
+ private readonly callbackBeforeRedirect: IdentityBeforeRedirectCallback;
77
+
78
+ // Caches
79
+ private readonly sessionStorageCache: Cache;
80
+ private readonly localStorageCache: Cache;
81
+ private enableSessionCaching: boolean;
82
+
83
+ // REST clients
84
+ private readonly spid: RESTClient;
85
+ private readonly oauthService: RESTClient;
86
+ private readonly bffService: RESTClient;
87
+ private readonly sessionService: RESTClient;
88
+ private readonly globalSessionService: RESTClient;
89
+ private readonly usedSessionServiceGetSessionEndpoint: 'v2/session' | 'session';
90
+
91
+ // Session state
89
92
  /**
90
93
  * @internal Starts as `{}` before the first `hasSession()` call, then stores the latest
91
94
  * object response from hasSession().
92
95
  */
93
- _session: SessionObjectResponse;
94
- _spid: RESTClient;
95
- _oauthService: RESTClient;
96
- _bffService: RESTClient;
97
- _sessionService: RESTClient;
98
- _globalSessionService: RESTClient;
99
- _usedSessionServiceGetSessionEndpoint: 'v2/session' | 'session';
100
- _hasSessionInProgress?: false | Promise<SessionResponse>;
101
- popup?: Window | null;
102
- setVarnishCookie?: boolean;
103
- varnishExpiresIn?: number;
104
- varnishCookieDomain?: string;
96
+ private session: SessionObjectResponse;
97
+ private hasSessionInProgress?: false | Promise<SessionResponse>;
98
+
99
+ // Popup & Varnish cookie state
100
+ private popup?: Window | null;
101
+ private setVarnishCookie?: boolean;
102
+ private varnishExpiresIn?: number;
103
+ private varnishCookieDomain?: string;
105
104
 
106
105
  /**
107
106
  * @param options
@@ -124,7 +123,6 @@ export class Identity extends TinyEmitter {
124
123
  window = globalWindow(),
125
124
  callbackBeforeRedirect = () => {},
126
125
  }: IdentityOptions) {
127
- super();
128
126
  assert(isNonEmptyString(clientId), 'clientId parameter is required');
129
127
  assert(isObject(window), 'The reference to window is missing');
130
128
  assert(!redirectUri || isUrl(redirectUri), 'redirectUri parameter is invalid');
@@ -135,64 +133,66 @@ export class Identity extends TinyEmitter {
135
133
  assert(isStr(env), `env parameter is invalid: ${env}`);
136
134
 
137
135
  spidTalk.emulate(window);
138
- this._sessionInitiatedSent = false;
139
136
  this.window = window;
140
137
  this.clientId = clientId;
141
- this.sessionStorageCache = new Cache(() => this.window && this.window.sessionStorage);
142
- this.localStorageCache = new Cache(() => this.window && this.window.localStorage);
143
138
  this.redirectUri = redirectUri;
144
139
  this.env = env;
145
140
  this.log = log;
146
141
  this.callbackBeforeRedirect = callbackBeforeRedirect;
147
- this._sessionDomain = sessionDomain;
148
142
 
143
+ this.sessionStorageCache = new Cache(() => this.window && this.window.sessionStorage);
144
+ this.localStorageCache = new Cache(() => this.window && this.window.localStorage);
149
145
  // Internal hack: set to false to always refresh from hassession
150
- this._enableSessionCaching = true;
146
+ this.enableSessionCaching = true;
151
147
 
152
- // Old session
153
- this._session = {};
148
+ this.session = {};
154
149
 
155
150
  const accountClientParams = { client_id: this.clientId, redirect_uri: this.redirectUri };
156
151
  const clientSdrn = buildClientSdrn(this.env, this.clientId);
157
152
 
158
- this._sessionService = createAccountRestClient({
159
- serverUrl: sessionDomain,
153
+ this.spid = createAccountRestClient({
154
+ serverUrl: urlMapper(env, ENDPOINTS.SPiD),
160
155
  log: this.log,
161
- defaultParams: {
162
- client_sdrn: clientSdrn,
163
- redirect_uri: this.redirectUri,
164
- sdk_version: version,
165
- },
156
+ defaultParams: accountClientParams,
166
157
  });
167
- this._usedSessionServiceGetSessionEndpoint =
168
- this._sessionService.url.pathname && this._sessionService.url.pathname.length <= 1
169
- ? 'v2/session'
170
- : 'session';
171
-
172
- this._spid = createAccountRestClient({
158
+ this.oauthService = createAccountRestClient({
173
159
  serverUrl: urlMapper(env, ENDPOINTS.SPiD),
174
160
  log: this.log,
175
161
  defaultParams: accountClientParams,
176
162
  });
177
- this._bffService = createAccountRestClient({
163
+ this.bffService = createAccountRestClient({
178
164
  serverUrl: urlMapper(env, ENDPOINTS.BFF),
179
165
  log: this.log,
180
166
  defaultParams: accountClientParams,
181
167
  });
182
- this._oauthService = createAccountRestClient({
183
- serverUrl: urlMapper(env, ENDPOINTS.SPiD),
168
+ this.sessionService = createAccountRestClient({
169
+ serverUrl: sessionDomain,
184
170
  log: this.log,
185
- defaultParams: accountClientParams,
171
+ defaultParams: {
172
+ client_sdrn: clientSdrn,
173
+ redirect_uri: this.redirectUri,
174
+ sdk_version: version,
175
+ },
186
176
  });
187
- this._globalSessionService = createAccountRestClient({
177
+ this.globalSessionService = createAccountRestClient({
188
178
  serverUrl: urlMapper(env, ENDPOINTS.SESSION_SERVICE),
189
179
  log: this.log,
190
180
  defaultParams: { client_sdrn: clientSdrn, sdk_version: version },
191
181
  });
182
+ this.usedSessionServiceGetSessionEndpoint =
183
+ this.sessionService.url.pathname && this.sessionService.url.pathname.length <= 1
184
+ ? 'v2/session'
185
+ : 'session';
192
186
 
193
187
  this._unblockSessionCall();
188
+ }
194
189
 
195
- registerAndDispatchInGlobal(window, 'schIdentity', this);
190
+ addEventListener(type: AccountEventName, listener: EventListener): void {
191
+ this.eventTarget.addEventListener(type, listener);
192
+ }
193
+
194
+ removeEventListener(type: AccountEventName, listener: EventListener): void {
195
+ this.eventTarget.removeEventListener(type, listener);
196
196
  }
197
197
 
198
198
  /**
@@ -200,7 +200,7 @@ export class Identity extends TinyEmitter {
200
200
  * @private
201
201
  */
202
202
  _getTabId(): number | undefined {
203
- if (this._enableSessionCaching) {
203
+ if (this.enableSessionCaching) {
204
204
  const tabId = this.sessionStorageCache.get(TAB_ID_KEY);
205
205
  if (typeof tabId !== 'number') {
206
206
  this.sessionStorageCache.set(TAB_ID_KEY, TAB_ID, TAB_ID_TTL);
@@ -244,80 +244,6 @@ export class Identity extends TinyEmitter {
244
244
  this.localStorageCache.delete(SESSION_CALL_BLOCKED_CACHE_KEY);
245
245
  }
246
246
 
247
- /**
248
- * Emits the relevant events based on the previous and new reply from hasSession
249
- * @private
250
- * @param previous
251
- * @param current
252
- */
253
- _emitSessionEvent(previous: object, current: object): void {
254
- const previousUserId = isSessionSuccessResponse(previous) ? previous.userId : undefined;
255
- const currentUserId = isSessionSuccessResponse(current) ? current.userId : undefined;
256
- const previousUserStatus = isSessionSuccessResponse(previous)
257
- ? previous.userStatus
258
- : undefined;
259
- const currentUserStatus = isSessionSuccessResponse(current)
260
- ? current.userStatus
261
- : undefined;
262
-
263
- /**
264
- * Emitted when the user is logged in (This happens as a result of calling
265
- * {@link Identity#hasSession}, so it is also emitted if the user was previously logged in)
266
- * @event Identity#login
267
- */
268
- if (currentUserId) {
269
- this.emit('login', current);
270
- }
271
- /**
272
- * Emitted when the user logged out
273
- * @event Identity#logout
274
- */
275
- if (previousUserId && !currentUserId) {
276
- this.emit('logout', current);
277
- }
278
- /**
279
- * Emitted when the user is changed. This happens as a result of calling
280
- * {@link Identity#hasSession}, and is emitted if there was a user both before and after
281
- * this invocation, and the userId has now changed
282
- * @event Identity#userChange
283
- */
284
- if (previousUserId && currentUserId && previousUserId !== currentUserId) {
285
- this.emit('userChange', current);
286
- }
287
- if (previousUserId || currentUserId) {
288
- /**
289
- * Emitted when the session is changed. More accurately, this event is emitted if there
290
- * was a logged-in user either before or after {@link Identity#hasSession} was called.
291
- * In practice, this means the event is emitted a lot
292
- * @event Identity#sessionChange
293
- */
294
- this.emit('sessionChange', current);
295
- } else {
296
- /**
297
- * Emitted when there is no logged-in user. More specifically, it means that there was
298
- * no logged-in user neither before nor after {@link Identity#hasSession} was called
299
- * @event Identity#notLoggedin
300
- */
301
- this.emit('notLoggedin', current);
302
- }
303
- /**
304
- * Emitted when the session is first created
305
- * @event Identity#sessionInit
306
- */
307
- if (currentUserId && !this._sessionInitiatedSent) {
308
- this._sessionInitiatedSent = true;
309
- this.emit('sessionInit', current);
310
- }
311
- /**
312
- * Emitted when the user status changes. This happens as a result of calling
313
- * {@link Identity#hasSession}
314
- * @event Identity#statusChange
315
- */
316
- if (previousUserStatus !== currentUserStatus) {
317
- this.emit('statusChange', current);
318
- }
319
- }
320
-
321
247
  /**
322
248
  * Close this.popup if it exists and is open
323
249
  * @private
@@ -406,10 +332,10 @@ export class Identity extends TinyEmitter {
406
332
  */
407
333
  _clearVarnishCookie(): void {
408
334
  const baseDomain =
409
- this._session &&
410
- isSessionSuccessResponse(this._session) &&
411
- typeof this._session.baseDomain === 'string'
412
- ? this._session.baseDomain
335
+ this.session &&
336
+ isSessionSuccessResponse(this.session) &&
337
+ typeof this.session.baseDomain === 'string'
338
+ ? this.session.baseDomain
413
339
  : this.window.location.hostname;
414
340
 
415
341
  const domain = this.varnishCookieDomain || baseDomain || '';
@@ -417,53 +343,23 @@ export class Identity extends TinyEmitter {
417
343
  document.cookie = `SP_ID=nothing; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=.${domain}`;
418
344
  }
419
345
 
420
- /**
421
- * Log used settings and version
422
- * @throws {SDKError} - If log method is not provided
423
- */
424
- logSettings(): void {
425
- if (!this.log && !window.console) {
426
- throw new SDKError('You have to provide log method in constructor');
427
- }
428
-
429
- const log = this.log || console.log;
430
-
431
- const settings = {
432
- clientId: this.clientId,
433
- redirectUri: this.redirectUri,
434
- env: this.env,
435
- sessionDomain: this._sessionDomain,
436
- sdkVersion: version,
437
- };
438
-
439
- log(`Schibsted account SDK for browsers settings: \n${JSON.stringify(settings, null, 2)}`);
440
- }
441
-
442
346
  /**
443
347
  * @summary Queries the hassession endpoint and returns information about the status of the user
444
348
  * @remarks When we send a request to this endpoint, cookies sent along with the request
445
349
  * determines the status of the user.
446
350
  * @throws {SDKError} - If the call to the hasSession service fails in any way (this will happen
447
351
  * if, say, the user is not logged in)
448
- * @fires Identity#login
449
- * @fires Identity#logout
450
- * @fires Identity#userChange
451
- * @fires Identity#sessionChange
452
- * @fires Identity#notLoggedin
453
- * @fires Identity#sessionInit
454
- * @fires Identity#statusChange
455
- * @fires Identity#error
456
352
  */
457
353
  hasSession(): Promise<SessionResponse> {
458
354
  const isSessionCallBlocked = this._isSessionCallBlocked();
459
355
 
460
356
  if (isSessionCallBlocked) {
461
- const sessionData = normalizeSessionResponse(this._session);
357
+ const sessionData = normalizeSessionResponse(this.session);
462
358
  return Promise.resolve(isRedirectSessionPayload(sessionData) ? {} : sessionData);
463
359
  }
464
360
 
465
- if (this._hasSessionInProgress) {
466
- return this._hasSessionInProgress;
361
+ if (this.hasSessionInProgress) {
362
+ return this.hasSessionInProgress;
467
363
  }
468
364
 
469
365
  const _postProcess = (sessionData: SessionObjectResponse): SessionObjectResponse => {
@@ -474,8 +370,7 @@ export class Identity extends TinyEmitter {
474
370
  throw new SDKError('HasSession failed', errorObject);
475
371
  }
476
372
  this._maybeSetVarnishCookie(sessionData);
477
- this._emitSessionEvent(this._session, sessionData);
478
- this._session = sessionData;
373
+ this.session = sessionData;
479
374
  return sessionData;
480
375
  };
481
376
 
@@ -485,7 +380,7 @@ export class Identity extends TinyEmitter {
485
380
  };
486
381
 
487
382
  const _getSession = async (): Promise<SessionResponse> => {
488
- if (this._enableSessionCaching) {
383
+ if (this.enableSessionCaching) {
489
384
  // Try to resolve from cache (it has a TTL)
490
385
  const cachedSession = _getCachedSession();
491
386
  if (cachedSession) {
@@ -497,14 +392,14 @@ export class Identity extends TinyEmitter {
497
392
  }
498
393
  let sessionData: NormalizedSessionPayload | null = null;
499
394
  try {
500
- sessionData = await this._sessionService.get(
501
- this._usedSessionServiceGetSessionEndpoint,
395
+ sessionData = await this.sessionService.get(
396
+ this.usedSessionServiceGetSessionEndpoint,
502
397
  { tabId: this._getTabId() },
503
398
  normalizeSessionResponse,
504
399
  );
505
400
  } catch (err: unknown) {
506
401
  const cacheableError = isObject(err) ? err : undefined;
507
- if (cacheableError?.code === 400 && this._enableSessionCaching) {
402
+ if (cacheableError?.code === 400 && this.enableSessionCaching) {
508
403
  const errorExpiresIn =
509
404
  typeof cacheableError.expiresIn === 'number'
510
405
  ? cacheableError.expiresIn
@@ -516,7 +411,7 @@ export class Identity extends TinyEmitter {
516
411
  typeof cacheableError.code === 'number' &&
517
412
  cacheableError.code >= 500 &&
518
413
  cacheableError.code < 600 &&
519
- this._enableSessionCaching
414
+ this.enableSessionCaching
520
415
  ) {
521
416
  // Temporary fix: 30 seconds cache to limit number of calls when service is unavailable
522
417
  this.sessionStorageCache.set(HAS_SESSION_CACHE_KEY, { error: err }, 30 * 1000);
@@ -531,13 +426,13 @@ export class Identity extends TinyEmitter {
531
426
 
532
427
  await this.callbackBeforeRedirect();
533
428
 
534
- const redirectUrl = this._sessionService.makeUrl(sessionData.redirectURL, {
429
+ const redirectUrl = this.sessionService.makeUrl(sessionData.redirectURL, {
535
430
  tabId: this._getTabId(),
536
431
  });
537
432
  return redirectUrl;
538
433
  }
539
434
 
540
- if (this._enableSessionCaching) {
435
+ if (this.enableSessionCaching) {
541
436
  const expiresIn =
542
437
  1000 *
543
438
  (isSessionSuccessResponse(sessionData)
@@ -549,22 +444,21 @@ export class Identity extends TinyEmitter {
549
444
 
550
445
  return _postProcess(sessionData ?? {});
551
446
  };
552
- this._hasSessionInProgress = _getSession().then(
447
+ this.hasSessionInProgress = _getSession().then(
553
448
  (sessionData) => {
554
- this._hasSessionInProgress = false;
449
+ this.hasSessionInProgress = false;
555
450
  if (typeof sessionData === 'string') {
556
451
  this.window.location.href = sessionData;
557
452
  }
558
453
  return sessionData;
559
454
  },
560
455
  (err) => {
561
- this.emit('error', err);
562
- this._hasSessionInProgress = false;
456
+ this.hasSessionInProgress = false;
563
457
  throw new SDKError('HasSession failed', err);
564
458
  },
565
459
  );
566
460
 
567
- return this._hasSessionInProgress;
461
+ return this.hasSessionInProgress;
568
462
  }
569
463
 
570
464
  /**
@@ -581,6 +475,16 @@ export class Identity extends TinyEmitter {
581
475
  }
582
476
  }
583
477
 
478
+ /**
479
+ * Enables or disables caching for subsequent session lookups.
480
+ *
481
+ * Changing this setting does not remove an existing cached session. Use
482
+ * {@link Identity#clearCachedUserSession} to clear the cache explicitly.
483
+ */
484
+ setSessionCachingEnabled(enabled: boolean): void {
485
+ this.enableSessionCaching = enabled;
486
+ }
487
+
584
488
  /**
585
489
  * Removes the cached user session.
586
490
  */
@@ -618,11 +522,9 @@ export class Identity extends TinyEmitter {
618
522
  }
619
523
  return cloneDeep(user);
620
524
  }
621
-
622
525
  /**
623
526
  * @summary
624
- * In Schibsted account, there are multiple ways of identifying a user; the `userId`,
625
- * `uuid` and `externalId` used for identifying a user-merchant pair (see {@link Identity#getExternalId}).
527
+ * In Schibsted account, there are multiple ways of identifying a user; the `userId` or `uuid`.
626
528
  * There are reasons for them all to exist. The `userId` is a numeric identifier, but
627
529
  * since Schibsted account is deployed separately in Norway and Sweden, there are a lot of
628
530
  * duplicates. The `userId` was introduced early, so many sites still need to use them for
@@ -641,65 +543,6 @@ export class Identity extends TinyEmitter {
641
543
  throw new SDKError('The user is not connected to this merchant');
642
544
  }
643
545
 
644
- /**
645
- * @function
646
- * @summary
647
- * Retrieves the external identifier (`externalId`) for the authenticated user.
648
- *
649
- * In Schibsted Account there are multiple ways of identifying users, however for integrations with
650
- * third-parties it's recommended to use `externalId` as it does not disclose
651
- * any critical data whilst allowing for user identification.
652
- *
653
- * `externalId` is merchant-scoped using a pairwise identifier (`pairId`),
654
- * meaning the same user's ID will differ between merchants.
655
- * Additionally, this identifier is bound to the external party provided as argument.
656
- *
657
- * @param externalParty
658
- * @param optionalSuffix
659
- * @remarks This function calls {@link Identity#hasSession} internally and thus has the side
660
- * effect that it might perform an auto-login on the user
661
- * @throws {SDKError} If the `pairId` is missing in user session.
662
- * @throws {SDKError} If the `externalParty` is not defined
663
- * @return The merchant- and 3rd-party-specific `externalId`
664
- */
665
- async getExternalId(externalParty: string, optionalSuffix: string = ''): Promise<string> {
666
- const user = await this.hasSession();
667
- const pairId = isSessionSuccessResponse(user) ? user.pairId : undefined;
668
-
669
- if (!pairId) throw new SDKError('pairId missing in user session!');
670
-
671
- if (!externalParty || externalParty.length === 0) {
672
- throw new SDKError('externalParty cannot be empty');
673
- }
674
- const _toHexDigest = (hashBuffer: ArrayBuffer) => {
675
- // convert buffer to byte array
676
- const hashArray = Array.from(new Uint8Array(hashBuffer));
677
- // convert bytes to hex string
678
- return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
679
- };
680
-
681
- const _getSha256Digest = (data: BufferSource) => {
682
- return crypto.subtle.digest('SHA-256', data);
683
- };
684
-
685
- const _hashMessage = async (message: string) => {
686
- const msgUint8 = new TextEncoder().encode(message);
687
- return _getSha256Digest(msgUint8).then((it) => _toHexDigest(it));
688
- };
689
-
690
- const _constructMessage = (
691
- pairId: string,
692
- externalParty: string,
693
- optionalSuffix: string,
694
- ) => {
695
- return optionalSuffix
696
- ? `${pairId}:${externalParty}:${optionalSuffix}`
697
- : `${pairId}:${externalParty}`;
698
- };
699
-
700
- return _hashMessage(_constructMessage(pairId, externalParty, optionalSuffix));
701
- }
702
-
703
546
  /**
704
547
  * @summary Enables brands to programmatically get the current the SDRN based on the user's session.
705
548
  * @remarks This function calls {@link Identity#hasSession} internally and thus has the side
@@ -744,7 +587,7 @@ export class Identity extends TinyEmitter {
744
587
  */
745
588
  async getUserContextData(): Promise<SimplifiedLoginData | null> {
746
589
  try {
747
- return await this._globalSessionService.get('user-context', undefined, (value) =>
590
+ return await this.globalSessionService.get('user-context', undefined, (value) =>
748
591
  isObject(value) && isStr(value.identifier)
749
592
  ? {
750
593
  identifier: value.identifier,
@@ -782,6 +625,7 @@ export class Identity extends TinyEmitter {
782
625
  * @param options.xDomainId
783
626
  * @param options.xEnvironmentId
784
627
  * @param options.originCampaign
628
+ * @fires Identity#login
785
629
  * @return - Reference to popup window if created (or `null` otherwise)
786
630
  */
787
631
  login({
@@ -825,11 +669,25 @@ export class Identity extends TinyEmitter {
825
669
  width: 360,
826
670
  height: 570,
827
671
  });
672
+
828
673
  if (this.popup) {
674
+ this.eventTarget.dispatchEvent(
675
+ new CustomEvent('login', {
676
+ detail: { url, method: 'popup' },
677
+ }),
678
+ );
679
+
829
680
  return this.popup;
830
681
  }
831
682
  }
683
+
684
+ this.eventTarget.dispatchEvent(
685
+ new CustomEvent('login', {
686
+ detail: { url, method: 'default' },
687
+ }),
688
+ );
832
689
  this.window.location.href = url;
690
+
833
691
  return null;
834
692
  }
835
693
 
@@ -854,14 +712,19 @@ export class Identity extends TinyEmitter {
854
712
 
855
713
  /**
856
714
  * @summary Logs the user out from the Identity platform
857
- * @param redirectUri - Where to redirect the browser after logging out of Schibsted
858
- * account
715
+ * @param redirectUri - Where to redirect the browser after logging out of Schibsted account
716
+ * @fires Identity#logout
859
717
  */
860
718
  logout(redirectUri: string = this.redirectUri): void {
861
719
  this.sessionStorageCache.delete(HAS_SESSION_CACHE_KEY);
862
720
  this._maybeClearVarnishCookie();
863
- this.emit('logout');
864
- this.window.location.href = this.logoutUrl(redirectUri);
721
+ const url = this.logoutUrl(redirectUri);
722
+ this.eventTarget.dispatchEvent(
723
+ new CustomEvent('logout', {
724
+ detail: { url },
725
+ }),
726
+ );
727
+ this.window.location.href = url;
865
728
  }
866
729
 
867
730
  /**
@@ -920,7 +783,7 @@ export class Identity extends TinyEmitter {
920
783
  `the state parameter should be a non empty string but it is ${state}`,
921
784
  );
922
785
 
923
- return this._oauthService.makeUrl('oauth/authorize', {
786
+ return this.oauthService.makeUrl('oauth/authorize', {
924
787
  response_type: 'code',
925
788
  redirect_uri: redirectUri,
926
789
  scope,
@@ -947,7 +810,7 @@ export class Identity extends TinyEmitter {
947
810
  logoutUrl(redirectUri: string = this.redirectUri): string {
948
811
  assert(isUrl(redirectUri), `logoutUrl(): redirectUri is invalid`);
949
812
  const params = { redirect_uri: redirectUri };
950
- return this._sessionService.makeUrl('logout', params);
813
+ return this.sessionService.makeUrl('logout', params);
951
814
  }
952
815
 
953
816
  /**
@@ -955,18 +818,7 @@ export class Identity extends TinyEmitter {
955
818
  * @param redirectUri
956
819
  */
957
820
  accountUrl(redirectUri: string = this.redirectUri): string {
958
- return this._spid.makeUrl('profile-pages', {
959
- response_type: 'code',
960
- redirect_uri: redirectUri,
961
- });
962
- }
963
-
964
- /**
965
- * The phone editing page url
966
- * @param redirectUri
967
- */
968
- phonesUrl(redirectUri: string = this.redirectUri): string {
969
- return this._spid.makeUrl('profile-pages/about-you/phone', {
821
+ return this.spid.makeUrl('profile-pages', {
970
822
  response_type: 'code',
971
823
  redirect_uri: redirectUri,
972
824
  });
@@ -996,7 +848,7 @@ export class Identity extends TinyEmitter {
996
848
  if (options && options.encoding) {
997
849
  queryParams.encoding = options.encoding;
998
850
  }
999
- const widgetUrl = this._bffService.makeUrl('simplified-login-widget', queryParams, false);
851
+ const widgetUrl = this.bffService.makeUrl('simplified-login-widget', queryParams, false);
1000
852
 
1001
853
  const prepareLoginParams = async (
1002
854
  loginParams: SimplifiedLoginWidgetLoginOptions,
@@ -1056,11 +908,11 @@ export class Identity extends TinyEmitter {
1056
908
  * Emitted when the simplified login widget is displayed on the screen
1057
909
  * @event Identity#simplifiedLoginOpened
1058
910
  */
1059
- this.emit('simplifiedLoginOpened');
911
+ this.eventTarget.dispatchEvent(new Event('simplifiedLoginOpened'));
1060
912
  };
1061
913
 
1062
914
  const cancelLoginHandler = () => {
1063
- this.emit('simplifiedLoginCancelled');
915
+ this.eventTarget.dispatchEvent(new Event('simplifiedLoginCancelled'));
1064
916
  };
1065
917
 
1066
918
  if (hasOpenSimplifiedLoginWidget(window)) {
package/src/index.ts CHANGED
@@ -4,14 +4,14 @@
4
4
 
5
5
  export { Account } from './account.js';
6
6
  export { createAccountSdk, getAccountSdk } from './account-sdk.js';
7
+ export * from './globals.js';
7
8
  export { default as SDKError } from './sdk-error.js';
8
9
 
9
10
  /* public available types */
10
11
  export type {
11
12
  AccountConfig,
12
- AccountEventHandler,
13
+ AccountEventListener,
13
14
  AccountEventName,
14
- AccountSessionEventName,
15
15
  } from './types/account.js';
16
16
  export type { AccountEnvironment, LogFunction } from './types/common.js';
17
17
  export type {