@pega/auth 0.2.25 → 0.2.27

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.
@@ -1,17 +1,5 @@
1
1
  // This file wraps various calls related to logging in, logging out, etc.
2
2
  // that use the auth.html/auth.js to do the work of logging in via OAuth 2.0.
3
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
4
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
5
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
6
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
7
- };
8
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
9
- if (kind === "m") throw new TypeError("Private method is not writable");
10
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
11
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
12
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
13
- };
14
- var _AuthManager_instances, _AuthManager_ssKeyPrefix, _AuthManager_pegaAuth, _AuthManager_ssKeyConfigInfo, _AuthManager_ssKeySessionInfo, _AuthManager_ssKeyTokenInfo, _AuthManager_ssKeyState, _AuthManager_authConfig, _AuthManager_authDynState, _AuthManager_authHeader, _AuthManager_customTokenParamsCB, _AuthManager_bOAuthCustom, _AuthManager_tokenInfo, _AuthManager_userInfo, _AuthManager_usePASS, _AuthManager_beforeUnloadAdded, _AuthManager_tokenStorage, _AuthManager_transform, _AuthManager_foldSpot, _AuthManager_loadUserinfo, _AuthManager_loginProps, _AuthManager_promiseInitialize, _AuthManager_transformAndParse, _AuthManager_getStorage, _AuthManager_setStorage, _AuthManager_calcFoldSpot, _AuthManager_transformer, _AuthManager_doUnloadUpdates, _AuthManager_doBeforeUnload, _AuthManager_doPageHide, _AuthManager_loadState, _AuthManager_doOnLoad, _AuthManager_doAuthDynStateChanged, _AuthManager_initialize, _AuthManager_constellationInit, _AuthManager_customConstellationInit, _AuthManager_fireTokenAvailable, _AuthManager_processTokenOnLogin, _AuthManager_doCustomTokenParamsCB, _AuthManager_updateLoginStatus, _AuthManager_authFullReauth, _AuthManager_authTokenUpdated;
15
3
  // It utilizes a JS Class and private members to protect any sensitive tokens
16
4
  // and token obfuscation routines
17
5
  import { PegaAuth } from '../oauth-client/auth.js';
@@ -19,112 +7,158 @@ import { isEmptyObject } from './common-utils.js';
19
7
  import { getSdkConfig, SdkConfigAccess } from './config_access.js';
20
8
  // Meant to be a singleton...only one instance per page
21
9
  class AuthManager {
10
+ #ssKeyPrefix = 'rs';
11
+ iOSDevice = false;
12
+ // will store the PegaAuth (OAuth 2.0 client library) instance
13
+ #pegaAuth = null;
14
+ #ssKeyConfigInfo = '';
15
+ #ssKeySessionInfo = '';
16
+ #ssKeyTokenInfo = '';
17
+ #ssKeyState = `${this.#ssKeyPrefix}State`;
18
+ #authConfig = {};
19
+ #authDynState = {};
20
+ #authHeader = null;
21
+ #customTokenParamsCB = null;
22
+ // state that should be persisted across loads
23
+ state = { usePopup: false, noInitialRedirect: false, locale: null };
24
+ // # of properties within initial state object
25
+ stateKeysCount = 3;
26
+ bC11NBootstrapInProgress = false;
27
+ bC11NBootstrapComplete = false;
28
+ bCustomAuth = false;
29
+ #bOAuthCustom = false;
30
+ #tokenInfo;
31
+ #userInfo;
32
+ onLoadDone = false;
33
+ msReauthStart = null;
34
+ initInProgress = false;
35
+ isLoggedIn = false;
36
+ // Whether to pass a session storage key or structure to auth library
37
+ #usePASS = false;
38
+ #beforeUnloadAdded = false;
39
+ #tokenStorage = 'temp';
40
+ #transform = true;
41
+ #foldSpot = 2;
42
+ // Whether to load and cache user info as part of login
43
+ #loadUserinfo = false;
44
+ // Keep loginProps passed to loginIfNecessary
45
+ #loginProps = null;
46
+ // Promise for Initialization of PegaAuth and resolution callback
47
+ #promiseInitialize = null;
22
48
  constructor() {
23
- _AuthManager_instances.add(this);
24
- _AuthManager_ssKeyPrefix.set(this, 'rs');
25
- Object.defineProperty(this, "iOSDevice", {
26
- enumerable: true,
27
- configurable: true,
28
- writable: true,
29
- value: false
30
- });
31
- // will store the PegaAuth (OAuth 2.0 client library) instance
32
- _AuthManager_pegaAuth.set(this, null);
33
- _AuthManager_ssKeyConfigInfo.set(this, '');
34
- _AuthManager_ssKeySessionInfo.set(this, '');
35
- _AuthManager_ssKeyTokenInfo.set(this, '');
36
- _AuthManager_ssKeyState.set(this, `${__classPrivateFieldGet(this, _AuthManager_ssKeyPrefix, "f")}State`);
37
- _AuthManager_authConfig.set(this, {});
38
- _AuthManager_authDynState.set(this, {});
39
- _AuthManager_authHeader.set(this, null);
40
- _AuthManager_customTokenParamsCB.set(this, null);
41
- // state that should be persisted across loads
42
- Object.defineProperty(this, "state", {
43
- enumerable: true,
44
- configurable: true,
45
- writable: true,
46
- value: { usePopup: false, noInitialRedirect: false, locale: null }
47
- });
48
- // # of properties within initial state object
49
- Object.defineProperty(this, "stateKeysCount", {
50
- enumerable: true,
51
- configurable: true,
52
- writable: true,
53
- value: 3
54
- });
55
- Object.defineProperty(this, "bC11NBootstrapInProgress", {
56
- enumerable: true,
57
- configurable: true,
58
- writable: true,
59
- value: false
60
- });
61
- Object.defineProperty(this, "bCustomAuth", {
62
- enumerable: true,
63
- configurable: true,
64
- writable: true,
65
- value: false
66
- });
67
- _AuthManager_bOAuthCustom.set(this, false);
68
- _AuthManager_tokenInfo.set(this, void 0);
69
- _AuthManager_userInfo.set(this, void 0);
70
- Object.defineProperty(this, "onLoadDone", {
71
- enumerable: true,
72
- configurable: true,
73
- writable: true,
74
- value: false
75
- });
76
- Object.defineProperty(this, "msReauthStart", {
77
- enumerable: true,
78
- configurable: true,
79
- writable: true,
80
- value: null
81
- });
82
- Object.defineProperty(this, "initInProgress", {
83
- enumerable: true,
84
- configurable: true,
85
- writable: true,
86
- value: false
87
- });
88
- Object.defineProperty(this, "isLoggedIn", {
89
- enumerable: true,
90
- configurable: true,
91
- writable: true,
92
- value: false
93
- });
94
- // Whether to pass a session storage key or structure to auth library
95
- _AuthManager_usePASS.set(this, false);
96
- _AuthManager_beforeUnloadAdded.set(this, false);
97
- _AuthManager_tokenStorage.set(this, 'temp');
98
- _AuthManager_transform.set(this, true);
99
- _AuthManager_foldSpot.set(this, 2);
100
- // Whether to load and cache user info as part of login
101
- _AuthManager_loadUserinfo.set(this, false);
102
- // Keep loginProps passed to loginIfNecessary
103
- _AuthManager_loginProps.set(this, null);
104
- // Promise for Initialization of PegaAuth and resolution callback
105
- _AuthManager_promiseInitialize.set(this, null);
106
49
  // Auth Manager specific state is saved within session storage as important in redirect and popup window scenarios
107
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_loadState).call(this);
50
+ this.#loadState();
108
51
  this.iOSDevice = /iPad|iPhone|iPod/.test(navigator.userAgent);
109
52
  }
53
+ #transformAndParse(ssKey, ssItem, bForce = false) {
54
+ let obj = {};
55
+ try {
56
+ obj = JSON.parse(this.#transformer(ssKey, ssItem, false, bForce));
57
+ }
58
+ catch (e) {
59
+ // fall thru and return empty object
60
+ }
61
+ return obj;
62
+ }
63
+ // helper routine to retrieve JSON object stored in a session storage key
64
+ // a 2nd optional arg can also retrieve an individual attribute
65
+ #getStorage(ssKey, sAttrib = null) {
66
+ let ssItem = ssKey ? window.sessionStorage.getItem(ssKey) : null;
67
+ let obj = {};
68
+ if (this.#loginProps?.altStateStorage &&
69
+ !this.isLoggedIn &&
70
+ !ssItem &&
71
+ (ssKey === this.#ssKeyState || ssKey === this.#ssKeySessionInfo)) {
72
+ ssItem = window.localStorage.getItem(ssKey);
73
+ }
74
+ if (ssItem) {
75
+ try {
76
+ obj = JSON.parse(ssItem);
77
+ }
78
+ catch (e) {
79
+ obj = this.#transformAndParse(ssKey, ssItem, true);
80
+ }
81
+ }
82
+ return sAttrib ? obj[sAttrib] : obj;
83
+ }
84
+ // helper routine to set storage to the passed in JSON
85
+ #setStorage(ssKey, obj, bVerify = false) {
86
+ try {
87
+ // Set storage only if obj is not empty, else delete the storage
88
+ if (!obj || isEmptyObject(obj)) {
89
+ window.sessionStorage.removeItem(ssKey);
90
+ }
91
+ else {
92
+ // const bClear = (ssKey === this.#ssKeyState || ssKey === this.#ssKeySessionInfo);
93
+ const bClear = false;
94
+ const sValue = bClear
95
+ ? JSON.stringify(obj)
96
+ : this.#transformer(ssKey, JSON.stringify(obj), true);
97
+ window.sessionStorage.setItem(ssKey, sValue);
98
+ if (bVerify) {
99
+ const sStored = window.sessionStorage.getItem(ssKey);
100
+ if (sStored !== sValue) {
101
+ // eslint-disable-next-line no-console
102
+ console.error(`Failed to properly write sessionStorage (${ssKey})`);
103
+ }
104
+ }
105
+ if (this.#loginProps?.altStateStorage &&
106
+ !this.isLoggedIn &&
107
+ (ssKey === this.#ssKeyState || ssKey === this.#ssKeySessionInfo)) {
108
+ window.localStorage.setItem(ssKey, sValue);
109
+ }
110
+ }
111
+ }
112
+ catch (e) {
113
+ // eslint-disable-next-line no-console
114
+ console.error(`Exception ${e} on attempted write of sessionStorage (${ssKey})`);
115
+ }
116
+ }
117
+ #calcFoldSpot(s) {
118
+ const nOffset = 1;
119
+ const sChar = s.length > nOffset ? s.charAt(nOffset) : '2';
120
+ const nSpot = parseInt(sChar, 10);
121
+ this.#foldSpot = Number.isNaN(nSpot) ? 2 : (nSpot % 4) + 2;
122
+ }
123
+ // helper function to encode storage
124
+ #transformer(ssKey, s, bIn, bForce = false) {
125
+ const bTransform = bForce || this.#transform;
126
+ const fnFold = (x) => {
127
+ const nLen = x.length;
128
+ const nExtra = nLen % this.#foldSpot;
129
+ const nOffset = Math.floor(nLen / this.#foldSpot) + nExtra;
130
+ const nRem = x.length - nOffset;
131
+ return x.substring(bIn ? nOffset : nRem) + x.substring(0, bIn ? nOffset : nRem);
132
+ };
133
+ const bTknInfo = ssKey === this.#ssKeyTokenInfo;
134
+ if (bTknInfo && !bIn && bTransform) {
135
+ s = window.atob(fnFold(s));
136
+ }
137
+ // eslint-disable-next-line no-nested-ternary
138
+ let result = bTransform ? (bIn ? window.btoa(s) : window.atob(s)) : s;
139
+ if (bTknInfo && bIn && bTransform) {
140
+ result = fnFold(window.btoa(result));
141
+ }
142
+ return result;
143
+ }
110
144
  // Setter for authHeader (no getter)
111
145
  set authHeader(value) {
112
- __classPrivateFieldSet(this, _AuthManager_authHeader, value, "f");
146
+ this.#authHeader = value;
113
147
  // setAuthorizationHeader method not available til 8.8 so do safety check
114
148
  if (window.PCore?.getAuthUtils().setAuthorizationHeader) {
115
149
  const authHdr = value === null ? '' : value;
116
150
  window.PCore.getAuthUtils().setAuthorizationHeader(authHdr);
117
151
  }
118
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_updateLoginStatus).call(this);
152
+ this.#updateLoginStatus();
119
153
  }
120
154
  // Setter for customTokenParamsCB
121
155
  set customTokenParamsCB(fn) {
122
- __classPrivateFieldSet(this, _AuthManager_customTokenParamsCB, fn, "f");
156
+ this.#customTokenParamsCB = fn;
123
157
  }
124
158
  // Setter/getter for appName
125
159
  set appName(appName) {
126
160
  this.state.appName = appName;
127
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyState, "f"), this.state);
161
+ this.#setStorage(this.#ssKeyState, this.state);
128
162
  }
129
163
  get appName() {
130
164
  return this.state.appName;
@@ -132,7 +166,7 @@ class AuthManager {
132
166
  // Setter/getter for usePopupForRestOfSession
133
167
  set usePopupForRestOfSession(usePopup) {
134
168
  this.state.usePopup = usePopup;
135
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyState, "f"), this.state);
169
+ this.#setStorage(this.#ssKeyState, this.state);
136
170
  }
137
171
  get usePopupForRestOfSession() {
138
172
  return this.state.usePopup;
@@ -143,7 +177,7 @@ class AuthManager {
143
177
  this.usePopupForRestOfSession = true;
144
178
  }
145
179
  this.state.noInitialRedirect = bNoInitialRedirect;
146
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyState, "f"), this.state);
180
+ this.#setStorage(this.#ssKeyState, this.state);
147
181
  }
148
182
  get noInitialRedirect() {
149
183
  return this.state.noInitialRedirect || false;
@@ -151,7 +185,7 @@ class AuthManager {
151
185
  // Setter/getter for locale (override)
152
186
  set locale(localeOverride) {
153
187
  this.state.locale = localeOverride;
154
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyState, "f"), this.state);
188
+ this.#setStorage(this.#ssKeyState, this.state);
155
189
  }
156
190
  get locale() {
157
191
  return this.state.locale;
@@ -164,7 +198,7 @@ class AuthManager {
164
198
  else if (this.msReauthStart) {
165
199
  delete this.msReauthStart;
166
200
  }
167
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyState, "f"), this.state);
201
+ this.#setStorage(this.#ssKeyState, this.state);
168
202
  }
169
203
  get reauthStart() {
170
204
  return this.msReauthStart || 0;
@@ -173,22 +207,22 @@ class AuthManager {
173
207
  set keySuffix(s) {
174
208
  this.state.sfx = s || undefined;
175
209
  if (s) {
176
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyState, "f"), this.state);
210
+ this.#setStorage(this.#ssKeyState, this.state);
177
211
  // To make it a bit more obtuse reverse the string and use that as the actual suffix
178
212
  const sSfx = s.split('').reverse().join('');
179
- __classPrivateFieldSet(this, _AuthManager_ssKeyConfigInfo, `${__classPrivateFieldGet(this, _AuthManager_ssKeyPrefix, "f")}CI_${sSfx}`, "f");
180
- __classPrivateFieldSet(this, _AuthManager_ssKeySessionInfo, `${__classPrivateFieldGet(this, _AuthManager_ssKeyPrefix, "f")}SI_${sSfx}`, "f");
181
- __classPrivateFieldSet(this, _AuthManager_ssKeyTokenInfo, `${__classPrivateFieldGet(this, _AuthManager_ssKeyPrefix, "f")}TI_${sSfx}`, "f");
182
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_calcFoldSpot).call(this, sSfx);
213
+ this.#ssKeyConfigInfo = `${this.#ssKeyPrefix}CI_${sSfx}`;
214
+ this.#ssKeySessionInfo = `${this.#ssKeyPrefix}SI_${sSfx}`;
215
+ this.#ssKeyTokenInfo = `${this.#ssKeyPrefix}TI_${sSfx}`;
216
+ this.#calcFoldSpot(sSfx);
183
217
  }
184
218
  else {
185
- sessionStorage.removeItem(__classPrivateFieldGet(this, _AuthManager_ssKeyTokenInfo, "f"));
186
- sessionStorage.removeItem(__classPrivateFieldGet(this, _AuthManager_ssKeyConfigInfo, "f"));
187
- sessionStorage.removeItem(__classPrivateFieldGet(this, _AuthManager_ssKeySessionInfo, "f"));
188
- sessionStorage.removeItem(__classPrivateFieldGet(this, _AuthManager_ssKeyState, "f"));
189
- __classPrivateFieldSet(this, _AuthManager_ssKeyConfigInfo, '', "f");
190
- __classPrivateFieldSet(this, _AuthManager_ssKeySessionInfo, '', "f");
191
- __classPrivateFieldSet(this, _AuthManager_ssKeyTokenInfo, '', "f");
219
+ sessionStorage.removeItem(this.#ssKeyTokenInfo);
220
+ sessionStorage.removeItem(this.#ssKeyConfigInfo);
221
+ sessionStorage.removeItem(this.#ssKeySessionInfo);
222
+ sessionStorage.removeItem(this.#ssKeyState);
223
+ this.#ssKeyConfigInfo = '';
224
+ this.#ssKeySessionInfo = '';
225
+ this.#ssKeyTokenInfo = '';
192
226
  }
193
227
  }
194
228
  /**
@@ -196,25 +230,444 @@ class AuthManager {
196
230
  */
197
231
  clear(bFullReauth = false) {
198
232
  if (!this.bCustomAuth) {
199
- __classPrivateFieldSet(this, _AuthManager_authHeader, null, "f");
233
+ this.#authHeader = null;
200
234
  }
201
235
  // Clear any established auth tokens
202
- __classPrivateFieldSet(this, _AuthManager_tokenInfo, null, "f");
203
- sessionStorage.removeItem(__classPrivateFieldGet(this, _AuthManager_ssKeyTokenInfo, "f"));
236
+ this.#tokenInfo = null;
237
+ sessionStorage.removeItem(this.#ssKeyTokenInfo);
204
238
  this.isLoggedIn = false;
205
239
  // reset the initial redirect as well by using this setter
206
240
  this.usePopupForRestOfSession = bFullReauth;
207
241
  if (!bFullReauth) {
208
- if (!__classPrivateFieldGet(this, _AuthManager_usePASS, "f")) {
209
- __classPrivateFieldSet(this, _AuthManager_authConfig, {}, "f");
210
- __classPrivateFieldSet(this, _AuthManager_authDynState, {}, "f");
242
+ if (!this.#usePASS) {
243
+ this.#authConfig = {};
244
+ this.#authDynState = {};
211
245
  }
212
246
  // keySuffix setter has cleanup logic
213
247
  this.keySuffix = '';
214
248
  }
215
249
  }
250
+ // Found beforeunload to not work well on iOS browsers, and pagehide to work better
251
+ // However also seeing some scenario like navigating to a different page on Chrome & Firefox only invoking beforeunload
252
+ // Chrome, Firefox, Safari browsers sequence on page reload: beforeunload, pagehide, visibilitychange
253
+ // visibilitychange is fired whenever a tab is made visible and when it is hidden
254
+ #doUnloadUpdates() {
255
+ // Safari and particularly Safari on mobile devices doesn't seem to load this on first main redirect or
256
+ // reliably, so have moved to having PegaAuth manage writing all state props to session storage
257
+ this.#setStorage(this.#ssKeyState, this.state);
258
+ this.#setStorage(this.#ssKeySessionInfo, this.#authDynState);
259
+ // If tokenStorage was always, token would already be there
260
+ if (this.#tokenStorage === 'temp') {
261
+ this.#setStorage(this.#ssKeyTokenInfo, this.#tokenInfo);
262
+ }
263
+ }
264
+ #doBeforeUnload() {
265
+ this.#doUnloadUpdates();
266
+ }
267
+ #doPageHide() {
268
+ this.#doUnloadUpdates();
269
+ }
270
+ #loadState() {
271
+ // Note: State storage key doesn't have a client id associated with it
272
+ const oState = this.#getStorage(this.#ssKeyState);
273
+ if (oState) {
274
+ Object.assign(this.state, oState);
275
+ if (this.state.sfx) {
276
+ // Setter sets up the ssKey values as well
277
+ this.keySuffix = this.state.sfx;
278
+ }
279
+ }
280
+ }
281
+ // This is only called from initialize after #ssKey values are setup
282
+ #doOnLoad() {
283
+ if (!this.onLoadDone) {
284
+ // This authConfig state doesn't collide with other calculated static state...so load it first
285
+ // Note: transform setting will have already been loaded into #authConfig at this point
286
+ this.#authDynState = this.#getStorage(this.#ssKeySessionInfo);
287
+ this.#tokenInfo = this.#getStorage(this.#ssKeyTokenInfo);
288
+ if (this.#tokenStorage !== 'always') {
289
+ sessionStorage.removeItem(this.#ssKeyTokenInfo);
290
+ // Finding on iOS browsers the pageHide event is sometimes not happening causing failed redirects.
291
+ if (!this.iOSDevice) {
292
+ sessionStorage.removeItem(this.#ssKeySessionInfo);
293
+ }
294
+ }
295
+ this.onLoadDone = true;
296
+ }
297
+ }
298
+ // Callback when auth dynamic state has changed. Decide whether to persisting it based on
299
+ // config settings
300
+ #doAuthDynStateChanged() {
301
+ // If tokenStorage is setup for always then always persist the auth dynamic state as well
302
+ if (this.#tokenStorage === 'always' || this.iOSDevice) {
303
+ this.#setStorage(this.#ssKeySessionInfo, this.#authDynState);
304
+ }
305
+ }
306
+ /**
307
+ * Initialize OAuth config structure members and create authMgr instance (if necessary)
308
+ * bNew - governs whether to create new sessionStorage or load existing one
309
+ */
310
+ async #initialize(bNew = false) {
311
+ if (!bNew && this.#promiseInitialize) {
312
+ return this.#promiseInitialize;
313
+ }
314
+ this.#promiseInitialize = new Promise(resolve => {
315
+ /* if (!this.initInProgress && (bNew || isEmptyObject(this.#authConfig) || !this.#pegaAuth)) { */
316
+ this.initInProgress = true;
317
+ getSdkConfig().then(sdkConfig => {
318
+ const sdkConfigAuth = sdkConfig.authConfig;
319
+ const sdkConfigServer = sdkConfig.serverConfig;
320
+ const serverType = sdkConfigServer.serverType || 'infinity';
321
+ const bInfinity = serverType === 'infinity';
322
+ let pegaUrl = bInfinity
323
+ ? sdkConfigServer.infinityRestServerUrl
324
+ : sdkConfigServer.launchpadRestServerUrl;
325
+ // Expecting boolean true/false or undefined
326
+ const secureCookie = !!sdkConfigAuth.secureCookie;
327
+ const bNoInitialRedirect = this.noInitialRedirect;
328
+ const appAliasSeg = sdkConfigServer.appAlias ? `app/${sdkConfigServer.appAlias}/` : '';
329
+ // Construct default OAuth endpoints (if not explicitly specified)
330
+ if (pegaUrl) {
331
+ // Cope with trailing slash being present
332
+ if (!pegaUrl.endsWith('/')) {
333
+ pegaUrl += '/';
334
+ }
335
+ if (!sdkConfigAuth.authorize) {
336
+ sdkConfigAuth.authorize = bInfinity
337
+ ? `${pegaUrl}PRRestService/oauth2/v1/authorize`
338
+ : `${pegaUrl}uas/oauth/authorize`;
339
+ }
340
+ const infinityOAuth2Url = bInfinity
341
+ ? pegaUrl + (secureCookie && appAliasSeg ? `${appAliasSeg}api/` : 'PRRestService/')
342
+ : '';
343
+ if (!sdkConfigAuth.token) {
344
+ sdkConfigAuth.token = bInfinity
345
+ ? `${infinityOAuth2Url}oauth2/v1/token`
346
+ : `${pegaUrl}uas/oauth/token`;
347
+ }
348
+ if (!sdkConfigAuth.revoke) {
349
+ // Launchpad still does not have a revoke endpoint
350
+ sdkConfigAuth.revoke = bInfinity ? `${infinityOAuth2Url}oauth2/v1/revoke` : '';
351
+ }
352
+ if (!sdkConfigAuth.redirectUri) {
353
+ sdkConfigAuth.redirectUri = `${window.location.origin}${window.location.pathname}`;
354
+ }
355
+ if (!sdkConfigAuth.userinfo) {
356
+ sdkConfigAuth.userinfo = bInfinity
357
+ ? `${pegaUrl}${appAliasSeg}api/oauthclients/v1/userinfo/JSON`
358
+ : '';
359
+ }
360
+ }
361
+ // Auth service alias
362
+ if (!sdkConfigAuth.authService) {
363
+ sdkConfigAuth.authService = 'pega';
364
+ }
365
+ // mashupAuthService provides way to have a different auth service for embedded
366
+ if (!sdkConfigAuth.mashupAuthService) {
367
+ sdkConfigAuth.mashupAuthService = sdkConfigAuth.authService;
368
+ }
369
+ // Construct path to auth.html (used for case when not doing a main window redirect)
370
+ let sNoMainRedirectUri = sdkConfigAuth.redirectUri;
371
+ const nLastPathSep = sNoMainRedirectUri.lastIndexOf('/');
372
+ sNoMainRedirectUri =
373
+ nLastPathSep !== -1
374
+ ? `${sNoMainRedirectUri.substring(0, nLastPathSep + 1)}auth.html`
375
+ : `${sNoMainRedirectUri}/auth.html`;
376
+ const portalGrantType = sdkConfigAuth.portalGrantType || 'authCode';
377
+ const mashupGrantType = sdkConfigAuth.mashupGrantType || 'authCode';
378
+ // Some grant types are only available with confidential registrations and require a client secret
379
+ const clientSecret = bNoInitialRedirect
380
+ ? sdkConfigAuth.mashupClientSecret
381
+ : sdkConfigAuth.portalClientSecret;
382
+ const pegaAuthConfig = {
383
+ serverType,
384
+ clientId: bNoInitialRedirect
385
+ ? sdkConfigAuth.mashupClientId
386
+ : sdkConfigAuth.portalClientId,
387
+ grantType: bNoInitialRedirect ? mashupGrantType : portalGrantType,
388
+ tokenUri: sdkConfigAuth.token,
389
+ revokeUri: sdkConfigAuth.revoke,
390
+ userinfoUri: sdkConfigAuth.userinfo,
391
+ authService: bNoInitialRedirect
392
+ ? sdkConfigAuth.mashupAuthService
393
+ : sdkConfigAuth.authService,
394
+ appAlias: sdkConfigServer.appAlias || '',
395
+ useLocking: true
396
+ };
397
+ if (clientSecret) {
398
+ pegaAuthConfig.clientSecret = clientSecret;
399
+ }
400
+ if (serverType === 'launchpad' && pegaAuthConfig.grantType === 'authCode') {
401
+ pegaAuthConfig.noPKCE = true;
402
+ }
403
+ // Invoke keySuffix setter
404
+ // Was using pegaAuthConfig.clientId as key but more secure to just use a random string as getting
405
+ // both a clientId and the refresh token could yield a new access token.
406
+ // Suffix is so we might in future move to an array of suffixes based on the appName, so might store
407
+ // both portal and embedded tokens/session info at same time
408
+ if (!this.state?.sfx) {
409
+ // Just using a random number to make the suffix unique on each session
410
+ this.keySuffix = `${Math.ceil(Math.random() * 100000000)}`;
411
+ }
412
+ this.#authConfig.transform =
413
+ sdkConfigAuth.transform !== undefined ? sdkConfigAuth.transform : this.#transform;
414
+ // Using property in class as authConfig may be empty at times
415
+ this.#transform = this.#authConfig.transform;
416
+ if (sdkConfigAuth.tokenStorage !== undefined) {
417
+ this.#tokenStorage = sdkConfigAuth.tokenStorage;
418
+ }
419
+ if (sdkConfigAuth.secureCookie) {
420
+ this.#authConfig.secureCookie = true;
421
+ }
422
+ // Get latest state once client ids, transform and tokenStorage have been established
423
+ this.#doOnLoad();
424
+ // If no clientId is specified assume not OAuth but custom auth
425
+ if (pegaAuthConfig.grantType === 'none' || !pegaAuthConfig.clientId) {
426
+ this.bCustomAuth = true;
427
+ return;
428
+ }
429
+ // For some OAuth grant type scenarios we opt to pass the Orchestration Engine just an authHeader as
430
+ // service broker doesn't have proper support for dealing with refreshing or revoking these:
431
+ // * customBearer (except when secureCookie being used)
432
+ // * confidential grant types (ones with clientSecret)
433
+ // (With 25.1 orchestration engine does support this if client_secret is specified on bootstrap)
434
+ this.#bOAuthCustom =
435
+ (pegaAuthConfig.grantType === 'customBearer' && !secureCookie) || clientSecret;
436
+ if (pegaAuthConfig.grantType === 'authCode') {
437
+ const authCodeProps = {
438
+ authorizeUri: sdkConfigAuth.authorize,
439
+ // If we have already specified a redirect on the authorize redirect, we need to continue to use that
440
+ // on token endpoint
441
+ redirectUri: bNoInitialRedirect || this.usePopupForRestOfSession
442
+ ? sNoMainRedirectUri
443
+ : sdkConfigAuth.redirectUri
444
+ };
445
+ if ('silentTimeout' in sdkConfigAuth) {
446
+ authCodeProps.silentTimeout = sdkConfigAuth.silentTimeout;
447
+ }
448
+ if (bNoInitialRedirect &&
449
+ pegaAuthConfig.authService === 'pega' &&
450
+ sdkConfigAuth.mashupUserIdentifier &&
451
+ sdkConfigAuth.mashupPassword) {
452
+ authCodeProps.userIdentifier = sdkConfigAuth.mashupUserIdentifier;
453
+ authCodeProps.password = sdkConfigAuth.mashupPassword;
454
+ }
455
+ if ('iframeLoginUI' in sdkConfigAuth) {
456
+ authCodeProps.iframeLoginUI =
457
+ sdkConfigAuth.iframeLoginUI.toString().toLowerCase() === 'true';
458
+ }
459
+ Object.assign(pegaAuthConfig, authCodeProps);
460
+ }
461
+ else if (pegaAuthConfig.grantType === 'passwordCreds') {
462
+ pegaAuthConfig.userIdentifier = sdkConfigAuth.mashupUserIdentifier;
463
+ pegaAuthConfig.password = sdkConfigAuth.mashupPassword;
464
+ }
465
+ Object.assign(this.#authConfig, pegaAuthConfig);
466
+ // Add beforeunload and page hide handlers to write out key properties that we want to survive a
467
+ // browser reload
468
+ if (!this.#beforeUnloadAdded && (!this.#usePASS || this.#tokenStorage !== 'always')) {
469
+ window.addEventListener('beforeunload', this.#doBeforeUnload.bind(this));
470
+ window.addEventListener('pagehide', this.#doPageHide.bind(this));
471
+ this.#beforeUnloadAdded = true;
472
+ }
473
+ // Initialize PegaAuth OAuth 2.0 client library
474
+ if (this.#usePASS) {
475
+ this.#setStorage(this.#ssKeyConfigInfo, this.#authConfig);
476
+ this.#setStorage(this.#ssKeySessionInfo, this.#authDynState);
477
+ this.#pegaAuth = new PegaAuth(this.#ssKeyConfigInfo, this.#ssKeySessionInfo);
478
+ }
479
+ else {
480
+ this.#authConfig.fnDynStateChangedCB = this.#doAuthDynStateChanged.bind(this);
481
+ this.#pegaAuth = new PegaAuth(this.#authConfig, this.#authDynState);
482
+ }
483
+ this.initInProgress = false;
484
+ resolve(this.#pegaAuth);
485
+ });
486
+ });
487
+ return this.#promiseInitialize;
488
+ }
489
+ /**
490
+ * Initiate the process to get the Constellation bootstrap shell loaded and initialized
491
+ * @param {Object} tokenInfo
492
+ * @param {Function} authTokenUpdated - callback invoked when Constellation JS Engine silently updates
493
+ * an expired access_token
494
+ * @param {Function} fnReauth - callback invoked when a full or custom reauth is needed
495
+ */
496
+ #constellationInit(tokenInfo, authTokenUpdated, fnReauth) {
497
+ const constellationBootConfig = {};
498
+ const sdkConfigServer = SdkConfigAccess.getSdkConfigServer();
499
+ const sdkConfigAuth = SdkConfigAccess.getSdkConfigAuth();
500
+ const authConfig = this.#authConfig;
501
+ // Set up constellationConfig with data that bootstrapWithAuthHeader expects
502
+ constellationBootConfig.customRendering = true;
503
+ constellationBootConfig.restServerUrl = sdkConfigServer.infinityRestServerUrl;
504
+ // NOTE: Needs a trailing slash! So add one if not provided
505
+ if (!sdkConfigServer.sdkContentServerUrl.endsWith('/')) {
506
+ sdkConfigServer.sdkContentServerUrl = `${sdkConfigServer.sdkContentServerUrl}/`;
507
+ }
508
+ constellationBootConfig.staticContentServerUrl = `${sdkConfigServer.sdkContentServerUrl}constellation/`;
509
+ if (!constellationBootConfig.staticContentServerUrl.endsWith('/')) {
510
+ constellationBootConfig.staticContentServerUrl = `${constellationBootConfig.staticContentServerUrl}/`;
511
+ }
512
+ // If appAlias specified, use it
513
+ if (sdkConfigServer.appAlias) {
514
+ constellationBootConfig.appAlias = sdkConfigServer.appAlias;
515
+ }
516
+ // Determine whether to send credentials with DX API transactions
517
+ if (sdkConfigAuth.customCookies) {
518
+ constellationBootConfig.customCookies = true;
519
+ }
520
+ if (this.#bOAuthCustom || !tokenInfo) {
521
+ if (tokenInfo) {
522
+ this.#authHeader = `${tokenInfo.token_type} ${tokenInfo.access_token}`;
523
+ }
524
+ if (this.#authHeader) {
525
+ constellationBootConfig.authorizationHeader = this.#authHeader;
526
+ }
527
+ }
528
+ else {
529
+ // Pass in auth info to Constellation
530
+ constellationBootConfig.authInfo = {
531
+ authType: 'OAuth2.0',
532
+ tokenInfo,
533
+ // Set whether we want constellation to try to do a full re-Auth or not ()
534
+ // true doesn't seem to be working in SDK scenario so always passing false for now
535
+ popupReauth: false /* !this.noInitialRedirect */,
536
+ client_id: authConfig.clientId,
537
+ client_secret: authConfig.clientSecret,
538
+ authentication_service: authConfig.authService,
539
+ redirect_uri: authConfig.redirectUri,
540
+ endPoints: {
541
+ authorize: authConfig.authorizeUri,
542
+ token: authConfig.tokenUri,
543
+ revoke: authConfig.revokeUri
544
+ },
545
+ secureCookie: authConfig.secureCookie,
546
+ onTokenRetrieval: authTokenUpdated
547
+ };
548
+ }
549
+ // Turn off dynamic load components (should be able to do it here instead of after load?)
550
+ constellationBootConfig.dynamicLoadComponents = false;
551
+ // Set envType if appropriate
552
+ if (authConfig.serverType === 'launchpad') {
553
+ constellationBootConfig.envType = 'LAUNCHPAD';
554
+ }
555
+ // Set locale override if specified
556
+ const localeOverride = this.locale;
557
+ if (localeOverride) {
558
+ constellationBootConfig.locale = localeOverride;
559
+ }
560
+ // Set additional headers if specified
561
+ const additionalHeaders = this.#loginProps.additionalHeaders;
562
+ if (additionalHeaders) {
563
+ constellationBootConfig.additionalHeaders = additionalHeaders;
564
+ }
565
+ if (this.bC11NBootstrapInProgress) {
566
+ return;
567
+ }
568
+ this.bC11NBootstrapInProgress = true;
569
+ // Note that staticContentServerUrl already ends with a slash (see above), so no slash added.
570
+ // In order to have this import succeed needed to use the webpackIgnore magic comment tag.
571
+ // See: https://webpack.js.org/api/module-methods/
572
+ import(
573
+ /* webpackIgnore: true */ `${constellationBootConfig.staticContentServerUrl}bootstrap-shell.js?v=${Date.now()}`).then(bootstrapShell => {
574
+ // NOTE: once this callback is done, we lose the ability to access loadMashup.
575
+ // So, create a reference to it
576
+ window.myLoadMashup = bootstrapShell.loadMashup;
577
+ window.myLoadPortal = bootstrapShell.loadPortal;
578
+ window.myLoadDefaultPortal = bootstrapShell.loadDefaultPortal;
579
+ bootstrapShell
580
+ .bootstrapWithAuthHeader(constellationBootConfig, 'pega-root')
581
+ .then(() => {
582
+ // eslint-disable-next-line no-console
583
+ console.log('ConstellationJS bootstrap successful!');
584
+ this.bC11NBootstrapInProgress = false;
585
+ this.bC11NBootstrapComplete = true;
586
+ // Setup listener for the reauth event
587
+ if (!this.#bOAuthCustom && tokenInfo) {
588
+ PCore.getPubSubUtils().subscribe(PCore.getConstants().PUB_SUB_EVENTS.EVENT_FULL_REAUTH, fnReauth, 'authFullReauth');
589
+ }
590
+ else {
591
+ // customReauth event introduced with 8.8
592
+ const sEvent = PCore.getConstants().PUB_SUB_EVENTS.EVENT_CUSTOM_REAUTH;
593
+ if (sEvent) {
594
+ PCore.getPubSubUtils().subscribe(sEvent, fnReauth, 'doReauth');
595
+ }
596
+ }
597
+ // Fire SdkConstellationReady event so bridge and app route can do expected post PCore initializations
598
+ const event = new CustomEvent('SdkConstellationReady', {});
599
+ document.dispatchEvent(event);
600
+ })
601
+ .catch(e => {
602
+ // Assume error caught is because token is not valid and attempt a full reauth
603
+ // eslint-disable-next-line no-console
604
+ console.error(`ConstellationJS bootstrap failed. ${e}`);
605
+ this.bC11NBootstrapInProgress = false;
606
+ fnReauth();
607
+ });
608
+ });
609
+ /* Ends here */
610
+ }
611
+ #customConstellationInit(fnReauth) {
612
+ this.#constellationInit(null, null, fnReauth);
613
+ }
614
+ #fireTokenAvailable(token, bLoadC11N = true) {
615
+ if (!token) {
616
+ // This is used on page reload to load the token from sessionStorage and carry on
617
+ token = this.#tokenInfo;
618
+ if (!token) {
619
+ return;
620
+ }
621
+ }
622
+ this.#tokenInfo = token;
623
+ if (this.#tokenStorage === 'always') {
624
+ this.#setStorage(this.#ssKeyTokenInfo, this.#tokenInfo);
625
+ }
626
+ this.#updateLoginStatus();
627
+ // this.isLoggedIn is getting updated in updateLoginStatus
628
+ this.isLoggedIn = true;
629
+ this.usePopupForRestOfSession = true;
630
+ if (!window.PCore && bLoadC11N) {
631
+ this.#constellationInit(token, this.#authTokenUpdated.bind(this), this.#authRefreshOrFullReauth.bind(this));
632
+ }
633
+ /*
634
+ // Create and dispatch the SdkLoggedIn event to trigger constellationInit
635
+ const event = new CustomEvent('SdkLoggedIn', { detail: { authConfig, tokenInfo: token } });
636
+ document.dispatchEvent(event);
637
+ */
638
+ }
639
+ #processTokenOnLogin(token, bLoadC11N = true) {
640
+ this.#tokenInfo = token;
641
+ if (this.#tokenStorage === 'always') {
642
+ this.#setStorage(this.#ssKeyTokenInfo, this.#tokenInfo);
643
+ }
644
+ if (this.#bOAuthCustom) {
645
+ // authHeader setter will also set #authHeader and invoke getAuthUtils().setAuthorizationHeader
646
+ this.authHeader = `${token.token_type} ${token.access_token}`;
647
+ }
648
+ if (window.PCore && !this.#authHeader) {
649
+ PCore.getAuthUtils().setTokens(token);
650
+ }
651
+ else {
652
+ this.#fireTokenAvailable(token, bLoadC11N);
653
+ }
654
+ }
655
+ #doCustomTokenParamsCB() {
656
+ if (this.#authConfig.grantType === 'customBearer' && this.#customTokenParamsCB) {
657
+ try {
658
+ const customTokenParams = this.#customTokenParamsCB();
659
+ if (customTokenParams) {
660
+ this.#authConfig.customTokenParams = customTokenParams;
661
+ }
662
+ }
663
+ catch (e) {
664
+ // eslint-disable-next-line no-console
665
+ console.error(`Error on customTokenParams callback. ${e}`);
666
+ }
667
+ }
668
+ }
216
669
  updateRedirectUri(sRedirectUri) {
217
- __classPrivateFieldGet(this, _AuthManager_authConfig, "f").redirectUri = sRedirectUri;
670
+ this.#authConfig.redirectUri = sRedirectUri;
218
671
  }
219
672
  /**
220
673
  * Get available portals which supports SDK
@@ -230,9 +683,9 @@ class AuthManager {
230
683
  const appAlias = serverConfig.appAlias;
231
684
  const appAliasPath = appAlias ? `/app/${appAlias}` : '';
232
685
  const arExcludedPortals = serverConfig.excludePortals;
233
- const additionalHeaders = __classPrivateFieldGet(this, _AuthManager_loginProps, "f").additionalHeaders || {};
234
- const oHeaders = __classPrivateFieldGet(this, _AuthManager_authHeader, "f")
235
- ? { Authorization: __classPrivateFieldGet(this, _AuthManager_authHeader, "f"), ...additionalHeaders }
686
+ const additionalHeaders = this.#loginProps.additionalHeaders || {};
687
+ const oHeaders = this.#authHeader
688
+ ? { Authorization: this.#authHeader, ...additionalHeaders }
236
689
  : additionalHeaders;
237
690
  const headers = {
238
691
  'Content-Type': 'application/json',
@@ -243,7 +696,7 @@ class AuthManager {
243
696
  return fetch(`${serverUrl}${appAliasPath}/api/v1/data/${dataPageName}`, {
244
697
  method: 'GET',
245
698
  headers,
246
- credentials: __classPrivateFieldGet(this, _AuthManager_authConfig, "f").secureCookie ? 'include' : 'omit'
699
+ credentials: this.#authConfig.secureCookie ? 'include' : 'omit'
247
700
  })
248
701
  .then(response => {
249
702
  if (response.ok && response.status === 200) {
@@ -284,27 +737,97 @@ class AuthManager {
284
737
  });
285
738
  });
286
739
  }
740
+ #updateLoginStatus() {
741
+ if (!this.#authHeader && this.#tokenInfo?.access_token) {
742
+ // Use setter to set this securely
743
+ this.authHeader = `${this.#tokenInfo.token_type} ${this.#tokenInfo.access_token}`;
744
+ }
745
+ this.isLoggedIn =
746
+ !!(this.#authHeader && this.#authHeader.length > 0) ||
747
+ (this.#authConfig.secureCookie && Object.keys(this.#tokenInfo || {}).length > 0);
748
+ }
749
+ // Initiate a full OAuth re-authorization (any refresh token has also expired).
750
+ #authFullReauth() {
751
+ const bHandleHere = true; // Other alternative is to raise an event and have someone else handle it
752
+ if (this.reauthStart) {
753
+ const reauthIgnoreInterval = 300000; // 5 minutes
754
+ const currTime = Date.now();
755
+ const bReauthInProgress = currTime - this.reauthStart <= reauthIgnoreInterval;
756
+ if (bReauthInProgress) {
757
+ return;
758
+ }
759
+ }
760
+ if (bHandleHere) {
761
+ // Don't want to do a full clear of authMgr as will loose state props (like sessionIndex). Rather just clear the tokens
762
+ this.clear(true);
763
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
764
+ login(true);
765
+ }
766
+ else {
767
+ // Fire the SdkFullReauth event to indicate a new token is needed (PCore.getAuthUtils.setTokens method
768
+ // should be used to communicate the new token to Constellation JS Engine.
769
+ const event = new CustomEvent('SdkFullReauth', {
770
+ detail: this.#processTokenOnLogin.bind(this)
771
+ });
772
+ document.dispatchEvent(event);
773
+ }
774
+ }
775
+ #authRefresh(tokenInfo) {
776
+ const bBootstrapComplete = this.bC11NBootstrapComplete;
777
+ this.#initialize(false).then(aMgr => {
778
+ aMgr.refreshToken(tokenInfo.refresh_token).then(token => {
779
+ if (token?.token_type) {
780
+ this.#processTokenOnLogin(token, !bBootstrapComplete);
781
+ }
782
+ else {
783
+ this.#authFullReauth();
784
+ }
785
+ });
786
+ });
787
+ }
788
+ #isRefreshTokenAvailable() {
789
+ return ((!this.#authConfig.secureCookie && this.#tokenInfo?.refresh_token) ||
790
+ (this.#authConfig.secureCookie && this.#tokenInfo.is_refresh_token_enabled));
791
+ }
792
+ // Do a full reauth or token refresh
793
+ #authRefreshOrFullReauth() {
794
+ if (this.#authHeader && this.#authConfig.grantType === 'none') {
795
+ // Should never come down this path
796
+ }
797
+ else if (this.#isRefreshTokenAvailable() &&
798
+ (this.#authConfig.secureCookie || this.#bOAuthCustom || !this.bC11NBootstrapComplete)) {
799
+ // If not doing custom and have a refresh token, then attempt a refresh
800
+ this.#authRefresh(this.#tokenInfo);
801
+ }
802
+ else {
803
+ this.#authFullReauth();
804
+ }
805
+ }
806
+ // Passive update where just session storage is updated so can be used on a window refresh
807
+ #authTokenUpdated(tokenInfo) {
808
+ this.#tokenInfo = tokenInfo;
809
+ }
287
810
  // TODO: Cope with 401 and refresh token if possible (or just hope that it succeeds during login)
288
811
  /**
289
812
  * Retrieve UserInfo for current authentication service
290
813
  */
291
814
  getUserInfo() {
292
- if (__classPrivateFieldGet(this, _AuthManager_userInfo, "f")) {
293
- return __classPrivateFieldGet(this, _AuthManager_userInfo, "f");
815
+ if (this.#userInfo) {
816
+ return this.#userInfo;
294
817
  }
295
- return __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_initialize).call(this, false).then(aMgr => {
296
- return aMgr.getUserinfo(__classPrivateFieldGet(this, _AuthManager_tokenInfo, "f").access_token).then(data => {
297
- __classPrivateFieldSet(this, _AuthManager_userInfo, data, "f");
298
- return __classPrivateFieldGet(this, _AuthManager_userInfo, "f");
818
+ return this.#initialize(false).then(aMgr => {
819
+ return aMgr.getUserinfo(this.#tokenInfo.access_token).then(data => {
820
+ this.#userInfo = data;
821
+ return this.#userInfo;
299
822
  });
300
823
  });
301
824
  }
302
825
  login(bFullReauth = false) {
303
826
  if (this.bCustomAuth)
304
827
  return;
305
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_initialize).call(this, !bFullReauth).then(aMgr => {
828
+ this.#initialize(!bFullReauth).then(aMgr => {
306
829
  const sdkConfigAuth = SdkConfigAccess.getSdkConfigAuth();
307
- if (__classPrivateFieldGet(this, _AuthManager_authConfig, "f").grantType === 'authCode') {
830
+ if (this.#authConfig.grantType === 'authCode') {
308
831
  const bMainRedirect = !this.noInitialRedirect;
309
832
  let sRedirectUri = sdkConfigAuth.redirectUri;
310
833
  // If initial main redirect is OK, redirect to main page, otherwise will authorize in a popup window
@@ -325,12 +848,12 @@ class AuthManager {
325
848
  this.updateRedirectUri(sRedirectUri);
326
849
  }
327
850
  return new Promise((resolve, reject) => {
328
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_doCustomTokenParamsCB).call(this);
851
+ this.#doCustomTokenParamsCB();
329
852
  aMgr
330
853
  .login()
331
854
  .then(token => {
332
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_processTokenOnLogin).call(this, token);
333
- if (__classPrivateFieldGet(this, _AuthManager_loadUserinfo, "f")) {
855
+ this.#processTokenOnLogin(token);
856
+ if (this.#loadUserinfo) {
334
857
  this.getUserInfo();
335
858
  }
336
859
  resolve(token.access_token);
@@ -351,17 +874,17 @@ class AuthManager {
351
874
  const state = urlParams.get('state');
352
875
  // If state should also match before accepting code
353
876
  if (code) {
354
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_initialize).call(this, false).then(aMgr => {
877
+ this.#initialize(false).then(aMgr => {
355
878
  if (aMgr.checkStateMatch(state)) {
356
879
  aMgr.getToken(code).then(token => {
357
880
  // Remove any altStateStorage
358
- if (__classPrivateFieldGet(this, _AuthManager_loginProps, "f")?.altStateStorage) {
359
- window.localStorage.removeItem(__classPrivateFieldGet(this, _AuthManager_ssKeySessionInfo, "f"));
360
- window.localStorage.removeItem(__classPrivateFieldGet(this, _AuthManager_ssKeyState, "f"));
881
+ if (this.#loginProps?.altStateStorage) {
882
+ window.localStorage.removeItem(this.#ssKeySessionInfo);
883
+ window.localStorage.removeItem(this.#ssKeyState);
361
884
  }
362
885
  if (token && token.token_type) {
363
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_processTokenOnLogin).call(this, token, false);
364
- if (__classPrivateFieldGet(this, _AuthManager_loadUserinfo, "f")) {
886
+ this.#processTokenOnLogin(token, false);
887
+ if (this.#loadUserinfo) {
365
888
  this.getUserInfo();
366
889
  }
367
890
  if (fnLoggedInCB) {
@@ -387,14 +910,14 @@ class AuthManager {
387
910
  }
388
911
  loginIfNecessary(loginProps) {
389
912
  const { appName, deferLogin, redirectDoneCB, locale } = loginProps;
390
- __classPrivateFieldSet(this, _AuthManager_loginProps, { ...loginProps }, "f");
913
+ this.#loginProps = { ...loginProps };
391
914
  const noMainRedirect = !loginProps.mainRedirect;
392
915
  // We need to load state before making any decisions. If appName is not there
393
916
  // and this is not the first time load...suspect something is wrong and we need to reload
394
917
  if (Object.keys(this.state).length <= this.stateKeysCount || !this.appName) {
395
918
  // Once appName is defined it should exceed this count. If not there should be no
396
919
  // harm trying once more
397
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_loadState).call(this);
920
+ this.#loadState();
398
921
  }
399
922
  // If no initial redirect status of page changed...clear AuthMgr
400
923
  const currNoMainRedirect = this.noInitialRedirect;
@@ -413,9 +936,9 @@ class AuthManager {
413
936
  }
414
937
  // If custom auth no need to do any OAuth logic
415
938
  if (this.bCustomAuth) {
416
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_updateLoginStatus).call(this);
939
+ this.#updateLoginStatus();
417
940
  if (!window.PCore) {
418
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_customConstellationInit).call(this, () => {
941
+ this.#customConstellationInit(() => {
419
942
  // Fire the SdkCustomReauth event to indicate a new authHeader is needed. Event listener should invoke sdkSetAuthHeader
420
943
  // to communicate the new token to sdk (and Constellation JS Engine)
421
944
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
@@ -444,7 +967,7 @@ class AuthManager {
444
967
  window.location.replace(window.location.pathname);
445
968
  };
446
969
  // INC-B43979 had strange case where sessionStorage was empty after redirects
447
- if (!this.state.sfx && !__classPrivateFieldGet(this, _AuthManager_loginProps, "f")?.altStateStorage) {
970
+ if (!this.state.sfx && !this.#loginProps?.altStateStorage) {
448
971
  // Reload the page to trigger another login. Invoking login method here instead didn't
449
972
  // resolve the issue in client environment.
450
973
  this.clear();
@@ -453,11 +976,11 @@ class AuthManager {
453
976
  return this.authRedirectCallback(window.location.href, redirectDoneCB || cbDefault);
454
977
  }
455
978
  if (!deferLogin) {
456
- return __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_initialize).call(this, false).then(() => {
457
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_updateLoginStatus).call(this);
979
+ return this.#initialize(false).then(() => {
980
+ this.#updateLoginStatus();
458
981
  if (this.isLoggedIn) {
459
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_fireTokenAvailable).call(this, __classPrivateFieldGet(this, _AuthManager_tokenInfo, "f"));
460
- if (__classPrivateFieldGet(this, _AuthManager_loadUserinfo, "f")) {
982
+ this.#fireTokenAvailable(this.#tokenInfo);
983
+ if (this.#loadUserinfo) {
461
984
  this.getUserInfo();
462
985
  }
463
986
  }
@@ -468,10 +991,10 @@ class AuthManager {
468
991
  }
469
992
  }
470
993
  logout() {
471
- if (__classPrivateFieldGet(this, _AuthManager_beforeUnloadAdded, "f")) {
472
- window.removeEventListener('beforeunload', __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_doBeforeUnload).bind(this));
473
- window.removeEventListener('pagehide', __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_doPageHide).bind(this));
474
- __classPrivateFieldSet(this, _AuthManager_beforeUnloadAdded, false, "f");
994
+ if (this.#beforeUnloadAdded) {
995
+ window.removeEventListener('beforeunload', this.#doBeforeUnload.bind(this));
996
+ window.removeEventListener('pagehide', this.#doPageHide.bind(this));
997
+ this.#beforeUnloadAdded = false;
475
998
  }
476
999
  return new Promise(resolve => {
477
1000
  const fnClearAndResolve = () => {
@@ -485,8 +1008,8 @@ class AuthManager {
485
1008
  return;
486
1009
  }
487
1010
  // For secure cookie there will not be an access_token so just check for token_type
488
- if (__classPrivateFieldGet(this, _AuthManager_tokenInfo, "f") && __classPrivateFieldGet(this, _AuthManager_tokenInfo, "f").token_type) {
489
- if (window.PCore && !__classPrivateFieldGet(this, _AuthManager_bOAuthCustom, "f")) {
1011
+ if (this.#tokenInfo && this.#tokenInfo.token_type) {
1012
+ if (window.PCore && !this.#bOAuthCustom) {
490
1013
  window.PCore.getAuthUtils()
491
1014
  .revokeTokens()
492
1015
  .catch(err => {
@@ -498,11 +1021,11 @@ class AuthManager {
498
1021
  });
499
1022
  }
500
1023
  else {
501
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_initialize).call(this, false).then(aMgr => {
1024
+ this.#initialize(false).then(aMgr => {
502
1025
  aMgr
503
- .revokeTokens(__classPrivateFieldGet(this, _AuthManager_authConfig, "f").secureCookie ? 'cookie' : __classPrivateFieldGet(this, _AuthManager_tokenInfo, "f").access_token, __classPrivateFieldGet(this, _AuthManager_authConfig, "f").secureCookie && __classPrivateFieldGet(this, _AuthManager_tokenInfo, "f").is_refresh_token_enabled
1026
+ .revokeTokens(this.#authConfig.secureCookie ? 'cookie' : this.#tokenInfo.access_token, this.#authConfig.secureCookie && this.#tokenInfo.is_refresh_token_enabled
504
1027
  ? 'cookie'
505
- : __classPrivateFieldGet(this, _AuthManager_tokenInfo, "f").refresh_token)
1028
+ : this.#tokenInfo.refresh_token)
506
1029
  .then(() => {
507
1030
  // Go to finally
508
1031
  })
@@ -518,515 +1041,6 @@ class AuthManager {
518
1041
  });
519
1042
  }
520
1043
  }
521
- _AuthManager_ssKeyPrefix = new WeakMap(), _AuthManager_pegaAuth = new WeakMap(), _AuthManager_ssKeyConfigInfo = new WeakMap(), _AuthManager_ssKeySessionInfo = new WeakMap(), _AuthManager_ssKeyTokenInfo = new WeakMap(), _AuthManager_ssKeyState = new WeakMap(), _AuthManager_authConfig = new WeakMap(), _AuthManager_authDynState = new WeakMap(), _AuthManager_authHeader = new WeakMap(), _AuthManager_customTokenParamsCB = new WeakMap(), _AuthManager_bOAuthCustom = new WeakMap(), _AuthManager_tokenInfo = new WeakMap(), _AuthManager_userInfo = new WeakMap(), _AuthManager_usePASS = new WeakMap(), _AuthManager_beforeUnloadAdded = new WeakMap(), _AuthManager_tokenStorage = new WeakMap(), _AuthManager_transform = new WeakMap(), _AuthManager_foldSpot = new WeakMap(), _AuthManager_loadUserinfo = new WeakMap(), _AuthManager_loginProps = new WeakMap(), _AuthManager_promiseInitialize = new WeakMap(), _AuthManager_instances = new WeakSet(), _AuthManager_transformAndParse = function _AuthManager_transformAndParse(ssKey, ssItem, bForce = false) {
522
- let obj = {};
523
- try {
524
- obj = JSON.parse(__classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_transformer).call(this, ssKey, ssItem, false, bForce));
525
- }
526
- catch (e) {
527
- // fall thru and return empty object
528
- }
529
- return obj;
530
- }, _AuthManager_getStorage = function _AuthManager_getStorage(ssKey, sAttrib = null) {
531
- let ssItem = ssKey ? window.sessionStorage.getItem(ssKey) : null;
532
- let obj = {};
533
- if (__classPrivateFieldGet(this, _AuthManager_loginProps, "f")?.altStateStorage &&
534
- !this.isLoggedIn &&
535
- !ssItem &&
536
- (ssKey === __classPrivateFieldGet(this, _AuthManager_ssKeyState, "f") || ssKey === __classPrivateFieldGet(this, _AuthManager_ssKeySessionInfo, "f"))) {
537
- ssItem = window.localStorage.getItem(ssKey);
538
- }
539
- if (ssItem) {
540
- try {
541
- obj = JSON.parse(ssItem);
542
- }
543
- catch (e) {
544
- obj = __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_transformAndParse).call(this, ssKey, ssItem, true);
545
- }
546
- }
547
- return sAttrib ? obj[sAttrib] : obj;
548
- }, _AuthManager_setStorage = function _AuthManager_setStorage(ssKey, obj, bVerify = false) {
549
- try {
550
- // Set storage only if obj is not empty, else delete the storage
551
- if (!obj || isEmptyObject(obj)) {
552
- window.sessionStorage.removeItem(ssKey);
553
- }
554
- else {
555
- // const bClear = (ssKey === this.#ssKeyState || ssKey === this.#ssKeySessionInfo);
556
- const bClear = false;
557
- const sValue = bClear
558
- ? JSON.stringify(obj)
559
- : __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_transformer).call(this, ssKey, JSON.stringify(obj), true);
560
- window.sessionStorage.setItem(ssKey, sValue);
561
- if (bVerify) {
562
- const sStored = window.sessionStorage.getItem(ssKey);
563
- if (sStored !== sValue) {
564
- // eslint-disable-next-line no-console
565
- console.error(`Failed to properly write sessionStorage (${ssKey})`);
566
- }
567
- }
568
- if (__classPrivateFieldGet(this, _AuthManager_loginProps, "f")?.altStateStorage &&
569
- !this.isLoggedIn &&
570
- (ssKey === __classPrivateFieldGet(this, _AuthManager_ssKeyState, "f") || ssKey === __classPrivateFieldGet(this, _AuthManager_ssKeySessionInfo, "f"))) {
571
- window.localStorage.setItem(ssKey, sValue);
572
- }
573
- }
574
- }
575
- catch (e) {
576
- // eslint-disable-next-line no-console
577
- console.error(`Exception ${e} on attempted write of sessionStorage (${ssKey})`);
578
- }
579
- }, _AuthManager_calcFoldSpot = function _AuthManager_calcFoldSpot(s) {
580
- const nOffset = 1;
581
- const sChar = s.length > nOffset ? s.charAt(nOffset) : '2';
582
- const nSpot = parseInt(sChar, 10);
583
- __classPrivateFieldSet(this, _AuthManager_foldSpot, Number.isNaN(nSpot) ? 2 : (nSpot % 4) + 2, "f");
584
- }, _AuthManager_transformer = function _AuthManager_transformer(ssKey, s, bIn, bForce = false) {
585
- const bTransform = bForce || __classPrivateFieldGet(this, _AuthManager_transform, "f");
586
- const fnFold = (x) => {
587
- const nLen = x.length;
588
- const nExtra = nLen % __classPrivateFieldGet(this, _AuthManager_foldSpot, "f");
589
- const nOffset = Math.floor(nLen / __classPrivateFieldGet(this, _AuthManager_foldSpot, "f")) + nExtra;
590
- const nRem = x.length - nOffset;
591
- return x.substring(bIn ? nOffset : nRem) + x.substring(0, bIn ? nOffset : nRem);
592
- };
593
- const bTknInfo = ssKey === __classPrivateFieldGet(this, _AuthManager_ssKeyTokenInfo, "f");
594
- if (bTknInfo && !bIn && bTransform) {
595
- s = window.atob(fnFold(s));
596
- }
597
- // eslint-disable-next-line no-nested-ternary
598
- let result = bTransform ? (bIn ? window.btoa(s) : window.atob(s)) : s;
599
- if (bTknInfo && bIn && bTransform) {
600
- result = fnFold(window.btoa(result));
601
- }
602
- return result;
603
- }, _AuthManager_doUnloadUpdates = function _AuthManager_doUnloadUpdates() {
604
- // Safari and particularly Safari on mobile devices doesn't seem to load this on first main redirect or
605
- // reliably, so have moved to having PegaAuth manage writing all state props to session storage
606
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyState, "f"), this.state);
607
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeySessionInfo, "f"), __classPrivateFieldGet(this, _AuthManager_authDynState, "f"));
608
- // If tokenStorage was always, token would already be there
609
- if (__classPrivateFieldGet(this, _AuthManager_tokenStorage, "f") === 'temp') {
610
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyTokenInfo, "f"), __classPrivateFieldGet(this, _AuthManager_tokenInfo, "f"));
611
- }
612
- }, _AuthManager_doBeforeUnload = function _AuthManager_doBeforeUnload() {
613
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_doUnloadUpdates).call(this);
614
- }, _AuthManager_doPageHide = function _AuthManager_doPageHide() {
615
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_doUnloadUpdates).call(this);
616
- }, _AuthManager_loadState = function _AuthManager_loadState() {
617
- // Note: State storage key doesn't have a client id associated with it
618
- const oState = __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_getStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyState, "f"));
619
- if (oState) {
620
- Object.assign(this.state, oState);
621
- if (this.state.sfx) {
622
- // Setter sets up the ssKey values as well
623
- this.keySuffix = this.state.sfx;
624
- }
625
- }
626
- }, _AuthManager_doOnLoad = function _AuthManager_doOnLoad() {
627
- if (!this.onLoadDone) {
628
- // This authConfig state doesn't collide with other calculated static state...so load it first
629
- // Note: transform setting will have already been loaded into #authConfig at this point
630
- __classPrivateFieldSet(this, _AuthManager_authDynState, __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_getStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeySessionInfo, "f")), "f");
631
- __classPrivateFieldSet(this, _AuthManager_tokenInfo, __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_getStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyTokenInfo, "f")), "f");
632
- if (__classPrivateFieldGet(this, _AuthManager_tokenStorage, "f") !== 'always') {
633
- sessionStorage.removeItem(__classPrivateFieldGet(this, _AuthManager_ssKeyTokenInfo, "f"));
634
- // Finding on iOS browsers the pageHide event is sometimes not happening causing failed redirects.
635
- if (!this.iOSDevice) {
636
- sessionStorage.removeItem(__classPrivateFieldGet(this, _AuthManager_ssKeySessionInfo, "f"));
637
- }
638
- }
639
- this.onLoadDone = true;
640
- }
641
- }, _AuthManager_doAuthDynStateChanged = function _AuthManager_doAuthDynStateChanged() {
642
- // If tokenStorage is setup for always then always persist the auth dynamic state as well
643
- if (__classPrivateFieldGet(this, _AuthManager_tokenStorage, "f") === 'always' || this.iOSDevice) {
644
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeySessionInfo, "f"), __classPrivateFieldGet(this, _AuthManager_authDynState, "f"));
645
- }
646
- }, _AuthManager_initialize =
647
- /**
648
- * Initialize OAuth config structure members and create authMgr instance (if necessary)
649
- * bNew - governs whether to create new sessionStorage or load existing one
650
- */
651
- async function _AuthManager_initialize(bNew = false) {
652
- if (!bNew && __classPrivateFieldGet(this, _AuthManager_promiseInitialize, "f")) {
653
- return __classPrivateFieldGet(this, _AuthManager_promiseInitialize, "f");
654
- }
655
- __classPrivateFieldSet(this, _AuthManager_promiseInitialize, new Promise(resolve => {
656
- /* if (!this.initInProgress && (bNew || isEmptyObject(this.#authConfig) || !this.#pegaAuth)) { */
657
- this.initInProgress = true;
658
- getSdkConfig().then(sdkConfig => {
659
- const sdkConfigAuth = sdkConfig.authConfig;
660
- const sdkConfigServer = sdkConfig.serverConfig;
661
- const serverType = sdkConfigServer.serverType || 'infinity';
662
- const bInfinity = serverType === 'infinity';
663
- let pegaUrl = bInfinity
664
- ? sdkConfigServer.infinityRestServerUrl
665
- : sdkConfigServer.launchpadRestServerUrl;
666
- // Expecting boolean true/false or undefined
667
- const secureCookie = !!sdkConfigAuth.secureCookie;
668
- const bNoInitialRedirect = this.noInitialRedirect;
669
- const appAliasSeg = sdkConfigServer.appAlias ? `app/${sdkConfigServer.appAlias}/` : '';
670
- // Construct default OAuth endpoints (if not explicitly specified)
671
- if (pegaUrl) {
672
- // Cope with trailing slash being present
673
- if (!pegaUrl.endsWith('/')) {
674
- pegaUrl += '/';
675
- }
676
- if (!sdkConfigAuth.authorize) {
677
- sdkConfigAuth.authorize = bInfinity
678
- ? `${pegaUrl}PRRestService/oauth2/v1/authorize`
679
- : `${pegaUrl}uas/oauth/authorize`;
680
- }
681
- const infinityOAuth2Url = bInfinity
682
- ? pegaUrl + (secureCookie && appAliasSeg ? `${appAliasSeg}api/` : 'PRRestService/')
683
- : '';
684
- if (!sdkConfigAuth.token) {
685
- sdkConfigAuth.token = bInfinity
686
- ? `${infinityOAuth2Url}oauth2/v1/token`
687
- : `${pegaUrl}uas/oauth/token`;
688
- }
689
- if (!sdkConfigAuth.revoke) {
690
- // Launchpad still does not have a revoke endpoint
691
- sdkConfigAuth.revoke = bInfinity ? `${infinityOAuth2Url}oauth2/v1/revoke` : '';
692
- }
693
- if (!sdkConfigAuth.redirectUri) {
694
- sdkConfigAuth.redirectUri = `${window.location.origin}${window.location.pathname}`;
695
- }
696
- if (!sdkConfigAuth.userinfo) {
697
- sdkConfigAuth.userinfo = bInfinity
698
- ? `${pegaUrl}${appAliasSeg}api/oauthclients/v1/userinfo/JSON`
699
- : '';
700
- }
701
- }
702
- // Auth service alias
703
- if (!sdkConfigAuth.authService) {
704
- sdkConfigAuth.authService = 'pega';
705
- }
706
- // mashupAuthService provides way to have a different auth service for embedded
707
- if (!sdkConfigAuth.mashupAuthService) {
708
- sdkConfigAuth.mashupAuthService = sdkConfigAuth.authService;
709
- }
710
- // Construct path to auth.html (used for case when not doing a main window redirect)
711
- let sNoMainRedirectUri = sdkConfigAuth.redirectUri;
712
- const nLastPathSep = sNoMainRedirectUri.lastIndexOf('/');
713
- sNoMainRedirectUri =
714
- nLastPathSep !== -1
715
- ? `${sNoMainRedirectUri.substring(0, nLastPathSep + 1)}auth.html`
716
- : `${sNoMainRedirectUri}/auth.html`;
717
- const portalGrantType = sdkConfigAuth.portalGrantType || 'authCode';
718
- const mashupGrantType = sdkConfigAuth.mashupGrantType || 'authCode';
719
- // Some grant types are only available with confidential registrations and require a client secret
720
- const clientSecret = bNoInitialRedirect
721
- ? sdkConfigAuth.mashupClientSecret
722
- : sdkConfigAuth.portalClientSecret;
723
- const pegaAuthConfig = {
724
- serverType,
725
- clientId: bNoInitialRedirect
726
- ? sdkConfigAuth.mashupClientId
727
- : sdkConfigAuth.portalClientId,
728
- grantType: bNoInitialRedirect ? mashupGrantType : portalGrantType,
729
- tokenUri: sdkConfigAuth.token,
730
- revokeUri: sdkConfigAuth.revoke,
731
- userinfoUri: sdkConfigAuth.userinfo,
732
- authService: bNoInitialRedirect
733
- ? sdkConfigAuth.mashupAuthService
734
- : sdkConfigAuth.authService,
735
- appAlias: sdkConfigServer.appAlias || '',
736
- useLocking: true
737
- };
738
- if (clientSecret) {
739
- pegaAuthConfig.clientSecret = clientSecret;
740
- }
741
- if (serverType === 'launchpad' && pegaAuthConfig.grantType === 'authCode') {
742
- pegaAuthConfig.noPKCE = true;
743
- }
744
- // Invoke keySuffix setter
745
- // Was using pegaAuthConfig.clientId as key but more secure to just use a random string as getting
746
- // both a clientId and the refresh token could yield a new access token.
747
- // Suffix is so we might in future move to an array of suffixes based on the appName, so might store
748
- // both portal and embedded tokens/session info at same time
749
- if (!this.state?.sfx) {
750
- // Just using a random number to make the suffix unique on each session
751
- this.keySuffix = `${Math.ceil(Math.random() * 100000000)}`;
752
- }
753
- __classPrivateFieldGet(this, _AuthManager_authConfig, "f").transform =
754
- sdkConfigAuth.transform !== undefined ? sdkConfigAuth.transform : __classPrivateFieldGet(this, _AuthManager_transform, "f");
755
- // Using property in class as authConfig may be empty at times
756
- __classPrivateFieldSet(this, _AuthManager_transform, __classPrivateFieldGet(this, _AuthManager_authConfig, "f").transform, "f");
757
- if (sdkConfigAuth.tokenStorage !== undefined) {
758
- __classPrivateFieldSet(this, _AuthManager_tokenStorage, sdkConfigAuth.tokenStorage, "f");
759
- }
760
- if (sdkConfigAuth.secureCookie) {
761
- __classPrivateFieldGet(this, _AuthManager_authConfig, "f").secureCookie = true;
762
- }
763
- // Get latest state once client ids, transform and tokenStorage have been established
764
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_doOnLoad).call(this);
765
- // If no clientId is specified assume not OAuth but custom auth
766
- if (pegaAuthConfig.grantType === 'none' || !pegaAuthConfig.clientId) {
767
- this.bCustomAuth = true;
768
- return;
769
- }
770
- // For some OAuth grant type scenarios we opt to pass the Orchestration Engine just an authHeader as
771
- // service broker doesn't have proper support for dealing with refreshing or revoking these:
772
- // * customBearer (except when secureCookie being used)
773
- // * confidential grant types (ones with clientSecret)
774
- // (With 25.1 orchestration engine does support this if client_secret is specified on bootstrap)
775
- __classPrivateFieldSet(this, _AuthManager_bOAuthCustom, (pegaAuthConfig.grantType === 'customBearer' && !secureCookie) || clientSecret, "f");
776
- if (pegaAuthConfig.grantType === 'authCode') {
777
- const authCodeProps = {
778
- authorizeUri: sdkConfigAuth.authorize,
779
- // If we have already specified a redirect on the authorize redirect, we need to continue to use that
780
- // on token endpoint
781
- redirectUri: bNoInitialRedirect || this.usePopupForRestOfSession
782
- ? sNoMainRedirectUri
783
- : sdkConfigAuth.redirectUri
784
- };
785
- if ('silentTimeout' in sdkConfigAuth) {
786
- authCodeProps.silentTimeout = sdkConfigAuth.silentTimeout;
787
- }
788
- if (bNoInitialRedirect &&
789
- pegaAuthConfig.authService === 'pega' &&
790
- sdkConfigAuth.mashupUserIdentifier &&
791
- sdkConfigAuth.mashupPassword) {
792
- authCodeProps.userIdentifier = sdkConfigAuth.mashupUserIdentifier;
793
- authCodeProps.password = sdkConfigAuth.mashupPassword;
794
- }
795
- if ('iframeLoginUI' in sdkConfigAuth) {
796
- authCodeProps.iframeLoginUI =
797
- sdkConfigAuth.iframeLoginUI.toString().toLowerCase() === 'true';
798
- }
799
- Object.assign(pegaAuthConfig, authCodeProps);
800
- }
801
- else if (pegaAuthConfig.grantType === 'passwordCreds') {
802
- pegaAuthConfig.userIdentifier = sdkConfigAuth.mashupUserIdentifier;
803
- pegaAuthConfig.password = sdkConfigAuth.mashupPassword;
804
- }
805
- Object.assign(__classPrivateFieldGet(this, _AuthManager_authConfig, "f"), pegaAuthConfig);
806
- // Add beforeunload and page hide handlers to write out key properties that we want to survive a
807
- // browser reload
808
- if (!__classPrivateFieldGet(this, _AuthManager_beforeUnloadAdded, "f") && (!__classPrivateFieldGet(this, _AuthManager_usePASS, "f") || __classPrivateFieldGet(this, _AuthManager_tokenStorage, "f") !== 'always')) {
809
- window.addEventListener('beforeunload', __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_doBeforeUnload).bind(this));
810
- window.addEventListener('pagehide', __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_doPageHide).bind(this));
811
- __classPrivateFieldSet(this, _AuthManager_beforeUnloadAdded, true, "f");
812
- }
813
- // Initialize PegaAuth OAuth 2.0 client library
814
- if (__classPrivateFieldGet(this, _AuthManager_usePASS, "f")) {
815
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyConfigInfo, "f"), __classPrivateFieldGet(this, _AuthManager_authConfig, "f"));
816
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeySessionInfo, "f"), __classPrivateFieldGet(this, _AuthManager_authDynState, "f"));
817
- __classPrivateFieldSet(this, _AuthManager_pegaAuth, new PegaAuth(__classPrivateFieldGet(this, _AuthManager_ssKeyConfigInfo, "f"), __classPrivateFieldGet(this, _AuthManager_ssKeySessionInfo, "f")), "f");
818
- }
819
- else {
820
- __classPrivateFieldGet(this, _AuthManager_authConfig, "f").fnDynStateChangedCB = __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_doAuthDynStateChanged).bind(this);
821
- __classPrivateFieldSet(this, _AuthManager_pegaAuth, new PegaAuth(__classPrivateFieldGet(this, _AuthManager_authConfig, "f"), __classPrivateFieldGet(this, _AuthManager_authDynState, "f")), "f");
822
- }
823
- this.initInProgress = false;
824
- resolve(__classPrivateFieldGet(this, _AuthManager_pegaAuth, "f"));
825
- });
826
- }), "f");
827
- return __classPrivateFieldGet(this, _AuthManager_promiseInitialize, "f");
828
- }, _AuthManager_constellationInit = function _AuthManager_constellationInit(tokenInfo, authTokenUpdated, fnReauth) {
829
- const constellationBootConfig = {};
830
- const sdkConfigServer = SdkConfigAccess.getSdkConfigServer();
831
- const sdkConfigAuth = SdkConfigAccess.getSdkConfigAuth();
832
- const authConfig = __classPrivateFieldGet(this, _AuthManager_authConfig, "f");
833
- // Set up constellationConfig with data that bootstrapWithAuthHeader expects
834
- constellationBootConfig.customRendering = true;
835
- constellationBootConfig.restServerUrl = sdkConfigServer.infinityRestServerUrl;
836
- // NOTE: Needs a trailing slash! So add one if not provided
837
- if (!sdkConfigServer.sdkContentServerUrl.endsWith('/')) {
838
- sdkConfigServer.sdkContentServerUrl = `${sdkConfigServer.sdkContentServerUrl}/`;
839
- }
840
- constellationBootConfig.staticContentServerUrl = `${sdkConfigServer.sdkContentServerUrl}constellation/`;
841
- if (!constellationBootConfig.staticContentServerUrl.endsWith('/')) {
842
- constellationBootConfig.staticContentServerUrl = `${constellationBootConfig.staticContentServerUrl}/`;
843
- }
844
- // If appAlias specified, use it
845
- if (sdkConfigServer.appAlias) {
846
- constellationBootConfig.appAlias = sdkConfigServer.appAlias;
847
- }
848
- // Determine whether to send credentials with DX API transactions
849
- if (sdkConfigAuth.customCookies) {
850
- constellationBootConfig.customCookies = true;
851
- }
852
- if (__classPrivateFieldGet(this, _AuthManager_bOAuthCustom, "f") || !tokenInfo) {
853
- if (tokenInfo) {
854
- __classPrivateFieldSet(this, _AuthManager_authHeader, `${tokenInfo.token_type} ${tokenInfo.access_token}`, "f");
855
- }
856
- if (__classPrivateFieldGet(this, _AuthManager_authHeader, "f")) {
857
- constellationBootConfig.authorizationHeader = __classPrivateFieldGet(this, _AuthManager_authHeader, "f");
858
- }
859
- }
860
- else {
861
- // Pass in auth info to Constellation
862
- constellationBootConfig.authInfo = {
863
- authType: 'OAuth2.0',
864
- tokenInfo,
865
- // Set whether we want constellation to try to do a full re-Auth or not ()
866
- // true doesn't seem to be working in SDK scenario so always passing false for now
867
- popupReauth: false /* !this.noInitialRedirect */,
868
- client_id: authConfig.clientId,
869
- client_secret: authConfig.clientSecret,
870
- authentication_service: authConfig.authService,
871
- redirect_uri: authConfig.redirectUri,
872
- endPoints: {
873
- authorize: authConfig.authorizeUri,
874
- token: authConfig.tokenUri,
875
- revoke: authConfig.revokeUri
876
- },
877
- secureCookie: authConfig.secureCookie,
878
- onTokenRetrieval: authTokenUpdated
879
- };
880
- }
881
- // Turn off dynamic load components (should be able to do it here instead of after load?)
882
- constellationBootConfig.dynamicLoadComponents = false;
883
- // Set envType if appropriate
884
- if (authConfig.serverType === 'launchpad') {
885
- constellationBootConfig.envType = 'LAUNCHPAD';
886
- }
887
- // Set locale override if specified
888
- const localeOverride = this.locale;
889
- if (localeOverride) {
890
- constellationBootConfig.locale = localeOverride;
891
- }
892
- // Set additional headers if specified
893
- const additionalHeaders = __classPrivateFieldGet(this, _AuthManager_loginProps, "f").additionalHeaders;
894
- if (additionalHeaders) {
895
- constellationBootConfig.additionalHeaders = additionalHeaders;
896
- }
897
- if (this.bC11NBootstrapInProgress) {
898
- return;
899
- }
900
- this.bC11NBootstrapInProgress = true;
901
- // Note that staticContentServerUrl already ends with a slash (see above), so no slash added.
902
- // In order to have this import succeed needed to use the webpackIgnore magic comment tag.
903
- // See: https://webpack.js.org/api/module-methods/
904
- import(
905
- /* webpackIgnore: true */ `${constellationBootConfig.staticContentServerUrl}bootstrap-shell.js?v=${Date.now()}`).then(bootstrapShell => {
906
- // NOTE: once this callback is done, we lose the ability to access loadMashup.
907
- // So, create a reference to it
908
- window.myLoadMashup = bootstrapShell.loadMashup;
909
- window.myLoadPortal = bootstrapShell.loadPortal;
910
- window.myLoadDefaultPortal = bootstrapShell.loadDefaultPortal;
911
- bootstrapShell
912
- .bootstrapWithAuthHeader(constellationBootConfig, 'pega-root')
913
- .then(() => {
914
- // eslint-disable-next-line no-console
915
- console.log('ConstellationJS bootstrap successful!');
916
- this.bC11NBootstrapInProgress = false;
917
- // Setup listener for the reauth event
918
- if (!__classPrivateFieldGet(this, _AuthManager_bOAuthCustom, "f") && tokenInfo) {
919
- PCore.getPubSubUtils().subscribe(PCore.getConstants().PUB_SUB_EVENTS.EVENT_FULL_REAUTH, fnReauth, 'authFullReauth');
920
- }
921
- else {
922
- // customReauth event introduced with 8.8
923
- const sEvent = PCore.getConstants().PUB_SUB_EVENTS.EVENT_CUSTOM_REAUTH;
924
- if (sEvent) {
925
- PCore.getPubSubUtils().subscribe(sEvent, fnReauth, 'doReauth');
926
- }
927
- }
928
- // Fire SdkConstellationReady event so bridge and app route can do expected post PCore initializations
929
- const event = new CustomEvent('SdkConstellationReady', {});
930
- document.dispatchEvent(event);
931
- })
932
- .catch(e => {
933
- // Assume error caught is because token is not valid and attempt a full reauth
934
- // eslint-disable-next-line no-console
935
- console.error(`ConstellationJS bootstrap failed. ${e}`);
936
- this.bC11NBootstrapInProgress = false;
937
- fnReauth();
938
- });
939
- });
940
- /* Ends here */
941
- }, _AuthManager_customConstellationInit = function _AuthManager_customConstellationInit(fnReauth) {
942
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_constellationInit).call(this, null, null, fnReauth);
943
- }, _AuthManager_fireTokenAvailable = function _AuthManager_fireTokenAvailable(token, bLoadC11N = true) {
944
- if (!token) {
945
- // This is used on page reload to load the token from sessionStorage and carry on
946
- token = __classPrivateFieldGet(this, _AuthManager_tokenInfo, "f");
947
- if (!token) {
948
- return;
949
- }
950
- }
951
- __classPrivateFieldSet(this, _AuthManager_tokenInfo, token, "f");
952
- if (__classPrivateFieldGet(this, _AuthManager_tokenStorage, "f") === 'always') {
953
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyTokenInfo, "f"), __classPrivateFieldGet(this, _AuthManager_tokenInfo, "f"));
954
- }
955
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_updateLoginStatus).call(this);
956
- // this.isLoggedIn is getting updated in updateLoginStatus
957
- this.isLoggedIn = true;
958
- this.usePopupForRestOfSession = true;
959
- if (!window.PCore && bLoadC11N) {
960
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_constellationInit).call(this, token, __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_authTokenUpdated).bind(this), __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_authFullReauth).bind(this));
961
- }
962
- /*
963
- // Create and dispatch the SdkLoggedIn event to trigger constellationInit
964
- const event = new CustomEvent('SdkLoggedIn', { detail: { authConfig, tokenInfo: token } });
965
- document.dispatchEvent(event);
966
- */
967
- }, _AuthManager_processTokenOnLogin = function _AuthManager_processTokenOnLogin(token, bLoadC11N = true) {
968
- __classPrivateFieldSet(this, _AuthManager_tokenInfo, token, "f");
969
- if (__classPrivateFieldGet(this, _AuthManager_tokenStorage, "f") === 'always') {
970
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_setStorage).call(this, __classPrivateFieldGet(this, _AuthManager_ssKeyTokenInfo, "f"), __classPrivateFieldGet(this, _AuthManager_tokenInfo, "f"));
971
- }
972
- if (__classPrivateFieldGet(this, _AuthManager_bOAuthCustom, "f")) {
973
- // authHeader setter will also set #authHeader and invoke getAuthUtils().setAuthorizationHeader
974
- this.authHeader = `${token.token_type} ${token.access_token}`;
975
- }
976
- if (window.PCore && !__classPrivateFieldGet(this, _AuthManager_authHeader, "f")) {
977
- PCore.getAuthUtils().setTokens(token);
978
- }
979
- else {
980
- __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_fireTokenAvailable).call(this, token, bLoadC11N);
981
- }
982
- }, _AuthManager_doCustomTokenParamsCB = function _AuthManager_doCustomTokenParamsCB() {
983
- if (__classPrivateFieldGet(this, _AuthManager_authConfig, "f").grantType === 'customBearer' && __classPrivateFieldGet(this, _AuthManager_customTokenParamsCB, "f")) {
984
- try {
985
- const customTokenParams = __classPrivateFieldGet(this, _AuthManager_customTokenParamsCB, "f").call(this);
986
- if (customTokenParams) {
987
- __classPrivateFieldGet(this, _AuthManager_authConfig, "f").customTokenParams = customTokenParams;
988
- }
989
- }
990
- catch (e) {
991
- // eslint-disable-next-line no-console
992
- console.error(`Error on customTokenParams callback. ${e}`);
993
- }
994
- }
995
- }, _AuthManager_updateLoginStatus = function _AuthManager_updateLoginStatus() {
996
- if (!__classPrivateFieldGet(this, _AuthManager_authHeader, "f") && __classPrivateFieldGet(this, _AuthManager_tokenInfo, "f")?.access_token) {
997
- // Use setter to set this securely
998
- this.authHeader = `${__classPrivateFieldGet(this, _AuthManager_tokenInfo, "f").token_type} ${__classPrivateFieldGet(this, _AuthManager_tokenInfo, "f").access_token}`;
999
- }
1000
- this.isLoggedIn =
1001
- !!(__classPrivateFieldGet(this, _AuthManager_authHeader, "f") && __classPrivateFieldGet(this, _AuthManager_authHeader, "f").length > 0) ||
1002
- (__classPrivateFieldGet(this, _AuthManager_authConfig, "f").secureCookie && Object.keys(__classPrivateFieldGet(this, _AuthManager_tokenInfo, "f") || {}).length > 0);
1003
- }, _AuthManager_authFullReauth = function _AuthManager_authFullReauth() {
1004
- const bHandleHere = true; // Other alternative is to raise an event and have someone else handle it
1005
- if (this.reauthStart) {
1006
- const reauthIgnoreInterval = 300000; // 5 minutes
1007
- const currTime = Date.now();
1008
- const bReauthInProgress = currTime - this.reauthStart <= reauthIgnoreInterval;
1009
- if (bReauthInProgress) {
1010
- return;
1011
- }
1012
- }
1013
- if (bHandleHere) {
1014
- // Don't want to do a full clear of authMgr as will loose state props (like sessionIndex). Rather just clear the tokens
1015
- this.clear(true);
1016
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
1017
- login(true);
1018
- }
1019
- else {
1020
- // Fire the SdkFullReauth event to indicate a new token is needed (PCore.getAuthUtils.setTokens method
1021
- // should be used to communicate the new token to Constellation JS Engine.
1022
- const event = new CustomEvent('SdkFullReauth', {
1023
- detail: __classPrivateFieldGet(this, _AuthManager_instances, "m", _AuthManager_processTokenOnLogin).bind(this)
1024
- });
1025
- document.dispatchEvent(event);
1026
- }
1027
- }, _AuthManager_authTokenUpdated = function _AuthManager_authTokenUpdated(tokenInfo) {
1028
- __classPrivateFieldSet(this, _AuthManager_tokenInfo, tokenInfo, "f");
1029
- };
1030
1044
  const gAuthMgr = new AuthManager();
1031
1045
  // TODO: Cope with 401 and refresh token if possible (or just hope that it succeeds during login)
1032
1046
  /**