@glideidentity/web-client-sdk 4.4.8-beta.1 → 4.4.8-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.
- package/dist/adapters/react/usePhoneAuth.d.ts +1 -1
- package/dist/adapters/vue/useClient.d.ts +3 -3
- package/dist/adapters/vue/usePhoneAuth.d.ts +1 -1
- package/dist/browser/web-client-sdk.min.js +1 -1
- package/dist/core/phone-auth/api-types.d.ts +112 -27
- package/dist/core/phone-auth/client.d.ts +13 -11
- package/dist/core/phone-auth/client.js +257 -248
- package/dist/core/phone-auth/index.d.ts +1 -1
- package/dist/core/phone-auth/index.js +7 -2
- package/dist/core/phone-auth/strategies/desktop.d.ts +1 -0
- package/dist/core/phone-auth/strategies/desktop.js +64 -18
- package/dist/core/phone-auth/type-guards.d.ts +61 -43
- package/dist/core/phone-auth/type-guards.js +82 -44
- package/dist/core/phone-auth/ui/modal.js +14 -1
- package/dist/core/version.js +1 -1
- package/dist/esm/adapters/react/usePhoneAuth.d.ts +1 -1
- package/dist/esm/adapters/vue/useClient.d.ts +3 -3
- package/dist/esm/adapters/vue/usePhoneAuth.d.ts +1 -1
- package/dist/esm/core/phone-auth/api-types.d.ts +112 -27
- package/dist/esm/core/phone-auth/client.d.ts +13 -11
- package/dist/esm/core/phone-auth/client.js +257 -248
- package/dist/esm/core/phone-auth/index.d.ts +1 -1
- package/dist/esm/core/phone-auth/index.js +3 -1
- package/dist/esm/core/phone-auth/strategies/desktop.d.ts +1 -0
- package/dist/esm/core/phone-auth/strategies/desktop.js +64 -18
- package/dist/esm/core/phone-auth/type-guards.d.ts +61 -43
- package/dist/esm/core/phone-auth/type-guards.js +76 -41
- package/dist/esm/core/phone-auth/ui/modal.js +14 -1
- package/dist/esm/core/version.js +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +3 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -2
- package/package.json +1 -1
|
@@ -3,4 +3,6 @@ export * from './types';
|
|
|
3
3
|
export { PhoneAuthErrorCode, isPhoneAuthError, isUserError, getUserMessage, isErrorCode, getRetryDelay, isRetryableError, serializeError, createErrorBreadcrumb } from './error-utils';
|
|
4
4
|
export { validatePhoneNumber, validatePlmn, validateUseCaseRequirements, validateConsentData, validateNonce } from './validation-utils';
|
|
5
5
|
export { MobileDebugConsole } from './ui/mobile-debug-console';
|
|
6
|
-
export {
|
|
6
|
+
export { isExtendedResponse, isCredential, isAuthCredential, isLinkStrategy, isTS43Strategy, isDesktopStrategy, getStrategy, hasPollingControls, hasTrigger,
|
|
7
|
+
// Deprecated aliases
|
|
8
|
+
isHeadlessResult, requiresPolling, requiresUserAction } from './type-guards';
|
|
@@ -55,6 +55,7 @@ export declare class DesktopHandler implements StrategyHandler {
|
|
|
55
55
|
private pollingAttempts;
|
|
56
56
|
private isCancelled;
|
|
57
57
|
private onCancel?;
|
|
58
|
+
private pollingReject?;
|
|
58
59
|
/**
|
|
59
60
|
* Maps backend HTTP status codes to client status
|
|
60
61
|
* @param httpStatus HTTP status code from backend
|
|
@@ -57,7 +57,20 @@ export class DesktopHandler {
|
|
|
57
57
|
if (desktopData && desktopData.data && typeof desktopData.data === 'object') {
|
|
58
58
|
const innerData = desktopData.data;
|
|
59
59
|
// Try to extract from inner data
|
|
60
|
-
|
|
60
|
+
// Support both single QR (qr_code_image) and dual-platform QR (ios/android)
|
|
61
|
+
if (innerData.ios_qr_image || innerData.android_qr_image) {
|
|
62
|
+
// Dual-platform QR format
|
|
63
|
+
qrCode = {
|
|
64
|
+
iosQRCode: innerData.ios_qr_image,
|
|
65
|
+
androidQRCode: innerData.android_qr_image,
|
|
66
|
+
iosUrl: innerData.ios_url,
|
|
67
|
+
androidUrl: innerData.android_url
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Single QR format (legacy)
|
|
72
|
+
qrCode = innerData.qr_code_image || innerData.qr_code;
|
|
73
|
+
}
|
|
61
74
|
sessionId = innerData.session_id;
|
|
62
75
|
pollingEndpoint = innerData.status_url;
|
|
63
76
|
pollingInterval = innerData.polling_interval;
|
|
@@ -84,33 +97,44 @@ export class DesktopHandler {
|
|
|
84
97
|
options.onQRCodeReady(qrCode);
|
|
85
98
|
}
|
|
86
99
|
// Use polling endpoint with this priority:
|
|
87
|
-
// 1. Developer-provided endpoint from options
|
|
100
|
+
// 1. Developer-provided endpoint from options (highest priority)
|
|
88
101
|
// 2. Backend-provided endpoint
|
|
89
|
-
// 3.
|
|
90
|
-
|
|
91
|
-
|
|
102
|
+
// 3. Hardcoded fallback
|
|
103
|
+
console.log('[Desktop QR] Polling endpoint selection:');
|
|
104
|
+
console.log(' - options?.pollingEndpoint:', options === null || options === void 0 ? void 0 : options.pollingEndpoint);
|
|
105
|
+
console.log(' - backend pollingEndpoint:', pollingEndpoint);
|
|
106
|
+
let finalPollingEndpoint = options === null || options === void 0 ? void 0 : options.pollingEndpoint;
|
|
107
|
+
let endpointSource = 'options';
|
|
92
108
|
if (!finalPollingEndpoint) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
session: data.session,
|
|
96
|
-
error: 'No polling endpoint provided - configure endpoints.polling or ensure backend provides status_url'
|
|
97
|
-
};
|
|
109
|
+
finalPollingEndpoint = pollingEndpoint; // Backend-provided status_url
|
|
110
|
+
endpointSource = 'backend';
|
|
98
111
|
}
|
|
112
|
+
if (!finalPollingEndpoint) {
|
|
113
|
+
// Use hardcoded fallback - this will be constructed in the polling function
|
|
114
|
+
console.log('[Desktop QR] No polling endpoint provided, will use hardcoded fallback');
|
|
115
|
+
endpointSource = 'fallback';
|
|
116
|
+
}
|
|
117
|
+
console.log('[Desktop QR] Selected endpoint:', finalPollingEndpoint, 'from source:', endpointSource);
|
|
99
118
|
// Start polling for authentication status
|
|
100
119
|
const finalPollingInterval = (options === null || options === void 0 ? void 0 : options.pollingInterval) || pollingInterval || 2000;
|
|
101
120
|
const maxAttempts = (options === null || options === void 0 ? void 0 : options.maxPollingAttempts) || 150; // Default to 5 minutes
|
|
102
|
-
|
|
103
|
-
|
|
121
|
+
console.log(`[Desktop QR] Starting polling - endpoint source: ${endpointSource}, interval: ${finalPollingInterval}ms, max attempts: ${maxAttempts}`);
|
|
122
|
+
return this.startPolling(finalPollingEndpoint || '', // Pass empty string if undefined, will use fallback
|
|
123
|
+
sessionId, finalPollingInterval, maxAttempts, expiresIn || 300, // Default 5 minutes expiry
|
|
124
|
+
options, endpointSource // Pass the endpoint source for logging
|
|
125
|
+
);
|
|
104
126
|
});
|
|
105
127
|
}
|
|
106
128
|
/**
|
|
107
129
|
* Start polling for authentication status
|
|
108
130
|
*/
|
|
109
|
-
startPolling(
|
|
110
|
-
return __awaiter(this,
|
|
131
|
+
startPolling(endpoint_1, sessionId_1, interval_1, maxAttempts_1, expiresIn_1, options_1) {
|
|
132
|
+
return __awaiter(this, arguments, void 0, function* (endpoint, sessionId, interval, maxAttempts, expiresIn, options, endpointSource = 'unknown') {
|
|
111
133
|
const startTime = Date.now();
|
|
112
134
|
const expiryTime = startTime + (expiresIn * 1000);
|
|
113
135
|
return new Promise((resolve, reject) => {
|
|
136
|
+
// Store the reject function so we can call it from cancel()
|
|
137
|
+
this.pollingReject = reject;
|
|
114
138
|
const poll = () => __awaiter(this, void 0, void 0, function* () {
|
|
115
139
|
try {
|
|
116
140
|
// Check if cancelled
|
|
@@ -125,9 +149,10 @@ export class DesktopHandler {
|
|
|
125
149
|
message: 'Authentication cancelled'
|
|
126
150
|
});
|
|
127
151
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
152
|
+
// Reject the promise with a cancellation error
|
|
153
|
+
reject({
|
|
154
|
+
code: 'USER_DENIED',
|
|
155
|
+
message: 'Authentication cancelled by user'
|
|
131
156
|
});
|
|
132
157
|
return;
|
|
133
158
|
}
|
|
@@ -175,12 +200,19 @@ export class DesktopHandler {
|
|
|
175
200
|
const url = new URL(endpoint);
|
|
176
201
|
statusUrl = `${url.protocol}//${url.host}/public/public/status/${sessionId}`;
|
|
177
202
|
}
|
|
203
|
+
else if (endpoint && endpoint !== '') {
|
|
204
|
+
// Relative path provided (e.g. '/api/phone-auth/status')
|
|
205
|
+
// Append session ID to the provided endpoint
|
|
206
|
+
statusUrl = `${endpoint}/${sessionId}`;
|
|
207
|
+
}
|
|
178
208
|
else {
|
|
179
|
-
//
|
|
209
|
+
// No endpoint provided - use hardcoded fallback
|
|
180
210
|
// This ensures it goes through the same domain and uses the app's API configuration
|
|
181
211
|
statusUrl = `/api/phone-auth/status/${sessionId}`;
|
|
182
212
|
}
|
|
183
213
|
// Poll the public endpoint - no authentication required
|
|
214
|
+
console.log(`[Desktop QR] Polling status (attempt ${this.pollingAttempts}/${maxAttempts})`);
|
|
215
|
+
console.log(`[Desktop QR] Using ${endpointSource} endpoint: ${statusUrl}`);
|
|
184
216
|
const response = yield fetch(statusUrl, {
|
|
185
217
|
method: 'GET',
|
|
186
218
|
headers: {
|
|
@@ -188,6 +220,7 @@ export class DesktopHandler {
|
|
|
188
220
|
// No Authorization header needed for public endpoint
|
|
189
221
|
}
|
|
190
222
|
});
|
|
223
|
+
console.log(`[Desktop QR] Status response: ${response.status} ${response.statusText}`);
|
|
191
224
|
// Backend Status Code Mapping:
|
|
192
225
|
// - 200 OK: Session exists (body has 'pending' or 'completed' status)
|
|
193
226
|
// - 410 Gone: Session expired after timeout
|
|
@@ -215,6 +248,7 @@ export class DesktopHandler {
|
|
|
215
248
|
});
|
|
216
249
|
}
|
|
217
250
|
// Return the session data for next steps
|
|
251
|
+
this.pollingReject = undefined; // Clear the reject function on success
|
|
218
252
|
resolve({
|
|
219
253
|
authenticated: true,
|
|
220
254
|
credential: result.credential || result.session_key || sessionId,
|
|
@@ -339,10 +373,12 @@ export class DesktopHandler {
|
|
|
339
373
|
*/
|
|
340
374
|
stopPolling() {
|
|
341
375
|
if (this.pollingIntervalId) {
|
|
376
|
+
console.log('[Desktop QR] Stopping polling');
|
|
342
377
|
clearInterval(this.pollingIntervalId);
|
|
343
378
|
this.pollingIntervalId = undefined;
|
|
344
379
|
}
|
|
345
380
|
this.pollingAttempts = 0;
|
|
381
|
+
// Don't clear pollingReject here - it's needed by cancel()
|
|
346
382
|
}
|
|
347
383
|
/**
|
|
348
384
|
* Format response for backend processing
|
|
@@ -374,15 +410,25 @@ export class DesktopHandler {
|
|
|
374
410
|
this.stopPolling();
|
|
375
411
|
this.isCancelled = false;
|
|
376
412
|
this.onCancel = undefined;
|
|
413
|
+
this.pollingReject = undefined;
|
|
377
414
|
}
|
|
378
415
|
/**
|
|
379
416
|
* Cancel the ongoing authentication
|
|
380
417
|
*/
|
|
381
418
|
cancel() {
|
|
382
419
|
var _a;
|
|
420
|
+
console.log('[Desktop QR] Cancelling authentication');
|
|
383
421
|
this.isCancelled = true;
|
|
384
422
|
this.stopPolling();
|
|
385
423
|
(_a = this.onCancel) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
424
|
+
// Immediately reject the polling promise
|
|
425
|
+
if (this.pollingReject) {
|
|
426
|
+
this.pollingReject({
|
|
427
|
+
code: 'USER_DENIED',
|
|
428
|
+
message: 'Authentication cancelled by user'
|
|
429
|
+
});
|
|
430
|
+
this.pollingReject = undefined;
|
|
431
|
+
}
|
|
386
432
|
}
|
|
387
433
|
}
|
|
388
434
|
/**
|
|
@@ -4,29 +4,29 @@
|
|
|
4
4
|
* These utilities help developers work with the SDK responses in a type-safe way
|
|
5
5
|
* without having to write their own type checking logic.
|
|
6
6
|
*/
|
|
7
|
-
import type {
|
|
7
|
+
import type { AnyExtendedResponse, DesktopExtendedResponse, LinkExtendedResponse, TS43ExtendedResponse, AuthCredential } from './api-types';
|
|
8
8
|
/**
|
|
9
|
-
* Type guard to check if the result is
|
|
10
|
-
* or a Credential (
|
|
9
|
+
* Type guard to check if the result is an ExtendedResponse (extended mode)
|
|
10
|
+
* or a Credential (standard mode).
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* ```typescript
|
|
14
|
-
* const result = await invokeSecurePrompt(sdkRequest);
|
|
14
|
+
* const result = await invokeSecurePrompt(sdkRequest, { executionMode: 'extended' });
|
|
15
15
|
*
|
|
16
|
-
* if (
|
|
17
|
-
* // TypeScript knows this is
|
|
16
|
+
* if (isExtendedResponse(result)) {
|
|
17
|
+
* // TypeScript knows this is ExtendedResponse
|
|
18
18
|
* console.log(result.strategy);
|
|
19
|
-
* await result.
|
|
19
|
+
* await result.cancel();
|
|
20
20
|
* } else {
|
|
21
21
|
* // TypeScript knows this is a Credential
|
|
22
22
|
* const processedResult = await verifyPhoneNumberCredential(result, session);
|
|
23
23
|
* }
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
|
26
|
-
export declare function
|
|
26
|
+
export declare function isExtendedResponse(result: any): result is AnyExtendedResponse;
|
|
27
27
|
/**
|
|
28
|
-
* Type guard to check if the result is a Credential (
|
|
29
|
-
* A credential is either a string token or an object without
|
|
28
|
+
* Type guard to check if the result is a Credential (standard mode response).
|
|
29
|
+
* A credential is either a string token or an object without ExtendedResponse properties.
|
|
30
30
|
*
|
|
31
31
|
* @example
|
|
32
32
|
* ```typescript
|
|
@@ -40,55 +40,61 @@ export declare function isCredential(result: any): result is string | {
|
|
|
40
40
|
[aggregator_id: string]: string | string[];
|
|
41
41
|
};
|
|
42
42
|
/**
|
|
43
|
-
* Type guard to check if
|
|
43
|
+
* Type guard to check if the result is an AuthCredential object.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* if (isAuthCredential(result)) {
|
|
48
|
+
* console.log(result.credential);
|
|
49
|
+
* console.log(result.authenticated);
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function isAuthCredential(result: any): result is AuthCredential;
|
|
54
|
+
/**
|
|
55
|
+
* Type guard to check if an ExtendedResponse is using the Link strategy.
|
|
44
56
|
* Link strategy involves opening an app link (App Clip on iOS, app on Android).
|
|
45
57
|
*
|
|
46
58
|
* @example
|
|
47
59
|
* ```typescript
|
|
48
|
-
* if (
|
|
49
|
-
* //
|
|
50
|
-
*
|
|
51
|
-
* await result.
|
|
60
|
+
* if (isExtendedResponse(result) && isLinkStrategy(result)) {
|
|
61
|
+
* // Re-trigger app opening if needed
|
|
62
|
+
* result.trigger();
|
|
63
|
+
* await result.credential;
|
|
52
64
|
* }
|
|
53
65
|
* ```
|
|
54
66
|
*/
|
|
55
|
-
export declare function isLinkStrategy(result:
|
|
56
|
-
strategy: 'link';
|
|
57
|
-
};
|
|
67
|
+
export declare function isLinkStrategy(result: AnyExtendedResponse): result is LinkExtendedResponse;
|
|
58
68
|
/**
|
|
59
|
-
* Type guard to check if
|
|
69
|
+
* Type guard to check if an ExtendedResponse is using the TS43 strategy.
|
|
60
70
|
* TS43 strategy uses the browser's Digital Credentials API.
|
|
61
71
|
*
|
|
62
72
|
* @example
|
|
63
73
|
* ```typescript
|
|
64
|
-
* if (
|
|
65
|
-
* //
|
|
66
|
-
*
|
|
74
|
+
* if (isExtendedResponse(result) && isTS43Strategy(result)) {
|
|
75
|
+
* // Re-trigger credential request if needed
|
|
76
|
+
* await result.trigger();
|
|
67
77
|
* }
|
|
68
78
|
* ```
|
|
69
79
|
*/
|
|
70
|
-
export declare function isTS43Strategy(result:
|
|
71
|
-
strategy: 'ts43';
|
|
72
|
-
};
|
|
80
|
+
export declare function isTS43Strategy(result: AnyExtendedResponse): result is TS43ExtendedResponse;
|
|
73
81
|
/**
|
|
74
|
-
* Type guard to check if
|
|
82
|
+
* Type guard to check if an ExtendedResponse is using the Desktop strategy.
|
|
75
83
|
* Desktop strategy involves QR codes for cross-device authentication.
|
|
76
84
|
*
|
|
77
85
|
* @example
|
|
78
86
|
* ```typescript
|
|
79
|
-
* if (
|
|
87
|
+
* if (isExtendedResponse(result) && isDesktopStrategy(result)) {
|
|
80
88
|
* // Show custom QR code UI
|
|
81
|
-
* displayQRCode(result.
|
|
82
|
-
* await result.
|
|
89
|
+
* displayQRCode(result.qr_code_data);
|
|
90
|
+
* await result.start_polling();
|
|
83
91
|
* }
|
|
84
92
|
* ```
|
|
85
93
|
*/
|
|
86
|
-
export declare function isDesktopStrategy(result:
|
|
87
|
-
strategy: 'desktop';
|
|
88
|
-
};
|
|
94
|
+
export declare function isDesktopStrategy(result: AnyExtendedResponse): result is DesktopExtendedResponse;
|
|
89
95
|
/**
|
|
90
96
|
* Helper function to safely get the authentication strategy from any result.
|
|
91
|
-
* Returns undefined if the result is not
|
|
97
|
+
* Returns undefined if the result is not an ExtendedResponse.
|
|
92
98
|
*
|
|
93
99
|
* @example
|
|
94
100
|
* ```typescript
|
|
@@ -100,26 +106,38 @@ export declare function isDesktopStrategy(result: HeadlessResult): result is Hea
|
|
|
100
106
|
*/
|
|
101
107
|
export declare function getStrategy(result: any): 'link' | 'ts43' | 'desktop' | undefined;
|
|
102
108
|
/**
|
|
103
|
-
* Helper function to determine if a result
|
|
104
|
-
* Link and Desktop strategies
|
|
109
|
+
* Helper function to determine if a result has polling controls.
|
|
110
|
+
* Link and Desktop strategies have polling controls in extended mode.
|
|
105
111
|
*
|
|
106
112
|
* @example
|
|
107
113
|
* ```typescript
|
|
108
|
-
* if (
|
|
109
|
-
* await result.
|
|
114
|
+
* if (hasPollingControls(result)) {
|
|
115
|
+
* await result.start_polling();
|
|
110
116
|
* }
|
|
111
117
|
* ```
|
|
112
118
|
*/
|
|
113
|
-
export declare function
|
|
119
|
+
export declare function hasPollingControls(result: any): boolean;
|
|
114
120
|
/**
|
|
115
|
-
* Helper function to determine if a result
|
|
116
|
-
*
|
|
121
|
+
* Helper function to determine if a result has a trigger method.
|
|
122
|
+
* Link and TS43 strategies have trigger methods in extended mode.
|
|
117
123
|
*
|
|
118
124
|
* @example
|
|
119
125
|
* ```typescript
|
|
120
|
-
* if (
|
|
121
|
-
*
|
|
126
|
+
* if (hasTrigger(result)) {
|
|
127
|
+
* result.trigger();
|
|
122
128
|
* }
|
|
123
129
|
* ```
|
|
124
130
|
*/
|
|
125
|
-
export declare function
|
|
131
|
+
export declare function hasTrigger(result: any): boolean;
|
|
132
|
+
/**
|
|
133
|
+
* @deprecated Use isExtendedResponse instead
|
|
134
|
+
*/
|
|
135
|
+
export declare const isHeadlessResult: typeof isExtendedResponse;
|
|
136
|
+
/**
|
|
137
|
+
* @deprecated Use hasPollingControls instead
|
|
138
|
+
*/
|
|
139
|
+
export declare const requiresPolling: typeof hasPollingControls;
|
|
140
|
+
/**
|
|
141
|
+
* @deprecated This function is no longer needed as extended mode handles user actions differently
|
|
142
|
+
*/
|
|
143
|
+
export declare const requiresUserAction: (result: any) => boolean;
|
|
@@ -5,33 +5,34 @@
|
|
|
5
5
|
* without having to write their own type checking logic.
|
|
6
6
|
*/
|
|
7
7
|
/**
|
|
8
|
-
* Type guard to check if the result is
|
|
9
|
-
* or a Credential (
|
|
8
|
+
* Type guard to check if the result is an ExtendedResponse (extended mode)
|
|
9
|
+
* or a Credential (standard mode).
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
12
12
|
* ```typescript
|
|
13
|
-
* const result = await invokeSecurePrompt(sdkRequest);
|
|
13
|
+
* const result = await invokeSecurePrompt(sdkRequest, { executionMode: 'extended' });
|
|
14
14
|
*
|
|
15
|
-
* if (
|
|
16
|
-
* // TypeScript knows this is
|
|
15
|
+
* if (isExtendedResponse(result)) {
|
|
16
|
+
* // TypeScript knows this is ExtendedResponse
|
|
17
17
|
* console.log(result.strategy);
|
|
18
|
-
* await result.
|
|
18
|
+
* await result.cancel();
|
|
19
19
|
* } else {
|
|
20
20
|
* // TypeScript knows this is a Credential
|
|
21
21
|
* const processedResult = await verifyPhoneNumberCredential(result, session);
|
|
22
22
|
* }
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
export function
|
|
25
|
+
export function isExtendedResponse(result) {
|
|
26
26
|
return result &&
|
|
27
27
|
typeof result === 'object' &&
|
|
28
28
|
'strategy' in result &&
|
|
29
|
-
'
|
|
30
|
-
|
|
29
|
+
'credential' in result &&
|
|
30
|
+
'cancel' in result &&
|
|
31
|
+
typeof result.cancel === 'function';
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
|
-
* Type guard to check if the result is a Credential (
|
|
34
|
-
* A credential is either a string token or an object without
|
|
34
|
+
* Type guard to check if the result is a Credential (standard mode response).
|
|
35
|
+
* A credential is either a string token or an object without ExtendedResponse properties.
|
|
35
36
|
*
|
|
36
37
|
* @example
|
|
37
38
|
* ```typescript
|
|
@@ -47,22 +48,40 @@ export function isCredential(result) {
|
|
|
47
48
|
// String credentials are valid
|
|
48
49
|
if (typeof result === 'string')
|
|
49
50
|
return true;
|
|
50
|
-
// Object credentials should NOT have
|
|
51
|
+
// Object credentials should NOT have ExtendedResponse properties
|
|
51
52
|
if (typeof result === 'object') {
|
|
52
|
-
return !('strategy' in result) && !('
|
|
53
|
+
return !('strategy' in result) && !('credential' in result) && !('cancel' in result);
|
|
53
54
|
}
|
|
54
55
|
return false;
|
|
55
56
|
}
|
|
56
57
|
/**
|
|
57
|
-
* Type guard to check if
|
|
58
|
+
* Type guard to check if the result is an AuthCredential object.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* if (isAuthCredential(result)) {
|
|
63
|
+
* console.log(result.credential);
|
|
64
|
+
* console.log(result.authenticated);
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export function isAuthCredential(result) {
|
|
69
|
+
return result &&
|
|
70
|
+
typeof result === 'object' &&
|
|
71
|
+
'credential' in result &&
|
|
72
|
+
'authenticated' in result &&
|
|
73
|
+
'session' in result;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Type guard to check if an ExtendedResponse is using the Link strategy.
|
|
58
77
|
* Link strategy involves opening an app link (App Clip on iOS, app on Android).
|
|
59
78
|
*
|
|
60
79
|
* @example
|
|
61
80
|
* ```typescript
|
|
62
|
-
* if (
|
|
63
|
-
* //
|
|
64
|
-
*
|
|
65
|
-
* await result.
|
|
81
|
+
* if (isExtendedResponse(result) && isLinkStrategy(result)) {
|
|
82
|
+
* // Re-trigger app opening if needed
|
|
83
|
+
* result.trigger();
|
|
84
|
+
* await result.credential;
|
|
66
85
|
* }
|
|
67
86
|
* ```
|
|
68
87
|
*/
|
|
@@ -70,14 +89,14 @@ export function isLinkStrategy(result) {
|
|
|
70
89
|
return result.strategy === 'link';
|
|
71
90
|
}
|
|
72
91
|
/**
|
|
73
|
-
* Type guard to check if
|
|
92
|
+
* Type guard to check if an ExtendedResponse is using the TS43 strategy.
|
|
74
93
|
* TS43 strategy uses the browser's Digital Credentials API.
|
|
75
94
|
*
|
|
76
95
|
* @example
|
|
77
96
|
* ```typescript
|
|
78
|
-
* if (
|
|
79
|
-
* //
|
|
80
|
-
*
|
|
97
|
+
* if (isExtendedResponse(result) && isTS43Strategy(result)) {
|
|
98
|
+
* // Re-trigger credential request if needed
|
|
99
|
+
* await result.trigger();
|
|
81
100
|
* }
|
|
82
101
|
* ```
|
|
83
102
|
*/
|
|
@@ -85,15 +104,15 @@ export function isTS43Strategy(result) {
|
|
|
85
104
|
return result.strategy === 'ts43';
|
|
86
105
|
}
|
|
87
106
|
/**
|
|
88
|
-
* Type guard to check if
|
|
107
|
+
* Type guard to check if an ExtendedResponse is using the Desktop strategy.
|
|
89
108
|
* Desktop strategy involves QR codes for cross-device authentication.
|
|
90
109
|
*
|
|
91
110
|
* @example
|
|
92
111
|
* ```typescript
|
|
93
|
-
* if (
|
|
112
|
+
* if (isExtendedResponse(result) && isDesktopStrategy(result)) {
|
|
94
113
|
* // Show custom QR code UI
|
|
95
|
-
* displayQRCode(result.
|
|
96
|
-
* await result.
|
|
114
|
+
* displayQRCode(result.qr_code_data);
|
|
115
|
+
* await result.start_polling();
|
|
97
116
|
* }
|
|
98
117
|
* ```
|
|
99
118
|
*/
|
|
@@ -102,7 +121,7 @@ export function isDesktopStrategy(result) {
|
|
|
102
121
|
}
|
|
103
122
|
/**
|
|
104
123
|
* Helper function to safely get the authentication strategy from any result.
|
|
105
|
-
* Returns undefined if the result is not
|
|
124
|
+
* Returns undefined if the result is not an ExtendedResponse.
|
|
106
125
|
*
|
|
107
126
|
* @example
|
|
108
127
|
* ```typescript
|
|
@@ -113,38 +132,54 @@ export function isDesktopStrategy(result) {
|
|
|
113
132
|
* ```
|
|
114
133
|
*/
|
|
115
134
|
export function getStrategy(result) {
|
|
116
|
-
if (
|
|
135
|
+
if (isExtendedResponse(result)) {
|
|
117
136
|
return result.strategy;
|
|
118
137
|
}
|
|
119
138
|
return undefined;
|
|
120
139
|
}
|
|
121
140
|
/**
|
|
122
|
-
* Helper function to determine if a result
|
|
123
|
-
* Link and Desktop strategies
|
|
141
|
+
* Helper function to determine if a result has polling controls.
|
|
142
|
+
* Link and Desktop strategies have polling controls in extended mode.
|
|
124
143
|
*
|
|
125
144
|
* @example
|
|
126
145
|
* ```typescript
|
|
127
|
-
* if (
|
|
128
|
-
* await result.
|
|
146
|
+
* if (hasPollingControls(result)) {
|
|
147
|
+
* await result.start_polling();
|
|
129
148
|
* }
|
|
130
149
|
* ```
|
|
131
150
|
*/
|
|
132
|
-
export function
|
|
133
|
-
if (!
|
|
151
|
+
export function hasPollingControls(result) {
|
|
152
|
+
if (!isExtendedResponse(result))
|
|
134
153
|
return false;
|
|
135
|
-
return result.strategy === 'link'
|
|
154
|
+
return (result.strategy === 'link' && 'start_polling' in result) ||
|
|
155
|
+
(result.strategy === 'desktop' && 'start_polling' in result);
|
|
136
156
|
}
|
|
137
157
|
/**
|
|
138
|
-
* Helper function to determine if a result
|
|
139
|
-
*
|
|
158
|
+
* Helper function to determine if a result has a trigger method.
|
|
159
|
+
* Link and TS43 strategies have trigger methods in extended mode.
|
|
140
160
|
*
|
|
141
161
|
* @example
|
|
142
162
|
* ```typescript
|
|
143
|
-
* if (
|
|
144
|
-
*
|
|
163
|
+
* if (hasTrigger(result)) {
|
|
164
|
+
* result.trigger();
|
|
145
165
|
* }
|
|
146
166
|
* ```
|
|
147
167
|
*/
|
|
148
|
-
export function
|
|
149
|
-
|
|
168
|
+
export function hasTrigger(result) {
|
|
169
|
+
if (!isExtendedResponse(result))
|
|
170
|
+
return false;
|
|
171
|
+
return 'trigger' in result && typeof result.trigger === 'function';
|
|
150
172
|
}
|
|
173
|
+
// Export legacy function names as deprecated aliases for backward compatibility
|
|
174
|
+
/**
|
|
175
|
+
* @deprecated Use isExtendedResponse instead
|
|
176
|
+
*/
|
|
177
|
+
export const isHeadlessResult = isExtendedResponse;
|
|
178
|
+
/**
|
|
179
|
+
* @deprecated Use hasPollingControls instead
|
|
180
|
+
*/
|
|
181
|
+
export const requiresPolling = hasPollingControls;
|
|
182
|
+
/**
|
|
183
|
+
* @deprecated This function is no longer needed as extended mode handles user actions differently
|
|
184
|
+
*/
|
|
185
|
+
export const requiresUserAction = (result) => false;
|
|
@@ -50,6 +50,11 @@ export class AuthModal {
|
|
|
50
50
|
*/
|
|
51
51
|
showQRCode(qrCodeData, statusMessage = 'Scan QR code with your phone') {
|
|
52
52
|
console.log('[Modal] showQRCode called with:', qrCodeData);
|
|
53
|
+
// If modal is already open, don't recreate it
|
|
54
|
+
if (this.isOpen) {
|
|
55
|
+
console.log('[Modal] Modal already open, skipping recreation');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
53
58
|
// Check if it's the new dual-platform format with VALID Android QR code
|
|
54
59
|
if (typeof qrCodeData === 'object' && qrCodeData.iosQRCode) {
|
|
55
60
|
const hasValidAndroidQR = qrCodeData.androidQRCode &&
|
|
@@ -59,6 +64,8 @@ export class AuthModal {
|
|
|
59
64
|
if (hasValidAndroidQR) {
|
|
60
65
|
console.log('[Modal] Using dual-platform modal');
|
|
61
66
|
this.createDualPlatformQRModal(qrCodeData, statusMessage);
|
|
67
|
+
// Note: createDualPlatformQRModal calls show() internally
|
|
68
|
+
return;
|
|
62
69
|
}
|
|
63
70
|
else {
|
|
64
71
|
console.log('[Modal] Android QR missing/empty, using single iOS QR');
|
|
@@ -119,6 +126,8 @@ export class AuthModal {
|
|
|
119
126
|
<p class="glide-auth-status" id="glide-platform-message">Scan with your iPhone to authenticate</p>
|
|
120
127
|
</div>
|
|
121
128
|
`);
|
|
129
|
+
// IMPORTANT: Call show() to actually display the modal!
|
|
130
|
+
this.show();
|
|
122
131
|
}
|
|
123
132
|
/**
|
|
124
133
|
* Sets a callback to be called when the modal is cancelled/closed
|
|
@@ -292,7 +301,11 @@ export class AuthModal {
|
|
|
292
301
|
// Add close button handler
|
|
293
302
|
const closeBtn = this.container.querySelector('.glide-auth-close');
|
|
294
303
|
if (closeBtn) {
|
|
295
|
-
closeBtn.addEventListener('click', () =>
|
|
304
|
+
closeBtn.addEventListener('click', () => {
|
|
305
|
+
var _a;
|
|
306
|
+
(_a = this.closeCallback) === null || _a === void 0 ? void 0 : _a.call(this); // Call cancellation callback if set
|
|
307
|
+
this.close();
|
|
308
|
+
});
|
|
296
309
|
}
|
|
297
310
|
// Add backdrop click handler
|
|
298
311
|
this.backdrop.addEventListener('click', (e) => {
|
package/dist/esm/core/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// SDK version - injected at build time
|
|
2
|
-
export const SDK_VERSION = '4.4.8-beta.
|
|
2
|
+
export const SDK_VERSION = '4.4.8-beta.2';
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { PhoneAuthClient } from './core/phone-auth';
|
|
2
2
|
export type { AuthConfig as PhoneAuthConfig, PhoneAuthOptions, PhoneAuthResult, AuthError as PhoneAuthError, AuthStep as PhoneAuthStep } from './core/phone-auth';
|
|
3
3
|
export { PhoneAuthErrorCode, isPhoneAuthError, isUserError, getUserMessage, isErrorCode, getRetryDelay, isRetryableError, serializeError, createErrorBreadcrumb } from './core/phone-auth';
|
|
4
|
-
export {
|
|
5
|
-
export type { PhoneAuthCallbacks, PLMN, SessionInfo,
|
|
4
|
+
export { isExtendedResponse, isCredential, isAuthCredential, isLinkStrategy, isTS43Strategy, isDesktopStrategy, getStrategy, hasPollingControls, hasTrigger, isHeadlessResult, requiresPolling, requiresUserAction } from './core/phone-auth';
|
|
5
|
+
export type { PhoneAuthCallbacks, PLMN, SessionInfo, InvokeOptions, ExecutionMode, AuthCredential, AnyExtendedResponse, DesktopExtendedResponse, LinkExtendedResponse, TS43ExtendedResponse, PrepareRequest, PrepareResponse, GetPhoneNumberRequest, GetPhoneNumberResponse, VerifyPhoneNumberRequest, VerifyPhoneNumberResponse, SecureCredentialRequest, SecureCredentialResponse, DigitalCredential, TS43Data, LinkData, DesktopData, ClientInfo, ConsentData, BrowserErrorType, BrowserErrorCodeType, BrowserNameType } from './core/phone-auth/types';
|
|
6
6
|
export { USE_CASE as UseCase, AUTHENTICATION_STRATEGY as AuthenticationStrategy, BrowserError, BrowserErrorCode, BrowserName } from './core/phone-auth/types';
|
|
7
7
|
export { DesktopHandler, showQRCodeModal, createQRCodeDisplay } from './core/phone-auth/strategies/desktop';
|
|
8
8
|
export type { DesktopAuthOptions, DesktopAuthResult, PollingStatus, QRCodeData } from './core/phone-auth/strategies/desktop';
|
package/dist/esm/index.js
CHANGED
|
@@ -3,7 +3,9 @@ export { PhoneAuthClient } from './core/phone-auth';
|
|
|
3
3
|
// Phone Auth Error Utilities
|
|
4
4
|
export { PhoneAuthErrorCode, isPhoneAuthError, isUserError, getUserMessage, isErrorCode, getRetryDelay, isRetryableError, serializeError, createErrorBreadcrumb } from './core/phone-auth';
|
|
5
5
|
// Phone Auth Type Guards and Helpers
|
|
6
|
-
export {
|
|
6
|
+
export { isExtendedResponse, isCredential, isAuthCredential, isLinkStrategy, isTS43Strategy, isDesktopStrategy, getStrategy, hasPollingControls, hasTrigger,
|
|
7
|
+
// Deprecated aliases
|
|
8
|
+
isHeadlessResult, requiresPolling, requiresUserAction } from './core/phone-auth';
|
|
7
9
|
// Export constants for use case and strategy
|
|
8
10
|
export { USE_CASE as UseCase, AUTHENTICATION_STRATEGY as AuthenticationStrategy, BrowserError, BrowserErrorCode, BrowserName } from './core/phone-auth/types';
|
|
9
11
|
// Desktop Strategy Exports
|