@vizbeetv/homesso-sdk-qa 1.0.1

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/es6/index.mjs ADDED
@@ -0,0 +1,1712 @@
1
+ /******************************************************************************
2
+ Copyright (c) Microsoft Corporation.
3
+
4
+ Permission to use, copy, modify, and/or distribute this software for any
5
+ purpose with or without fee is hereby granted.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13
+ PERFORMANCE OF THIS SOFTWARE.
14
+ ***************************************************************************** */
15
+
16
+ function __awaiter(thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ }
25
+
26
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
27
+ var e = new Error(message);
28
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
29
+ };
30
+
31
+ /**
32
+ * @const VizbeeConstants
33
+ * @description Metrics Constants used throughout the Vizbee Home SSO implementation
34
+ */
35
+ const VizbeeMetricsConstants = {
36
+ // Events
37
+ METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_RECEIVED: 'SCREEN_HOMESSO_SIGNIN_RECEIVED',
38
+ METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_STATUS: 'SCREEN_HOMESSO_SIGNIN_STATUS',
39
+ // Attributes
40
+ METRICS_ATTR_SCREEN_HOMESSO_SDK_VERSION: 'SCREEN_HOMESSO_SDK_VERSION',
41
+ METRICS_ATTR_IS_SCREEN_SIGNED_IN: 'IS_SCREEN_SIGNED_IN',
42
+ METRICS_ATTR_IS_REMOTE_SIGNED_IN: 'IS_REMOTE_SIGNED_IN',
43
+ METRICS_ATTR_IS_SCREEN_SIGN_IN_STATUS: 'SCREEN_SIGN_IN_STATUS',
44
+ METRICS_ATTR_SCREEN_HOMESSO_USER_ID: 'SCREEN_HOMESSO_USER_ID',
45
+ METRICS_ATTR_SCREEN_HOMESSO_USER_INFO: 'SCREEN_HOMESSO_USER_INFO',
46
+ METRICS_ATTR_HOMESSO_SIGN_IN_TYPE: 'HOMESSO_SIGN_IN_TYPE',
47
+ METRICS_ATTR_REMOTE_DEVICE_ID: 'REMOTE_DEVICE_ID',
48
+ METRICS_ATTR_REMOTE_DEVICE_TYPE: 'REMOTE_DEVICE_TYPE',
49
+ METRICS_ATTR_REMOTE_FRIENDLY_NAME: 'REMOTE_FRIENDLY_NAME',
50
+ METRICS_ATTR_REMOTE_NETWORK_SESSION_ID: 'REMOTE_NETWORK_SESSION_ID',
51
+ METRICS_ATTR_USER_LOGIN_TYPE: 'user_login_type',
52
+ METRICS_ATTR_USER_IS_SIGNED_IN: 'user_is_signed_in',
53
+ METRICS_ATTR_USER_LOGIN: 'user_login',
54
+ METRICS_ATTR_USER_NAME: 'user_name',
55
+ METRICS_ATTR_USER_SUBSCRIPTION_TYPE: 'user_subscription_type',
56
+ METRICS_ATTR_USER_SUBSCRIPTION_VALUE: 'user_subscription_value',
57
+ METRICS_ATTR_USER_SUBSCRIPTION_RENEWAL_TYPE: 'user_subscription_renewal_type',
58
+ METRICS_ATTR_USER_ADDITIONAL_INFO: 'user_additional_info',
59
+ };
60
+
61
+ /**
62
+ * Logger
63
+ * A flexible logging system for TypeScript SDK with
64
+ * enable/disable capabilities and different log levels.
65
+ *
66
+ * Features:
67
+ * - Multiple severity levels from ERROR to TRACE
68
+ * - Colored console output with timestamps
69
+ * - Local storage persistence with size management
70
+ * - Environment-aware execution (handles environments without localStorage)
71
+ * - Export and clearing capabilities
72
+ */
73
+ /**
74
+ * Defines logging severity levels in ascending order of verbosity.
75
+ * Lower values indicate higher severity. This hierarchy ensures
76
+ * that when a specific level is set, all logs of that level and
77
+ * higher severity (lower enum value) will be captured.
78
+ */
79
+ var LogLevel;
80
+ (function (LogLevel) {
81
+ /** Critical application errors that prevent proper functioning */
82
+ LogLevel[LogLevel["ERROR"] = 0] = "ERROR";
83
+ /** Important issues that don't stop execution but require attention */
84
+ LogLevel[LogLevel["WARN"] = 1] = "WARN";
85
+ /** General operational information about system behavior */
86
+ LogLevel[LogLevel["INFO"] = 2] = "INFO";
87
+ /** Detailed diagnostic information for troubleshooting */
88
+ LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG";
89
+ /** Extremely verbose execution flow information */
90
+ LogLevel[LogLevel["TRACE"] = 4] = "TRACE";
91
+ })(LogLevel || (LogLevel = {}));
92
+ /**
93
+ * Default configuration applied when creating a new logger
94
+ * without explicit settings. These values can be overridden
95
+ * through the constructor or setConfig method.
96
+ */
97
+ const DEFAULT_CONFIG = {
98
+ enabled: false,
99
+ level: LogLevel.ERROR,
100
+ useTimestamp: true,
101
+ useColors: true,
102
+ logToConsole: true,
103
+ logToStorage: false,
104
+ maxStorageLogs: 1000,
105
+ };
106
+ /**
107
+ * Core logger implementation that provides multiple severity levels,
108
+ * configurable outputs, and flexible message formatting.
109
+ *
110
+ * The logger handles both console output and storage persistence,
111
+ * with environment detection to gracefully handle different contexts.
112
+ */
113
+ class Logger {
114
+ /**
115
+ * Creates a new logger instance with optional custom configuration.
116
+ * The provided configuration is merged with default settings.
117
+ *
118
+ * @param config - Partial configuration to override default values
119
+ */
120
+ constructor(config = {}) {
121
+ /**
122
+ * Storage key used for persisting logs in localStorage.
123
+ * Prefixed with 'vizbee_homesso_' to avoid collisions.
124
+ */
125
+ this.storageKey = 'vizbee_homesso_logs';
126
+ this.config = Object.assign(Object.assign({}, DEFAULT_CONFIG), config);
127
+ // Initialize storage if enabled in the configuration
128
+ if (this.config.logToStorage) {
129
+ this.initializeStorage();
130
+ }
131
+ }
132
+ /**
133
+ * Enables or disables all logging functionality.
134
+ * When disabled, no logs will be output regardless of level.
135
+ *
136
+ * @param enabled - Whether logging should be active (defaults to true)
137
+ */
138
+ enable(enabled = true) {
139
+ this.config.enabled = enabled;
140
+ this.info(`Logger ${enabled ? 'enabled' : 'disabled'}`);
141
+ }
142
+ /**
143
+ * Sets the minimum severity level for capturing logs.
144
+ * Only logs at this level and more severe levels will be processed.
145
+ *
146
+ * @param level - The minimum LogLevel to capture
147
+ */
148
+ setLevel(level) {
149
+ this.config.level = level;
150
+ this.info(`Log level set to ${LogLevel[level]}`);
151
+ }
152
+ /**
153
+ * Returns a copy of the current logger configuration.
154
+ * Returns a new object to prevent accidental modification.
155
+ *
156
+ * @returns The complete current configuration
157
+ */
158
+ getConfig() {
159
+ return Object.assign({}, this.config);
160
+ }
161
+ /**
162
+ * Updates logger configuration with new settings.
163
+ * Merges the provided settings with the existing configuration.
164
+ *
165
+ * @param config - Partial configuration to apply
166
+ */
167
+ setConfig(config) {
168
+ // Store current storage setting to detect changes
169
+ const wasStorageEnabled = this.config.logToStorage;
170
+ // Update configuration by merging with existing settings
171
+ this.config = Object.assign(Object.assign({}, this.config), config);
172
+ // Initialize storage if it was just enabled
173
+ if (!wasStorageEnabled && this.config.logToStorage) {
174
+ this.initializeStorage();
175
+ }
176
+ this.info('Logger configuration updated');
177
+ }
178
+ /**
179
+ * Logs an error message (highest severity).
180
+ * Use for critical failures that prevent proper operation.
181
+ *
182
+ * @param message - The error message to log
183
+ * @param data - Optional supplementary information
184
+ */
185
+ error(message, ...data) {
186
+ this.log(LogLevel.ERROR, message, data);
187
+ }
188
+ /**
189
+ * Logs a warning message.
190
+ * Use for potential issues that don't stop execution.
191
+ *
192
+ * @param message - The warning message to log
193
+ * @param data - Optional supplementary information
194
+ */
195
+ warn(message, ...data) {
196
+ this.log(LogLevel.WARN, message, data);
197
+ }
198
+ /**
199
+ * Logs an informational message.
200
+ * Use for general application state and noteworthy events.
201
+ *
202
+ * @param message - The info message to log
203
+ * @param data - Optional supplementary information
204
+ */
205
+ info(message, ...data) {
206
+ this.log(LogLevel.INFO, message, data);
207
+ }
208
+ /**
209
+ * Logs a debug message.
210
+ * Use for detailed information helpful during development.
211
+ *
212
+ * @param message - The debug message to log
213
+ * @param data - Optional supplementary information
214
+ */
215
+ debug(message, ...data) {
216
+ this.log(LogLevel.DEBUG, message, data);
217
+ }
218
+ /**
219
+ * Logs a trace message (lowest severity/highest verbosity).
220
+ * Use for extremely detailed execution path tracking.
221
+ *
222
+ * @param message - The trace message to log
223
+ * @param data - Optional supplementary information
224
+ */
225
+ trace(message, ...data) {
226
+ this.log(LogLevel.TRACE, message, data);
227
+ }
228
+ /**
229
+ * Core logging method that handles level filtering and message routing.
230
+ * Formats the message and sends it to appropriate outputs based on configuration.
231
+ *
232
+ * @param level - Log severity level
233
+ * @param message - The message to log
234
+ * @param data - Additional data to include with the log
235
+ */
236
+ log(level, message, data = []) {
237
+ // Early return if logging is disabled or level is too verbose
238
+ if (!this.config.enabled || level > this.config.level) {
239
+ return;
240
+ }
241
+ // Format components based on configuration
242
+ const timestamp = this.config.useTimestamp
243
+ ? `[${new Date().toISOString()}]`
244
+ : '';
245
+ const levelName = `[${LogLevel[level]}]`;
246
+ // Create the formatted message with application prefix
247
+ const formattedMessage = `${timestamp}[VizbeeHomeSSO]${levelName}: ${message}`;
248
+ // Send to appropriate outputs based on configuration
249
+ if (this.config.logToConsole) {
250
+ this.logToConsole(level, formattedMessage, data);
251
+ }
252
+ if (this.config.logToStorage) {
253
+ this.logToStorage(formattedMessage, data);
254
+ }
255
+ }
256
+ /**
257
+ * Handles console output with optional color styling.
258
+ * Applies different colors based on log level for better readability.
259
+ *
260
+ * @param level - Log severity level
261
+ * @param message - Formatted message to output
262
+ * @param data - Additional data to log
263
+ */
264
+ logToConsole(level, message, data) {
265
+ const hasData = data && data.length > 0;
266
+ // Apply color styling if enabled
267
+ if (this.config.useColors) {
268
+ const styles = this.getConsoleStyles(level);
269
+ if (hasData) {
270
+ console.log(`%c${message}`, styles, ...data);
271
+ }
272
+ else {
273
+ console.log(`%c${message}`, styles);
274
+ }
275
+ }
276
+ else {
277
+ // Plain output without colors
278
+ if (hasData) {
279
+ console.log(message, ...data);
280
+ }
281
+ else {
282
+ console.log(message);
283
+ }
284
+ }
285
+ }
286
+ /**
287
+ * Determines CSS styling for console output based on log level.
288
+ * Returns different colors to visually distinguish log levels.
289
+ *
290
+ * @param level - Log severity level
291
+ * @returns CSS style string for console output
292
+ */
293
+ getConsoleStyles(level) {
294
+ switch (level) {
295
+ case LogLevel.ERROR:
296
+ return 'color: #FF5252; font-weight: bold'; // Bright red, bold
297
+ case LogLevel.WARN:
298
+ return 'color: #FFC107; font-weight: bold'; // Amber, bold
299
+ case LogLevel.INFO:
300
+ return 'color: #2196F3'; // Blue
301
+ case LogLevel.DEBUG:
302
+ return 'color: #4CAF50'; // Green
303
+ case LogLevel.TRACE:
304
+ return 'color: #9E9E9E'; // Gray
305
+ default:
306
+ return '';
307
+ }
308
+ }
309
+ /**
310
+ * Sets up localStorage for persisting logs if available.
311
+ * Creates the initial empty logs array if not already present.
312
+ * Gracefully handles environments without localStorage access.
313
+ */
314
+ initializeStorage() {
315
+ try {
316
+ // Verify localStorage is available in this environment
317
+ if (typeof localStorage !== 'undefined') {
318
+ // Create empty logs array if not already initialized
319
+ if (!localStorage.getItem(this.storageKey)) {
320
+ localStorage.setItem(this.storageKey, JSON.stringify([]));
321
+ }
322
+ }
323
+ }
324
+ catch (error) {
325
+ // Handle environments where localStorage is not available or blocked
326
+ console.warn('localStorage not available for logging', error);
327
+ this.config.logToStorage = false;
328
+ }
329
+ }
330
+ /**
331
+ * Persists a log entry to localStorage with rotation management.
332
+ * Removes oldest entries when the maximum count is exceeded.
333
+ * Handles storage errors gracefully.
334
+ *
335
+ * @param message - Formatted message to store
336
+ * @param data - Additional data to include
337
+ */
338
+ logToStorage(message, data) {
339
+ try {
340
+ if (typeof localStorage !== 'undefined') {
341
+ // Retrieve current logs
342
+ const logs = JSON.parse(localStorage.getItem(this.storageKey) || '[]');
343
+ // Add new log entry
344
+ logs.push({
345
+ timestamp: new Date().toISOString(),
346
+ message,
347
+ data: data.length > 0 ? JSON.stringify(data) : undefined,
348
+ });
349
+ // Apply size limit by removing oldest logs if needed
350
+ if (logs.length > (this.config.maxStorageLogs || 1000)) {
351
+ logs.shift(); // Remove oldest log
352
+ }
353
+ // Save updated logs back to storage
354
+ localStorage.setItem(this.storageKey, JSON.stringify(logs));
355
+ }
356
+ }
357
+ catch (error) {
358
+ console.error('Failed to write logs to storage', error);
359
+ }
360
+ }
361
+ /**
362
+ * Exports all stored logs as a JSON string.
363
+ * Returns an empty array string if storage is unavailable.
364
+ *
365
+ * @returns JSON string containing all stored logs
366
+ */
367
+ exportLogs() {
368
+ try {
369
+ if (typeof localStorage !== 'undefined') {
370
+ const logs = localStorage.getItem(this.storageKey) || '[]';
371
+ return logs;
372
+ }
373
+ }
374
+ catch (error) {
375
+ console.error('Failed to export logs', error);
376
+ }
377
+ return '[]';
378
+ }
379
+ /**
380
+ * Clears all logs from storage.
381
+ * Replaces the current logs with an empty array.
382
+ */
383
+ clearLogs() {
384
+ try {
385
+ if (typeof localStorage !== 'undefined') {
386
+ localStorage.setItem(this.storageKey, JSON.stringify([]));
387
+ this.info('Logs cleared from storage');
388
+ }
389
+ }
390
+ catch (error) {
391
+ console.error('Failed to clear logs', error);
392
+ }
393
+ }
394
+ }
395
+ /**
396
+ * Default singleton logger instance with standard configuration.
397
+ * Available as a ready-to-use logger throughout the application.
398
+ * For custom configurations, create additional Logger instances.
399
+ */
400
+ const logger = new Logger();
401
+
402
+ const LOG_TAG$1 = 'VizbeeHomeSSOManager';
403
+ /* eslint-disable @typescript-eslint/no-explicit-any */
404
+ class VizbeeMetricsManager {
405
+ constructor() {
406
+ var _a, _b, _c;
407
+ this.senderInfo = null;
408
+ this.getSignInInfo = () => __awaiter(this, void 0, void 0, function* () { return []; });
409
+ if ((_c = (_b = (_a = window === null || window === void 0 ? void 0 : window.vizbee) === null || _a === void 0 ? void 0 : _a.continuity) === null || _b === void 0 ? void 0 : _b.analytics) === null || _c === void 0 ? void 0 : _c.AnalyticsProvider) {
410
+ this.metricsManager =
411
+ new window.vizbee.continuity.analytics.AnalyticsProvider();
412
+ // Create a wrapper with 'provider' property
413
+ const attributesProvider = {
414
+ getAttributes: () => this.getAttributes(),
415
+ };
416
+ this.metricsManager.addProvider(attributesProvider, '.*');
417
+ }
418
+ }
419
+ log(event, attributes, bypassAttributeProviders = false) {
420
+ if (!this.metricsManager) {
421
+ return;
422
+ }
423
+ logger.debug(`[${LOG_TAG$1}][log] - Logging metrics event: `, event, attributes, bypassAttributeProviders);
424
+ if (event ===
425
+ VizbeeMetricsConstants.METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_RECEIVED) {
426
+ this.senderInfo = attributes.senderInfo;
427
+ }
428
+ const attributesToBeSent = this.addDefaultAttributes();
429
+ attributesToBeSent[VizbeeMetricsConstants.METRICS_ATTR_IS_SCREEN_SIGNED_IN] = attributes.isScreenSignedIn;
430
+ attributesToBeSent[VizbeeMetricsConstants.METRICS_ATTR_IS_REMOTE_SIGNED_IN] = attributes.isRemoteSignedIn;
431
+ attributesToBeSent[VizbeeMetricsConstants.METRICS_ATTR_HOMESSO_SIGN_IN_TYPE] = attributes.signInType;
432
+ attributesToBeSent[VizbeeMetricsConstants.METRICS_ATTR_IS_SCREEN_SIGN_IN_STATUS] = attributes.signInState;
433
+ if (attributes.userId) {
434
+ attributesToBeSent[VizbeeMetricsConstants.METRICS_ATTR_SCREEN_HOMESSO_USER_ID] = attributes.userId;
435
+ }
436
+ logger.debug(`[${LOG_TAG$1}][log] - Logging metrics event: `, event, attributesToBeSent);
437
+ this.metricsManager.logMetrics(event, attributesToBeSent);
438
+ }
439
+ setCustomAttributes(customAttributes) {
440
+ this.metricsManager.setCustomAttributes(customAttributes);
441
+ }
442
+ getAttributes() {
443
+ return this.createAttributesJson();
444
+ }
445
+ createAttributesJson() {
446
+ return __awaiter(this, void 0, void 0, function* () {
447
+ const attributes = {};
448
+ const userInfoArray = [];
449
+ const signInInfoList = yield this.getSignInInfo();
450
+ signInInfoList === null || signInInfoList === void 0 ? void 0 : signInInfoList.forEach((signInInfo) => {
451
+ const userInfoObject = this.createUserInfoObject(signInInfo);
452
+ userInfoArray.push(userInfoObject);
453
+ });
454
+ attributes[VizbeeMetricsConstants.METRICS_ATTR_SCREEN_HOMESSO_USER_INFO] =
455
+ userInfoArray;
456
+ return attributes;
457
+ });
458
+ }
459
+ createUserInfoObject(signInInfo) {
460
+ const UNKNOWN_VALUE = 'UNKNOWN';
461
+ const userInfo = {
462
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_LOGIN_TYPE]: signInInfo.userLoginType,
463
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_IS_SIGNED_IN]: signInInfo.isSignedIn,
464
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_LOGIN]: signInInfo.userLogin || UNKNOWN_VALUE,
465
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_NAME]: signInInfo.userName || UNKNOWN_VALUE,
466
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_SUBSCRIPTION_TYPE]: signInInfo.userSubscriptionType || UNKNOWN_VALUE,
467
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_SUBSCRIPTION_VALUE]: signInInfo.userSubscriptionValue || UNKNOWN_VALUE,
468
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_SUBSCRIPTION_RENEWAL_TYPE]: signInInfo.userSubscriptionRenewalType || UNKNOWN_VALUE,
469
+ };
470
+ if (signInInfo.userAdditionalInfo) {
471
+ userInfo[VizbeeMetricsConstants.METRICS_ATTR_USER_ADDITIONAL_INFO] =
472
+ signInInfo.userAdditionalInfo || {};
473
+ }
474
+ return userInfo;
475
+ }
476
+ addDefaultAttributes() {
477
+ var _a, _b, _c, _d;
478
+ const attributes = {};
479
+ attributes[VizbeeMetricsConstants.METRICS_ATTR_SCREEN_HOMESSO_SDK_VERSION] =
480
+ '1.0.1';
481
+ attributes['REMOTE_FRIENDLY_NAME'] = (_a = this.senderInfo) === null || _a === void 0 ? void 0 : _a.friendlyName;
482
+ attributes['REMOTE_DEVICE_ID'] = (_b = this.senderInfo) === null || _b === void 0 ? void 0 : _b.deviceId;
483
+ attributes['REMOTE_DEVICE_TYPE'] = (_c = this.senderInfo) === null || _c === void 0 ? void 0 : _c.deviceType;
484
+ attributes['REMOTE_NETWORK_SESSION_ID'] = (_d = this.senderInfo) === null || _d === void 0 ? void 0 : _d.networkSessionId;
485
+ return attributes;
486
+ }
487
+ }
488
+
489
+ /**
490
+ * @const VizbeeConstants
491
+ * @description Constants used throughout the Vizbee Home SSO implementation
492
+ */
493
+ const VizbeeConstants = {
494
+ EVENT_SSO_NAME: 'tv.vizbee.homesso.signin',
495
+ // Sign in event keys
496
+ KEY_SUB_TYPE: 'sub_type',
497
+ KEY_SIGN_IN_STATUS: 'sstatus',
498
+ KEY_STATE: 'sstate',
499
+ KEY_CUSTOM_DATA: 'custom_data',
500
+ KEY_REG_CODE: 'regcode',
501
+ // Custom metadata keys
502
+ KEY_START_SIGN_IN_INFO: 'sinfo',
503
+ KEY_IS_SIGNED_IN: 'is_signed_in',
504
+ KEY_SIGN_IN_TYPE: 'stype',
505
+ KEY_DEVICE_MODEL: 'device_model',
506
+ KEY_DEVICE_OS: 'device_os',
507
+ // Event subtypes
508
+ EVENT_SUBTYPE_START_SIGN_IN: 'start_sign_in',
509
+ EVENT_SUBTYPE_SIGN_IN_STATUS: 'sign_in_status',
510
+ // SDK events types
511
+ VIZBEE_SESSION_READY: 'vizbee-bicast-session-ready',
512
+ };
513
+ // Enum for sign in states
514
+ var VizbeeSignInState;
515
+ (function (VizbeeSignInState) {
516
+ VizbeeSignInState["SIGN_IN_NOT_STARTED"] = "not_started";
517
+ VizbeeSignInState["SIGN_IN_IN_PROGRESS"] = "in_progress";
518
+ VizbeeSignInState["SIGN_IN_COMPLETED"] = "completed";
519
+ VizbeeSignInState["SIGN_IN_FAILED"] = "failed";
520
+ VizbeeSignInState["SIGN_IN_CANCELLED"] = "cancelled";
521
+ })(VizbeeSignInState || (VizbeeSignInState = {}));
522
+
523
+ /* eslint-disable @typescript-eslint/no-explicit-any */
524
+ // Base abstract class for sign in status
525
+ class VizbeeSignInStatus {
526
+ constructor(signInType, customData) {
527
+ this.signInType = signInType;
528
+ this.customData = customData;
529
+ }
530
+ serialize() {
531
+ return {
532
+ [VizbeeConstants.KEY_SIGN_IN_TYPE]: this.signInType,
533
+ [VizbeeConstants.KEY_STATE]: this.getState(),
534
+ [VizbeeConstants.KEY_CUSTOM_DATA]: this.customData,
535
+ };
536
+ }
537
+ }
538
+ // Progress status class
539
+ class ProgressStatus extends VizbeeSignInStatus {
540
+ constructor(signInType, customData = null) {
541
+ super(signInType, customData);
542
+ this.signInType = signInType;
543
+ this.customData = customData;
544
+ }
545
+ getState() {
546
+ return VizbeeSignInState.SIGN_IN_IN_PROGRESS;
547
+ }
548
+ }
549
+ // Success status class
550
+ class SuccessStatus extends VizbeeSignInStatus {
551
+ constructor(signInType, userId = null, customData = null) {
552
+ super(signInType, customData);
553
+ this.signInType = signInType;
554
+ this.userId = userId;
555
+ this.customData = customData;
556
+ }
557
+ getState() {
558
+ return VizbeeSignInState.SIGN_IN_COMPLETED;
559
+ }
560
+ }
561
+ // Failure status class
562
+ class FailureStatus extends VizbeeSignInStatus {
563
+ constructor(signInType, isCancelled, reason = null, exception = null, customData = null) {
564
+ super(signInType, customData);
565
+ this.signInType = signInType;
566
+ this.isCancelled = isCancelled;
567
+ this.reason = reason;
568
+ this.exception = exception;
569
+ this.customData = customData;
570
+ }
571
+ getState() {
572
+ return this.isCancelled
573
+ ? VizbeeSignInState.SIGN_IN_CANCELLED
574
+ : VizbeeSignInState.SIGN_IN_FAILED;
575
+ }
576
+ }
577
+
578
+ /**
579
+ * @fileoverview Configuration and type definitions for Vizbee Home SSO UI components
580
+ * Defines interfaces and default configurations for various modal states and themes
581
+ */
582
+ /**
583
+ * Enum defining the different types of sign-in modals available in the system
584
+ */
585
+ var SignInModalType;
586
+ (function (SignInModalType) {
587
+ SignInModalType["INFORMATION"] = "information";
588
+ SignInModalType["PROGRESS"] = "progress";
589
+ SignInModalType["SUCCESS"] = "success";
590
+ })(SignInModalType || (SignInModalType = {}));
591
+ /**
592
+ * Default theme configuration with basic color scheme
593
+ */
594
+ const defaultTheme = {
595
+ primaryColor: '#000000',
596
+ secondaryColor: '#262626',
597
+ tertiaryColor: '#FFFFFF',
598
+ subTextColor: undefined,
599
+ primaryFont: undefined,
600
+ secondaryFont: undefined,
601
+ direction: 'ltr',
602
+ };
603
+ /**
604
+ * Collection of Base64 encoded icon images used in different modal states
605
+ */
606
+ const icons = {
607
+ vzb_unconnected: `data:image/png;base64,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`,
608
+ vzb_connection_progress_0: `data:image/png;base64,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`,
609
+ vzb_connection_progress_1: `data:image/png;base64,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`,
610
+ vzb_connection_progress_2: `data:image/png;base64,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`,
611
+ vzb_connected: `data:image/png;base64,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`,
612
+ };
613
+ /**
614
+ * Default configuration for informational sign-in modal
615
+ * Shown when initial sign-in process starts
616
+ */
617
+ const defaultInformationalModalConfig = {
618
+ enable: true,
619
+ options: {
620
+ width: undefined,
621
+ backgroundColor: undefined,
622
+ marginBottom: undefined,
623
+ marginRight: undefined,
624
+ direction: undefined,
625
+ iconBase64String: icons['vzb_unconnected'],
626
+ iconWidth: undefined,
627
+ iconHeight: undefined,
628
+ iconMarginRight: undefined,
629
+ titleText: 'Mobile Sign In',
630
+ titleTextFontFamily: undefined,
631
+ titleTextFontColor: undefined,
632
+ titleTextFontSize: undefined,
633
+ descriptionText: 'Please use your mobile app to complete the sign in process.',
634
+ descriptionTextFontFamily: undefined,
635
+ descriptionTextFontColor: undefined,
636
+ descriptionTextFontSize: undefined,
637
+ position: 'bottom-right',
638
+ borderColor: undefined,
639
+ borderWidth: undefined,
640
+ boxShadow: undefined,
641
+ height: undefined,
642
+ minHeight: undefined,
643
+ padding: undefined,
644
+ borderRadius: undefined,
645
+ edgeMargin: undefined,
646
+ marginTop: undefined,
647
+ marginLeft: undefined,
648
+ titleTextFontWeight: undefined,
649
+ titleTextLineHeight: undefined,
650
+ titleMarginBottom: undefined,
651
+ descriptionTextFontWeight: undefined,
652
+ descriptionTextLineHeight: undefined,
653
+ },
654
+ };
655
+ /**
656
+ * Default configuration for progress sign-in modal
657
+ * Shown while sign-in is in progress
658
+ */
659
+ const defaultProgressModalConfig = {
660
+ enable: true,
661
+ options: {
662
+ width: undefined,
663
+ backgroundColor: undefined,
664
+ marginBottom: undefined,
665
+ marginRight: undefined,
666
+ direction: undefined,
667
+ iconBase64String: icons['vzb_connection_progress_0'],
668
+ iconBase64Strings: [
669
+ icons['vzb_connection_progress_0'],
670
+ icons['vzb_connection_progress_1'],
671
+ icons['vzb_connection_progress_2'],
672
+ icons['vzb_connection_progress_1'],
673
+ ],
674
+ iconWidth: undefined,
675
+ iconHeight: undefined,
676
+ iconMarginRight: undefined,
677
+ titleText: undefined,
678
+ titleTextFontFamily: undefined,
679
+ titleTextFontColor: undefined,
680
+ titleTextFontSize: undefined,
681
+ descriptionText: 'Signing in using your mobile app ...',
682
+ descriptionTextFontFamily: undefined,
683
+ descriptionTextFontColor: undefined,
684
+ descriptionTextFontSize: undefined,
685
+ position: 'bottom-right',
686
+ borderColor: undefined,
687
+ borderWidth: undefined,
688
+ boxShadow: undefined,
689
+ height: undefined,
690
+ minHeight: undefined,
691
+ padding: undefined,
692
+ borderRadius: undefined,
693
+ edgeMargin: undefined,
694
+ marginTop: undefined,
695
+ marginLeft: undefined,
696
+ titleTextFontWeight: undefined,
697
+ titleTextLineHeight: undefined,
698
+ titleMarginBottom: undefined,
699
+ descriptionTextFontWeight: undefined,
700
+ descriptionTextLineHeight: undefined,
701
+ },
702
+ };
703
+ /**
704
+ * Default configuration for success sign-in modal
705
+ * Shown when sign-in process completes successfully
706
+ */
707
+ const defaultSuccessModalConfig = {
708
+ enable: true,
709
+ options: {
710
+ width: undefined,
711
+ backgroundColor: undefined,
712
+ marginBottom: undefined,
713
+ marginRight: undefined,
714
+ direction: undefined,
715
+ iconBase64String: icons['vzb_connected'],
716
+ iconWidth: undefined,
717
+ iconHeight: undefined,
718
+ iconMarginRight: undefined,
719
+ titleText: 'Mobile Sign In Successful!',
720
+ titleTextFontFamily: undefined,
721
+ titleTextFontColor: undefined,
722
+ titleTextFontSize: undefined,
723
+ descriptionText: 'Cast or select any content to start watching.',
724
+ descriptionTextFontFamily: undefined,
725
+ descriptionTextFontColor: undefined,
726
+ descriptionTextFontSize: undefined,
727
+ position: 'bottom-right',
728
+ duration: 10000,
729
+ borderColor: undefined,
730
+ borderWidth: undefined,
731
+ boxShadow: undefined,
732
+ height: undefined,
733
+ minHeight: undefined,
734
+ padding: undefined,
735
+ borderRadius: undefined,
736
+ edgeMargin: undefined,
737
+ marginTop: undefined,
738
+ marginLeft: undefined,
739
+ titleTextFontWeight: undefined,
740
+ titleTextLineHeight: undefined,
741
+ titleMarginBottom: undefined,
742
+ descriptionTextFontWeight: undefined,
743
+ descriptionTextLineHeight: undefined,
744
+ },
745
+ };
746
+
747
+ /* eslint-disable @typescript-eslint/no-explicit-any */
748
+ /**
749
+ * Singleton class responsible for managing UI configurations for Home SSO experience
750
+ * Handles theme customization and specific modal configurations for different sign-in states
751
+ */
752
+ class VizbeeHomeSSOUIManager {
753
+ /**
754
+ * Private constructor to enforce singleton pattern
755
+ * Initializes configurations with default values using deep merge
756
+ */
757
+ constructor() {
758
+ this.themeConfig = this.deepMerge({}, defaultTheme);
759
+ this.commonModalConfig = this.deepMerge({});
760
+ this.informationalModalConfig =
761
+ this.deepMerge(defaultInformationalModalConfig.options);
762
+ this.progressModalConfig = this.deepMerge(defaultProgressModalConfig.options);
763
+ this.successModalConfig = this.deepMerge(defaultSuccessModalConfig.options);
764
+ }
765
+ /**
766
+ * Gets the singleton instance of VizbeeHomeSSOUIManager
767
+ * Creates a new instance if one doesn't exist
768
+ * @returns The singleton instance of VizbeeHomeSSOUIManager
769
+ */
770
+ static getInstance() {
771
+ if (!VizbeeHomeSSOUIManager.instance) {
772
+ VizbeeHomeSSOUIManager.instance = new VizbeeHomeSSOUIManager();
773
+ }
774
+ return VizbeeHomeSSOUIManager.instance;
775
+ }
776
+ /**
777
+ * Creates a deep clone of an object or array
778
+ * @param obj - Object to clone
779
+ * @returns Deep cloned copy of the input
780
+ */
781
+ deepClone(obj) {
782
+ // Handle primitives and null
783
+ if (obj === null || typeof obj !== 'object') {
784
+ return obj;
785
+ }
786
+ try {
787
+ // Attempt JSON serialization - this will throw on circular references
788
+ return JSON.parse(JSON.stringify(obj));
789
+ }
790
+ catch (error) {
791
+ // Fall back to manual deep cloning when JSON serialization fails
792
+ return this.fallbackDeepClone(obj);
793
+ }
794
+ }
795
+ // Fallback manual deep clone that handles circular references
796
+ fallbackDeepClone(obj, visited = new Map()) {
797
+ if (obj === null || typeof obj !== 'object') {
798
+ return obj;
799
+ }
800
+ // Handle circular references
801
+ if (visited.has(obj)) {
802
+ return visited.get(obj);
803
+ }
804
+ // Handle arrays
805
+ if (Array.isArray(obj)) {
806
+ const clone = [];
807
+ visited.set(obj, clone);
808
+ for (let i = 0; i < obj.length; i++) {
809
+ clone[i] = this.fallbackDeepClone(obj[i], visited);
810
+ }
811
+ return clone;
812
+ }
813
+ // Handle objects
814
+ const clone = {};
815
+ visited.set(obj, clone);
816
+ Object.keys(obj).forEach(key => {
817
+ clone[key] = this.fallbackDeepClone(obj[key], visited);
818
+ });
819
+ return clone;
820
+ }
821
+ /**
822
+ * Performs a deep merge of multiple objects
823
+ * @param target - Base object to merge into
824
+ * @param sources - Array of objects to merge from
825
+ * @returns Merged object combining all sources into target
826
+ */
827
+ deepMerge(target, ...sources) {
828
+ const result = JSON.parse(JSON.stringify(target));
829
+ if (sources.length === 0)
830
+ return result;
831
+ for (const source of sources) {
832
+ if (!source)
833
+ continue;
834
+ for (const key of Object.keys(source)) {
835
+ const sourceValue = source[key];
836
+ if (sourceValue === undefined)
837
+ continue;
838
+ if (sourceValue === null) {
839
+ result[key] = null;
840
+ continue;
841
+ }
842
+ if (typeof sourceValue === 'object' && !Array.isArray(sourceValue)) {
843
+ if (!result[key] || typeof result[key] !== 'object') {
844
+ result[key] = {};
845
+ }
846
+ result[key] = this.deepMerge(result[key], sourceValue);
847
+ }
848
+ else {
849
+ result[key] = JSON.parse(JSON.stringify(sourceValue));
850
+ }
851
+ }
852
+ }
853
+ return result;
854
+ }
855
+ /**
856
+ * Maps theme configuration to modal configuration properties
857
+ * @param theme - Current theme configuration
858
+ * @returns Partial modal configuration based on theme
859
+ */
860
+ mapThemeToModalConfig(theme) {
861
+ return {
862
+ borderColor: theme.primaryColor,
863
+ backgroundColor: theme.secondaryColor,
864
+ titleTextFontColor: theme.tertiaryColor,
865
+ descriptionTextFontColor: theme.subTextColor,
866
+ titleTextFontFamily: theme.primaryFont,
867
+ descriptionTextFontFamily: theme.secondaryFont,
868
+ direction: theme.direction,
869
+ };
870
+ }
871
+ /**
872
+ * Returns default configurations for all modal types
873
+ * @returns Object containing default configs for informational, progress, and success modals
874
+ */
875
+ getDefaultConfig() {
876
+ const themeBasedConfig = this.mapThemeToModalConfig(this.themeConfig);
877
+ const informational = this.deepMerge(defaultInformationalModalConfig.options, themeBasedConfig);
878
+ const progress = this.deepMerge(defaultProgressModalConfig.options, themeBasedConfig);
879
+ const successBase = this.deepMerge(defaultSuccessModalConfig.options, themeBasedConfig);
880
+ return {
881
+ informational,
882
+ progress,
883
+ success: Object.assign(Object.assign({}, successBase), { duration: defaultSuccessModalConfig.options.duration }),
884
+ };
885
+ }
886
+ /**
887
+ * Updates the current theme configuration
888
+ * @param theme - Partial theme configuration to merge with current theme
889
+ */
890
+ setTheme(theme) {
891
+ this.themeConfig = this.deepMerge(defaultTheme, theme);
892
+ }
893
+ /**
894
+ * Retrieves current theme configuration
895
+ * @returns Deep clone of current theme configuration
896
+ */
897
+ getTheme() {
898
+ return this.deepClone(this.themeConfig);
899
+ }
900
+ /**
901
+ * Updates common modal configuration applied to all modal types
902
+ * @param config - Partial configuration to merge with current common config
903
+ */
904
+ setCommonModalConfig(config) {
905
+ this.commonModalConfig = this.deepMerge(this.commonModalConfig, config);
906
+ }
907
+ /**
908
+ * Updates informational sign-in modal configuration
909
+ * @param config - Partial configuration to merge with current informational config
910
+ */
911
+ setInformationalSignInModalConfig(config) {
912
+ this.informationalModalConfig = this.deepMerge(this.informationalModalConfig, config);
913
+ }
914
+ /**
915
+ * Updates progress sign-in modal configuration
916
+ * @param config - Partial configuration to merge with current progress config
917
+ */
918
+ setProgressSignInModalConfig(config) {
919
+ this.progressModalConfig = this.deepMerge(this.progressModalConfig, config);
920
+ }
921
+ /**
922
+ * Updates success sign-in modal configuration
923
+ * @param config - Partial configuration to merge with current success config
924
+ */
925
+ setSuccessSignInModalConfig(config) {
926
+ this.successModalConfig = this.deepMerge(this.successModalConfig, config);
927
+ }
928
+ /**
929
+ * Retrieves complete configuration for informational sign-in modal
930
+ * Combines default, theme-based, common, and specific configurations
931
+ * @returns Complete informational modal configuration
932
+ */
933
+ getInformationalSignInModalConfig() {
934
+ const themeBasedConfig = this.mapThemeToModalConfig(this.themeConfig);
935
+ return this.deepMerge(defaultInformationalModalConfig.options, themeBasedConfig, this.commonModalConfig, this.informationalModalConfig);
936
+ }
937
+ /**
938
+ * Retrieves complete configuration for progress sign-in modal
939
+ * Combines default, theme-based, common, and specific configurations
940
+ * @returns Complete progress modal configuration
941
+ */
942
+ getProgressSignInModalConfig() {
943
+ const themeBasedConfig = this.mapThemeToModalConfig(this.themeConfig);
944
+ return this.deepMerge(defaultProgressModalConfig.options, themeBasedConfig, this.commonModalConfig, this.progressModalConfig);
945
+ }
946
+ /**
947
+ * Retrieves complete configuration for success sign-in modal
948
+ * Combines default, theme-based, common, and specific configurations
949
+ * @returns Complete success modal configuration
950
+ */
951
+ getSuccessSignInModalConfig() {
952
+ const themeBasedConfig = this.mapThemeToModalConfig(this.themeConfig);
953
+ const baseConfig = this.deepMerge(defaultSuccessModalConfig.options, themeBasedConfig, this.commonModalConfig, this.successModalConfig);
954
+ return Object.assign(Object.assign({}, baseConfig), { duration: this.successModalConfig.duration });
955
+ }
956
+ }
957
+
958
+ /**
959
+ * A class that manages the display of snackbar notifications with customizable styling and animations
960
+ */
961
+ class VizbeeSnackbar {
962
+ /**
963
+ * Creates a new instance of VizbeeSnackbar
964
+ */
965
+ constructor() {
966
+ this.BASE_DIMENSIONS = {
967
+ REFERENCE_WIDTH: 1920,
968
+ REFERENCE_HEIGHT: 1080,
969
+ WIDTH: 720,
970
+ PADDING: 20,
971
+ BORDER_RADIUS: 20,
972
+ BORDER_WIDTH: 2,
973
+ MARGIN: 32,
974
+ ICON_SIZE: 40,
975
+ ICON_MARGIN: 12,
976
+ TITLE_FONT_SIZE: 32,
977
+ MESSAGE_FONT_SIZE: 28,
978
+ };
979
+ this.uiManager = VizbeeHomeSSOUIManager.getInstance();
980
+ this.setupContainer();
981
+ }
982
+ /**
983
+ * Shows the snackbar with the specified options
984
+ */
985
+ show(options) {
986
+ this.hide();
987
+ clearTimeout(this.showSnackbarTimerId);
988
+ this.showSnackbarTimerId = window.setTimeout(() => {
989
+ this.createSnackbar(options);
990
+ if (this.currentSnackbar) {
991
+ this.currentSnackbar.style.transform =
992
+ this.getSlideTransform('top-right');
993
+ }
994
+ if (options === null || options === void 0 ? void 0 : options.shouldAnimateIcon) {
995
+ this.startIconAnimation(options.iconBase64Strings);
996
+ }
997
+ if ((options === null || options === void 0 ? void 0 : options.duration) && options.duration > 0) {
998
+ this.timeoutId = window.setTimeout(() => this.hide(), options.duration);
999
+ }
1000
+ }, 1000);
1001
+ }
1002
+ /**
1003
+ * Hides the currently displayed snackbar
1004
+ */
1005
+ hide() {
1006
+ this.stopIconAnimation();
1007
+ if (this.timeoutId) {
1008
+ clearTimeout(this.timeoutId);
1009
+ this.timeoutId = undefined;
1010
+ }
1011
+ if (this.currentSnackbar) {
1012
+ this.currentSnackbar.style.transform = this.getSlideTransform('bottom-right', true);
1013
+ this.currentSnackbar.style.opacity = '0';
1014
+ setTimeout(() => {
1015
+ var _a;
1016
+ if (((_a = this.currentSnackbar) === null || _a === void 0 ? void 0 : _a.parentNode) === this.container) {
1017
+ this.container.removeChild(this.currentSnackbar);
1018
+ }
1019
+ this.currentSnackbar = undefined;
1020
+ }, 300);
1021
+ }
1022
+ }
1023
+ getScreenScale() {
1024
+ const width = window.innerWidth;
1025
+ return width / this.BASE_DIMENSIONS.REFERENCE_WIDTH;
1026
+ }
1027
+ scaleValue(value) {
1028
+ return Math.round(value * this.getScreenScale());
1029
+ }
1030
+ setupContainer() {
1031
+ this.container = document.createElement('div');
1032
+ this.container.style.cssText = `
1033
+ position: fixed;
1034
+ z-index: 9999;
1035
+ pointer-events: none;
1036
+ width: 100%;
1037
+ height: 100%;
1038
+ top: 0;
1039
+ left: 0;
1040
+ `;
1041
+ document.body.appendChild(this.container);
1042
+ }
1043
+ getSlideTransform(position, hide = false) {
1044
+ const transformValue = '150%';
1045
+ const isTop = position.includes('top');
1046
+ return `translateY(${(hide === isTop ? '-' : '') + transformValue})`;
1047
+ }
1048
+ getPositionStyles(position, edgeMargin) {
1049
+ const margin = edgeMargin || this.scaleValue(this.BASE_DIMENSIONS.MARGIN) + 'px';
1050
+ const positions = {
1051
+ 'top-right': `top: ${margin}; right: ${margin};`,
1052
+ 'top-left': `top: ${margin}; left: ${margin};`,
1053
+ 'bottom-right': `bottom: ${margin}; right: ${margin};`,
1054
+ 'bottom-left': `bottom: ${margin}; left: ${margin};`,
1055
+ };
1056
+ return positions[position];
1057
+ }
1058
+ startIconAnimation(iconBase64Strings) {
1059
+ if (this.animationInterval) {
1060
+ clearInterval(this.animationInterval);
1061
+ }
1062
+ if (!iconBase64Strings || iconBase64Strings.length === 0) {
1063
+ return;
1064
+ }
1065
+ let currentIndex = 0;
1066
+ this.animationInterval = window.setInterval(() => {
1067
+ if (this.currentIconElement) {
1068
+ currentIndex = (currentIndex + 1) % iconBase64Strings.length;
1069
+ this.currentIconElement.src = iconBase64Strings[currentIndex];
1070
+ }
1071
+ }, 500);
1072
+ }
1073
+ stopIconAnimation() {
1074
+ if (this.animationInterval) {
1075
+ clearInterval(this.animationInterval);
1076
+ this.animationInterval = undefined;
1077
+ }
1078
+ }
1079
+ /**
1080
+ * Whether the snackbar should render right-to-left.
1081
+ * Defaults to LTR when no direction is provided.
1082
+ */
1083
+ isRtl(options) {
1084
+ return ((options === null || options === void 0 ? void 0 : options.direction) || 'ltr') === 'rtl';
1085
+ }
1086
+ createSnackbar(options) {
1087
+ const snackbar = document.createElement('div');
1088
+ snackbar.style.cssText = this.getSnackbarStyles(options);
1089
+ const isRtl = this.isRtl(options);
1090
+ const contentWrapper = this.createContentWrapper(isRtl);
1091
+ const iconBase64 = options === null || options === void 0 ? void 0 : options.iconBase64String;
1092
+ if (iconBase64) {
1093
+ const iconWrapper = this.createIconWrapper(iconBase64, options.iconWidth, options.iconHeight, options.iconMarginRight, isRtl);
1094
+ contentWrapper.appendChild(iconWrapper);
1095
+ }
1096
+ const textWrapper = this.createTextWrapper(options);
1097
+ contentWrapper.appendChild(textWrapper);
1098
+ snackbar.appendChild(contentWrapper);
1099
+ this.container.appendChild(snackbar);
1100
+ this.currentSnackbar = snackbar;
1101
+ requestAnimationFrame(() => {
1102
+ snackbar.style.opacity = '1';
1103
+ snackbar.style.transform = 'translateY(0)';
1104
+ });
1105
+ }
1106
+ getSnackbarStyles(options) {
1107
+ var _a;
1108
+ const theme = this.uiManager.getTheme();
1109
+ const borderColor = (options === null || options === void 0 ? void 0 : options.borderColor) || theme.primaryColor;
1110
+ const borderWidth = (options === null || options === void 0 ? void 0 : options.borderWidth) ||
1111
+ this.scaleValue(this.BASE_DIMENSIONS.BORDER_WIDTH) + 'px';
1112
+ const boxShadow = (options === null || options === void 0 ? void 0 : options.boxShadow) ||
1113
+ `0 ${this.scaleValue(2)}px ${this.scaleValue(8)}px rgba(0, 0, 0, 0.4)`;
1114
+ const padding = (options === null || options === void 0 ? void 0 : options.padding) || this.scaleValue(this.BASE_DIMENSIONS.PADDING) + 'px';
1115
+ const borderRadius = (options === null || options === void 0 ? void 0 : options.borderRadius) ||
1116
+ this.scaleValue(this.BASE_DIMENSIONS.BORDER_RADIUS) + 'px';
1117
+ return `
1118
+ position: absolute;
1119
+ display: flex;
1120
+ background: ${(options === null || options === void 0 ? void 0 : options.backgroundColor) || 'rgba(0, 0, 0, 0.75)'};
1121
+ color: white;
1122
+ width: ${(options === null || options === void 0 ? void 0 : options.width) || this.scaleValue(this.BASE_DIMENSIONS.WIDTH) + 'px'};
1123
+ ${(options === null || options === void 0 ? void 0 : options.height) ? `height: ${options.height};` : ''}
1124
+ ${(options === null || options === void 0 ? void 0 : options.minHeight) ? `min-height: ${options.minHeight};` : ''}
1125
+ padding: ${padding};
1126
+ border-radius: ${borderRadius};
1127
+ border: ${borderWidth} solid ${borderColor};
1128
+ box-shadow: ${boxShadow};
1129
+ font-family: ${theme.primaryFont || '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'};
1130
+ pointer-events: auto;
1131
+ transition: all 0.3s ease;
1132
+ opacity: 0;
1133
+ margin-top: ${(options === null || options === void 0 ? void 0 : options.marginTop) || '0'};
1134
+ margin-right: ${(options === null || options === void 0 ? void 0 : options.marginRight) || '0'};
1135
+ margin-bottom: ${(options === null || options === void 0 ? void 0 : options.marginBottom) || '0'};
1136
+ margin-left: ${(options === null || options === void 0 ? void 0 : options.marginLeft) || '0'};
1137
+ ${this.getPositionStyles((options === null || options === void 0 ? void 0 : options.position) || 'bottom-right', options === null || options === void 0 ? void 0 : options.edgeMargin)}
1138
+ transform: translateY(${((_a = options === null || options === void 0 ? void 0 : options.position) === null || _a === void 0 ? void 0 : _a.includes('top')) ? '-150%' : '150%'});
1139
+ `;
1140
+ }
1141
+ createContentWrapper(isRtl = false) {
1142
+ const wrapper = document.createElement('div');
1143
+ // `row-reverse` places the icon on the trailing (right) side for RTL.
1144
+ // Using an explicit flex-direction keeps ordering deterministic across TV
1145
+ // browsers rather than relying on `direction`-driven flex reordering.
1146
+ wrapper.style.cssText = `
1147
+ display: flex;
1148
+ flex-direction: ${isRtl ? 'row-reverse' : 'row'};
1149
+ align-items: flex-start;
1150
+ height: 100%;
1151
+ width: 100%;
1152
+ `;
1153
+ return wrapper;
1154
+ }
1155
+ createIconWrapper(iconBase64, width, height, marginRight, isRtl = false) {
1156
+ const wrapper = document.createElement('div');
1157
+ const iconSize = this.scaleValue(this.BASE_DIMENSIONS.ICON_SIZE);
1158
+ const iconGap = marginRight || this.scaleValue(this.BASE_DIMENSIONS.ICON_MARGIN) + 'px';
1159
+ // The gap always sits between the icon and the text. In RTL the icon is on
1160
+ // the right (row-reverse), so the gap belongs on its left instead.
1161
+ const iconGapSide = isRtl ? 'margin-left' : 'margin-right';
1162
+ wrapper.style.cssText = `
1163
+ ${iconGapSide}: ${iconGap};
1164
+ display: flex;
1165
+ align-items: flex-start;
1166
+ justify-content: center;
1167
+ min-width: ${width || iconSize + 'px'};
1168
+ width: ${width || iconSize + 'px'};
1169
+ height: ${height || iconSize + 'px'};
1170
+ color: white;
1171
+ margin-top: 0;
1172
+ `;
1173
+ const iconElement = document.createElement('img');
1174
+ iconElement.src = iconBase64;
1175
+ iconElement.style.cssText = `
1176
+ width: 100%;
1177
+ height: 100%;
1178
+ object-fit: contain;
1179
+ vertical-align: middle;
1180
+ `;
1181
+ this.currentIconElement = iconElement;
1182
+ wrapper.appendChild(iconElement);
1183
+ return wrapper;
1184
+ }
1185
+ createTextWrapper(options) {
1186
+ const isRtl = this.isRtl(options);
1187
+ const wrapper = document.createElement('div');
1188
+ // `direction` drives bidi text shaping; `text-align` aligns the title and
1189
+ // description to the leading edge. Both inherit to the child text elements.
1190
+ wrapper.style.cssText = `
1191
+ flex: 1;
1192
+ display: flex;
1193
+ flex-direction: column;
1194
+ justify-content: flex-start;
1195
+ direction: ${isRtl ? 'rtl' : 'ltr'};
1196
+ text-align: ${isRtl ? 'right' : 'left'};
1197
+ `;
1198
+ if (options === null || options === void 0 ? void 0 : options.titleText) {
1199
+ const titleElement = document.createElement('div');
1200
+ titleElement.style.cssText = `
1201
+ font-size: ${(options === null || options === void 0 ? void 0 : options.titleTextFontSize) || this.scaleValue(this.BASE_DIMENSIONS.TITLE_FONT_SIZE) + 'px'};
1202
+ font-family: ${(options === null || options === void 0 ? void 0 : options.titleTextFontFamily) || '-apple-system'};
1203
+ color: ${(options === null || options === void 0 ? void 0 : options.titleTextFontColor) || 'white'};
1204
+ font-weight: ${(options === null || options === void 0 ? void 0 : options.titleTextFontWeight) || '500'};
1205
+ margin-bottom: ${(options === null || options === void 0 ? void 0 : options.titleMarginBottom) || this.scaleValue(4) + 'px'};
1206
+ line-height: ${(options === null || options === void 0 ? void 0 : options.titleTextLineHeight) || '1.2'};
1207
+ `;
1208
+ titleElement.textContent = options.titleText;
1209
+ wrapper.appendChild(titleElement);
1210
+ }
1211
+ const messageElement = document.createElement('div');
1212
+ messageElement.style.cssText = `
1213
+ font-size: ${(options === null || options === void 0 ? void 0 : options.descriptionTextFontSize) ||
1214
+ this.scaleValue((options === null || options === void 0 ? void 0 : options.titleText)
1215
+ ? this.BASE_DIMENSIONS.MESSAGE_FONT_SIZE
1216
+ : this.BASE_DIMENSIONS.TITLE_FONT_SIZE) + 'px'};
1217
+ font-family: ${(options === null || options === void 0 ? void 0 : options.descriptionTextFontFamily) || '-apple-system'};
1218
+ color: ${(options === null || options === void 0 ? void 0 : options.descriptionTextFontColor) || 'rgba(255, 255, 255, 0.9)'};
1219
+ font-weight: ${(options === null || options === void 0 ? void 0 : options.descriptionTextFontWeight) || 'normal'};
1220
+ line-height: ${(options === null || options === void 0 ? void 0 : options.descriptionTextLineHeight) || '1.3'};
1221
+ `;
1222
+ messageElement.textContent = options.descriptionText;
1223
+ wrapper.appendChild(messageElement);
1224
+ return wrapper;
1225
+ }
1226
+ }
1227
+
1228
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1229
+ const LOG_TAG = 'VizbeeHomeSSOManager';
1230
+ /**
1231
+ * Manages Single Sign-On (SSO) functionality between mobile and TV devices in the Vizbee ecosystem.
1232
+ * Implements singleton pattern for global state management.
1233
+ *
1234
+ * @remarks
1235
+ * This class serves as the central manager for SSO operations, handling:
1236
+ * - Communication between mobile and TV devices
1237
+ * - Sign-in status management and updates
1238
+ * - UI state management
1239
+ * - Analytics and metrics tracking
1240
+ *
1241
+ * @class VizbeeHomeSSOManager
1242
+ * @public
1243
+ */
1244
+ class VizbeeHomeSSOManager {
1245
+ /**
1246
+ * Private constructor to enforce singleton pattern
1247
+ * Initializes necessary components and sets up default handlers
1248
+ *
1249
+ * @internal
1250
+ */
1251
+ constructor() {
1252
+ /** @internal List of sign-in information for different services */
1253
+ this.signInInfoList = [];
1254
+ /** @internal Tracks if remote device is signed in */
1255
+ this.isRemoteSignedIn = false;
1256
+ /** @internal Tracks if screen device is signed in */
1257
+ this.isScreenSignedIn = false;
1258
+ /** @internal Tracks if sign-in process is currently active */
1259
+ this.isSignInInProgress = false;
1260
+ /** @internal Information about the sender device */
1261
+ this.senderInfo = null;
1262
+ /**
1263
+ * Modal display preferences for the SSO UI
1264
+ * @public
1265
+ */
1266
+ this.modalPreferences = {};
1267
+ this.vizbeeHomeSSOUIManager = VizbeeHomeSSOUIManager.getInstance();
1268
+ this.snackbar = new VizbeeSnackbar();
1269
+ this.vizbeeMetricsManager = new VizbeeMetricsManager();
1270
+ }
1271
+ /**
1272
+ * Gets the singleton instance of VizbeeHomeSSOManager
1273
+ * Creates a new instance if one doesn't exist
1274
+ *
1275
+ * @returns The singleton instance of the SSO manager
1276
+ * @public
1277
+ */
1278
+ static getInstance() {
1279
+ if (!VizbeeHomeSSOManager.instance) {
1280
+ VizbeeHomeSSOManager.instance = new VizbeeHomeSSOManager();
1281
+ }
1282
+ return VizbeeHomeSSOManager.instance;
1283
+ }
1284
+ init() {
1285
+ this.initializeVizbeeSession();
1286
+ }
1287
+ /**
1288
+ * Sets up a handler for processing sign-in events from mobile devices
1289
+ *
1290
+ * @param handler - Callback function to process sign-in information and provide status updates
1291
+ * @public
1292
+ */
1293
+ setSignInHandler(handler) {
1294
+ logger.debug(`[${LOG_TAG}][setSignInHandler] - setSignInHandler called`);
1295
+ if (!handler) {
1296
+ logger.error(`[${LOG_TAG}][setSignInHandler] - Error: Sign-in handler is missing`);
1297
+ return;
1298
+ }
1299
+ if (typeof handler !== 'function') {
1300
+ logger.error(`[${LOG_TAG}][setSignInHandler] - Error: Sign-in handler is not a function`);
1301
+ return;
1302
+ }
1303
+ logger.info(`[${LOG_TAG}][setSignInHandler] - Setting sign-in handler`);
1304
+ this.signInHandler = handler;
1305
+ }
1306
+ /**
1307
+ * Sets the callback for retrieving sign-in information
1308
+ *
1309
+ * @param getSignInInfo - Async callback that provides the list of sign-in information
1310
+ * @public
1311
+ */
1312
+ setSignInInfoGetter(getSignInInfo) {
1313
+ if (!getSignInInfo) {
1314
+ logger.error(`[${LOG_TAG}][setSignInInfoGetter] - Error: GetSignInInfo callback is missing`);
1315
+ return;
1316
+ }
1317
+ if (typeof getSignInInfo !== 'function') {
1318
+ logger.error(`[${LOG_TAG}][setSignInInfoGetter] - Error: GetSignInInfo is not a function`);
1319
+ return;
1320
+ }
1321
+ if (!this.vizbeeMetricsManager) {
1322
+ logger.error(`[${LOG_TAG}][setSignInInfoGetter] - Error: Metrics manager is missing`);
1323
+ return;
1324
+ }
1325
+ if (!this.vizbeeMetricsManager.getSignInInfo) {
1326
+ logger.error(`[${LOG_TAG}][setSignInInfoGetter] - Error: GetAttributes callback is missing`);
1327
+ return;
1328
+ }
1329
+ this.vizbeeMetricsManager.getSignInInfo = getSignInInfo;
1330
+ }
1331
+ /**
1332
+ * Handles sign-in progress updates
1333
+ * Updates UI, sends status to mobile device, and logs metrics
1334
+ *
1335
+ * @param progressStatus - Current progress status of the sign-in process
1336
+ * @public
1337
+ */
1338
+ onProgress(progressStatus) {
1339
+ logger.info(`[${LOG_TAG}][onProgress] - OnProgress is invoked`);
1340
+ this.isSignInInProgress = true;
1341
+ this.sendStatusToSender(progressStatus);
1342
+ this.updateProgressUI();
1343
+ this.vizbeeMetricsManager.log(VizbeeMetricsConstants.METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_STATUS, {
1344
+ isScreenSignedIn: false,
1345
+ isRemoteSignedIn: this.isRemoteSignedIn,
1346
+ signInState: progressStatus.getState(),
1347
+ userId: null,
1348
+ signInType: progressStatus.signInType,
1349
+ });
1350
+ }
1351
+ /**
1352
+ * Handles successful sign-in completion
1353
+ * Updates UI, sends success status to mobile device, and logs metrics
1354
+ *
1355
+ * @param successStatus - Success status details
1356
+ * @public
1357
+ */
1358
+ onSuccess(successStatus) {
1359
+ logger.info(`[${LOG_TAG}][onSuccess] - OnSuccess is invoked`);
1360
+ this.isSignInInProgress = false;
1361
+ this.isRemoteSignedIn = true;
1362
+ this.sendStatusToSender(successStatus);
1363
+ this.updateSuccessUI();
1364
+ this.vizbeeMetricsManager.log(VizbeeMetricsConstants.METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_STATUS, {
1365
+ isScreenSignedIn: true,
1366
+ isRemoteSignedIn: this.isRemoteSignedIn,
1367
+ signInState: successStatus.getState(),
1368
+ userId: successStatus.userId,
1369
+ signInType: successStatus.signInType,
1370
+ });
1371
+ }
1372
+ /**
1373
+ * Handles sign-in failures
1374
+ * Updates UI and sends failure status to mobile device
1375
+ *
1376
+ * @param failureStatus - Failure status details
1377
+ * @public
1378
+ */
1379
+ onFailure(failureStatus) {
1380
+ logger.info(`[${LOG_TAG}][onFailure] - OnFailure is invoked`);
1381
+ this.isSignInInProgress = false;
1382
+ this.sendStatusToSender(failureStatus);
1383
+ this.updateFailureUI();
1384
+ this.vizbeeMetricsManager.log(VizbeeMetricsConstants.METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_STATUS, {
1385
+ isScreenSignedIn: false,
1386
+ isRemoteSignedIn: this.isRemoteSignedIn,
1387
+ signInState: failureStatus.getState(),
1388
+ userId: null,
1389
+ signInType: failureStatus.signInType,
1390
+ });
1391
+ }
1392
+ /**
1393
+ * Adds custom attributes for metrics tracking
1394
+ *
1395
+ * @param customEventAttributes - Dictionary of custom attributes to track
1396
+ * @public
1397
+ */
1398
+ addCustomEventAttributes(customEventAttributes) {
1399
+ var _a;
1400
+ if (customEventAttributes) {
1401
+ (_a = this.vizbeeMetricsManager) === null || _a === void 0 ? void 0 : _a.setCustomAttributes(customEventAttributes);
1402
+ }
1403
+ }
1404
+ /**
1405
+ * Initializes Vizbee session and messaging client
1406
+ *
1407
+ * @throws Error if initialization fails
1408
+ * @internal
1409
+ */
1410
+ initializeVizbeeSession() {
1411
+ var _a, _b;
1412
+ try {
1413
+ logger.info(`[${LOG_TAG}][initializeVizbeeSession] - Initializing Vizbee session`);
1414
+ // Check if vizbee and continuity exist before accessing xmessages
1415
+ if (!((_b = (_a = window.vizbee) === null || _a === void 0 ? void 0 : _a.continuity) === null || _b === void 0 ? void 0 : _b.xmessages)) {
1416
+ throw new Error('Vizbee continuity or xmessages not initialized');
1417
+ }
1418
+ // Access VizbeeBicastSessionManager directly from the existing object
1419
+ const sessionManager = new window.vizbee.continuity.xmessages.VizbeeBicastSessionManager();
1420
+ if (!sessionManager) {
1421
+ throw new Error('Session manager initialization failed');
1422
+ }
1423
+ // add sessionStateListener
1424
+ logger.debug(`[${LOG_TAG}]initializeVizbeeSession - Adding session state listener`);
1425
+ sessionManager.addSessionStateListener({
1426
+ onSessionStateChanged: (state) => {
1427
+ logger.info(`[${LOG_TAG}][onSessionStateChanged] - Session state changed:`, state);
1428
+ if (state === 3) {
1429
+ this.vizbeeSession = sessionManager.getSession();
1430
+ this.vizbeeMessagingClient =
1431
+ this.vizbeeSession.getMessagingClient();
1432
+ if (this.signInHandler) {
1433
+ logger.info(`[${LOG_TAG}][onSessionStateChanged] - Adding sign-in request receiver`);
1434
+ this.vizbeeMessagingClient.addReceiver(VizbeeConstants.EVENT_SSO_NAME, (payload, namespace, device) => __awaiter(this, void 0, void 0, function* () {
1435
+ logger.debug(`[${LOG_TAG}][onSessionStateChanged] - Received sign-in request on namespace:`, namespace);
1436
+ this.senderInfo = device;
1437
+ yield this.handleSignInRequest(payload, this.signInHandler);
1438
+ }));
1439
+ }
1440
+ else {
1441
+ logger.warn(`[${LOG_TAG}][onSessionStateChanged] - Error: Sign-in handler is missing`);
1442
+ }
1443
+ }
1444
+ },
1445
+ });
1446
+ }
1447
+ catch (error) {
1448
+ logger.warn(`[${LOG_TAG}][onSessionStateChanged] - Error initializing Vizbee session:`, error);
1449
+ throw error;
1450
+ }
1451
+ }
1452
+ /**
1453
+ * Processes incoming sign-in requests
1454
+ * Validates request and triggers appropriate handler
1455
+ *
1456
+ * @param payload - Sign-in request payload
1457
+ * @param handler - Callback to handle the sign-in request
1458
+ * @internal
1459
+ */
1460
+ handleSignInRequest(payload, handler) {
1461
+ return __awaiter(this, void 0, void 0, function* () {
1462
+ var _a, _b;
1463
+ const senderSignInInfo = payload[VizbeeConstants.KEY_START_SIGN_IN_INFO];
1464
+ if (!senderSignInInfo) {
1465
+ logger.warn(`[${LOG_TAG}][handleSignInRequest] - Error: Sender info is missing`);
1466
+ return;
1467
+ }
1468
+ const signInType = senderSignInInfo[VizbeeConstants.KEY_SIGN_IN_TYPE];
1469
+ this.isScreenSignedIn = yield this.isUserAlreadySignedIn(signInType);
1470
+ this.isRemoteSignedIn = payload[VizbeeConstants.KEY_START_SIGN_IN_INFO][VizbeeConstants.KEY_IS_SIGNED_IN];
1471
+ this.vizbeeMetricsManager.log(VizbeeMetricsConstants.METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_RECEIVED, {
1472
+ isScreenSignedIn: this.isScreenSignedIn,
1473
+ isRemoteSignedIn: this.isRemoteSignedIn,
1474
+ signInType: signInType,
1475
+ senderInfo: this.senderInfo,
1476
+ });
1477
+ if (yield this.shouldIgnoreSignInRequest()) {
1478
+ return;
1479
+ }
1480
+ const signInInfo = {
1481
+ isSignedIn: this.isRemoteSignedIn,
1482
+ signInType: signInType,
1483
+ deviceId: (_a = this.senderInfo) === null || _a === void 0 ? void 0 : _a.deviceId,
1484
+ deviceType: (_b = this.senderInfo) === null || _b === void 0 ? void 0 : _b.deviceType,
1485
+ customData: {},
1486
+ };
1487
+ handler(signInInfo, this.handleSignInStatus.bind(this));
1488
+ });
1489
+ }
1490
+ /**
1491
+ * Determines if a sign-in request should be ignored
1492
+ * Checks various conditions like existing sign-in state
1493
+ *
1494
+ * @returns Promise<boolean> indicating if request should be ignored
1495
+ * @internal
1496
+ */
1497
+ shouldIgnoreSignInRequest() {
1498
+ return __awaiter(this, void 0, void 0, function* () {
1499
+ if (this.isScreenSignedIn) {
1500
+ logger.info(`[${LOG_TAG}][shouldIgnoreSignInRequest] - User is already signed in`);
1501
+ return true;
1502
+ }
1503
+ return false;
1504
+ });
1505
+ }
1506
+ /**
1507
+ * Checks if user is already signed in for a specific sign-in type
1508
+ *
1509
+ * @param signInType - Type of sign-in to check
1510
+ * @returns Promise<boolean> indicating if user is signed in
1511
+ * @internal
1512
+ */
1513
+ isUserAlreadySignedIn(signInType) {
1514
+ return __awaiter(this, void 0, void 0, function* () {
1515
+ var _a, _b;
1516
+ try {
1517
+ const attributes = yield ((_b = (_a = this.vizbeeMetricsManager) === null || _a === void 0 ? void 0 : _a.getAttributes) === null || _b === void 0 ? void 0 : _b.call(_a));
1518
+ const signInInfoList = attributes === null || attributes === void 0 ? void 0 : attributes['SCREEN_HOMESSO_USER_INFO'];
1519
+ logger.info(`[${LOG_TAG}][isUserAlreadySignedIn] - signInInfoList`, signInInfoList);
1520
+ const tvSignInInfo = signInInfoList.find((info) => info.user_login_type === signInType);
1521
+ logger.debug(`[${LOG_TAG}][isUserAlreadySignedIn] - TV sign in status fetched:`, tvSignInInfo);
1522
+ return tvSignInInfo === null || tvSignInInfo === void 0 ? void 0 : tvSignInInfo.user_is_signed_in;
1523
+ }
1524
+ catch (error) {
1525
+ logger.warn(`[${LOG_TAG}][isUserAlreadySignedIn] - Error checking sign-in status:`, error);
1526
+ return false;
1527
+ }
1528
+ });
1529
+ }
1530
+ /**
1531
+ * Handles sign-in status updates
1532
+ * Routes status updates to appropriate handlers
1533
+ *
1534
+ * @param status - Current status of the sign-in process
1535
+ * @internal
1536
+ */
1537
+ handleSignInStatus(status) {
1538
+ var _a, _b;
1539
+ if (status instanceof ProgressStatus) {
1540
+ const regcode = (_a = status.customData) === null || _a === void 0 ? void 0 : _a.regcode;
1541
+ if (regcode) {
1542
+ this.onProgress(status);
1543
+ }
1544
+ }
1545
+ else if (status instanceof SuccessStatus) {
1546
+ const userEmail = (_b = status.customData) === null || _b === void 0 ? void 0 : _b.email;
1547
+ if (userEmail) {
1548
+ this.onSuccess(status);
1549
+ }
1550
+ }
1551
+ else if (status instanceof FailureStatus) {
1552
+ this.onFailure(status);
1553
+ }
1554
+ }
1555
+ /**
1556
+ * Sends status updates to mobile device
1557
+ *
1558
+ * @param status - Status to send to mobile device
1559
+ * @internal
1560
+ */
1561
+ sendStatusToSender(status) {
1562
+ const signInStatus = this.serializeStatus(status);
1563
+ const data = {
1564
+ [VizbeeConstants.KEY_SUB_TYPE]: VizbeeConstants.EVENT_SUBTYPE_SIGN_IN_STATUS,
1565
+ [VizbeeConstants.KEY_SIGN_IN_STATUS]: signInStatus,
1566
+ };
1567
+ this.vizbeeMessagingClient.send(data, VizbeeConstants.EVENT_SSO_NAME);
1568
+ }
1569
+ /**
1570
+ * Serializes status objects for transmission to mobile device
1571
+ *
1572
+ * @param status - Status object to serialize
1573
+ * @returns Serialized status object or null if invalid status type
1574
+ * @internal
1575
+ */
1576
+ serializeStatus(status) {
1577
+ if (status instanceof ProgressStatus) {
1578
+ return status.serialize();
1579
+ }
1580
+ else if (status instanceof SuccessStatus) {
1581
+ return status.serialize();
1582
+ }
1583
+ else if (status instanceof FailureStatus) {
1584
+ return status.serialize();
1585
+ }
1586
+ return null;
1587
+ }
1588
+ /**
1589
+ * Updates UI for sign-in progress state
1590
+ * Shows appropriate modal based on remote sign-in status
1591
+ *
1592
+ * @internal
1593
+ */
1594
+ updateProgressUI() {
1595
+ if (!this.isRemoteSignedIn) {
1596
+ const modalOptions = this.vizbeeHomeSSOUIManager.getInformationalSignInModalConfig();
1597
+ this.snackbar.show(modalOptions);
1598
+ }
1599
+ else {
1600
+ const modalOptions = this.vizbeeHomeSSOUIManager.getProgressSignInModalConfig();
1601
+ this.snackbar.show(Object.assign(Object.assign({}, modalOptions), { shouldAnimateIcon: true }));
1602
+ }
1603
+ }
1604
+ /**
1605
+ * Updates UI for successful sign-in
1606
+ * Shows success modal with appropriate message
1607
+ *
1608
+ * @internal
1609
+ */
1610
+ updateSuccessUI() {
1611
+ // Enforce only the success duration; leave title/description to the
1612
+ // integrator's config (or the defaults) so the success toast can be
1613
+ // themed/localized like the informational and progress modals.
1614
+ this.vizbeeHomeSSOUIManager.setSuccessSignInModalConfig({ duration: 10000 });
1615
+ const modalOptions = this.vizbeeHomeSSOUIManager.getSuccessSignInModalConfig();
1616
+ this.snackbar.show(modalOptions);
1617
+ }
1618
+ /**
1619
+ * Updates UI for failed sign-in
1620
+ * Hides any active modals
1621
+ *
1622
+ * @internal
1623
+ */
1624
+ updateFailureUI() {
1625
+ this.snackbar.hide();
1626
+ }
1627
+ }
1628
+ /** @internal Singleton instance of the manager */
1629
+ VizbeeHomeSSOManager.instance = null;
1630
+
1631
+ const UNKNOWN_VALUE = 'UNKNOWN';
1632
+
1633
+ /**
1634
+ * @class HomeSSOContext
1635
+ * @description Context provider for Vizbee Home SSO functionality
1636
+ */
1637
+ class HomeSSOContext {
1638
+ constructor() {
1639
+ this.homeSSOUIManager = null;
1640
+ }
1641
+ /**
1642
+ * Gets the singleton instance of HomeSSOContext
1643
+ * @returns The singleton instance of HomeSSOContext
1644
+ */
1645
+ static getInstance() {
1646
+ if (!HomeSSOContext.instance) {
1647
+ HomeSSOContext.instance = new HomeSSOContext();
1648
+ }
1649
+ return HomeSSOContext.instance;
1650
+ }
1651
+ /**
1652
+ * Gets the HomeSSOManager instance
1653
+ * @returns The singleton instance of VizbeeHomeSSOManager
1654
+ */
1655
+ getHomeSSOManager() {
1656
+ return VizbeeHomeSSOManager.getInstance();
1657
+ }
1658
+ /**
1659
+ * Gets the HomeSSOUIManager instance
1660
+ * @param config Optional UI configuration including theme settings
1661
+ * @returns The singleton instance of VizbeeHomeSSOUIManager
1662
+ */
1663
+ getHomeSSOUIManager() {
1664
+ return VizbeeHomeSSOUIManager.getInstance();
1665
+ }
1666
+ enableLogger(enable) {
1667
+ logger.setConfig({
1668
+ enabled: enable,
1669
+ });
1670
+ }
1671
+ setLoggerLevel(level) {
1672
+ logger.setConfig({
1673
+ enabled: true,
1674
+ level: level,
1675
+ });
1676
+ }
1677
+ }
1678
+ HomeSSOContext.instance = null;
1679
+ const init = () => {
1680
+ // Initialize the global namespace
1681
+ if (typeof window !== 'undefined') {
1682
+ if (!window.vizbee) {
1683
+ window.addEventListener('VIZBEE_SDK_READY', () => {
1684
+ if (window.vizbee) {
1685
+ setupHomeSSO();
1686
+ }
1687
+ });
1688
+ }
1689
+ else {
1690
+ setupHomeSSO();
1691
+ }
1692
+ }
1693
+ };
1694
+ const setupHomeSSO = () => {
1695
+ window.vizbee.homesso = {
1696
+ HomeSSOContext: HomeSSOContext,
1697
+ messages: {
1698
+ ProgressStatus,
1699
+ SuccessStatus,
1700
+ FailureStatus,
1701
+ },
1702
+ LoggerLevel: LogLevel,
1703
+ // Replaced at build time with package.json's version by
1704
+ // @rollup/plugin-replace (same token the metrics manager uses), so
1705
+ // integrators can read the loaded SDK version off the namespace.
1706
+ VERSION: '1.0.1',
1707
+ };
1708
+ window.dispatchEvent(new Event('VIZBEE_HOMESSO_READY'));
1709
+ };
1710
+ init();
1711
+
1712
+ export { FailureStatus, HomeSSOContext, LogLevel, ProgressStatus, SuccessStatus, UNKNOWN_VALUE, VizbeeHomeSSOManager, VizbeeHomeSSOUIManager };