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