@glideidentity/web-client-sdk 5.1.3 → 6.0.0-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 (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 +439 -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 +435 -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 +534 -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,590 +0,0 @@
1
- /**
2
- * Desktop Strategy Handler
3
- * Handles QR code-based authentication for desktop browsers
4
- * Manages QR code display and polling for authentication status
5
- */
6
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
7
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
8
- return new (P || (P = Promise))(function (resolve, reject) {
9
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
10
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
11
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
12
- step((generator = generator.apply(thisArg, _arguments || [])).next());
13
- });
14
- };
15
- export class DesktopHandler {
16
- constructor() {
17
- this.pollingAttempts = 0;
18
- this.isCancelled = false;
19
- this.isPollingInProgress = false;
20
- }
21
- /**
22
- * Maps backend HTTP status codes to client status
23
- * @param httpStatus HTTP status code from backend
24
- * @param bodyStatus Optional status from response body (for 200 OK responses)
25
- * @returns Mapped status string for client use
26
- */
27
- mapBackendStatus(httpStatus, bodyStatus) {
28
- switch (httpStatus) {
29
- case 200:
30
- // For 200 OK, check the body status
31
- return bodyStatus === 'completed' ? 'authenticated' : 'pending';
32
- case 410:
33
- return 'expired';
34
- case 422:
35
- return 'error'; // Failed or cancelled
36
- case 404:
37
- return 'error'; // Session not found
38
- case 400:
39
- return 'error'; // Invalid session key
40
- default:
41
- return 'error';
42
- }
43
- }
44
- /**
45
- * Invoke desktop authentication with QR code
46
- * Returns QR code data for display and starts polling if endpoint is provided
47
- */
48
- invoke(data, options) {
49
- return __awaiter(this, void 0, void 0, function* () {
50
- const desktopData = data.data;
51
- // Extract QR code from nested or flat structure, checking multiple field names
52
- let qrCode;
53
- let sessionId;
54
- let pollingEndpoint;
55
- let pollingInterval;
56
- let expiresIn;
57
- // Check nested structure first (data.data.qr_code_image or data.data.qr_code)
58
- if (desktopData && desktopData.data && typeof desktopData.data === 'object') {
59
- const innerData = desktopData.data;
60
- // Try to extract from inner data
61
- // Support both single QR (qr_code_image) and dual-platform QR (ios/android)
62
- if (innerData.ios_qr_image && innerData.android_qr_image) {
63
- // Dual-platform QR format - both must be present
64
- qrCode = {
65
- iosQRCode: innerData.ios_qr_image,
66
- androidQRCode: innerData.android_qr_image,
67
- iosUrl: innerData.ios_url,
68
- androidUrl: innerData.android_url
69
- };
70
- }
71
- else if (innerData.ios_qr_image || innerData.android_qr_image) {
72
- // Only one platform QR - use as single QR format
73
- qrCode = innerData.ios_qr_image || innerData.android_qr_image;
74
- }
75
- else {
76
- // Single QR format (legacy)
77
- qrCode = innerData.qr_code_image || innerData.qr_code;
78
- }
79
- sessionId = innerData.session_id;
80
- pollingEndpoint = innerData.status_url;
81
- pollingInterval = innerData.polling_interval;
82
- expiresIn = innerData.expires_in;
83
- }
84
- // Fall back to flat structure if no QR code found
85
- if (!qrCode && desktopData) {
86
- qrCode = desktopData.qr_code_image || desktopData.qr_code;
87
- sessionId = sessionId || desktopData.session_id;
88
- pollingEndpoint = pollingEndpoint || desktopData.status_url || desktopData.polling_endpoint;
89
- pollingInterval = pollingInterval || desktopData.polling_interval;
90
- expiresIn = expiresIn || desktopData.expires_in;
91
- }
92
- // Validate QR code exists
93
- if (!qrCode) {
94
- throw new Error('Invalid desktop authentication data: missing QR code');
95
- }
96
- // Validate session ID exists
97
- if (!sessionId) {
98
- throw new Error('Invalid desktop authentication data: missing session ID');
99
- }
100
- // Notify that QR code is ready
101
- if (options === null || options === void 0 ? void 0 : options.onQRCodeReady) {
102
- options.onQRCodeReady(qrCode);
103
- }
104
- // Use polling endpoint with this priority:
105
- // 1. Developer-provided endpoint from options (highest priority)
106
- // 2. Backend-provided endpoint
107
- // 3. Hardcoded fallback
108
- console.log('[Desktop QR] Polling endpoint selection:');
109
- console.log(' - options?.pollingEndpoint:', options === null || options === void 0 ? void 0 : options.pollingEndpoint);
110
- console.log(' - backend pollingEndpoint:', pollingEndpoint);
111
- let finalPollingEndpoint = options === null || options === void 0 ? void 0 : options.pollingEndpoint;
112
- let endpointSource = 'options';
113
- if (!finalPollingEndpoint) {
114
- finalPollingEndpoint = pollingEndpoint; // Backend-provided status_url
115
- endpointSource = 'backend';
116
- }
117
- if (!finalPollingEndpoint) {
118
- // Use hardcoded fallback - this will be constructed in the polling function
119
- console.log('[Desktop QR] No polling endpoint provided, will use hardcoded fallback');
120
- endpointSource = 'fallback';
121
- }
122
- console.log('[Desktop QR] Selected endpoint:', finalPollingEndpoint, 'from source:', endpointSource);
123
- // Start polling for authentication status
124
- const finalPollingInterval = (options === null || options === void 0 ? void 0 : options.pollingInterval) || pollingInterval || 2000;
125
- const maxAttempts = (options === null || options === void 0 ? void 0 : options.maxPollingAttempts) || 30; // Default to 1 minute
126
- console.log(`[Desktop QR] Starting polling - endpoint source: ${endpointSource}, interval: ${finalPollingInterval}ms, max attempts: ${maxAttempts}`);
127
- return this.startPolling(finalPollingEndpoint || '', // Pass empty string if undefined, will use fallback
128
- sessionId, finalPollingInterval, maxAttempts, expiresIn || 300, // Default 5 minutes expiry
129
- options, endpointSource // Pass the endpoint source for logging
130
- );
131
- });
132
- }
133
- /**
134
- * Start polling for authentication status
135
- */
136
- startPolling(endpoint_1, sessionId_1, interval_1, maxAttempts_1, expiresIn_1, options_1) {
137
- return __awaiter(this, arguments, void 0, function* (endpoint, sessionId, interval, maxAttempts, expiresIn, options, endpointSource = 'unknown') {
138
- const startTime = Date.now();
139
- const expiryTime = startTime + (expiresIn * 1000);
140
- return new Promise((resolve, reject) => {
141
- // Store the reject function so we can call it from cancel()
142
- this.pollingReject = reject;
143
- const poll = () => __awaiter(this, void 0, void 0, function* () {
144
- // Skip if another poll is already in progress
145
- if (this.isPollingInProgress) {
146
- return;
147
- }
148
- try {
149
- this.isPollingInProgress = true;
150
- // Check if cancelled
151
- if (this.isCancelled) {
152
- this.stopPolling();
153
- if (options === null || options === void 0 ? void 0 : options.onCancel) {
154
- options.onCancel();
155
- }
156
- if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
157
- options.onStatusUpdate({
158
- status: 'cancelled',
159
- message: 'Authentication cancelled'
160
- });
161
- }
162
- // Reject the promise with a cancellation error
163
- reject({
164
- code: 'USER_DENIED',
165
- message: 'Authentication cancelled by user'
166
- });
167
- return;
168
- }
169
- // Check if expired
170
- if (Date.now() > expiryTime) {
171
- this.stopPolling();
172
- if (options === null || options === void 0 ? void 0 : options.onExpired) {
173
- options.onExpired();
174
- }
175
- if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
176
- options.onStatusUpdate({
177
- status: 'expired',
178
- message: 'QR code has expired'
179
- });
180
- }
181
- resolve({
182
- authenticated: false,
183
- error: 'Authentication expired'
184
- });
185
- return;
186
- }
187
- // Check max attempts
188
- if (this.pollingAttempts >= maxAttempts) {
189
- this.stopPolling();
190
- if (options === null || options === void 0 ? void 0 : options.onTimeout) {
191
- options.onTimeout();
192
- }
193
- if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
194
- options.onStatusUpdate({
195
- status: 'error',
196
- message: 'Polling timeout reached'
197
- });
198
- }
199
- resolve({
200
- authenticated: false,
201
- error: 'Polling timeout'
202
- });
203
- return;
204
- }
205
- // Build public status endpoint URL - use relative path for proxied requests
206
- let statusUrl;
207
- // Extract base URL and construct public endpoint
208
- if (endpoint && (endpoint.startsWith('http://') || endpoint.startsWith('https://'))) {
209
- // Full URL provided - use as is
210
- statusUrl = endpoint;
211
- }
212
- else if (endpoint && endpoint !== '') {
213
- // Relative path provided (e.g. '/api/phone-auth/status')
214
- // Append session ID to the provided endpoint
215
- statusUrl = `${endpoint}/${sessionId}`;
216
- }
217
- else {
218
- // No endpoint provided - use hardcoded fallback
219
- // This ensures it goes through the same domain and uses the app's API configuration
220
- statusUrl = `/api/phone-auth/status/${sessionId}`;
221
- }
222
- // Poll the public endpoint - no authentication required
223
- console.log(`[Desktop QR] Polling status (attempt ${this.pollingAttempts}/${maxAttempts})`);
224
- console.log(`[Desktop QR] Using ${endpointSource} endpoint: ${statusUrl}`);
225
- // Build headers
226
- const headers = {
227
- 'Accept': 'application/json'
228
- };
229
- // Add developer header if devEnv is set
230
- if (options === null || options === void 0 ? void 0 : options.devEnv) {
231
- headers['developer'] = options.devEnv;
232
- console.log(`[Desktop QR] Adding developer header: ${options.devEnv}`);
233
- }
234
- const response = yield fetch(statusUrl, {
235
- method: 'GET',
236
- headers
237
- });
238
- console.log(`[Desktop QR] Status response: ${response.status} ${response.statusText}`);
239
- // Backend Status Code Mapping:
240
- // - 200 OK: Session exists (body has 'pending' or 'completed' status)
241
- // - 410 Gone: Session expired after timeout
242
- // - 422 Unprocessable Entity: Authentication failed or cancelled
243
- // - 404 Not Found: Session doesn't exist
244
- // - 400 Bad Request: Invalid session key format
245
- // Handle response based on HTTP status code
246
- if (response.status === 200) {
247
- const result = yield response.json();
248
- if (result.status === 'completed') {
249
- // Authentication completed successfully
250
- this.stopPolling();
251
- // Close the modal if it exists
252
- const modal = document.querySelector('[style*="position: fixed"]');
253
- if (modal && modal.querySelector('#desktop-auth-status')) {
254
- setTimeout(() => {
255
- modal.remove();
256
- }, 500); // Brief delay to show success message
257
- }
258
- if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
259
- options.onStatusUpdate({
260
- status: 'authenticated',
261
- message: 'Authentication successful',
262
- data: result
263
- });
264
- }
265
- // Return the session data for next steps
266
- this.pollingReject = undefined; // Clear the reject function on success
267
- resolve({
268
- authenticated: true,
269
- credential: result.credential || result.session_key || sessionId,
270
- session: result.session || {
271
- session_key: result.session_key || sessionId,
272
- status: result.status,
273
- protocol: result.protocol,
274
- created_at: result.created_at,
275
- last_updated: result.last_updated
276
- }
277
- });
278
- }
279
- else if (result.status === 'pending') {
280
- // Continue polling
281
- this.pollingAttempts++;
282
- if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
283
- options.onStatusUpdate({
284
- status: 'pending',
285
- message: `Waiting for authentication (attempt ${this.pollingAttempts}/${maxAttempts})`
286
- });
287
- }
288
- }
289
- }
290
- else if (response.status === 410) {
291
- // Session expired
292
- this.stopPolling();
293
- const errorData = yield response.json().catch(() => ({ message: 'Session expired' }));
294
- // Close the modal on error
295
- const modal = document.querySelector('[style*="position: fixed"]');
296
- if (modal && modal.querySelector('#desktop-auth-status')) {
297
- setTimeout(() => {
298
- modal.remove();
299
- }, 500);
300
- }
301
- if (options === null || options === void 0 ? void 0 : options.onExpired) {
302
- options.onExpired();
303
- }
304
- if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
305
- options.onStatusUpdate({
306
- status: 'expired',
307
- message: errorData.message || 'Session has expired'
308
- });
309
- }
310
- resolve({
311
- authenticated: false,
312
- error: errorData.message || 'Session expired'
313
- });
314
- }
315
- else if (response.status === 422) {
316
- // Authentication failed
317
- this.stopPolling();
318
- const errorData = yield response.json().catch(() => ({ message: 'Authentication failed' }));
319
- // Close the modal on error
320
- const modal = document.querySelector('[style*="position: fixed"]');
321
- if (modal && modal.querySelector('#desktop-auth-status')) {
322
- setTimeout(() => {
323
- modal.remove();
324
- }, 500);
325
- }
326
- const isUserCancelled = errorData.code === 'USER_CANCELLED';
327
- if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
328
- options.onStatusUpdate({
329
- status: 'error',
330
- message: errorData.message || 'Authentication failed'
331
- });
332
- }
333
- resolve({
334
- authenticated: false,
335
- error: isUserCancelled
336
- ? 'User cancelled authentication'
337
- : (errorData.message || 'Authentication failed')
338
- });
339
- }
340
- else if (response.status === 404) {
341
- // Session not found
342
- this.stopPolling();
343
- if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
344
- options.onStatusUpdate({
345
- status: 'error',
346
- message: 'Session not found'
347
- });
348
- }
349
- resolve({
350
- authenticated: false,
351
- error: 'Session not found'
352
- });
353
- }
354
- else if (response.status === 400) {
355
- // Invalid session key
356
- this.stopPolling();
357
- const errorData = yield response.json().catch(() => ({ message: 'Invalid session key' }));
358
- resolve({
359
- authenticated: false,
360
- error: errorData.message || 'Invalid session key'
361
- });
362
- }
363
- else {
364
- // Unexpected status - continue polling
365
- this.pollingAttempts++;
366
- }
367
- }
368
- catch (error) {
369
- // Network or other error - continue polling
370
- this.pollingAttempts++;
371
- if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
372
- options.onStatusUpdate({
373
- status: 'pending',
374
- message: `Network error, retrying... (attempt ${this.pollingAttempts}/${maxAttempts})`
375
- });
376
- }
377
- }
378
- finally {
379
- // Always clear the polling flag when done
380
- this.isPollingInProgress = false;
381
- }
382
- });
383
- // Start initial poll
384
- poll();
385
- // Set up interval for subsequent polls
386
- this.pollingIntervalId = setInterval(poll, interval);
387
- });
388
- });
389
- }
390
- /**
391
- * Stop polling
392
- */
393
- stopPolling() {
394
- if (this.pollingIntervalId) {
395
- console.log('[Desktop QR] Stopping polling');
396
- clearInterval(this.pollingIntervalId);
397
- this.pollingIntervalId = undefined;
398
- }
399
- this.pollingAttempts = 0;
400
- this.isPollingInProgress = false;
401
- // Don't clear pollingReject here - it's needed by cancel()
402
- }
403
- /**
404
- * Check if polling is currently active
405
- */
406
- isPolling() {
407
- return this.pollingIntervalId !== undefined;
408
- }
409
- /**
410
- * Format response for backend processing
411
- * Desktop strategy typically returns the credential from mobile authentication
412
- */
413
- formatResponse(response) {
414
- if (!response.authenticated || !response.credential) {
415
- throw new Error('Authentication not completed');
416
- }
417
- return {
418
- credential: response.credential,
419
- session: response.session
420
- };
421
- }
422
- /**
423
- * Check if desktop authentication is supported
424
- * Desktop auth with QR codes works in any modern browser
425
- */
426
- isSupported() {
427
- // Check for required browser APIs
428
- return typeof window !== 'undefined' &&
429
- typeof fetch !== 'undefined' &&
430
- typeof Promise !== 'undefined';
431
- }
432
- /**
433
- * Clean up resources (stop polling if active)
434
- */
435
- cleanup() {
436
- this.stopPolling();
437
- this.isCancelled = false;
438
- this.onCancel = undefined;
439
- this.pollingReject = undefined;
440
- }
441
- /**
442
- * Cancel the ongoing authentication
443
- */
444
- cancel() {
445
- var _a;
446
- console.log('[Desktop QR] Cancelling authentication');
447
- this.isCancelled = true;
448
- this.stopPolling();
449
- (_a = this.onCancel) === null || _a === void 0 ? void 0 : _a.call(this);
450
- // Immediately reject the polling promise
451
- if (this.pollingReject) {
452
- this.pollingReject({
453
- code: 'USER_DENIED',
454
- message: 'Authentication cancelled by user'
455
- });
456
- this.pollingReject = undefined;
457
- }
458
- }
459
- }
460
- /**
461
- * Helper function to display QR code in a modal or inline
462
- */
463
- export function createQRCodeDisplay(qrCodeData, options) {
464
- const container = (options === null || options === void 0 ? void 0 : options.container) || document.createElement('div');
465
- container.className = 'phone-auth-qr-container';
466
- // Determine QR code to display
467
- let qrCodeSrc;
468
- if (typeof qrCodeData === 'string') {
469
- // Simple string QR code
470
- qrCodeSrc = qrCodeData;
471
- }
472
- else if (qrCodeData && typeof qrCodeData === 'object') {
473
- // QRCodeData object - prefer iOS QR if available
474
- if (qrCodeData.iosQRCode) {
475
- qrCodeSrc = qrCodeData.iosQRCode;
476
- }
477
- else if (qrCodeData.androidQRCode) {
478
- qrCodeSrc = qrCodeData.androidQRCode;
479
- }
480
- else {
481
- throw new Error('Invalid QRCodeData: missing QR code images');
482
- }
483
- }
484
- else {
485
- throw new Error('Invalid qrCodeData: must be string or QRCodeData object');
486
- }
487
- // Create QR code image
488
- const img = document.createElement('img');
489
- img.src = qrCodeSrc;
490
- img.alt = 'QR Code for authentication';
491
- img.style.width = `${(options === null || options === void 0 ? void 0 : options.size) || 256}px`;
492
- img.style.height = `${(options === null || options === void 0 ? void 0 : options.size) || 256}px`;
493
- img.style.display = 'block';
494
- img.style.margin = '0 auto';
495
- // Add title if provided
496
- if (options === null || options === void 0 ? void 0 : options.title) {
497
- const title = document.createElement('h3');
498
- title.textContent = options.title;
499
- title.style.textAlign = 'center';
500
- title.style.marginBottom = '1rem';
501
- container.appendChild(title);
502
- }
503
- container.appendChild(img);
504
- // Add description if provided
505
- if (options === null || options === void 0 ? void 0 : options.description) {
506
- const desc = document.createElement('p');
507
- desc.textContent = options.description;
508
- desc.style.textAlign = 'center';
509
- desc.style.marginTop = '1rem';
510
- desc.style.color = '#666';
511
- container.appendChild(desc);
512
- }
513
- return container;
514
- }
515
- /**
516
- * Helper function to create a modal for QR code display
517
- * Supports both string QR codes and QRCodeData objects for dual-platform support
518
- */
519
- export function showQRCodeModal(qrCodeData, options) {
520
- // Create modal overlay
521
- const overlay = document.createElement('div');
522
- overlay.style.cssText = `
523
- position: fixed;
524
- top: 0;
525
- left: 0;
526
- right: 0;
527
- bottom: 0;
528
- background-color: rgba(0, 0, 0, 0.5);
529
- display: flex;
530
- align-items: center;
531
- justify-content: center;
532
- z-index: 9999;
533
- `;
534
- // Create modal content
535
- const modal = document.createElement('div');
536
- modal.style.cssText = `
537
- background: white;
538
- padding: 2rem;
539
- border-radius: 8px;
540
- max-width: 400px;
541
- position: relative;
542
- `;
543
- // Add close button
544
- const closeBtn = document.createElement('button');
545
- closeBtn.textContent = '×';
546
- closeBtn.style.cssText = `
547
- position: absolute;
548
- top: 10px;
549
- right: 10px;
550
- background: none;
551
- border: none;
552
- font-size: 24px;
553
- cursor: pointer;
554
- color: #999;
555
- `;
556
- closeBtn.onclick = () => {
557
- document.body.removeChild(overlay);
558
- if (options === null || options === void 0 ? void 0 : options.onClose) {
559
- options.onClose();
560
- }
561
- };
562
- modal.appendChild(closeBtn);
563
- // Add QR code display
564
- const qrDisplay = createQRCodeDisplay(qrCodeData, {
565
- title: (options === null || options === void 0 ? void 0 : options.title) || 'Scan QR Code to Authenticate',
566
- description: (options === null || options === void 0 ? void 0 : options.description) || 'Use your mobile device to scan this QR code'
567
- });
568
- modal.appendChild(qrDisplay);
569
- // Add loading spinner placeholder
570
- const statusDiv = document.createElement('div');
571
- statusDiv.id = 'desktop-auth-status';
572
- statusDiv.style.cssText = `
573
- text-align: center;
574
- margin-top: 1rem;
575
- color: #666;
576
- font-size: 14px;
577
- `;
578
- modal.appendChild(statusDiv);
579
- overlay.appendChild(modal);
580
- document.body.appendChild(overlay);
581
- // Close modal on overlay click
582
- overlay.onclick = (e) => {
583
- if (e.target === overlay) {
584
- document.body.removeChild(overlay);
585
- if (options === null || options === void 0 ? void 0 : options.onClose) {
586
- options.onClose();
587
- }
588
- }
589
- };
590
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * Strategy Handlers Export
3
- * Provides implementations for TS43, Link, and Desktop authentication strategies
4
- */
5
- export type { StrategyHandler } from './types';
6
- export { TS43Handler } from './ts43';
7
- export { LinkHandler } from './link';
8
- export type { LinkAuthOptions, LinkAuthResult, PollingStatus as LinkPollingStatus } from './link';
9
- export { DesktopHandler, createQRCodeDisplay, showQRCodeModal } from './desktop';
10
- export type { DesktopAuthOptions, DesktopAuthResult, PollingStatus } from './desktop';
11
- export type { TS43Data, LinkData } from '../types';
@@ -1,7 +0,0 @@
1
- /**
2
- * Strategy Handlers Export
3
- * Provides implementations for TS43, Link, and Desktop authentication strategies
4
- */
5
- export { TS43Handler } from './ts43';
6
- export { LinkHandler } from './link';
7
- export { DesktopHandler, createQRCodeDisplay, showQRCodeModal } from './desktop';