@glideidentity/web-client-sdk 5.1.3 → 6.0.0-beta.2

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 (203) hide show
  1. package/README.md +337 -526
  2. package/dist/browser/web-client-sdk.min.js +1 -1
  3. package/dist/cjs/adapters/index.js +15 -0
  4. package/dist/cjs/adapters/react.js +192 -0
  5. package/dist/cjs/adapters/vanilla.js +38 -0
  6. package/dist/cjs/adapters/vue.js +187 -0
  7. package/dist/cjs/browser.js +58 -0
  8. package/dist/cjs/client/http.js +159 -0
  9. package/dist/cjs/client/index.js +19 -0
  10. package/dist/cjs/client/logger.js +135 -0
  11. package/dist/cjs/client/phone-auth-client.js +428 -0
  12. package/dist/cjs/client/strategies/polling.js +177 -0
  13. package/dist/cjs/core/errors.js +204 -0
  14. package/dist/cjs/core/index.js +83 -0
  15. package/dist/cjs/core/type-guards.js +196 -0
  16. package/dist/cjs/core/types.js +25 -0
  17. package/dist/{core/phone-auth/validation-utils.js → cjs/core/validators.js} +70 -23
  18. package/dist/cjs/index.js +81 -0
  19. package/dist/cjs/ui/index.js +11 -0
  20. package/dist/{core/phone-auth → cjs}/ui/mobile-debug-console.js +149 -78
  21. package/dist/cjs/ui/modal.js +1122 -0
  22. package/dist/esm/adapters/index.js +11 -0
  23. package/dist/esm/adapters/react.js +182 -0
  24. package/dist/esm/adapters/vanilla.js +29 -0
  25. package/dist/esm/adapters/vue.js +177 -0
  26. package/dist/esm/browser.js +30 -11
  27. package/dist/esm/client/http.js +156 -0
  28. package/dist/esm/client/index.js +11 -0
  29. package/dist/esm/client/logger.js +131 -0
  30. package/dist/esm/client/phone-auth-client.js +424 -0
  31. package/dist/esm/client/strategies/polling.js +174 -0
  32. package/dist/esm/core/errors.js +193 -0
  33. package/dist/esm/core/index.js +60 -0
  34. package/dist/esm/core/type-guards.js +181 -0
  35. package/dist/esm/core/types.js +22 -1
  36. package/dist/esm/core/{phone-auth/validation-utils.js → validators.js} +66 -21
  37. package/dist/esm/index.js +45 -17
  38. package/dist/esm/ui/index.js +5 -0
  39. package/dist/esm/{core/phone-auth/ui → ui}/mobile-debug-console.js +149 -78
  40. package/dist/esm/ui/modal.js +1117 -0
  41. package/dist/types/adapters/index.d.ts +10 -0
  42. package/dist/types/adapters/index.d.ts.map +1 -0
  43. package/dist/types/adapters/react.d.ts +70 -0
  44. package/dist/types/adapters/react.d.ts.map +1 -0
  45. package/dist/types/adapters/vanilla.d.ts +29 -0
  46. package/dist/types/adapters/vanilla.d.ts.map +1 -0
  47. package/dist/types/adapters/vue.d.ts +71 -0
  48. package/dist/types/adapters/vue.d.ts.map +1 -0
  49. package/dist/types/browser.d.ts +27 -0
  50. package/dist/types/browser.d.ts.map +1 -0
  51. package/dist/types/client/http.d.ts +41 -0
  52. package/dist/types/client/http.d.ts.map +1 -0
  53. package/dist/types/client/index.d.ts +10 -0
  54. package/dist/types/client/index.d.ts.map +1 -0
  55. package/dist/types/client/logger.d.ts +36 -0
  56. package/dist/types/client/logger.d.ts.map +1 -0
  57. package/dist/types/client/phone-auth-client.d.ts +91 -0
  58. package/dist/types/client/phone-auth-client.d.ts.map +1 -0
  59. package/dist/types/client/strategies/polling.d.ts +36 -0
  60. package/dist/types/client/strategies/polling.d.ts.map +1 -0
  61. package/dist/types/core/errors.d.ts +71 -0
  62. package/dist/types/core/errors.d.ts.map +1 -0
  63. package/dist/types/core/index.d.ts +38 -0
  64. package/dist/types/core/index.d.ts.map +1 -0
  65. package/dist/types/core/type-guards.d.ts +118 -0
  66. package/dist/types/core/type-guards.d.ts.map +1 -0
  67. package/dist/types/core/types.d.ts +535 -0
  68. package/dist/types/core/types.d.ts.map +1 -0
  69. package/dist/types/core/validators.d.ts +63 -0
  70. package/dist/types/core/validators.d.ts.map +1 -0
  71. package/dist/types/index.d.ts +40 -0
  72. package/dist/types/index.d.ts.map +1 -0
  73. package/dist/types/ui/index.d.ts +6 -0
  74. package/dist/types/ui/index.d.ts.map +1 -0
  75. package/dist/{esm/core/phone-auth → types}/ui/mobile-debug-console.d.ts +1 -0
  76. package/dist/types/ui/mobile-debug-console.d.ts.map +1 -0
  77. package/dist/types/ui/modal.d.ts +87 -0
  78. package/dist/types/ui/modal.d.ts.map +1 -0
  79. package/package.json +48 -34
  80. package/dist/adapters/angular/client.service.d.ts +0 -7
  81. package/dist/adapters/angular/client.service.js +0 -30
  82. package/dist/adapters/angular/index.d.ts +0 -3
  83. package/dist/adapters/angular/index.js +0 -18
  84. package/dist/adapters/angular/phone-auth.service.d.ts +0 -38
  85. package/dist/adapters/angular/phone-auth.service.js +0 -130
  86. package/dist/adapters/react/index.d.ts +0 -9
  87. package/dist/adapters/react/index.js +0 -28
  88. package/dist/adapters/react/useClient.d.ts +0 -26
  89. package/dist/adapters/react/useClient.js +0 -121
  90. package/dist/adapters/react/usePhoneAuth.d.ts +0 -23
  91. package/dist/adapters/react/usePhoneAuth.js +0 -95
  92. package/dist/adapters/vanilla/client.d.ts +0 -8
  93. package/dist/adapters/vanilla/client.js +0 -33
  94. package/dist/adapters/vanilla/index.d.ts +0 -3
  95. package/dist/adapters/vanilla/index.js +0 -18
  96. package/dist/adapters/vanilla/phone-auth.d.ts +0 -46
  97. package/dist/adapters/vanilla/phone-auth.js +0 -138
  98. package/dist/adapters/vue/index.d.ts +0 -10
  99. package/dist/adapters/vue/index.js +0 -36
  100. package/dist/adapters/vue/useClient.d.ts +0 -115
  101. package/dist/adapters/vue/useClient.js +0 -131
  102. package/dist/adapters/vue/usePhoneAuth.d.ts +0 -94
  103. package/dist/adapters/vue/usePhoneAuth.js +0 -103
  104. package/dist/browser.d.ts +0 -7
  105. package/dist/browser.js +0 -31
  106. package/dist/core/client.d.ts +0 -22
  107. package/dist/core/client.js +0 -77
  108. package/dist/core/logger.d.ts +0 -130
  109. package/dist/core/logger.js +0 -370
  110. package/dist/core/phone-auth/api-types.d.ts +0 -593
  111. package/dist/core/phone-auth/api-types.js +0 -215
  112. package/dist/core/phone-auth/client.d.ts +0 -189
  113. package/dist/core/phone-auth/client.js +0 -1441
  114. package/dist/core/phone-auth/error-utils.d.ts +0 -110
  115. package/dist/core/phone-auth/error-utils.js +0 -350
  116. package/dist/core/phone-auth/index.d.ts +0 -7
  117. package/dist/core/phone-auth/index.js +0 -50
  118. package/dist/core/phone-auth/status-types.d.ts +0 -107
  119. package/dist/core/phone-auth/status-types.js +0 -31
  120. package/dist/core/phone-auth/strategies/desktop.d.ts +0 -122
  121. package/dist/core/phone-auth/strategies/desktop.js +0 -596
  122. package/dist/core/phone-auth/strategies/index.d.ts +0 -11
  123. package/dist/core/phone-auth/strategies/index.js +0 -15
  124. package/dist/core/phone-auth/strategies/link.d.ts +0 -89
  125. package/dist/core/phone-auth/strategies/link.js +0 -384
  126. package/dist/core/phone-auth/strategies/ts43.d.ts +0 -32
  127. package/dist/core/phone-auth/strategies/ts43.js +0 -161
  128. package/dist/core/phone-auth/strategies/types.d.ts +0 -18
  129. package/dist/core/phone-auth/strategies/types.js +0 -6
  130. package/dist/core/phone-auth/type-guards.d.ts +0 -143
  131. package/dist/core/phone-auth/type-guards.js +0 -198
  132. package/dist/core/phone-auth/types.d.ts +0 -237
  133. package/dist/core/phone-auth/types.js +0 -93
  134. package/dist/core/phone-auth/ui/mobile-debug-console.d.ts +0 -25
  135. package/dist/core/phone-auth/ui/modal.d.ts +0 -88
  136. package/dist/core/phone-auth/ui/modal.js +0 -598
  137. package/dist/core/phone-auth/validation-utils.d.ts +0 -44
  138. package/dist/core/types.d.ts +0 -62
  139. package/dist/core/types.js +0 -2
  140. package/dist/core/version.d.ts +0 -1
  141. package/dist/core/version.js +0 -5
  142. package/dist/esm/adapters/angular/client.service.d.ts +0 -7
  143. package/dist/esm/adapters/angular/client.service.js +0 -27
  144. package/dist/esm/adapters/angular/index.d.ts +0 -3
  145. package/dist/esm/adapters/angular/index.js +0 -4
  146. package/dist/esm/adapters/angular/phone-auth.service.d.ts +0 -38
  147. package/dist/esm/adapters/angular/phone-auth.service.js +0 -127
  148. package/dist/esm/adapters/react/index.d.ts +0 -9
  149. package/dist/esm/adapters/react/index.js +0 -8
  150. package/dist/esm/adapters/react/useClient.d.ts +0 -26
  151. package/dist/esm/adapters/react/useClient.js +0 -116
  152. package/dist/esm/adapters/react/usePhoneAuth.d.ts +0 -23
  153. package/dist/esm/adapters/react/usePhoneAuth.js +0 -92
  154. package/dist/esm/adapters/vanilla/client.d.ts +0 -8
  155. package/dist/esm/adapters/vanilla/client.js +0 -29
  156. package/dist/esm/adapters/vanilla/index.d.ts +0 -3
  157. package/dist/esm/adapters/vanilla/index.js +0 -4
  158. package/dist/esm/adapters/vanilla/phone-auth.d.ts +0 -46
  159. package/dist/esm/adapters/vanilla/phone-auth.js +0 -134
  160. package/dist/esm/adapters/vue/index.d.ts +0 -10
  161. package/dist/esm/adapters/vue/index.js +0 -11
  162. package/dist/esm/adapters/vue/useClient.d.ts +0 -115
  163. package/dist/esm/adapters/vue/useClient.js +0 -127
  164. package/dist/esm/adapters/vue/usePhoneAuth.d.ts +0 -94
  165. package/dist/esm/adapters/vue/usePhoneAuth.js +0 -100
  166. package/dist/esm/browser.d.ts +0 -7
  167. package/dist/esm/core/client.d.ts +0 -22
  168. package/dist/esm/core/client.js +0 -70
  169. package/dist/esm/core/logger.d.ts +0 -130
  170. package/dist/esm/core/logger.js +0 -359
  171. package/dist/esm/core/phone-auth/api-types.d.ts +0 -593
  172. package/dist/esm/core/phone-auth/api-types.js +0 -203
  173. package/dist/esm/core/phone-auth/client.d.ts +0 -189
  174. package/dist/esm/core/phone-auth/client.js +0 -1404
  175. package/dist/esm/core/phone-auth/error-utils.d.ts +0 -110
  176. package/dist/esm/core/phone-auth/error-utils.js +0 -338
  177. package/dist/esm/core/phone-auth/index.d.ts +0 -7
  178. package/dist/esm/core/phone-auth/index.js +0 -8
  179. package/dist/esm/core/phone-auth/status-types.d.ts +0 -107
  180. package/dist/esm/core/phone-auth/status-types.js +0 -26
  181. package/dist/esm/core/phone-auth/strategies/desktop.d.ts +0 -122
  182. package/dist/esm/core/phone-auth/strategies/desktop.js +0 -590
  183. package/dist/esm/core/phone-auth/strategies/index.d.ts +0 -11
  184. package/dist/esm/core/phone-auth/strategies/index.js +0 -7
  185. package/dist/esm/core/phone-auth/strategies/link.d.ts +0 -89
  186. package/dist/esm/core/phone-auth/strategies/link.js +0 -380
  187. package/dist/esm/core/phone-auth/strategies/ts43.d.ts +0 -32
  188. package/dist/esm/core/phone-auth/strategies/ts43.js +0 -157
  189. package/dist/esm/core/phone-auth/strategies/types.d.ts +0 -18
  190. package/dist/esm/core/phone-auth/strategies/types.js +0 -5
  191. package/dist/esm/core/phone-auth/type-guards.d.ts +0 -143
  192. package/dist/esm/core/phone-auth/type-guards.js +0 -185
  193. package/dist/esm/core/phone-auth/types.d.ts +0 -237
  194. package/dist/esm/core/phone-auth/types.js +0 -76
  195. package/dist/esm/core/phone-auth/ui/modal.d.ts +0 -88
  196. package/dist/esm/core/phone-auth/ui/modal.js +0 -594
  197. package/dist/esm/core/phone-auth/validation-utils.d.ts +0 -44
  198. package/dist/esm/core/types.d.ts +0 -62
  199. package/dist/esm/core/version.d.ts +0 -1
  200. package/dist/esm/core/version.js +0 -2
  201. package/dist/esm/index.d.ts +0 -12
  202. package/dist/index.d.ts +0 -12
  203. package/dist/index.js +0 -55
@@ -1,88 +0,0 @@
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
- */
8
- import type { InvokeOptions } from '../api-types';
9
- import type { QRCodeData } from '../strategies/desktop';
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
- */
20
- export declare class AuthModal {
21
- private container;
22
- private backdrop;
23
- private isOpen;
24
- private options;
25
- private callbacks;
26
- private closeCallback?;
27
- constructor(options?: InvokeOptions['modalOptions'], callbacks?: InvokeOptions['callbacks']);
28
- private handleEscapeKey;
29
- /**
30
- * Escape HTML to prevent XSS attacks
31
- */
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
- */
37
- showQRCode(qrCodeData: string | QRCodeData, statusMessage?: string): 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
- */
45
- setCloseCallback(callback: () => void): void;
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
- */
63
- private createModal;
64
- /**
65
- * Injects CSS styles for the modal
66
- */
67
- private injectStyles;
68
- /**
69
- * Shows the modal with animation
70
- */
71
- show(): void;
72
- /**
73
- * Setup click handlers for iOS/Android platform toggle
74
- */
75
- private setupPlatformToggles;
76
- /**
77
- * Closes the modal with animation
78
- */
79
- close(): void;
80
- /**
81
- * Removes modal elements from DOM
82
- */
83
- private cleanup;
84
- /**
85
- * Check if modal is currently open
86
- */
87
- isModalOpen(): boolean;
88
- }
@@ -1,594 +0,0 @@
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
- */
8
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
- return new (P || (P = Promise))(function (resolve, reject) {
11
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
- step((generator = generator.apply(thisArg, _arguments || [])).next());
15
- });
16
- };
17
- /**
18
- * Creates and manages a modal dialog for authentication
19
- *
20
- * @example
21
- * const modal = new AuthModal({
22
- * title: "Verify Your Phone",
23
- * description: "Complete authentication to continue"
24
- * });
25
- * modal.show();
26
- */
27
- export class AuthModal {
28
- constructor(options, callbacks) {
29
- this.container = null;
30
- this.backdrop = null;
31
- this.isOpen = false;
32
- this.options = options || {};
33
- this.callbacks = callbacks || {};
34
- // Bind escape key handler
35
- this.handleEscapeKey = this.handleEscapeKey.bind(this);
36
- }
37
- handleEscapeKey(event) {
38
- var _a, _b;
39
- if (event.key === 'Escape' && this.isOpen) {
40
- // Check if escape closing is enabled (default true)
41
- if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.closeOnEscape) !== false) {
42
- (_b = this.closeCallback) === null || _b === void 0 ? void 0 : _b.call(this); // Call the cancellation callback if set
43
- this.close();
44
- }
45
- }
46
- }
47
- /**
48
- * Escape HTML to prevent XSS attacks
49
- */
50
- escapeHtml(unsafe) {
51
- return unsafe
52
- .replace(/&/g, "&amp;")
53
- .replace(/</g, "&lt;")
54
- .replace(/>/g, "&gt;")
55
- .replace(/"/g, "&quot;")
56
- .replace(/'/g, "&#039;");
57
- }
58
- /**
59
- * Shows the modal with a QR code for desktop authentication
60
- * Supports both single QR code (legacy) and dual-platform QR codes (iOS + Android)
61
- */
62
- showQRCode(qrCodeData, statusMessage = 'Scan QR code with your phone') {
63
- console.log('[Modal] showQRCode called with:', qrCodeData);
64
- // If modal is already open, don't recreate it
65
- if (this.isOpen) {
66
- console.log('[Modal] Modal already open, skipping recreation');
67
- return;
68
- }
69
- // Check if it's the new dual-platform format with VALID Android QR code
70
- if (typeof qrCodeData === 'object' && qrCodeData.iosQRCode) {
71
- const hasValidAndroidQR = qrCodeData.androidQRCode &&
72
- qrCodeData.androidQRCode.length > 0 &&
73
- qrCodeData.androidQRCode !== qrCodeData.iosQRCode;
74
- console.log('[Modal] Has valid Android QR?', hasValidAndroidQR);
75
- if (hasValidAndroidQR) {
76
- console.log('[Modal] Using dual-platform modal');
77
- this.createDualPlatformQRModal(qrCodeData, statusMessage);
78
- // Note: createDualPlatformQRModal calls show() internally
79
- return;
80
- }
81
- else {
82
- console.log('[Modal] Android QR missing/empty, using single iOS QR');
83
- // Only iOS QR code available - show single QR
84
- this.createModal(`
85
- <div class="glide-auth-qr-container">
86
- <img src="${this.escapeHtml(qrCodeData.iosQRCode)}" alt="QR Code" class="glide-auth-qr-code" />
87
- <p class="glide-auth-status">Scan with your iPhone to authenticate</p>
88
- </div>
89
- `);
90
- }
91
- }
92
- else {
93
- console.log('[Modal] Using legacy single QR code modal');
94
- // Legacy single QR code
95
- this.createModal(`
96
- <div class="glide-auth-qr-container">
97
- <img src="${this.escapeHtml(qrCodeData)}" alt="QR Code" class="glide-auth-qr-code" />
98
- <p class="glide-auth-status">${this.escapeHtml(statusMessage)}</p>
99
- </div>
100
- `);
101
- }
102
- this.show();
103
- }
104
- /**
105
- * Creates a modal with iOS/Android platform toggle
106
- */
107
- createDualPlatformQRModal(qrCodeData, statusMessage) {
108
- this.createModal(`
109
- <div class="glide-auth-qr-container">
110
- <!-- Platform Switcher -->
111
- <div class="glide-platform-switcher">
112
- <button class="glide-platform-btn glide-platform-ios active" data-platform="ios">
113
- <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
114
- <path d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z"/>
115
- </svg>
116
- <span>iOS</span>
117
- </button>
118
- <button class="glide-platform-btn glide-platform-android" data-platform="android">
119
- <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
120
- <path d="M17.6 9.48l1.84-3.18c.16-.31.04-.69-.26-.85-.29-.15-.65-.06-.83.22l-1.88 3.24c-2.86-1.21-6.08-1.21-8.94 0L5.65 5.67c-.19-.28-.54-.38-.83-.22-.3.16-.42.54-.26.85l1.84 3.18C4.08 11.08 2.4 13.97 2.4 17.2h19.2c0-3.23-1.68-6.12-4.0-7.72zM7.0 14.8c-.66 0-1.2-.54-1.2-1.2s.54-1.2 1.2-1.2 1.2.54 1.2 1.2-.54 1.2-1.2 1.2zm10 0c-.66 0-1.2-.54-1.2-1.2s.54-1.2 1.2-1.2 1.2.54 1.2 1.2-.54 1.2-1.2 1.2z"/>
121
- </svg>
122
- <span>Android</span>
123
- </button>
124
- </div>
125
-
126
- <!-- QR Code Image -->
127
- <img
128
- id="glide-qr-code-img"
129
- src="${this.escapeHtml(qrCodeData.iosQRCode)}"
130
- alt="QR Code"
131
- class="glide-auth-qr-code"
132
- data-ios="${this.escapeHtml(qrCodeData.iosQRCode)}"
133
- data-android="${this.escapeHtml(qrCodeData.androidQRCode || '')}"
134
- />
135
-
136
- <!-- Status Message -->
137
- <p class="glide-auth-status" id="glide-platform-message">Scan with your iPhone to authenticate</p>
138
- </div>
139
- `);
140
- // IMPORTANT: Call show() to actually display the modal!
141
- this.show();
142
- }
143
- /**
144
- * Sets a callback to be called when the modal is cancelled/closed
145
- */
146
- setCloseCallback(callback) {
147
- this.closeCallback = callback;
148
- }
149
- /**
150
- * Shows the modal with a button for Link authentication (App Clips)
151
- * IMPORTANT: The button click is required for iOS to recognize the app link
152
- */
153
- showLinkButton(url, buttonText) {
154
- return new Promise((resolve) => {
155
- var _a, _b, _c;
156
- const text = buttonText || ((_a = this.options) === null || _a === void 0 ? void 0 : _a.buttonText) || 'Open Verification App';
157
- this.createModal(`
158
- <div class="glide-auth-link-container">
159
- <p class="glide-auth-description">
160
- ${((_b = this.options) === null || _b === void 0 ? void 0 : _b.description) || 'Click below to verify your phone number'}
161
- </p>
162
- <button class="glide-auth-button" id="glide-auth-link-button">
163
- ${text}
164
- </button>
165
- <p class="glide-auth-helper-text">
166
- You'll be redirected to complete verification
167
- </p>
168
- </div>
169
- `);
170
- // Show modal first so elements are in the DOM
171
- this.show();
172
- // Add click handler for the button AFTER modal is in DOM
173
- // CRITICAL: This click event is required for iOS to recognize the app link
174
- // Do NOT call window.open automatically - it must be triggered by user interaction
175
- const button = (_c = this.container) === null || _c === void 0 ? void 0 : _c.querySelector('#glide-auth-link-button');
176
- if (button) {
177
- button.addEventListener('click', (event) => {
178
- var _a, _b;
179
- (_b = (_a = this.callbacks) === null || _a === void 0 ? void 0 : _a.onAuthStart) === null || _b === void 0 ? void 0 : _b.call(_a);
180
- // User-initiated click is required for app links to work properly on iOS
181
- // This ensures the OS recognizes it should open an app, not just a browser tab
182
- window.open(url, '_blank');
183
- resolve();
184
- });
185
- }
186
- else {
187
- console.error('[Modal] Link button not found in modal');
188
- }
189
- });
190
- }
191
- /**
192
- * Shows the modal with a button for TS43 authentication
193
- * IMPORTANT: The button click is required for Digital Credentials API (transient activation)
194
- */
195
- showTS43Button(onAuthenticate) {
196
- return new Promise((resolve, reject) => {
197
- var _a, _b, _c;
198
- const text = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.buttonText) || 'Verify with Carrier';
199
- this.createModal(`
200
- <div class="glide-auth-ts43-container">
201
- <p class="glide-auth-description">
202
- ${((_b = this.options) === null || _b === void 0 ? void 0 : _b.description) || 'Verify using your carrier credentials'}
203
- </p>
204
- <button class="glide-auth-button" id="glide-auth-ts43-button">
205
- ${text}
206
- </button>
207
- <p class="glide-auth-helper-text">
208
- Secure verification through your mobile carrier
209
- </p>
210
- </div>
211
- `);
212
- // Show modal first so elements are in the DOM
213
- this.show();
214
- // Add click handler for the button AFTER modal is in DOM
215
- // CRITICAL: Digital Credentials API requires "transient activation" (user interaction)
216
- // Do NOT call onAuthenticate automatically - it must be triggered by user click
217
- const button = (_c = this.container) === null || _c === void 0 ? void 0 : _c.querySelector('#glide-auth-ts43-button');
218
- if (button) {
219
- button.addEventListener('click', (event) => __awaiter(this, void 0, void 0, function* () {
220
- var _a, _b, _c, _d, _e, _f;
221
- (_b = (_a = this.callbacks) === null || _a === void 0 ? void 0 : _a.onAuthStart) === null || _b === void 0 ? void 0 : _b.call(_a);
222
- button.setAttribute('disabled', 'true');
223
- button.textContent = 'Verifying...';
224
- try {
225
- const result = yield onAuthenticate();
226
- (_d = (_c = this.callbacks) === null || _c === void 0 ? void 0 : _c.onAuthComplete) === null || _d === void 0 ? void 0 : _d.call(_c, result);
227
- resolve(result);
228
- this.close();
229
- }
230
- catch (error) {
231
- (_f = (_e = this.callbacks) === null || _e === void 0 ? void 0 : _e.onError) === null || _f === void 0 ? void 0 : _f.call(_e, error);
232
- button.removeAttribute('disabled');
233
- button.textContent = text;
234
- reject(error);
235
- }
236
- }));
237
- }
238
- else {
239
- console.error('[Modal] TS43 button not found in modal');
240
- }
241
- });
242
- }
243
- /**
244
- * Updates the status message in the modal
245
- */
246
- updateStatus(message, isError = false) {
247
- var _a;
248
- const statusEl = (_a = this.container) === null || _a === void 0 ? void 0 : _a.querySelector('.glide-auth-status');
249
- if (statusEl) {
250
- statusEl.textContent = message;
251
- statusEl.className = isError ? 'glide-auth-status glide-auth-error' : 'glide-auth-status';
252
- }
253
- }
254
- /**
255
- * Creates the modal HTML structure
256
- */
257
- createModal(content) {
258
- var _a, _b, _c;
259
- // Clean up any existing modal
260
- this.cleanup();
261
- // Create backdrop (dark overlay)
262
- this.backdrop = document.createElement('div');
263
- this.backdrop.className = 'glide-auth-backdrop';
264
- this.backdrop.style.cssText = `
265
- position: fixed;
266
- top: 0;
267
- left: 0;
268
- right: 0;
269
- bottom: 0;
270
- background: rgba(0, 0, 0, 0.5);
271
- z-index: 9998;
272
- opacity: 0;
273
- transition: opacity 0.3s ease;
274
- `;
275
- // Create modal container
276
- this.container = document.createElement('div');
277
- this.container.className = `glide-auth-modal ${((_a = this.options) === null || _a === void 0 ? void 0 : _a.className) || ''}`;
278
- this.container.style.cssText = `
279
- position: fixed;
280
- top: 50%;
281
- left: 50%;
282
- transform: translate(-50%, -50%) scale(0.9);
283
- background: white;
284
- border-radius: 12px;
285
- padding: 24px;
286
- max-width: 400px;
287
- width: 90%;
288
- box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
289
- z-index: 9999;
290
- opacity: 0;
291
- transition: opacity 0.3s ease, transform 0.3s ease;
292
- `;
293
- // Add modal content
294
- this.container.innerHTML = `
295
- <div class="glide-auth-header">
296
- ${((_b = this.options) === null || _b === void 0 ? void 0 : _b.showCloseButton) !== false ? `
297
- <button class="glide-auth-close" aria-label="Close">
298
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
299
- <line x1="18" y1="6" x2="6" y2="18"></line>
300
- <line x1="6" y1="6" x2="18" y2="18"></line>
301
- </svg>
302
- </button>
303
- ` : ''}
304
- <h2 class="glide-auth-title">${((_c = this.options) === null || _c === void 0 ? void 0 : _c.title) || 'Phone Verification'}</h2>
305
- </div>
306
- <div class="glide-auth-content">
307
- ${content}
308
- </div>
309
- `;
310
- // Add styles
311
- this.injectStyles();
312
- // Add close button handler
313
- const closeBtn = this.container.querySelector('.glide-auth-close');
314
- if (closeBtn) {
315
- closeBtn.addEventListener('click', () => {
316
- var _a;
317
- (_a = this.closeCallback) === null || _a === void 0 ? void 0 : _a.call(this); // Call cancellation callback if set
318
- this.close();
319
- });
320
- }
321
- // Add backdrop click handler
322
- this.backdrop.addEventListener('click', (e) => {
323
- var _a, _b;
324
- // Only close if backdrop itself was clicked and closeOnBackdrop is enabled (default true)
325
- if (e.target === this.backdrop && ((_a = this.options) === null || _a === void 0 ? void 0 : _a.closeOnBackdrop) !== false) {
326
- (_b = this.closeCallback) === null || _b === void 0 ? void 0 : _b.call(this); // Call cancellation callback if set
327
- this.close();
328
- }
329
- });
330
- }
331
- /**
332
- * Injects CSS styles for the modal
333
- */
334
- injectStyles() {
335
- if (document.getElementById('glide-auth-styles'))
336
- return;
337
- const styles = document.createElement('style');
338
- styles.id = 'glide-auth-styles';
339
- styles.textContent = `
340
- .glide-auth-backdrop {
341
- backdrop-filter: blur(4px);
342
- }
343
-
344
- .glide-auth-modal {
345
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
346
- }
347
-
348
- .glide-auth-header {
349
- position: relative;
350
- margin-bottom: 20px;
351
- }
352
-
353
- .glide-auth-close {
354
- position: absolute;
355
- top: 0;
356
- right: 0;
357
- background: none;
358
- border: none;
359
- cursor: pointer;
360
- padding: 0;
361
- color: #666;
362
- transition: color 0.2s;
363
- }
364
-
365
- .glide-auth-close:hover {
366
- color: #000;
367
- }
368
-
369
- .glide-auth-title {
370
- margin: 0;
371
- font-size: 24px;
372
- font-weight: 600;
373
- color: #333;
374
- text-align: center;
375
- }
376
-
377
- .glide-auth-content {
378
- text-align: center;
379
- }
380
-
381
- .glide-auth-description {
382
- color: #666;
383
- margin: 0 0 20px 0;
384
- font-size: 16px;
385
- line-height: 1.5;
386
- }
387
-
388
- .glide-auth-button {
389
- background: #007AFF;
390
- color: white;
391
- border: none;
392
- border-radius: 8px;
393
- padding: 12px 24px;
394
- font-size: 16px;
395
- font-weight: 500;
396
- cursor: pointer;
397
- transition: background 0.2s, transform 0.1s;
398
- min-width: 200px;
399
- }
400
-
401
- .glide-auth-button:hover:not(:disabled) {
402
- background: #0051D5;
403
- transform: translateY(-1px);
404
- }
405
-
406
- .glide-auth-button:active {
407
- transform: translateY(0);
408
- }
409
-
410
- .glide-auth-button:disabled {
411
- opacity: 0.6;
412
- cursor: not-allowed;
413
- }
414
-
415
- .glide-auth-helper-text {
416
- color: #999;
417
- font-size: 14px;
418
- margin: 16px 0 0 0;
419
- }
420
-
421
- .glide-auth-qr-code {
422
- max-width: 256px;
423
- width: 100%;
424
- height: auto;
425
- margin: 20px auto;
426
- display: block;
427
- }
428
-
429
- .glide-auth-status {
430
- color: #666;
431
- font-size: 16px;
432
- margin: 16px 0;
433
- }
434
-
435
- .glide-auth-error {
436
- color: #FF3B30;
437
- }
438
-
439
- .glide-auth-qr-container,
440
- .glide-auth-link-container,
441
- .glide-auth-ts43-container {
442
- padding: 20px 0;
443
- }
444
-
445
- /* Platform Switcher Styles */
446
- .glide-platform-switcher {
447
- display: flex;
448
- justify-content: center;
449
- gap: 10px;
450
- margin-bottom: 20px;
451
- }
452
-
453
- .glide-platform-btn {
454
- display: flex;
455
- align-items: center;
456
- gap: 6px;
457
- padding: 10px 20px;
458
- border: 2px solid;
459
- background: transparent;
460
- border-radius: 8px;
461
- cursor: pointer;
462
- font-size: 14px;
463
- font-weight: 600;
464
- transition: all 0.2s ease;
465
- }
466
-
467
- .glide-platform-btn svg {
468
- flex-shrink: 0;
469
- }
470
-
471
- .glide-platform-ios {
472
- border-color: #007AFF;
473
- color: #007AFF;
474
- }
475
-
476
- .glide-platform-ios.active {
477
- background: #007AFF;
478
- color: white;
479
- }
480
-
481
- .glide-platform-ios:hover:not(.active) {
482
- background: rgba(0, 122, 255, 0.1);
483
- }
484
-
485
- .glide-platform-android {
486
- border-color: #3DDC84;
487
- color: #3DDC84;
488
- }
489
-
490
- .glide-platform-android.active {
491
- background: #3DDC84;
492
- color: white;
493
- }
494
-
495
- .glide-platform-android:hover:not(.active) {
496
- background: rgba(61, 220, 132, 0.1);
497
- }
498
- `;
499
- document.head.appendChild(styles);
500
- }
501
- /**
502
- * Shows the modal with animation
503
- */
504
- show() {
505
- var _a, _b;
506
- if (!this.container || !this.backdrop || this.isOpen)
507
- return;
508
- document.body.appendChild(this.backdrop);
509
- document.body.appendChild(this.container);
510
- // Add escape key listener for closing modal
511
- document.addEventListener('keydown', this.handleEscapeKey);
512
- // Setup platform toggle handlers if they exist
513
- this.setupPlatformToggles();
514
- // Trigger animation
515
- requestAnimationFrame(() => {
516
- if (this.backdrop && this.container) {
517
- this.backdrop.style.opacity = '1';
518
- this.container.style.opacity = '1';
519
- this.container.style.transform = 'translate(-50%, -50%) scale(1)';
520
- }
521
- });
522
- this.isOpen = true;
523
- (_b = (_a = this.callbacks) === null || _a === void 0 ? void 0 : _a.onOpen) === null || _b === void 0 ? void 0 : _b.call(_a);
524
- }
525
- /**
526
- * Setup click handlers for iOS/Android platform toggle
527
- */
528
- setupPlatformToggles() {
529
- var _a, _b, _c;
530
- const platformBtns = (_a = this.container) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.glide-platform-btn');
531
- const qrImg = (_b = this.container) === null || _b === void 0 ? void 0 : _b.querySelector('#glide-qr-code-img');
532
- const message = (_c = this.container) === null || _c === void 0 ? void 0 : _c.querySelector('#glide-platform-message');
533
- if (!platformBtns || !qrImg)
534
- return;
535
- platformBtns.forEach((btn) => {
536
- btn.addEventListener('click', (e) => {
537
- const target = e.currentTarget;
538
- const platform = target.getAttribute('data-platform');
539
- // Update active state
540
- platformBtns.forEach(b => b.classList.remove('active'));
541
- target.classList.add('active');
542
- // Switch QR code
543
- if (platform === 'ios') {
544
- qrImg.src = qrImg.getAttribute('data-ios') || '';
545
- if (message)
546
- message.textContent = 'Scan with your iPhone to authenticate';
547
- }
548
- else if (platform === 'android') {
549
- qrImg.src = qrImg.getAttribute('data-android') || '';
550
- if (message)
551
- message.textContent = 'Scan with your Android device to authenticate';
552
- }
553
- });
554
- });
555
- }
556
- /**
557
- * Closes the modal with animation
558
- */
559
- close() {
560
- if (!this.container || !this.backdrop || !this.isOpen)
561
- return;
562
- // Remove escape key listener
563
- document.removeEventListener('keydown', this.handleEscapeKey);
564
- // Animate out
565
- this.backdrop.style.opacity = '0';
566
- this.container.style.opacity = '0';
567
- this.container.style.transform = 'translate(-50%, -50%) scale(0.9)';
568
- // Clear any stored callbacks
569
- this.closeCallback = undefined;
570
- // Remove after animation
571
- setTimeout(() => {
572
- var _a, _b;
573
- this.cleanup();
574
- this.isOpen = false;
575
- (_b = (_a = this.callbacks) === null || _a === void 0 ? void 0 : _a.onClose) === null || _b === void 0 ? void 0 : _b.call(_a);
576
- }, 300);
577
- }
578
- /**
579
- * Removes modal elements from DOM
580
- */
581
- cleanup() {
582
- var _a, _b;
583
- (_a = this.container) === null || _a === void 0 ? void 0 : _a.remove();
584
- (_b = this.backdrop) === null || _b === void 0 ? void 0 : _b.remove();
585
- this.container = null;
586
- this.backdrop = null;
587
- }
588
- /**
589
- * Check if modal is currently open
590
- */
591
- isModalOpen() {
592
- return this.isOpen;
593
- }
594
- }