@glideidentity/web-client-sdk 5.0.1 → 5.1.1-beta.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.
Files changed (97) hide show
  1. package/README.md +8 -108
  2. package/dist/adapters/angular/index.js +1 -0
  3. package/dist/adapters/angular/phone-auth.service.d.ts +18 -0
  4. package/dist/adapters/angular/phone-auth.service.js +26 -0
  5. package/dist/adapters/react/index.js +3 -0
  6. package/dist/adapters/react/useClient.js +1 -0
  7. package/dist/adapters/react/usePhoneAuth.js +16 -1
  8. package/dist/adapters/vanilla/client.js +1 -0
  9. package/dist/adapters/vanilla/index.js +1 -0
  10. package/dist/adapters/vanilla/phone-auth.js +31 -0
  11. package/dist/adapters/vue/index.js +4 -0
  12. package/dist/adapters/vue/useClient.js +5 -0
  13. package/dist/adapters/vue/usePhoneAuth.js +20 -1
  14. package/dist/browser/web-client-sdk.min.js +1 -2
  15. package/dist/browser.js +6 -0
  16. package/dist/core/client.js +12 -0
  17. package/dist/core/logger.js +81 -1
  18. package/dist/core/phone-auth/api-types.d.ts +1 -4
  19. package/dist/core/phone-auth/api-types.js +83 -0
  20. package/dist/core/phone-auth/client.js +374 -38
  21. package/dist/core/phone-auth/error-utils.js +83 -1
  22. package/dist/core/phone-auth/index.d.ts +1 -1
  23. package/dist/core/phone-auth/index.js +2 -2
  24. package/dist/core/phone-auth/status-types.d.ts +78 -0
  25. package/dist/core/phone-auth/status-types.js +17 -0
  26. package/dist/core/phone-auth/strategies/desktop.d.ts +2 -0
  27. package/dist/core/phone-auth/strategies/desktop.js +136 -13
  28. package/dist/core/phone-auth/strategies/index.d.ts +4 -0
  29. package/dist/core/phone-auth/strategies/index.js +4 -0
  30. package/dist/core/phone-auth/strategies/link.d.ts +2 -0
  31. package/dist/core/phone-auth/strategies/link.js +97 -13
  32. package/dist/core/phone-auth/strategies/ts43.d.ts +19 -0
  33. package/dist/core/phone-auth/strategies/ts43.js +33 -2
  34. package/dist/core/phone-auth/strategies/types.js +4 -0
  35. package/dist/core/phone-auth/type-guards.js +131 -0
  36. package/dist/core/phone-auth/types.d.ts +5 -0
  37. package/dist/core/phone-auth/types.js +32 -0
  38. package/dist/core/phone-auth/ui/mobile-debug-console.js +28 -2
  39. package/dist/core/phone-auth/ui/modal.d.ts +55 -33
  40. package/dist/core/phone-auth/ui/modal.js +422 -889
  41. package/dist/core/phone-auth/validation-utils.d.ts +0 -9
  42. package/dist/core/phone-auth/validation-utils.js +34 -25
  43. package/dist/core/version.js +2 -1
  44. package/dist/esm/adapters/angular/index.js +1 -0
  45. package/dist/esm/adapters/angular/phone-auth.service.d.ts +18 -0
  46. package/dist/esm/adapters/angular/phone-auth.service.js +26 -0
  47. package/dist/esm/adapters/react/index.js +3 -0
  48. package/dist/esm/adapters/react/useClient.js +1 -0
  49. package/dist/esm/adapters/react/usePhoneAuth.js +16 -1
  50. package/dist/esm/adapters/vanilla/client.js +1 -0
  51. package/dist/esm/adapters/vanilla/index.js +1 -0
  52. package/dist/esm/adapters/vanilla/phone-auth.d.ts +24 -0
  53. package/dist/esm/adapters/vanilla/phone-auth.js +31 -0
  54. package/dist/esm/adapters/vue/index.js +4 -0
  55. package/dist/esm/adapters/vue/useClient.js +5 -0
  56. package/dist/esm/adapters/vue/usePhoneAuth.js +20 -1
  57. package/dist/esm/browser.js +6 -0
  58. package/dist/esm/core/client.d.ts +10 -0
  59. package/dist/esm/core/client.js +12 -0
  60. package/dist/esm/core/logger.d.ts +53 -0
  61. package/dist/esm/core/logger.js +81 -1
  62. package/dist/esm/core/phone-auth/api-types.d.ts +313 -1
  63. package/dist/esm/core/phone-auth/api-types.js +83 -0
  64. package/dist/esm/core/phone-auth/client.d.ts +144 -0
  65. package/dist/esm/core/phone-auth/client.js +375 -39
  66. package/dist/esm/core/phone-auth/error-utils.d.ts +29 -0
  67. package/dist/esm/core/phone-auth/error-utils.js +83 -1
  68. package/dist/esm/core/phone-auth/index.d.ts +1 -1
  69. package/dist/esm/core/phone-auth/index.js +4 -2
  70. package/dist/esm/core/phone-auth/status-types.d.ts +78 -0
  71. package/dist/esm/core/phone-auth/status-types.js +17 -0
  72. package/dist/esm/core/phone-auth/strategies/desktop.d.ts +65 -0
  73. package/dist/esm/core/phone-auth/strategies/desktop.js +136 -13
  74. package/dist/esm/core/phone-auth/strategies/index.d.ts +4 -0
  75. package/dist/esm/core/phone-auth/strategies/index.js +4 -0
  76. package/dist/esm/core/phone-auth/strategies/link.d.ts +50 -0
  77. package/dist/esm/core/phone-auth/strategies/link.js +97 -13
  78. package/dist/esm/core/phone-auth/strategies/ts43.d.ts +19 -0
  79. package/dist/esm/core/phone-auth/strategies/ts43.js +33 -2
  80. package/dist/esm/core/phone-auth/strategies/types.d.ts +13 -0
  81. package/dist/esm/core/phone-auth/strategies/types.js +4 -0
  82. package/dist/esm/core/phone-auth/type-guards.d.ts +128 -0
  83. package/dist/esm/core/phone-auth/type-guards.js +131 -0
  84. package/dist/esm/core/phone-auth/types.d.ts +113 -0
  85. package/dist/esm/core/phone-auth/types.js +32 -0
  86. package/dist/esm/core/phone-auth/ui/mobile-debug-console.d.ts +4 -0
  87. package/dist/esm/core/phone-auth/ui/mobile-debug-console.js +28 -2
  88. package/dist/esm/core/phone-auth/ui/modal.d.ts +68 -27
  89. package/dist/esm/core/phone-auth/ui/modal.js +422 -889
  90. package/dist/esm/core/phone-auth/validation-utils.d.ts +26 -4
  91. package/dist/esm/core/phone-auth/validation-utils.js +34 -24
  92. package/dist/esm/core/types.d.ts +35 -0
  93. package/dist/esm/core/version.js +2 -1
  94. package/dist/esm/index.js +9 -1
  95. package/dist/index.js +7 -0
  96. package/package.json +1 -1
  97. package/dist/browser/web-client-sdk.min.js.LICENSE.txt +0 -1
@@ -1,3 +1,27 @@
1
+ /**
2
+ * Type Guards and Helper Functions for Phone Authentication
3
+ *
4
+ * These utilities help developers work with the SDK responses in a type-safe way
5
+ * without having to write their own type checking logic.
6
+ */
7
+ /**
8
+ * Type guard to check if the result is an ExtendedResponse (extended mode)
9
+ * or a Credential (standard mode).
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const result = await invokeSecurePrompt(sdkRequest, { executionMode: 'extended' });
14
+ *
15
+ * if (isExtendedResponse(result)) {
16
+ * // TypeScript knows this is ExtendedResponse
17
+ * console.log(result.strategy);
18
+ * await result.cancel();
19
+ * } else {
20
+ * // TypeScript knows this is a Credential
21
+ * const processedResult = await verifyPhoneNumberCredential(result, session);
22
+ * }
23
+ * ```
24
+ */
1
25
  export function isExtendedResponse(result) {
2
26
  return result &&
3
27
  typeof result === 'object' &&
@@ -6,16 +30,41 @@ export function isExtendedResponse(result) {
6
30
  'cancel' in result &&
7
31
  typeof result.cancel === 'function';
8
32
  }
33
+ /**
34
+ * Type guard to check if the result is a Credential (standard mode response).
35
+ * A credential is either a string token or an object without ExtendedResponse properties.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * if (isCredential(result)) {
40
+ * // Process the credential directly
41
+ * const verified = await verifyPhoneNumberCredential(result, session);
42
+ * }
43
+ * ```
44
+ */
9
45
  export function isCredential(result) {
10
46
  if (!result)
11
47
  return false;
48
+ // String credentials are valid
12
49
  if (typeof result === 'string')
13
50
  return true;
51
+ // Object credentials should NOT have ExtendedResponse properties
14
52
  if (typeof result === 'object') {
15
53
  return !('strategy' in result) && !('credential' in result) && !('cancel' in result);
16
54
  }
17
55
  return false;
18
56
  }
57
+ /**
58
+ * Type guard to check if the result is an AuthCredential object.
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * if (isAuthCredential(result)) {
63
+ * console.log(result.credential);
64
+ * console.log(result.authenticated);
65
+ * }
66
+ * ```
67
+ */
19
68
  export function isAuthCredential(result) {
20
69
  return result &&
21
70
  typeof result === 'object' &&
@@ -23,32 +72,114 @@ export function isAuthCredential(result) {
23
72
  'authenticated' in result &&
24
73
  'session' in result;
25
74
  }
75
+ /**
76
+ * Type guard to check if an ExtendedResponse is using the Link strategy.
77
+ * Link strategy involves opening an app link (App Clip on iOS, app on Android).
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * if (isExtendedResponse(result) && isLinkStrategy(result)) {
82
+ * // Re-trigger app opening if needed
83
+ * result.trigger();
84
+ * await result.credential;
85
+ * }
86
+ * ```
87
+ */
26
88
  export function isLinkStrategy(result) {
27
89
  return result.strategy === 'link';
28
90
  }
91
+ /**
92
+ * Type guard to check if an ExtendedResponse is using the TS43 strategy.
93
+ * TS43 strategy uses the browser's Digital Credentials API.
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * if (isExtendedResponse(result) && isTS43Strategy(result)) {
98
+ * // Re-trigger credential request if needed
99
+ * await result.trigger();
100
+ * }
101
+ * ```
102
+ */
29
103
  export function isTS43Strategy(result) {
30
104
  return result.strategy === 'ts43';
31
105
  }
106
+ /**
107
+ * Type guard to check if an ExtendedResponse is using the Desktop strategy.
108
+ * Desktop strategy involves QR codes for cross-device authentication.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * if (isExtendedResponse(result) && isDesktopStrategy(result)) {
113
+ * // Show custom QR code UI
114
+ * displayQRCode(result.qr_code_data);
115
+ * await result.start_polling();
116
+ * }
117
+ * ```
118
+ */
32
119
  export function isDesktopStrategy(result) {
33
120
  return result.strategy === 'desktop';
34
121
  }
122
+ /**
123
+ * Helper function to safely get the authentication strategy from any result.
124
+ * Returns undefined if the result is not an ExtendedResponse.
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * const strategy = getStrategy(result);
129
+ * if (strategy === 'link') {
130
+ * // Handle link strategy
131
+ * }
132
+ * ```
133
+ */
35
134
  export function getStrategy(result) {
36
135
  if (isExtendedResponse(result)) {
37
136
  return result.strategy;
38
137
  }
39
138
  return undefined;
40
139
  }
140
+ /**
141
+ * Helper function to determine if a result has polling controls.
142
+ * Link and Desktop strategies have polling controls in extended mode.
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * if (hasPollingControls(result)) {
147
+ * await result.start_polling();
148
+ * }
149
+ * ```
150
+ */
41
151
  export function hasPollingControls(result) {
42
152
  if (!isExtendedResponse(result))
43
153
  return false;
44
154
  return (result.strategy === 'link' && 'start_polling' in result) ||
45
155
  (result.strategy === 'desktop' && 'start_polling' in result);
46
156
  }
157
+ /**
158
+ * Helper function to determine if a result has a trigger method.
159
+ * Link and TS43 strategies have trigger methods in extended mode.
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * if (hasTrigger(result)) {
164
+ * result.trigger();
165
+ * }
166
+ * ```
167
+ */
47
168
  export function hasTrigger(result) {
48
169
  if (!isExtendedResponse(result))
49
170
  return false;
50
171
  return 'trigger' in result && typeof result.trigger === 'function';
51
172
  }
173
+ // Export legacy function names as deprecated aliases for backward compatibility
174
+ /**
175
+ * @deprecated Use isExtendedResponse instead
176
+ */
52
177
  export const isHeadlessResult = isExtendedResponse;
178
+ /**
179
+ * @deprecated Use hasPollingControls instead
180
+ */
53
181
  export const requiresPolling = hasPollingControls;
182
+ /**
183
+ * @deprecated This function is no longer needed as extended mode handles user actions differently
184
+ */
54
185
  export const requiresUserAction = (result) => false;
@@ -1,33 +1,105 @@
1
+ /**
2
+ * Phone Authentication Types
3
+ *
4
+ * This file exports the types used by the Phone Auth SDK.
5
+ * All API types are imported from api-types.ts to ensure consistency.
6
+ * No backward compatibility - using clean API specification only.
7
+ */
1
8
  export * from './api-types';
2
9
  import type { PrepareRequest as APIPrepareRequest, GetPhoneNumberResponse, VerifyPhoneNumberResponse, UseCase as APIUseCase, AuthenticationStrategy as APIAuthStrategy } from './api-types';
3
10
  export type PhoneAuthOptions = APIPrepareRequest;
4
11
  export type PhoneAuthResult = GetPhoneNumberResponse | VerifyPhoneNumberResponse;
5
12
  export type UseCaseType = APIUseCase;
6
13
  export type AuthenticationStrategyType = APIAuthStrategy;
14
+ /**
15
+ * SDK-specific error codes from error-utils
16
+ */
7
17
  import type { PhoneAuthErrorCode as ErrorCodeFromUtils } from './error-utils';
8
18
  export type PhoneAuthErrorCode = ErrorCodeFromUtils;
19
+ /**
20
+ * SDK configuration callbacks
21
+ */
9
22
  export interface PhoneAuthCallbacks {
23
+ /**
24
+ * Called when cross-device authentication is detected (e.g., QR code shown)
25
+ */
10
26
  onCrossDeviceDetected?: () => void;
27
+ /**
28
+ * Called when a retry attempt is made
29
+ * @param attempt Current attempt number
30
+ * @param maxAttempts Maximum number of attempts
31
+ */
11
32
  onRetryAttempt?: (attempt: number, maxAttempts: number) => void;
33
+ /**
34
+ * Called when authentication times out
35
+ */
12
36
  onTimeout?: () => void;
37
+ /**
38
+ * Called when user cancels authentication
39
+ */
13
40
  onCancel?: () => void;
41
+ /**
42
+ * Called when polling starts
43
+ */
14
44
  onPollingStart?: () => void;
45
+ /**
46
+ * Called when polling stops
47
+ */
15
48
  onPollingStop?: () => void;
16
49
  }
50
+ /**
51
+ * SDK configuration options
52
+ */
17
53
  export interface AuthConfig extends PhoneAuthCallbacks {
54
+ /**
55
+ * Custom endpoints for authentication flow
56
+ */
18
57
  endpoints?: {
19
58
  prepare?: string;
20
59
  process?: string;
60
+ /** Desktop authentication status polling endpoint */
21
61
  polling?: string;
22
62
  };
63
+ /**
64
+ * Timeout for API calls in milliseconds
65
+ * @default 30000
66
+ */
23
67
  timeout?: number;
68
+ /**
69
+ * Polling interval in milliseconds for status checks
70
+ * @default 2000
71
+ */
24
72
  pollingInterval?: number;
73
+ /**
74
+ * Maximum polling attempts before timeout
75
+ * @default 30 (1 minute with 2s interval)
76
+ */
25
77
  maxPollingAttempts?: number;
78
+ /**
79
+ * Enable debug logging
80
+ * @default false
81
+ */
26
82
  debug?: boolean;
83
+ /**
84
+ * Developer environment for testing (e.g., 'dev1', 'dev2')
85
+ * When set, adds a 'developer' header to polling requests
86
+ */
87
+ devEnv?: string;
88
+ /**
89
+ * Developer tools configuration for debugging
90
+ */
27
91
  devtools?: {
92
+ /**
93
+ * Show mobile console overlay for on-device debugging
94
+ * Displays all console logs at the bottom of the screen
95
+ * @default false
96
+ */
28
97
  showMobileConsole?: boolean;
29
98
  };
30
99
  }
100
+ /**
101
+ * SDK-enhanced error type with additional context
102
+ */
31
103
  export interface AuthError {
32
104
  code: PhoneAuthErrorCode;
33
105
  message: string;
@@ -54,7 +126,13 @@ export interface AuthError {
54
126
  [key: string]: any;
55
127
  };
56
128
  }
129
+ /**
130
+ * SDK authentication flow steps
131
+ */
57
132
  export type AuthStep = 'idle' | 'requesting' | 'authenticating' | 'processing' | 'complete';
133
+ /**
134
+ * Browser error names
135
+ */
58
136
  export declare const BrowserError: {
59
137
  readonly NOT_ALLOWED: "NotAllowedError";
60
138
  readonly NETWORK: "NetworkError";
@@ -72,6 +150,9 @@ export declare const BrowserError: {
72
150
  readonly SYNTAX: "SyntaxError";
73
151
  };
74
152
  export type BrowserErrorType = typeof BrowserError[keyof typeof BrowserError];
153
+ /**
154
+ * Browser error codes
155
+ */
75
156
  export declare const BrowserErrorCode: {
76
157
  readonly USER_CANCELLED_DC_API: 19;
77
158
  readonly PERMISSION_DENIED: 1;
@@ -83,6 +164,9 @@ export declare const BrowserErrorCode: {
83
164
  readonly SECURITY: 18;
84
165
  };
85
166
  export type BrowserErrorCodeType = typeof BrowserErrorCode[keyof typeof BrowserErrorCode];
167
+ /**
168
+ * Browser names for detection
169
+ */
86
170
  export declare const BrowserName: {
87
171
  readonly CHROME: "Chrome";
88
172
  readonly EDGE: "Edge";
@@ -93,6 +177,9 @@ export declare const BrowserName: {
93
177
  readonly OTHER: "other";
94
178
  };
95
179
  export type BrowserNameType = typeof BrowserName[keyof typeof BrowserName];
180
+ /**
181
+ * Browser Digital Credential type (extends standard Credential)
182
+ */
96
183
  export interface DigitalCredential extends Credential {
97
184
  data: {
98
185
  vp_token: {
@@ -100,6 +187,9 @@ export interface DigitalCredential extends Credential {
100
187
  };
101
188
  };
102
189
  }
190
+ /**
191
+ * Browser credential request structure
192
+ */
103
193
  export interface SecureCredentialRequest {
104
194
  digital: {
105
195
  requests: Array<{
@@ -108,17 +198,40 @@ export interface SecureCredentialRequest {
108
198
  }>;
109
199
  };
110
200
  }
201
+ /**
202
+ * Authentication status constants
203
+ * Maps to both client-side states and backend responses
204
+ */
111
205
  export declare const AuthStatus: {
206
+ /** Authentication in progress */
112
207
  readonly PENDING: "pending";
208
+ /** Authentication completed successfully */
113
209
  readonly COMPLETED: "completed";
210
+ /** User cancelled authentication */
114
211
  readonly CANCELLED: "cancelled";
212
+ /** Authentication failed or expired */
115
213
  readonly FAILED: "failed";
214
+ /** Session expired (backend returns 410 Gone) */
116
215
  readonly EXPIRED: "expired";
216
+ /** Session not found (backend returns 404) */
117
217
  readonly NOT_FOUND: "not_found";
118
218
  };
119
219
  export type AuthStatusType = typeof AuthStatus[keyof typeof AuthStatus];
220
+ /**
221
+ * Controller for managing authentication sessions
222
+ * Allows cancellation and cleanup of ongoing authentication
223
+ */
120
224
  export interface AuthController {
225
+ /**
226
+ * Cancel the ongoing authentication
227
+ */
121
228
  cancel(): void;
229
+ /**
230
+ * The authentication promise
231
+ */
122
232
  promise: Promise<any>;
233
+ /**
234
+ * Current status of the authentication
235
+ */
123
236
  status: AuthStatusType;
124
237
  }
@@ -1,4 +1,20 @@
1
+ /**
2
+ * Phone Authentication Types
3
+ *
4
+ * This file exports the types used by the Phone Auth SDK.
5
+ * All API types are imported from api-types.ts to ensure consistency.
6
+ * No backward compatibility - using clean API specification only.
7
+ */
8
+ // ============================================================================
9
+ // RE-EXPORT ALL API TYPES
10
+ // ============================================================================
1
11
  export * from './api-types';
12
+ // ============================================================================
13
+ // BROWSER-SPECIFIC TYPES
14
+ // ============================================================================
15
+ /**
16
+ * Browser error names
17
+ */
2
18
  export const BrowserError = {
3
19
  NOT_ALLOWED: 'NotAllowedError',
4
20
  NETWORK: 'NetworkError',
@@ -15,6 +31,9 @@ export const BrowserError = {
15
31
  RANGE: 'RangeError',
16
32
  SYNTAX: 'SyntaxError'
17
33
  };
34
+ /**
35
+ * Browser error codes
36
+ */
18
37
  export const BrowserErrorCode = {
19
38
  USER_CANCELLED_DC_API: 19,
20
39
  PERMISSION_DENIED: 1,
@@ -25,6 +44,9 @@ export const BrowserErrorCode = {
25
44
  NETWORK: 19,
26
45
  SECURITY: 18
27
46
  };
47
+ /**
48
+ * Browser names for detection
49
+ */
28
50
  export const BrowserName = {
29
51
  CHROME: 'Chrome',
30
52
  EDGE: 'Edge',
@@ -34,11 +56,21 @@ export const BrowserName = {
34
56
  BRAVE: 'Brave',
35
57
  OTHER: 'other'
36
58
  };
59
+ /**
60
+ * Authentication status constants
61
+ * Maps to both client-side states and backend responses
62
+ */
37
63
  export const AuthStatus = {
64
+ /** Authentication in progress */
38
65
  PENDING: 'pending',
66
+ /** Authentication completed successfully */
39
67
  COMPLETED: 'completed',
68
+ /** User cancelled authentication */
40
69
  CANCELLED: 'cancelled',
70
+ /** Authentication failed or expired */
41
71
  FAILED: 'failed',
72
+ /** Session expired (backend returns 410 Gone) */
42
73
  EXPIRED: 'expired',
74
+ /** Session not found (backend returns 404) */
43
75
  NOT_FOUND: 'not_found'
44
76
  };
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Mobile Debug Console
3
+ * A lightweight console overlay for debugging on mobile devices where dev tools aren't available
4
+ */
1
5
  export declare class MobileDebugConsole {
2
6
  private static instance;
3
7
  private logs;
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Mobile Debug Console
3
+ * A lightweight console overlay for debugging on mobile devices where dev tools aren't available
4
+ */
1
5
  export class MobileDebugConsole {
2
6
  constructor() {
3
7
  this.logs = [];
@@ -32,13 +36,15 @@ export class MobileDebugConsole {
32
36
  ['log', 'error', 'warn', 'debug', 'info'].forEach(method => {
33
37
  const originalMethod = this.originalConsole[method];
34
38
  console[method] = (...args) => {
39
+ // Call original
35
40
  originalMethod.apply(console, args);
41
+ // Add to our display
36
42
  this.addLog(method, args);
37
43
  };
38
44
  });
39
45
  }
40
46
  addLog(type, args) {
41
- const timestamp = new Date().toTimeString().split(' ')[0];
47
+ const timestamp = new Date().toTimeString().split(' ')[0]; // HH:MM:SS
42
48
  const content = args.map(arg => {
43
49
  if (typeof arg === 'object') {
44
50
  try {
@@ -50,6 +56,7 @@ export class MobileDebugConsole {
50
56
  }
51
57
  return String(arg);
52
58
  }).join(' ');
59
+ // Create colored log entry
53
60
  const colors = {
54
61
  log: '#fff',
55
62
  error: '#ff6b6b',
@@ -65,6 +72,7 @@ export class MobileDebugConsole {
65
72
  </div>
66
73
  `;
67
74
  this.logs.push(logHtml);
75
+ // Keep only last 500 logs
68
76
  if (this.logs.length > 500) {
69
77
  this.logs.shift();
70
78
  }
@@ -73,13 +81,17 @@ export class MobileDebugConsole {
73
81
  updateDisplay() {
74
82
  if (!this.logsContainer || !this.isVisible)
75
83
  return;
84
+ // Check if scrolled to bottom before update
76
85
  this.isAtBottom = this.logsContainer.scrollHeight - this.logsContainer.scrollTop <= this.logsContainer.clientHeight + 50;
86
+ // Update content
77
87
  this.logsContainer.innerHTML = this.logs.join('');
88
+ // Auto-scroll only if was at bottom
78
89
  if (this.isAtBottom) {
79
90
  this.logsContainer.scrollTop = this.logsContainer.scrollHeight;
80
91
  }
81
92
  }
82
93
  createUI() {
94
+ // Create styles
83
95
  const style = document.createElement('style');
84
96
  style.textContent = `
85
97
  #mobile-debug-console {
@@ -172,11 +184,13 @@ export class MobileDebugConsole {
172
184
  }
173
185
  `;
174
186
  document.head.appendChild(style);
187
+ // Create container
175
188
  this.container = document.createElement('div');
176
189
  this.container.id = 'mobile-debug-console';
177
190
  if (!this.isVisible) {
178
191
  this.container.className = 'hidden';
179
192
  }
193
+ // Create header
180
194
  const header = document.createElement('div');
181
195
  header.id = 'debug-header';
182
196
  const title = document.createElement('div');
@@ -184,12 +198,15 @@ export class MobileDebugConsole {
184
198
  title.textContent = '📱 Mobile Debug Console';
185
199
  const buttons = document.createElement('div');
186
200
  buttons.id = 'debug-buttons';
201
+ // Clear button
187
202
  const clearBtn = document.createElement('button');
188
203
  clearBtn.textContent = 'Clear';
189
204
  clearBtn.onclick = () => this.clear();
205
+ // Show/Hide button
190
206
  const toggleBtn = document.createElement('button');
191
207
  toggleBtn.textContent = 'Hide';
192
208
  toggleBtn.onclick = () => this.toggle();
209
+ // Close button
193
210
  const closeBtn = document.createElement('button');
194
211
  closeBtn.textContent = '✕';
195
212
  closeBtn.style.color = '#ff6b6b';
@@ -199,20 +216,25 @@ export class MobileDebugConsole {
199
216
  buttons.appendChild(closeBtn);
200
217
  header.appendChild(title);
201
218
  header.appendChild(buttons);
219
+ // Create logs container
202
220
  this.logsContainer = document.createElement('div');
203
221
  this.logsContainer.id = 'debug-logs';
222
+ // Track scroll position
204
223
  this.logsContainer.addEventListener('scroll', () => {
205
224
  this.isAtBottom = this.logsContainer.scrollHeight - this.logsContainer.scrollTop <= this.logsContainer.clientHeight + 50;
206
225
  });
226
+ // Assemble
207
227
  this.container.appendChild(header);
208
228
  this.container.appendChild(this.logsContainer);
209
229
  document.body.appendChild(this.container);
230
+ // Create floating toggle button
210
231
  this.floatingToggle = document.createElement('button');
211
232
  this.floatingToggle.id = 'debug-floating-toggle';
212
- this.floatingToggle.innerHTML = '🖥️';
233
+ this.floatingToggle.innerHTML = '🖥️'; // Console icon
213
234
  this.floatingToggle.title = 'Show Debug Console';
214
235
  this.floatingToggle.onclick = () => this.toggle();
215
236
  document.body.appendChild(this.floatingToggle);
237
+ // Store reference for toggle button
216
238
  window.__debugToggleBtn = toggleBtn;
217
239
  }
218
240
  escapeHtml(text) {
@@ -243,15 +265,19 @@ export class MobileDebugConsole {
243
265
  }
244
266
  }
245
267
  cleanup() {
268
+ // Restore original console
246
269
  Object.keys(this.originalConsole).forEach(method => {
247
270
  console[method] = this.originalConsole[method];
248
271
  });
272
+ // Remove UI
249
273
  if (this.container) {
250
274
  this.container.remove();
251
275
  }
276
+ // Remove floating toggle
252
277
  if (this.floatingToggle) {
253
278
  this.floatingToggle.remove();
254
279
  }
280
+ // Clean up references
255
281
  delete window.__debugToggleBtn;
256
282
  }
257
283
  }
@@ -1,11 +1,22 @@
1
+ /**
2
+ * Modal UI Component for Phone Authentication
3
+ *
4
+ * This file creates the UI components (modals, buttons) that are shown
5
+ * when the SDK is NOT in headless mode. Think of it like a popup window
6
+ * that handles the authentication flow for you.
7
+ */
1
8
  import type { InvokeOptions } from '../api-types';
2
9
  import type { QRCodeData } from '../strategies/desktop';
3
- export type ModalViewMode = 'toggle' | 'dual' | 'pre-step';
4
- export type ModalTheme = 'dark' | 'light' | 'auto';
5
- export type AuthModalOptions = NonNullable<InvokeOptions['modalOptions']> & {
6
- viewMode?: ModalViewMode;
7
- theme?: ModalTheme;
8
- };
10
+ /**
11
+ * Creates and manages a modal dialog for authentication
12
+ *
13
+ * @example
14
+ * const modal = new AuthModal({
15
+ * title: "Verify Your Phone",
16
+ * description: "Complete authentication to continue"
17
+ * });
18
+ * modal.show();
19
+ */
9
20
  export declare class AuthModal {
10
21
  private container;
11
22
  private backdrop;
@@ -13,35 +24,65 @@ export declare class AuthModal {
13
24
  private options;
14
25
  private callbacks;
15
26
  private closeCallback?;
16
- private theme;
17
- private currentStep;
18
- private qrCodeData;
19
- private statusMessage;
20
- private originalBodyOverflow;
21
- private isClosing;
22
- private readonly iconApple;
23
- private readonly iconAndroid;
24
- private readonly iconBack;
25
- constructor(options?: AuthModalOptions, callbacks?: InvokeOptions['callbacks']);
26
- private shouldUseDarkMode;
27
+ constructor(options?: InvokeOptions['modalOptions'], callbacks?: InvokeOptions['callbacks']);
27
28
  private handleEscapeKey;
29
+ /**
30
+ * Escape HTML to prevent XSS attacks
31
+ */
28
32
  private escapeHtml;
33
+ /**
34
+ * Shows the modal with a QR code for desktop authentication
35
+ * Supports both single QR code (legacy) and dual-platform QR codes (iOS + Android)
36
+ */
29
37
  showQRCode(qrCodeData: string | QRCodeData, statusMessage?: string): void;
30
- updateStatus(status: string, isError?: boolean): void;
38
+ /**
39
+ * Creates a modal with iOS/Android platform toggle
40
+ */
41
+ private createDualPlatformQRModal;
42
+ /**
43
+ * Sets a callback to be called when the modal is cancelled/closed
44
+ */
31
45
  setCloseCallback(callback: () => void): void;
32
- private renderToggleMode;
33
- private renderDualMode;
34
- private renderPreStepMode;
35
- private setupPreStepListeners;
36
- private updatePreStepUI;
37
- private setupBackButton;
46
+ /**
47
+ * Shows the modal with a button for Link authentication (App Clips)
48
+ * IMPORTANT: The button click is required for iOS to recognize the app link
49
+ */
50
+ showLinkButton(url: string, buttonText?: string): Promise<void>;
51
+ /**
52
+ * Shows the modal with a button for TS43 authentication
53
+ * IMPORTANT: The button click is required for Digital Credentials API (transient activation)
54
+ */
55
+ showTS43Button(onAuthenticate: () => Promise<any>): Promise<any>;
56
+ /**
57
+ * Updates the status message in the modal
58
+ */
59
+ updateStatus(message: string, isError?: boolean): void;
60
+ /**
61
+ * Creates the modal HTML structure
62
+ */
38
63
  private createModal;
39
- private setupHelpInteraction;
64
+ /**
65
+ * Injects CSS styles for the modal
66
+ */
40
67
  private injectStyles;
68
+ /**
69
+ * Shows the modal with animation
70
+ */
41
71
  show(): void;
72
+ /**
73
+ * Setup click handlers for iOS/Android platform toggle
74
+ */
42
75
  private setupPlatformToggles;
43
- private lockBodyScroll;
44
- private unlockBodyScroll;
76
+ /**
77
+ * Closes the modal with animation
78
+ */
45
79
  close(): void;
80
+ /**
81
+ * Removes modal elements from DOM
82
+ */
46
83
  private cleanup;
84
+ /**
85
+ * Check if modal is currently open
86
+ */
87
+ isModalOpen(): boolean;
47
88
  }