@monterosa/sdk-identify-kit 2.0.0-rc.3 → 2.0.0-rc.4
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/dist/api.d.ts +187 -173
- package/dist/bridge.d.ts +12 -3
- package/dist/credentials_store.d.ts +31 -0
- package/dist/identify.d.ts +4 -10
- package/dist/identify_options.d.ts +28 -0
- package/dist/identify_url.d.ts +25 -0
- package/dist/identity_options.d.ts +31 -0
- package/dist/index.cjs +444 -378
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +444 -378
- package/dist/index.js.map +1 -1
- package/dist/login_policy_store.d.ts +28 -0
- package/dist/types.d.ts +16 -43
- package/package.json +8 -8
package/dist/index.cjs
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var sdkCore = require('@monterosa/sdk-core');
|
|
6
5
|
var sdkUtil = require('@monterosa/sdk-util');
|
|
7
6
|
var sdkLauncherKit = require('@monterosa/sdk-launcher-kit');
|
|
7
|
+
var sdkCore = require('@monterosa/sdk-core');
|
|
8
8
|
var sdkConnectKit = require('@monterosa/sdk-connect-kit');
|
|
9
9
|
var sdkInteractInterop = require('@monterosa/sdk-interact-interop');
|
|
10
10
|
|
|
@@ -24,10 +24,8 @@ var IdentifyEvent;
|
|
|
24
24
|
IdentifyEvent["StateUpdated"] = "state_updated";
|
|
25
25
|
IdentifyEvent["LoginRequested"] = "login_requested";
|
|
26
26
|
IdentifyEvent["LogoutRequested"] = "logout_requested";
|
|
27
|
-
IdentifyEvent["SignatureUpdated"] = "signature_updated";
|
|
28
|
-
IdentifyEvent["UserdataUpdated"] = "userdata_updated";
|
|
29
27
|
IdentifyEvent["CredentialsUpdated"] = "credentials_updated";
|
|
30
|
-
IdentifyEvent["
|
|
28
|
+
IdentifyEvent["LoginPolicyUpdated"] = "login_policy_updated";
|
|
31
29
|
})(IdentifyEvent || (IdentifyEvent = {}));
|
|
32
30
|
/**
|
|
33
31
|
* Defines a set of error codes that may be encountered when using the
|
|
@@ -40,8 +38,6 @@ var IdentifyEvent;
|
|
|
40
38
|
* } catch (err) {
|
|
41
39
|
* if (err.code === IdentifyError.NoCredentials) {
|
|
42
40
|
* // handle missing credentials error
|
|
43
|
-
* } else if (err.code === IdentifyError.NotInitialised) {
|
|
44
|
-
* // handle initialization error
|
|
45
41
|
* } else {
|
|
46
42
|
* // handle other error types
|
|
47
43
|
* }
|
|
@@ -71,10 +67,6 @@ exports.IdentifyError = void 0;
|
|
|
71
67
|
* or have expired.
|
|
72
68
|
*/
|
|
73
69
|
IdentifyError["NoCredentials"] = "no_credentials";
|
|
74
|
-
/**
|
|
75
|
-
* Indicates the IdentifyKit has not been initialised properly.
|
|
76
|
-
*/
|
|
77
|
-
IdentifyError["NotInitialised"] = "not_initialised";
|
|
78
70
|
/**
|
|
79
71
|
* Indicates an error occurred in the parent app.
|
|
80
72
|
*/
|
|
@@ -99,7 +91,6 @@ const IdentifyErrorMessages = {
|
|
|
99
91
|
[exports.IdentifyError.ExtensionApiError]: (error) => `Identify extension API returned an error: ${error}`,
|
|
100
92
|
[exports.IdentifyError.ExtensionNotSetup]: () => 'Identify extension is not set up for this project',
|
|
101
93
|
[exports.IdentifyError.NoCredentials]: () => 'Identify credentials are not set',
|
|
102
|
-
[exports.IdentifyError.NotInitialised]: () => 'Identify instance is not initialised',
|
|
103
94
|
[exports.IdentifyError.ParentAppError]: (error) => `Parent application error: ${error}`,
|
|
104
95
|
[exports.IdentifyError.UnexpectedState]: (state) => `Unexpected LoginState: ${state}`,
|
|
105
96
|
[exports.IdentifyError.NoParentApplication]: () => 'No parent application available for delegation',
|
|
@@ -111,14 +102,9 @@ var IdentifyAction;
|
|
|
111
102
|
IdentifyAction["Logout"] = "identifyLogout";
|
|
112
103
|
IdentifyAction["RequestLogin"] = "identifyRequestLogin";
|
|
113
104
|
IdentifyAction["RequestLogout"] = "identifyRequestLogout";
|
|
114
|
-
IdentifyAction["
|
|
115
|
-
IdentifyAction["GetSessionSignature"] = "identifyGetSessionSignature";
|
|
105
|
+
IdentifyAction["GetCredentials"] = "identifyGetCredentials";
|
|
116
106
|
IdentifyAction["SetCredentials"] = "identifySetCredentials";
|
|
117
107
|
IdentifyAction["ClearCredentials"] = "identifyClearCredentials";
|
|
118
|
-
IdentifyAction["OnStateUpdated"] = "identifyOnStateUpdated";
|
|
119
|
-
IdentifyAction["OnCredentialsUpdated"] = "identifyOnCredentialsUpdated";
|
|
120
|
-
IdentifyAction["OnUserDataUpdated"] = "identifyOnUserDataUpdated";
|
|
121
|
-
IdentifyAction["OnSessionSignatureUpdated"] = "identifyOnSessionSignatureUpdated";
|
|
122
108
|
})(IdentifyAction || (IdentifyAction = {}));
|
|
123
109
|
|
|
124
110
|
/**
|
|
@@ -145,13 +131,12 @@ class Identify extends sdkUtil.Emitter {
|
|
|
145
131
|
super();
|
|
146
132
|
this.sdk = sdk;
|
|
147
133
|
this.wasLoggedIn = false;
|
|
148
|
-
this._credentials = null;
|
|
149
134
|
this._signature = null;
|
|
150
135
|
this._userData = null;
|
|
151
136
|
this._state = {
|
|
152
137
|
state: 'logged_out',
|
|
153
138
|
};
|
|
154
|
-
this._options = Object.assign({ strategy: 'email',
|
|
139
|
+
this._options = Object.assign({ strategy: 'email', version: 1 }, options);
|
|
155
140
|
}
|
|
156
141
|
static async fetchIdentifyHost(host, projectId) {
|
|
157
142
|
var _a, _b;
|
|
@@ -174,12 +159,13 @@ class Identify extends sdkUtil.Emitter {
|
|
|
174
159
|
case 'logged_in':
|
|
175
160
|
this.wasLoggedIn = true;
|
|
176
161
|
break;
|
|
177
|
-
case 'logged_out':
|
|
178
162
|
case 'error':
|
|
179
163
|
this.wasLoggedIn = false;
|
|
180
164
|
break;
|
|
165
|
+
case 'logged_out':
|
|
181
166
|
case 'pending':
|
|
182
|
-
// preserve wasLoggedIn
|
|
167
|
+
// preserve wasLoggedIn — these states reflect transient transport
|
|
168
|
+
// state, not a deliberate logout (credentials are the gate for that)
|
|
183
169
|
break;
|
|
184
170
|
default: {
|
|
185
171
|
// Exhaustiveness check: TypeScript errors if a new state is added
|
|
@@ -207,53 +193,29 @@ class Identify extends sdkUtil.Emitter {
|
|
|
207
193
|
this.signature = null;
|
|
208
194
|
}, SIGNATURE_TTL);
|
|
209
195
|
}
|
|
210
|
-
this.emit(IdentifyEvent.SignatureUpdated, this.signature);
|
|
211
196
|
}
|
|
212
197
|
get signature() {
|
|
213
198
|
return this._signature;
|
|
214
199
|
}
|
|
215
|
-
set credentials(credentials) {
|
|
216
|
-
if (this._credentials === credentials) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
this._credentials = credentials;
|
|
220
|
-
this.emit(IdentifyEvent.CredentialsUpdated, credentials);
|
|
221
|
-
}
|
|
222
|
-
get credentials() {
|
|
223
|
-
return this._credentials;
|
|
224
|
-
}
|
|
225
200
|
set userData(data) {
|
|
226
201
|
if (this._userData === data) {
|
|
227
202
|
return;
|
|
228
203
|
}
|
|
229
204
|
this._userData = data;
|
|
230
|
-
clearTimeout(this.userDataExpireTimeout);
|
|
231
|
-
this.emit(IdentifyEvent.UserdataUpdated, data);
|
|
232
205
|
}
|
|
233
206
|
get userData() {
|
|
234
207
|
return this._userData;
|
|
235
208
|
}
|
|
236
|
-
get shouldLoginOnReconnect() {
|
|
237
|
-
return (this.wasLoggedIn &&
|
|
238
|
-
this.options.loginPolicy === 'auto' &&
|
|
239
|
-
this.credentials !== null);
|
|
240
|
-
}
|
|
241
|
-
reset() {
|
|
242
|
-
this.credentials = null;
|
|
243
|
-
this.userData = null;
|
|
244
|
-
this.signature = null;
|
|
245
|
-
this.wasLoggedIn = false;
|
|
246
|
-
}
|
|
247
209
|
async getUrl(path = '') {
|
|
248
|
-
const {
|
|
210
|
+
const { host, projectId } = this.sdk.options;
|
|
249
211
|
if (this.host === undefined) {
|
|
250
212
|
this.host = await Identify.fetchIdentifyHost(host, projectId);
|
|
251
213
|
}
|
|
252
214
|
const url = new URL(this.host);
|
|
253
|
-
const { version,
|
|
215
|
+
const { version, strategy, provider } = this._options;
|
|
254
216
|
url.pathname = `/v${version}${path}`;
|
|
255
217
|
url.searchParams.set('projectId', projectId);
|
|
256
|
-
url.searchParams.set('deviceId',
|
|
218
|
+
url.searchParams.set('deviceId', sdkCore.getDeviceId());
|
|
257
219
|
url.searchParams.set('strategy', strategy);
|
|
258
220
|
if (provider !== undefined) {
|
|
259
221
|
url.searchParams.set('provider', provider);
|
|
@@ -288,6 +250,101 @@ function deleteExperience(experience) {
|
|
|
288
250
|
}
|
|
289
251
|
}
|
|
290
252
|
|
|
253
|
+
/**
|
|
254
|
+
* @license
|
|
255
|
+
* @monterosa/sdk-identify-kit
|
|
256
|
+
*
|
|
257
|
+
* Copyright © 2026 Monterosa Productions Limited. All rights reserved.
|
|
258
|
+
*
|
|
259
|
+
* More details on the license can be found at https://www.monterosa.co/sdk/license
|
|
260
|
+
*/
|
|
261
|
+
/**
|
|
262
|
+
* Locally-owned login policy.
|
|
263
|
+
*
|
|
264
|
+
* Defaults to `'disabled'`. Set via the public `setLoginPolicy`. Never
|
|
265
|
+
* propagated across the wire — each level owns its own policy.
|
|
266
|
+
*
|
|
267
|
+
* @internal
|
|
268
|
+
*/
|
|
269
|
+
class LoginPolicyStore extends sdkUtil.Emitter {
|
|
270
|
+
constructor() {
|
|
271
|
+
super();
|
|
272
|
+
this._policy = 'disabled';
|
|
273
|
+
}
|
|
274
|
+
static getInstance() {
|
|
275
|
+
if (!LoginPolicyStore.instance) {
|
|
276
|
+
LoginPolicyStore.instance = new LoginPolicyStore();
|
|
277
|
+
}
|
|
278
|
+
return LoginPolicyStore.instance;
|
|
279
|
+
}
|
|
280
|
+
get policy() {
|
|
281
|
+
return this._policy;
|
|
282
|
+
}
|
|
283
|
+
set policy(next) {
|
|
284
|
+
if (this._policy === next) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
this._policy = next;
|
|
288
|
+
this.emit(IdentifyEvent.LoginPolicyUpdated, next);
|
|
289
|
+
}
|
|
290
|
+
subscribe(handler) {
|
|
291
|
+
return sdkUtil.subscribe(this, IdentifyEvent.LoginPolicyUpdated, handler);
|
|
292
|
+
}
|
|
293
|
+
reset() {
|
|
294
|
+
this._policy = 'disabled';
|
|
295
|
+
this.off(IdentifyEvent.LoginPolicyUpdated);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* @license
|
|
301
|
+
* @monterosa/sdk-identify-kit
|
|
302
|
+
*
|
|
303
|
+
* Copyright © 2026 Monterosa Productions Limited. All rights reserved.
|
|
304
|
+
*
|
|
305
|
+
* More details on the license can be found at https://www.monterosa.co/sdk/license
|
|
306
|
+
*/
|
|
307
|
+
/**
|
|
308
|
+
* Root-owned credentials slot.
|
|
309
|
+
*
|
|
310
|
+
* Single source of truth at the root of an integration; an internal
|
|
311
|
+
* mirror at every other level, kept in sync via `Login` / `Logout`
|
|
312
|
+
* broadcasts. Not exposed publicly — public access flows through
|
|
313
|
+
* `setCredentials` / `getCredentials` / `clearCredentials` and
|
|
314
|
+
* `onCredentialsUpdated`.
|
|
315
|
+
*
|
|
316
|
+
* @internal
|
|
317
|
+
*/
|
|
318
|
+
class CredentialsStore extends sdkUtil.Emitter {
|
|
319
|
+
constructor() {
|
|
320
|
+
super();
|
|
321
|
+
this._credentials = null;
|
|
322
|
+
}
|
|
323
|
+
static getInstance() {
|
|
324
|
+
if (!CredentialsStore.instance) {
|
|
325
|
+
CredentialsStore.instance = new CredentialsStore();
|
|
326
|
+
}
|
|
327
|
+
return CredentialsStore.instance;
|
|
328
|
+
}
|
|
329
|
+
get credentials() {
|
|
330
|
+
return this._credentials;
|
|
331
|
+
}
|
|
332
|
+
set credentials(next) {
|
|
333
|
+
if (this._credentials === next) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
this._credentials = next;
|
|
337
|
+
this.emit(IdentifyEvent.CredentialsUpdated, next);
|
|
338
|
+
}
|
|
339
|
+
subscribe(handler) {
|
|
340
|
+
return sdkUtil.subscribe(this, IdentifyEvent.CredentialsUpdated, handler);
|
|
341
|
+
}
|
|
342
|
+
reset() {
|
|
343
|
+
this._credentials = null;
|
|
344
|
+
this.off(IdentifyEvent.CredentialsUpdated);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
291
348
|
/**
|
|
292
349
|
* @license
|
|
293
350
|
* identify-kit
|
|
@@ -296,8 +353,87 @@ function deleteExperience(experience) {
|
|
|
296
353
|
*
|
|
297
354
|
* More details on the license can be found at https://www.monterosa.co/sdk/license
|
|
298
355
|
*/
|
|
356
|
+
const loginPolicyStore = LoginPolicyStore.getInstance();
|
|
357
|
+
const credentialsStore = CredentialsStore.getInstance();
|
|
358
|
+
/**
|
|
359
|
+
* @internal
|
|
360
|
+
*/
|
|
299
361
|
const identifyKits = new Map();
|
|
300
|
-
|
|
362
|
+
/**
|
|
363
|
+
* Emitter for identify request events that are not tied to a specific
|
|
364
|
+
* identify instance (login / logout requests).
|
|
365
|
+
*
|
|
366
|
+
* @internal
|
|
367
|
+
*/
|
|
368
|
+
const requestsEmitter = new sdkUtil.Emitter();
|
|
369
|
+
/**
|
|
370
|
+
* Read the current locally-owned login policy.
|
|
371
|
+
*
|
|
372
|
+
* Returns `'disabled'` by default.
|
|
373
|
+
*
|
|
374
|
+
* @internal
|
|
375
|
+
*/
|
|
376
|
+
function getLoginPolicy() {
|
|
377
|
+
return loginPolicyStore.policy;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Set the locally-owned login policy.
|
|
381
|
+
*
|
|
382
|
+
* All `Identify` instances at this level honour the same policy; the
|
|
383
|
+
* value is never propagated across the wire (each level of a multi-level
|
|
384
|
+
* integration owns its own policy).
|
|
385
|
+
*
|
|
386
|
+
* Policy gates the Enmasse `loginTask` only — credentials always mirror
|
|
387
|
+
* from upstream regardless of policy. A `'disabled'` level still
|
|
388
|
+
* receives credentials via the module-load pull and the cascading
|
|
389
|
+
* `Login` / `Logout` broadcasts; it just doesn't attempt Enmasse
|
|
390
|
+
* validation against them.
|
|
391
|
+
*
|
|
392
|
+
* When the policy transitions to `'auto'`, enqueues a sync-state task
|
|
393
|
+
* for every existing identify so that any in-flight session is picked
|
|
394
|
+
* up.
|
|
395
|
+
*
|
|
396
|
+
* Idempotent: setting the same policy that's already in effect is a
|
|
397
|
+
* no-op.
|
|
398
|
+
*
|
|
399
|
+
* @param policy - `'auto'` to enable auto-login, `'disabled'` to opt out.
|
|
400
|
+
*/
|
|
401
|
+
function setLoginPolicy(policy) {
|
|
402
|
+
if (loginPolicyStore.policy === policy) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
loginPolicyStore.policy = policy;
|
|
406
|
+
if (policy !== 'auto') {
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
// On transition to 'auto': if the local credentials slot already
|
|
410
|
+
// has a value (typical after the non-root module-load pull, or after
|
|
411
|
+
// a setCredentials at the root, or after an upstream Login broadcast
|
|
412
|
+
// has cascaded down), enqueue a login task for each existing
|
|
413
|
+
// identify. If the slot is empty, do nothing — a future credentials
|
|
414
|
+
// arrival via `applyLogin` will trigger the login under this new
|
|
415
|
+
// policy.
|
|
416
|
+
const { credentials } = credentialsStore;
|
|
417
|
+
if (credentials === null) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
for (const identify of identifyKits.values()) {
|
|
421
|
+
enqueueLogin(identify, credentials);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Whether the user should be auto-logged in on reconnect.
|
|
426
|
+
*
|
|
427
|
+
* True when the user was previously logged in, the policy is `'auto'`,
|
|
428
|
+
* and credentials are available on the identify instance.
|
|
429
|
+
*
|
|
430
|
+
* @internal
|
|
431
|
+
*/
|
|
432
|
+
function shouldLoginOnReconnect(identify) {
|
|
433
|
+
return (identify.wasLoggedIn &&
|
|
434
|
+
getLoginPolicy() === 'auto' &&
|
|
435
|
+
credentialsStore.credentials !== null);
|
|
436
|
+
}
|
|
301
437
|
/**
|
|
302
438
|
* @internal
|
|
303
439
|
*/
|
|
@@ -334,17 +470,13 @@ async function api(url, token, method = 'GET') {
|
|
|
334
470
|
/**
|
|
335
471
|
* @internal
|
|
336
472
|
*/
|
|
337
|
-
async function
|
|
338
|
-
var _a;
|
|
473
|
+
async function sendParentRequest(action, payload) {
|
|
339
474
|
const parentApp = sdkLauncherKit.getParentApplication();
|
|
340
475
|
if (parentApp === null) {
|
|
341
476
|
throw sdkUtil.createError(exports.IdentifyError.NoParentApplication, IdentifyErrorMessages);
|
|
342
477
|
}
|
|
343
|
-
const { host, projectId } = identify.sdk.options;
|
|
344
|
-
// Preserve existing origin (relay) or set from current context (source)
|
|
345
|
-
const origin = (_a = payload === null || payload === void 0 ? void 0 : payload.origin) !== null && _a !== void 0 ? _a : { host, projectId };
|
|
346
478
|
try {
|
|
347
|
-
const response = await sdkLauncherKit.sendSdkRequest(parentApp, action,
|
|
479
|
+
const response = await sdkLauncherKit.sendSdkRequest(parentApp, action, payload);
|
|
348
480
|
const { error, data } = response.payload;
|
|
349
481
|
if (error !== undefined) {
|
|
350
482
|
throw sdkUtil.createError(exports.IdentifyError.ParentAppError, IdentifyErrorMessages, error);
|
|
@@ -360,12 +492,6 @@ async function parentAppRequest(identify, action, payload) {
|
|
|
360
492
|
throw err;
|
|
361
493
|
}
|
|
362
494
|
}
|
|
363
|
-
/**
|
|
364
|
-
* @internal
|
|
365
|
-
*/
|
|
366
|
-
function registerIdentifyHook(hook) {
|
|
367
|
-
identifyHooks.push(hook);
|
|
368
|
-
}
|
|
369
495
|
/**
|
|
370
496
|
* @internal
|
|
371
497
|
*/
|
|
@@ -389,6 +515,9 @@ const logoutWithRetry = sdkUtil.withRetryAsync(logout);
|
|
|
389
515
|
* @internal
|
|
390
516
|
*/
|
|
391
517
|
async function loginTask(identify, credentials) {
|
|
518
|
+
if (identify.state.state === 'logged_in') {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
392
521
|
try {
|
|
393
522
|
identify.state = {
|
|
394
523
|
state: 'pending',
|
|
@@ -402,6 +531,11 @@ async function loginTask(identify, credentials) {
|
|
|
402
531
|
}
|
|
403
532
|
}
|
|
404
533
|
catch (err) {
|
|
534
|
+
// Abandon any pending login/logout/sync tasks on failure — letting
|
|
535
|
+
// them run after an error would put the user in an inconsistent
|
|
536
|
+
// state. Note: this also drops tasks for unrelated identifies that
|
|
537
|
+
// share the queue; acceptable because the typical runtime has one
|
|
538
|
+
// identify per project.
|
|
405
539
|
taskQueue.clear();
|
|
406
540
|
identify.state = {
|
|
407
541
|
state: 'error',
|
|
@@ -414,6 +548,9 @@ async function loginTask(identify, credentials) {
|
|
|
414
548
|
* @internal
|
|
415
549
|
*/
|
|
416
550
|
async function logoutTask(identify) {
|
|
551
|
+
if (identify.state.state === 'logged_out') {
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
417
554
|
try {
|
|
418
555
|
identify.state = {
|
|
419
556
|
state: 'pending',
|
|
@@ -427,6 +564,8 @@ async function logoutTask(identify) {
|
|
|
427
564
|
}
|
|
428
565
|
}
|
|
429
566
|
catch (err) {
|
|
567
|
+
// Abandon any pending login/logout/sync tasks on failure — see
|
|
568
|
+
// `loginTask` for the rationale.
|
|
430
569
|
taskQueue.clear();
|
|
431
570
|
identify.state = {
|
|
432
571
|
state: 'error',
|
|
@@ -436,15 +575,53 @@ async function logoutTask(identify) {
|
|
|
436
575
|
}
|
|
437
576
|
}
|
|
438
577
|
/**
|
|
578
|
+
* Enqueue a `loginTask` for the given identify when `policy === 'auto'`.
|
|
579
|
+
* The downstream `Login` broadcast is emitted by {@link applyLogin}.
|
|
580
|
+
*
|
|
439
581
|
* @internal
|
|
440
582
|
*/
|
|
441
583
|
function enqueueLogin(identify, credentials, prioritise = false) {
|
|
442
|
-
if (
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
584
|
+
if (getLoginPolicy() !== 'auto') {
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
if (prioritise) {
|
|
588
|
+
taskQueue.enqueueFront(() => loginTask(identify, credentials));
|
|
589
|
+
}
|
|
590
|
+
else {
|
|
591
|
+
taskQueue.enqueue(() => loginTask(identify, credentials));
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Reset the identify's identity-derived caches and enqueue a `logoutTask`
|
|
596
|
+
* when `policy === 'auto'`.
|
|
597
|
+
*
|
|
598
|
+
* @internal
|
|
599
|
+
*/
|
|
600
|
+
function enqueueLogout(identify) {
|
|
601
|
+
identify.userData = null;
|
|
602
|
+
identify.signature = null;
|
|
603
|
+
if (getLoginPolicy() !== 'auto') {
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
taskQueue.enqueue(() => logoutTask(identify));
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Apply new credentials at this level: update the slot, enqueue a
|
|
610
|
+
* `loginTask` for every existing identify on the null-to-set transition,
|
|
611
|
+
* and broadcast `Login` downstream to every embedded experience.
|
|
612
|
+
*
|
|
613
|
+
* Idempotent on token refresh: re-setting an already-set slot updates
|
|
614
|
+
* the value and broadcasts, but does not re-enqueue logins (their
|
|
615
|
+
* `loginTask` would short-circuit on `state === 'logged_in'` anyway).
|
|
616
|
+
*
|
|
617
|
+
* @internal
|
|
618
|
+
*/
|
|
619
|
+
function applyLogin(credentials) {
|
|
620
|
+
const shouldLogin = credentialsStore.credentials === null;
|
|
621
|
+
credentialsStore.credentials = credentials;
|
|
622
|
+
if (shouldLogin) {
|
|
623
|
+
for (const identify of identifyKits.values()) {
|
|
624
|
+
enqueueLogin(identify, credentials);
|
|
448
625
|
}
|
|
449
626
|
}
|
|
450
627
|
for (const experience of getExperiences()) {
|
|
@@ -452,14 +629,50 @@ function enqueueLogin(identify, credentials, prioritise = false) {
|
|
|
452
629
|
}
|
|
453
630
|
}
|
|
454
631
|
/**
|
|
632
|
+
* Clear credentials at this level: null out the slot, enqueue a
|
|
633
|
+
* `logoutTask` for every existing identify on the set-to-null
|
|
634
|
+
* transition, and broadcast `Logout` downstream to every embedded
|
|
635
|
+
* experience.
|
|
636
|
+
*
|
|
455
637
|
* @internal
|
|
456
638
|
*/
|
|
457
|
-
function
|
|
458
|
-
|
|
459
|
-
|
|
639
|
+
function applyLogout() {
|
|
640
|
+
const shouldLogout = credentialsStore.credentials !== null;
|
|
641
|
+
credentialsStore.credentials = null;
|
|
642
|
+
if (shouldLogout) {
|
|
643
|
+
for (const identify of identifyKits.values()) {
|
|
644
|
+
enqueueLogout(identify);
|
|
645
|
+
}
|
|
460
646
|
}
|
|
461
647
|
for (const experience of getExperiences()) {
|
|
462
|
-
sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.Logout);
|
|
648
|
+
sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.Logout, {});
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Pull state from the parent application and apply locally.
|
|
653
|
+
*
|
|
654
|
+
* Fires once at non-root bridge module load, regardless of
|
|
655
|
+
* `loginPolicy` — token presence is the customer-side sign-in state and
|
|
656
|
+
* must mirror upstream whether or not we choose to validate against
|
|
657
|
+
* Enmasse. Best-effort: a missing or non-identify-kit parent silently
|
|
658
|
+
* resolves with no slot change.
|
|
659
|
+
*
|
|
660
|
+
* Uses {@link applyLogin} so the slot update cascades downstream to
|
|
661
|
+
* this level's own embedded experiences and per-identify loginTasks
|
|
662
|
+
* are enqueued under `loginPolicy === 'auto'`.
|
|
663
|
+
*
|
|
664
|
+
* @internal
|
|
665
|
+
*/
|
|
666
|
+
async function pullStateFromParent() {
|
|
667
|
+
let credentials;
|
|
668
|
+
try {
|
|
669
|
+
credentials = await getCredentials();
|
|
670
|
+
}
|
|
671
|
+
catch (_a) {
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
if (credentials !== null) {
|
|
675
|
+
applyLogin(credentials);
|
|
463
676
|
}
|
|
464
677
|
}
|
|
465
678
|
function getIdentify(sdkOrOptions, options) {
|
|
@@ -491,36 +704,31 @@ function getIdentify(sdkOrOptions, options) {
|
|
|
491
704
|
sdk = sdkCore.getSdk();
|
|
492
705
|
identifyOptions = {};
|
|
493
706
|
}
|
|
494
|
-
const {
|
|
707
|
+
const { projectId } = sdk.options;
|
|
495
708
|
if (identifyKits.has(projectId)) {
|
|
496
709
|
return identifyKits.get(projectId);
|
|
497
710
|
}
|
|
498
711
|
const identify = new Identify(sdk, identifyOptions);
|
|
499
|
-
for (const hook of identifyHooks) {
|
|
500
|
-
hook(identify);
|
|
501
|
-
}
|
|
502
712
|
watchConnectionStatus(identify);
|
|
503
713
|
identifyKits.set(projectId, identify);
|
|
504
714
|
return identify;
|
|
505
715
|
}
|
|
506
716
|
/**
|
|
507
|
-
*
|
|
717
|
+
* Requests a user login.
|
|
508
718
|
*
|
|
509
719
|
* @example
|
|
510
720
|
* ```javascript
|
|
511
721
|
* import { configure } from '@monterosa/sdk-core';
|
|
512
|
-
* import {
|
|
722
|
+
* import { requestLogin } from '@monterosa/sdk-identify-kit';
|
|
513
723
|
*
|
|
514
724
|
* configure({ host: '...', projectId: '...' });
|
|
515
725
|
*
|
|
516
726
|
* try {
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
* await requestLogin(identify);
|
|
727
|
+
* await requestLogin();
|
|
520
728
|
*
|
|
521
729
|
* console.log('Login request successful');
|
|
522
730
|
* } catch (err) {
|
|
523
|
-
* console.error('Error requesting login:',
|
|
731
|
+
* console.error('Error requesting login:', err.message)
|
|
524
732
|
* }
|
|
525
733
|
* ```
|
|
526
734
|
*
|
|
@@ -529,56 +737,67 @@ function getIdentify(sdkOrOptions, options) {
|
|
|
529
737
|
* the Monterosa SDK, the function delegates to the parent app
|
|
530
738
|
* to handle the login process.
|
|
531
739
|
*
|
|
532
|
-
* @param identify - An instance of the `IdentifyKit` class used for user
|
|
533
|
-
* identification.
|
|
534
740
|
* @returns A Promise that resolves with `void` when the login request
|
|
535
741
|
* is completed.
|
|
536
742
|
*/
|
|
537
|
-
async function requestLogin(
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
await parentAppRequest(identify, IdentifyAction.RequestLogin);
|
|
743
|
+
async function requestLogin() {
|
|
744
|
+
if (sdkLauncherKit.getParentApplication() !== null) {
|
|
745
|
+
await sendParentRequest(IdentifyAction.RequestLogin);
|
|
541
746
|
return;
|
|
542
747
|
}
|
|
543
|
-
|
|
748
|
+
requestsEmitter.emit(IdentifyEvent.LoginRequested);
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Read the current credentials, pulling from the parent application when
|
|
752
|
+
* called from an embedded experience.
|
|
753
|
+
*
|
|
754
|
+
* At the root this returns the canonical slot value. At a non-root
|
|
755
|
+
* experience this dispatches a `GetCredentials` request upstream and
|
|
756
|
+
* resolves with the response, ensuring the caller always sees the
|
|
757
|
+
* authoritative value rather than a possibly-stale local mirror.
|
|
758
|
+
*
|
|
759
|
+
* @returns A Promise that resolves to the current credentials, or `null`
|
|
760
|
+
* if none are set.
|
|
761
|
+
*/
|
|
762
|
+
async function getCredentials() {
|
|
763
|
+
if (sdkLauncherKit.getParentApplication() === null) {
|
|
764
|
+
return credentialsStore.credentials;
|
|
765
|
+
}
|
|
766
|
+
return sendParentRequest(IdentifyAction.GetCredentials);
|
|
544
767
|
}
|
|
545
768
|
/**
|
|
546
|
-
*
|
|
769
|
+
* Requests a user logout.
|
|
547
770
|
*
|
|
548
771
|
* @example
|
|
549
772
|
* ```javascript
|
|
550
|
-
* import {
|
|
551
|
-
* import {
|
|
773
|
+
* import { configure } from '@monterosa/sdk-core';
|
|
774
|
+
* import { requestLogout } from '@monterosa/sdk-identify-kit';
|
|
552
775
|
*
|
|
553
|
-
*
|
|
554
|
-
* const identify = getIdentify(space);
|
|
776
|
+
* configure({ host: '...', projectId: '...' });
|
|
555
777
|
*
|
|
556
778
|
* try {
|
|
557
|
-
* await requestLogout(
|
|
779
|
+
* await requestLogout();
|
|
558
780
|
*
|
|
559
781
|
* console.log('Logout request successful');
|
|
560
782
|
* } catch (err) {
|
|
561
|
-
* console.error('Error requesting logout:',
|
|
783
|
+
* console.error('Error requesting logout:', err.message)
|
|
562
784
|
* }
|
|
563
785
|
* ```
|
|
564
786
|
*
|
|
565
787
|
* @remarks
|
|
566
788
|
* - If the app is running within a third-party application that uses
|
|
567
|
-
* the
|
|
789
|
+
* the Monterosa SDK, the function delegates to the parent app
|
|
568
790
|
* to handle the logout process.
|
|
569
791
|
*
|
|
570
|
-
* @param identify - An instance of the `IdentifyKit` class used for user
|
|
571
|
-
* identification.
|
|
572
792
|
* @returns A Promise that resolves with `void` when the logout request
|
|
573
793
|
* is completed.
|
|
574
794
|
*/
|
|
575
|
-
async function requestLogout(
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
await parentAppRequest(identify, IdentifyAction.RequestLogout);
|
|
795
|
+
async function requestLogout() {
|
|
796
|
+
if (sdkLauncherKit.getParentApplication() !== null) {
|
|
797
|
+
await sendParentRequest(IdentifyAction.RequestLogout);
|
|
579
798
|
return;
|
|
580
799
|
}
|
|
581
|
-
|
|
800
|
+
requestsEmitter.emit(IdentifyEvent.LogoutRequested);
|
|
582
801
|
}
|
|
583
802
|
/**
|
|
584
803
|
* @internal
|
|
@@ -597,11 +816,6 @@ async function requestLogout(identify) {
|
|
|
597
816
|
* @returns A Promise that resolves to a `Signature` object.
|
|
598
817
|
*/
|
|
599
818
|
async function getSessionSignature(identify, credentials) {
|
|
600
|
-
const parentApp = sdkLauncherKit.getParentApplication();
|
|
601
|
-
if (parentApp !== null) {
|
|
602
|
-
const signature = await parentAppRequest(identify, IdentifyAction.GetSessionSignature, credentials);
|
|
603
|
-
return signature;
|
|
604
|
-
}
|
|
605
819
|
if (identify.signature !== null) {
|
|
606
820
|
return identify.signature;
|
|
607
821
|
}
|
|
@@ -612,59 +826,60 @@ async function getSessionSignature(identify, credentials) {
|
|
|
612
826
|
return signature;
|
|
613
827
|
}
|
|
614
828
|
/**
|
|
615
|
-
* A memoized version of the `getSessionSignature` function.
|
|
829
|
+
* A memoized version of the `getSessionSignature` function. Memo key is
|
|
830
|
+
* the credentials token, so both leaf-side and bridge-side callers share
|
|
831
|
+
* the same cache for the same token.
|
|
616
832
|
*/
|
|
617
833
|
const getSessionSignatureMemoized = sdkUtil.memoizePromise(getSessionSignature, (identify, credentials) => credentials.token, {
|
|
618
834
|
clearOnResolve: true,
|
|
619
835
|
clearOnReject: true,
|
|
620
836
|
});
|
|
621
837
|
/**
|
|
622
|
-
*
|
|
623
|
-
*
|
|
838
|
+
* Fetches user data for the given credentials.
|
|
839
|
+
*
|
|
840
|
+
* Credentials are required explicitly so the precondition is visible at
|
|
841
|
+
* the call site — without them the function cannot be called. Obtain a
|
|
842
|
+
* `Credentials` value via {@link getCredentials} or the
|
|
843
|
+
* {@link onCredentialsUpdated} callback.
|
|
624
844
|
*
|
|
625
845
|
* @example
|
|
626
846
|
* ```javascript
|
|
627
847
|
* import { configure } from '@monterosa/sdk-core';
|
|
628
|
-
* import {
|
|
848
|
+
* import {
|
|
849
|
+
* getIdentify,
|
|
850
|
+
* getUserData,
|
|
851
|
+
* getCredentials,
|
|
852
|
+
* } from '@monterosa/sdk-identify-kit';
|
|
629
853
|
*
|
|
630
854
|
* configure({ host: '...', projectId: '...' });
|
|
631
855
|
*
|
|
632
856
|
* const identify = getIdentify();
|
|
633
|
-
* const
|
|
857
|
+
* const credentials = await getCredentials();
|
|
634
858
|
*
|
|
635
|
-
*
|
|
859
|
+
* if (credentials !== null) {
|
|
860
|
+
* const userData = await getUserData(identify, credentials);
|
|
861
|
+
* console.log('User data:', userData);
|
|
862
|
+
* }
|
|
636
863
|
* ```
|
|
637
864
|
*
|
|
638
865
|
* @remarks
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
* to get user data.
|
|
642
|
-
*
|
|
643
|
-
* - If the request is successful, the function resolves with a key-value object
|
|
644
|
-
* representing user data. If not, a `MonterosaError` is thrown.
|
|
866
|
+
* Cached on the identify instance after the first successful fetch.
|
|
867
|
+
* Cleared on {@link clearCredentials} via the logout path.
|
|
645
868
|
*
|
|
646
869
|
* @param identify - An instance of `IdentifyKit` that provides the user
|
|
647
870
|
* identification functionality.
|
|
648
|
-
* @
|
|
649
|
-
*
|
|
650
|
-
*
|
|
651
|
-
*
|
|
871
|
+
* @param credentials - The user's authentication credentials. The
|
|
872
|
+
* request authorises against the value's token.
|
|
873
|
+
* @returns A Promise that resolves to a key-value object representing
|
|
874
|
+
* user data. The structure and content of the user data object depend
|
|
875
|
+
* on the identify service provider and may vary.
|
|
652
876
|
*/
|
|
653
|
-
async function getUserData(identify) {
|
|
654
|
-
const parentApp = sdkLauncherKit.getParentApplication();
|
|
655
|
-
if (parentApp !== null) {
|
|
656
|
-
const userData = await parentAppRequest(identify, IdentifyAction.GetUserData);
|
|
657
|
-
return userData;
|
|
658
|
-
}
|
|
659
|
-
// Return cached user data if available
|
|
877
|
+
async function getUserData(identify, credentials) {
|
|
660
878
|
if (identify.userData !== null) {
|
|
661
879
|
return identify.userData;
|
|
662
880
|
}
|
|
663
|
-
if (identify.credentials === null) {
|
|
664
|
-
throw sdkUtil.createError(exports.IdentifyError.NoCredentials, IdentifyErrorMessages);
|
|
665
|
-
}
|
|
666
881
|
const url = await identify.getUrl('/user');
|
|
667
|
-
const { data } = await api(url,
|
|
882
|
+
const { data } = await api(url, credentials.token);
|
|
668
883
|
identify.userData = data;
|
|
669
884
|
return data;
|
|
670
885
|
}
|
|
@@ -674,41 +889,32 @@ async function getUserData(identify) {
|
|
|
674
889
|
* @example
|
|
675
890
|
* ```javascript
|
|
676
891
|
* import { configure } from '@monterosa/sdk-core';
|
|
677
|
-
* import {
|
|
892
|
+
* import { setCredentials } from '@monterosa/sdk-identify-kit';
|
|
678
893
|
*
|
|
679
894
|
* configure({ host: '...', projectId: '...' });
|
|
680
895
|
*
|
|
681
|
-
*
|
|
682
|
-
* const identify = getIdentify();
|
|
683
|
-
*
|
|
684
|
-
* await setCredentials(identify, credentials)
|
|
896
|
+
* await setCredentials({ token: 'abc123' });
|
|
685
897
|
* ```
|
|
686
898
|
*
|
|
687
899
|
* @remarks
|
|
688
|
-
* -
|
|
689
|
-
*
|
|
690
|
-
*
|
|
900
|
+
* - At the root of an integration, the credentials are stored locally
|
|
901
|
+
* and a `Login` broadcast is sent to every embedded experience.
|
|
902
|
+
* - When called from an embedded experience, the call is relayed
|
|
903
|
+
* upstream via the `SetCredentials` wire action. The credentials are
|
|
904
|
+
* ultimately applied at the root and propagate back down via the
|
|
905
|
+
* cascading `Login` broadcast.
|
|
691
906
|
*
|
|
692
|
-
* - If the request is successful, the function resolves to `void`.
|
|
693
|
-
* If not, a `MonterosaError` is thrown.
|
|
694
|
-
*
|
|
695
|
-
* @param identify - An instance of `IdentifyKit` that provides the user
|
|
696
|
-
* identification functionality.
|
|
697
907
|
* @param credentials - An object representing the user's authentication
|
|
698
908
|
* credentials.
|
|
699
|
-
* @returns A Promise that resolves to `void
|
|
909
|
+
* @returns A Promise that resolves to `void` once the credentials have
|
|
910
|
+
* been written (root) or the upstream relay has completed (non-root).
|
|
700
911
|
*/
|
|
701
|
-
async function setCredentials(
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
await parentAppRequest(identify, IdentifyAction.SetCredentials, credentials);
|
|
912
|
+
async function setCredentials(credentials) {
|
|
913
|
+
if (sdkLauncherKit.getParentApplication() !== null) {
|
|
914
|
+
await sendParentRequest(IdentifyAction.SetCredentials, credentials);
|
|
705
915
|
return;
|
|
706
916
|
}
|
|
707
|
-
|
|
708
|
-
identify.credentials = credentials;
|
|
709
|
-
if (shouldLogin) {
|
|
710
|
-
enqueueLogin(identify, credentials);
|
|
711
|
-
}
|
|
917
|
+
applyLogin(credentials);
|
|
712
918
|
}
|
|
713
919
|
/**
|
|
714
920
|
* Clears the user's authentication credentials.
|
|
@@ -716,40 +922,30 @@ async function setCredentials(identify, credentials) {
|
|
|
716
922
|
* @example
|
|
717
923
|
* ```javascript
|
|
718
924
|
* import { configure } from '@monterosa/sdk-core';
|
|
719
|
-
* import {
|
|
925
|
+
* import { clearCredentials } from '@monterosa/sdk-identify-kit';
|
|
720
926
|
*
|
|
721
927
|
* configure({ host: '...', projectId: '...' });
|
|
722
928
|
*
|
|
723
|
-
*
|
|
724
|
-
*
|
|
725
|
-
* await clearCredentials(identify);
|
|
929
|
+
* await clearCredentials();
|
|
726
930
|
* ```
|
|
727
931
|
*
|
|
728
932
|
* @remarks
|
|
729
|
-
* -
|
|
730
|
-
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
733
|
-
*
|
|
734
|
-
*
|
|
735
|
-
*
|
|
736
|
-
* @
|
|
737
|
-
*
|
|
738
|
-
* @returns A Promise that resolves to `void`.
|
|
933
|
+
* - At the root of an integration, the credentials slot is cleared and
|
|
934
|
+
* a `Logout` broadcast is sent to every embedded experience.
|
|
935
|
+
* - When called from an embedded experience, the call is relayed
|
|
936
|
+
* upstream via the `ClearCredentials` wire action. The slot is
|
|
937
|
+
* cleared at the root and the cascading `Logout` broadcast propagates
|
|
938
|
+
* back down.
|
|
939
|
+
*
|
|
940
|
+
* @returns A Promise that resolves to `void` once the slot has been
|
|
941
|
+
* cleared (root) or the upstream relay has completed (non-root).
|
|
739
942
|
*/
|
|
740
|
-
async function clearCredentials(
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
await parentAppRequest(identify, IdentifyAction.ClearCredentials);
|
|
943
|
+
async function clearCredentials() {
|
|
944
|
+
if (sdkLauncherKit.getParentApplication() !== null) {
|
|
945
|
+
await sendParentRequest(IdentifyAction.ClearCredentials);
|
|
744
946
|
return;
|
|
745
947
|
}
|
|
746
|
-
|
|
747
|
-
identify.credentials = null;
|
|
748
|
-
identify.userData = null;
|
|
749
|
-
identify.signature = null;
|
|
750
|
-
if (shouldLogout) {
|
|
751
|
-
enqueueLogout(identify);
|
|
752
|
-
}
|
|
948
|
+
applyLogout();
|
|
753
949
|
}
|
|
754
950
|
/**
|
|
755
951
|
* Registers a callback function that will be called whenever the `LoginState`
|
|
@@ -783,19 +979,17 @@ function onStateUpdated(identify, callback) {
|
|
|
783
979
|
return sdkUtil.subscribe(identify, IdentifyEvent.StateUpdated, callback);
|
|
784
980
|
}
|
|
785
981
|
/**
|
|
786
|
-
* Registers a callback function that will be called whenever the
|
|
787
|
-
*
|
|
982
|
+
* Registers a callback function that will be called whenever the
|
|
983
|
+
* credentials slot is updated.
|
|
788
984
|
*
|
|
789
985
|
* @example
|
|
790
986
|
* ```javascript
|
|
791
987
|
* import { configure } from '@monterosa/sdk-core';
|
|
792
|
-
* import {
|
|
988
|
+
* import { onCredentialsUpdated } from '@monterosa/sdk-identify-kit';
|
|
793
989
|
*
|
|
794
990
|
* configure({ host: '...', projectId: '...' });
|
|
795
991
|
*
|
|
796
|
-
* const
|
|
797
|
-
*
|
|
798
|
-
* const unsubscribe = onCredentialsUpdated(identify, (credentials) => {
|
|
992
|
+
* const unsubscribe = onCredentialsUpdated((credentials) => {
|
|
799
993
|
* if (credentials !== null) {
|
|
800
994
|
* console.log("Credentials updated:", credentials);
|
|
801
995
|
* } else {
|
|
@@ -807,91 +1001,15 @@ function onStateUpdated(identify, callback) {
|
|
|
807
1001
|
* // unsubscribe();
|
|
808
1002
|
* ```
|
|
809
1003
|
*
|
|
810
|
-
* @param identify - An instance of `IdentifyKit` that provides the user
|
|
811
|
-
* identification functionality.
|
|
812
1004
|
* @param callback - The callback function to register. This function will be
|
|
813
1005
|
* called with the updated `Credentials` object as its only argument.
|
|
814
|
-
* If the value `null` is received, it indicates that the
|
|
815
|
-
* been cleared
|
|
1006
|
+
* If the value `null` is received, it indicates that the credentials have
|
|
1007
|
+
* been cleared.
|
|
816
1008
|
* @returns An `Unsubscribe` function that can be called to unregister
|
|
817
1009
|
* the callback function.
|
|
818
1010
|
*/
|
|
819
|
-
function onCredentialsUpdated(
|
|
820
|
-
return
|
|
821
|
-
}
|
|
822
|
-
/**
|
|
823
|
-
* Registers a callback function that will be called whenever the `Signature`
|
|
824
|
-
* object associated with the `IdentifyKit` instance is updated.
|
|
825
|
-
*
|
|
826
|
-
* @example
|
|
827
|
-
* ```javascript
|
|
828
|
-
* import { configure } from '@monterosa/sdk-core';
|
|
829
|
-
* import { getIdentify, onSignatureUpdated } from '@monterosa/sdk-identify-kit';
|
|
830
|
-
*
|
|
831
|
-
* configure({ host: '...', projectId: '...' });
|
|
832
|
-
*
|
|
833
|
-
* const identify = getIdentify();
|
|
834
|
-
*
|
|
835
|
-
* const unsubscribe = onSignatureUpdated(identify, (signature) => {
|
|
836
|
-
* if (signature !== null) {
|
|
837
|
-
* console.log("Signature updated:", signature);
|
|
838
|
-
* } else {
|
|
839
|
-
* console.log("Signature cleared.");
|
|
840
|
-
* }
|
|
841
|
-
* });
|
|
842
|
-
*
|
|
843
|
-
* // Call unsubscribe() to unregister the callback function
|
|
844
|
-
* // unsubscribe();
|
|
845
|
-
* ```
|
|
846
|
-
*
|
|
847
|
-
* @param identify - An instance of `IdentifyKit` that provides the user
|
|
848
|
-
* identification functionality.
|
|
849
|
-
* @param callback - The callback function to register. This function will be
|
|
850
|
-
* called with the updated `Signature` object as its only argument.
|
|
851
|
-
* If the value `null` is received, it indicates that the signature has
|
|
852
|
-
* been cleared
|
|
853
|
-
* @returns An `Unsubscribe` function that can be called to unregister
|
|
854
|
-
* the callback function.
|
|
855
|
-
*/
|
|
856
|
-
function onSignatureUpdated(identify, callback) {
|
|
857
|
-
return sdkUtil.subscribe(identify, IdentifyEvent.SignatureUpdated, callback);
|
|
858
|
-
}
|
|
859
|
-
/**
|
|
860
|
-
* Registers a callback function that will be called whenever the `UserData`
|
|
861
|
-
* object associated with the `IdentifyKit` instance is updated.
|
|
862
|
-
*
|
|
863
|
-
* @example
|
|
864
|
-
* ```javascript
|
|
865
|
-
* import { configure } from '@monterosa/sdk-core';
|
|
866
|
-
* import { getIdentify, onUserDataUpdated } from '@monterosa/sdk-identify-kit';
|
|
867
|
-
*
|
|
868
|
-
* configure({ host: '...', projectId: '...' });
|
|
869
|
-
*
|
|
870
|
-
* const identify = getIdentify();
|
|
871
|
-
*
|
|
872
|
-
* const unsubscribe = onUserDataUpdated(identify, (userData) => {
|
|
873
|
-
* if (userData !== null) {
|
|
874
|
-
* console.log("User's data updated:", userData);
|
|
875
|
-
* } else {
|
|
876
|
-
* console.log("User's data cleared.");
|
|
877
|
-
* }
|
|
878
|
-
* });
|
|
879
|
-
*
|
|
880
|
-
* // Call unsubscribe() to unregister the callback function
|
|
881
|
-
* // unsubscribe();
|
|
882
|
-
* ```
|
|
883
|
-
*
|
|
884
|
-
* @param identify - An instance of `IdentifyKit` that provides the user
|
|
885
|
-
* identification functionality.
|
|
886
|
-
* @param callback - The callback function to register. This function will be
|
|
887
|
-
* called with the updated `UserData` object as its only argument.
|
|
888
|
-
* If the value `null` is received, it indicates that the user's data has
|
|
889
|
-
* been cleared
|
|
890
|
-
* @returns An `Unsubscribe` function that can be called to unregister
|
|
891
|
-
* the callback function.
|
|
892
|
-
*/
|
|
893
|
-
function onUserDataUpdated(identify, callback) {
|
|
894
|
-
return sdkUtil.subscribe(identify, IdentifyEvent.UserdataUpdated, callback);
|
|
1011
|
+
function onCredentialsUpdated(callback) {
|
|
1012
|
+
return credentialsStore.subscribe(callback);
|
|
895
1013
|
}
|
|
896
1014
|
/**
|
|
897
1015
|
* Registers a callback function that will be called when a login is requested
|
|
@@ -900,13 +1018,11 @@ function onUserDataUpdated(identify, callback) {
|
|
|
900
1018
|
* @example
|
|
901
1019
|
* ```javascript
|
|
902
1020
|
* import { configure } from '@monterosa/sdk-core';
|
|
903
|
-
* import {
|
|
1021
|
+
* import { onLoginRequestedByExperience } from '@monterosa/sdk-identify-kit';
|
|
904
1022
|
*
|
|
905
1023
|
* configure({ host: '...', projectId: '...' });
|
|
906
1024
|
*
|
|
907
|
-
* const
|
|
908
|
-
*
|
|
909
|
-
* const unsubscribe = onLoginRequestedByExperience(identify, () => {
|
|
1025
|
+
* const unsubscribe = onLoginRequestedByExperience(() => {
|
|
910
1026
|
* showLoginForm();
|
|
911
1027
|
* });
|
|
912
1028
|
*
|
|
@@ -914,15 +1030,13 @@ function onUserDataUpdated(identify, callback) {
|
|
|
914
1030
|
* // unsubscribe();
|
|
915
1031
|
* ```
|
|
916
1032
|
*
|
|
917
|
-
* @param identify - An instance of `IdentifyKit` that provides the user
|
|
918
|
-
* identification functionality.
|
|
919
1033
|
* @param callback - The callback function to register. This function will
|
|
920
1034
|
* be called when a login is requested by an Experience.
|
|
921
1035
|
* @returns An `Unsubscribe` function that can be called to unregister
|
|
922
1036
|
* the callback function.
|
|
923
1037
|
*/
|
|
924
|
-
function onLoginRequestedByExperience(
|
|
925
|
-
return sdkUtil.subscribe(
|
|
1038
|
+
function onLoginRequestedByExperience(callback) {
|
|
1039
|
+
return sdkUtil.subscribe(requestsEmitter, IdentifyEvent.LoginRequested, callback);
|
|
926
1040
|
}
|
|
927
1041
|
/**
|
|
928
1042
|
* Registers a callback function that will be called when a logout is requested
|
|
@@ -930,13 +1044,12 @@ function onLoginRequestedByExperience(identify, callback) {
|
|
|
930
1044
|
*
|
|
931
1045
|
* @example
|
|
932
1046
|
* ```javascript
|
|
933
|
-
* import {
|
|
934
|
-
* import {
|
|
1047
|
+
* import { configure } from '@monterosa/sdk-core';
|
|
1048
|
+
* import { onLogoutRequestedByExperience } from '@monterosa/sdk-identify-kit';
|
|
935
1049
|
*
|
|
936
|
-
*
|
|
937
|
-
* const identify = getIdentify(space);
|
|
1050
|
+
* configure({ host: '...', projectId: '...' });
|
|
938
1051
|
*
|
|
939
|
-
* const unsubscribe = onLogoutRequestedByExperience(
|
|
1052
|
+
* const unsubscribe = onLogoutRequestedByExperience(() => {
|
|
940
1053
|
* // logout requested by experience
|
|
941
1054
|
* // perform logout from Auth service
|
|
942
1055
|
* });
|
|
@@ -945,15 +1058,13 @@ function onLoginRequestedByExperience(identify, callback) {
|
|
|
945
1058
|
* // unsubscribe();
|
|
946
1059
|
* ```
|
|
947
1060
|
*
|
|
948
|
-
* @param identify - An instance of `IdentifyKit` that provides the user
|
|
949
|
-
* identification functionality.
|
|
950
1061
|
* @param callback - The callback function to register. This function will
|
|
951
1062
|
* be called when a logout is requested by an Experience.
|
|
952
1063
|
* @returns An `Unsubscribe` function that can be called to unregister
|
|
953
1064
|
* the callback function.
|
|
954
1065
|
*/
|
|
955
|
-
function onLogoutRequestedByExperience(
|
|
956
|
-
return sdkUtil.subscribe(
|
|
1066
|
+
function onLogoutRequestedByExperience(callback) {
|
|
1067
|
+
return sdkUtil.subscribe(requestsEmitter, IdentifyEvent.LogoutRequested, callback);
|
|
957
1068
|
}
|
|
958
1069
|
/**
|
|
959
1070
|
*
|
|
@@ -962,8 +1073,8 @@ function onLogoutRequestedByExperience(identify, callback) {
|
|
|
962
1073
|
async function watchConnectionStatus(identify) {
|
|
963
1074
|
const conn = await sdkConnectKit.getConnect(identify.sdk.options.host);
|
|
964
1075
|
sdkConnectKit.onConnected(conn, () => {
|
|
965
|
-
if (identify
|
|
966
|
-
enqueueLogin(identify,
|
|
1076
|
+
if (shouldLoginOnReconnect(identify)) {
|
|
1077
|
+
enqueueLogin(identify, credentialsStore.credentials, true);
|
|
967
1078
|
}
|
|
968
1079
|
taskQueue.resume();
|
|
969
1080
|
});
|
|
@@ -1000,115 +1111,59 @@ async function watchConnectionStatus(identify) {
|
|
|
1000
1111
|
* More details on the license can be found at https://www.monterosa.co/sdk/license
|
|
1001
1112
|
*/
|
|
1002
1113
|
/**
|
|
1114
|
+
* Process an incoming `Login` / `Logout` broadcast from the parent
|
|
1115
|
+
* application. Updates the local credentials slot, enqueues login/logout
|
|
1116
|
+
* for every existing identify, and forwards the broadcast downstream to
|
|
1117
|
+
* this level's own embedded experiences — the mechanism that cascades a
|
|
1118
|
+
* root-level `setCredentials` through every nested experience.
|
|
1119
|
+
*
|
|
1003
1120
|
* @internal
|
|
1004
1121
|
*/
|
|
1005
|
-
function
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
return sdkLauncherKit.onSdkMessage(parentApp, async (message) => {
|
|
1011
|
-
switch (message.action) {
|
|
1012
|
-
case IdentifyAction.OnCredentialsUpdated: {
|
|
1013
|
-
identify.credentials = message.payload.data;
|
|
1014
|
-
break;
|
|
1015
|
-
}
|
|
1016
|
-
case IdentifyAction.OnSessionSignatureUpdated: {
|
|
1017
|
-
identify.signature = message.payload.data;
|
|
1018
|
-
break;
|
|
1019
|
-
}
|
|
1020
|
-
case IdentifyAction.OnUserDataUpdated: {
|
|
1021
|
-
identify.userData = message.payload.data;
|
|
1022
|
-
break;
|
|
1023
|
-
}
|
|
1024
|
-
case IdentifyAction.Login: {
|
|
1025
|
-
enqueueLogin(identify, message.payload);
|
|
1026
|
-
break;
|
|
1027
|
-
}
|
|
1028
|
-
case IdentifyAction.Logout: {
|
|
1029
|
-
enqueueLogout(identify);
|
|
1030
|
-
break;
|
|
1031
|
-
}
|
|
1122
|
+
function handleParentMessage(message) {
|
|
1123
|
+
switch (message.action) {
|
|
1124
|
+
case IdentifyAction.Login: {
|
|
1125
|
+
applyLogin(message.payload);
|
|
1126
|
+
break;
|
|
1032
1127
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
function getOrConfigureSdk(host, projectId) {
|
|
1039
|
-
const existingSdk = sdkCore.getSdks().find((sdk) => sdk.options.projectId === projectId);
|
|
1040
|
-
return existingSdk !== null && existingSdk !== void 0 ? existingSdk : sdkCore.configure({ host, projectId }, projectId);
|
|
1128
|
+
case IdentifyAction.Logout: {
|
|
1129
|
+
applyLogout();
|
|
1130
|
+
break;
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1041
1133
|
}
|
|
1042
1134
|
/**
|
|
1043
1135
|
* @internal
|
|
1044
1136
|
*/
|
|
1045
1137
|
function handleExperienceEmbedded(experience) {
|
|
1046
|
-
const identify = getIdentify(experience.sdk);
|
|
1047
|
-
// Send login action with current credentials to the new experience if available.
|
|
1048
|
-
// The bridge queues this message until the experience is initialised.
|
|
1049
|
-
if (identify.credentials) {
|
|
1050
|
-
sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.Login, identify.credentials);
|
|
1051
|
-
}
|
|
1052
|
-
const credentialsUpdatedUnsub = onCredentialsUpdated(identify, (data) => {
|
|
1053
|
-
sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.OnCredentialsUpdated, {
|
|
1054
|
-
data,
|
|
1055
|
-
});
|
|
1056
|
-
});
|
|
1057
|
-
const signatureUpdatedUnsub = onSignatureUpdated(identify, (data) => {
|
|
1058
|
-
sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.OnSessionSignatureUpdated, {
|
|
1059
|
-
data,
|
|
1060
|
-
});
|
|
1061
|
-
});
|
|
1062
|
-
const userDataUpdatedUnsub = onUserDataUpdated(identify, (data) => {
|
|
1063
|
-
sdkLauncherKit.sendSdkMessage(experience, IdentifyAction.OnUserDataUpdated, {
|
|
1064
|
-
data,
|
|
1065
|
-
});
|
|
1066
|
-
});
|
|
1067
1138
|
const sdkMessageUnsub = sdkLauncherKit.onSdkMessage(experience, async (message) => {
|
|
1068
1139
|
if (!Object.values(IdentifyAction).includes(message.action)) {
|
|
1069
1140
|
return;
|
|
1070
1141
|
}
|
|
1071
|
-
// Extract origin context from payload if available.
|
|
1072
|
-
// New clients include origin (host, projectId) to ensure correct project context
|
|
1073
|
-
// in multilevel integrations. Old clients don't send origin, so we fall back
|
|
1074
|
-
// to the experience's SDK to maintain backward compatibility.
|
|
1075
|
-
const { origin } = message.payload;
|
|
1076
|
-
const originSdk = origin
|
|
1077
|
-
? getOrConfigureSdk(origin.host, origin.projectId)
|
|
1078
|
-
: experience.sdk;
|
|
1079
|
-
const originIdentify = getIdentify(originSdk);
|
|
1080
1142
|
const respond = (payload) => sdkLauncherKit.respondToSdkMessage(experience, message, payload);
|
|
1081
1143
|
try {
|
|
1082
1144
|
switch (message.action) {
|
|
1083
1145
|
case IdentifyAction.RequestLogin: {
|
|
1084
|
-
await requestLogin(
|
|
1146
|
+
await requestLogin();
|
|
1085
1147
|
respond();
|
|
1086
1148
|
break;
|
|
1087
1149
|
}
|
|
1088
1150
|
case IdentifyAction.RequestLogout: {
|
|
1089
|
-
await requestLogout(
|
|
1151
|
+
await requestLogout();
|
|
1090
1152
|
respond();
|
|
1091
1153
|
break;
|
|
1092
1154
|
}
|
|
1093
|
-
case IdentifyAction.
|
|
1094
|
-
const data = await
|
|
1155
|
+
case IdentifyAction.GetCredentials: {
|
|
1156
|
+
const data = await getCredentials();
|
|
1095
1157
|
respond({ data });
|
|
1096
1158
|
break;
|
|
1097
1159
|
}
|
|
1098
|
-
case IdentifyAction.GetSessionSignature: {
|
|
1099
|
-
const signature = await getSessionSignatureMemoized(identify, message.payload);
|
|
1100
|
-
respond({ data: signature });
|
|
1101
|
-
break;
|
|
1102
|
-
}
|
|
1103
1160
|
case IdentifyAction.SetCredentials: {
|
|
1104
|
-
await setCredentials(
|
|
1105
|
-
token: message.payload.token,
|
|
1106
|
-
});
|
|
1161
|
+
await setCredentials(message.payload);
|
|
1107
1162
|
respond();
|
|
1108
1163
|
break;
|
|
1109
1164
|
}
|
|
1110
1165
|
case IdentifyAction.ClearCredentials: {
|
|
1111
|
-
await clearCredentials(
|
|
1166
|
+
await clearCredentials();
|
|
1112
1167
|
respond();
|
|
1113
1168
|
break;
|
|
1114
1169
|
}
|
|
@@ -1120,12 +1175,7 @@ function handleExperienceEmbedded(experience) {
|
|
|
1120
1175
|
});
|
|
1121
1176
|
}
|
|
1122
1177
|
});
|
|
1123
|
-
addExperience(experience, [
|
|
1124
|
-
credentialsUpdatedUnsub,
|
|
1125
|
-
signatureUpdatedUnsub,
|
|
1126
|
-
userDataUpdatedUnsub,
|
|
1127
|
-
sdkMessageUnsub,
|
|
1128
|
-
]);
|
|
1178
|
+
addExperience(experience, [sdkMessageUnsub]);
|
|
1129
1179
|
}
|
|
1130
1180
|
/**
|
|
1131
1181
|
* @internal
|
|
@@ -1133,26 +1183,42 @@ function handleExperienceEmbedded(experience) {
|
|
|
1133
1183
|
function handleExperienceUnmounted(experience) {
|
|
1134
1184
|
deleteExperience(experience);
|
|
1135
1185
|
}
|
|
1136
|
-
|
|
1186
|
+
/**
|
|
1187
|
+
* @internal
|
|
1188
|
+
*/
|
|
1189
|
+
function handleExperienceStateChange(experience, state) {
|
|
1137
1190
|
if (state === 'mounted') {
|
|
1138
1191
|
handleExperienceEmbedded(experience);
|
|
1192
|
+
return;
|
|
1139
1193
|
}
|
|
1140
|
-
|
|
1194
|
+
if (state === 'unmounted') {
|
|
1141
1195
|
handleExperienceUnmounted(experience);
|
|
1142
1196
|
}
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1197
|
+
}
|
|
1198
|
+
function subscribeToExperienceLifecycle() {
|
|
1199
|
+
sdkLauncherKit.onStateChanged(handleExperienceStateChange);
|
|
1200
|
+
}
|
|
1201
|
+
function connectToParentApplication() {
|
|
1202
|
+
const parentApp = sdkLauncherKit.getParentApplication();
|
|
1203
|
+
if (parentApp === null) {
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1206
|
+
sdkLauncherKit.onSdkMessage(parentApp, handleParentMessage);
|
|
1207
|
+
pullStateFromParent();
|
|
1208
|
+
}
|
|
1209
|
+
subscribeToExperienceLifecycle();
|
|
1210
|
+
connectToParentApplication();
|
|
1145
1211
|
|
|
1146
1212
|
exports.clearCredentials = clearCredentials;
|
|
1213
|
+
exports.getCredentials = getCredentials;
|
|
1147
1214
|
exports.getIdentify = getIdentify;
|
|
1148
1215
|
exports.getUserData = getUserData;
|
|
1149
1216
|
exports.onCredentialsUpdated = onCredentialsUpdated;
|
|
1150
1217
|
exports.onLoginRequestedByExperience = onLoginRequestedByExperience;
|
|
1151
1218
|
exports.onLogoutRequestedByExperience = onLogoutRequestedByExperience;
|
|
1152
|
-
exports.onSignatureUpdated = onSignatureUpdated;
|
|
1153
1219
|
exports.onStateUpdated = onStateUpdated;
|
|
1154
|
-
exports.onUserDataUpdated = onUserDataUpdated;
|
|
1155
1220
|
exports.requestLogin = requestLogin;
|
|
1156
1221
|
exports.requestLogout = requestLogout;
|
|
1157
1222
|
exports.setCredentials = setCredentials;
|
|
1223
|
+
exports.setLoginPolicy = setLoginPolicy;
|
|
1158
1224
|
//# sourceMappingURL=index.cjs.map
|