@glideidentity/web-client-sdk 5.1.3 → 6.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +337 -526
- package/dist/browser/web-client-sdk.min.js +1 -1
- package/dist/cjs/adapters/index.js +15 -0
- package/dist/cjs/adapters/react.js +192 -0
- package/dist/cjs/adapters/vanilla.js +38 -0
- package/dist/cjs/adapters/vue.js +187 -0
- package/dist/cjs/browser.js +58 -0
- package/dist/cjs/client/http.js +159 -0
- package/dist/cjs/client/index.js +19 -0
- package/dist/cjs/client/logger.js +135 -0
- package/dist/cjs/client/phone-auth-client.js +428 -0
- package/dist/cjs/client/strategies/polling.js +177 -0
- package/dist/cjs/core/errors.js +204 -0
- package/dist/cjs/core/index.js +83 -0
- package/dist/cjs/core/type-guards.js +196 -0
- package/dist/cjs/core/types.js +25 -0
- package/dist/{core/phone-auth/validation-utils.js → cjs/core/validators.js} +70 -23
- package/dist/cjs/index.js +81 -0
- package/dist/cjs/ui/index.js +11 -0
- package/dist/{core/phone-auth → cjs}/ui/mobile-debug-console.js +149 -78
- package/dist/cjs/ui/modal.js +1122 -0
- package/dist/esm/adapters/index.js +11 -0
- package/dist/esm/adapters/react.js +182 -0
- package/dist/esm/adapters/vanilla.js +29 -0
- package/dist/esm/adapters/vue.js +177 -0
- package/dist/esm/browser.js +30 -11
- package/dist/esm/client/http.js +156 -0
- package/dist/esm/client/index.js +11 -0
- package/dist/esm/client/logger.js +131 -0
- package/dist/esm/client/phone-auth-client.js +424 -0
- package/dist/esm/client/strategies/polling.js +174 -0
- package/dist/esm/core/errors.js +193 -0
- package/dist/esm/core/index.js +60 -0
- package/dist/esm/core/type-guards.js +181 -0
- package/dist/esm/core/types.js +22 -1
- package/dist/esm/core/{phone-auth/validation-utils.js → validators.js} +66 -21
- package/dist/esm/index.js +45 -17
- package/dist/esm/ui/index.js +5 -0
- package/dist/esm/{core/phone-auth/ui → ui}/mobile-debug-console.js +149 -78
- package/dist/esm/ui/modal.js +1117 -0
- package/dist/types/adapters/index.d.ts +10 -0
- package/dist/types/adapters/index.d.ts.map +1 -0
- package/dist/types/adapters/react.d.ts +70 -0
- package/dist/types/adapters/react.d.ts.map +1 -0
- package/dist/types/adapters/vanilla.d.ts +29 -0
- package/dist/types/adapters/vanilla.d.ts.map +1 -0
- package/dist/types/adapters/vue.d.ts +71 -0
- package/dist/types/adapters/vue.d.ts.map +1 -0
- package/dist/types/browser.d.ts +27 -0
- package/dist/types/browser.d.ts.map +1 -0
- package/dist/types/client/http.d.ts +41 -0
- package/dist/types/client/http.d.ts.map +1 -0
- package/dist/types/client/index.d.ts +10 -0
- package/dist/types/client/index.d.ts.map +1 -0
- package/dist/types/client/logger.d.ts +36 -0
- package/dist/types/client/logger.d.ts.map +1 -0
- package/dist/types/client/phone-auth-client.d.ts +91 -0
- package/dist/types/client/phone-auth-client.d.ts.map +1 -0
- package/dist/types/client/strategies/polling.d.ts +36 -0
- package/dist/types/client/strategies/polling.d.ts.map +1 -0
- package/dist/types/core/errors.d.ts +71 -0
- package/dist/types/core/errors.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +38 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/core/type-guards.d.ts +118 -0
- package/dist/types/core/type-guards.d.ts.map +1 -0
- package/dist/types/core/types.d.ts +535 -0
- package/dist/types/core/types.d.ts.map +1 -0
- package/dist/types/core/validators.d.ts +63 -0
- package/dist/types/core/validators.d.ts.map +1 -0
- package/dist/types/index.d.ts +40 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/ui/index.d.ts +6 -0
- package/dist/types/ui/index.d.ts.map +1 -0
- package/dist/{esm/core/phone-auth → types}/ui/mobile-debug-console.d.ts +1 -0
- package/dist/types/ui/mobile-debug-console.d.ts.map +1 -0
- package/dist/types/ui/modal.d.ts +87 -0
- package/dist/types/ui/modal.d.ts.map +1 -0
- package/package.json +48 -34
- package/dist/adapters/angular/client.service.d.ts +0 -7
- package/dist/adapters/angular/client.service.js +0 -30
- package/dist/adapters/angular/index.d.ts +0 -3
- package/dist/adapters/angular/index.js +0 -18
- package/dist/adapters/angular/phone-auth.service.d.ts +0 -38
- package/dist/adapters/angular/phone-auth.service.js +0 -130
- package/dist/adapters/react/index.d.ts +0 -9
- package/dist/adapters/react/index.js +0 -28
- package/dist/adapters/react/useClient.d.ts +0 -26
- package/dist/adapters/react/useClient.js +0 -121
- package/dist/adapters/react/usePhoneAuth.d.ts +0 -23
- package/dist/adapters/react/usePhoneAuth.js +0 -95
- package/dist/adapters/vanilla/client.d.ts +0 -8
- package/dist/adapters/vanilla/client.js +0 -33
- package/dist/adapters/vanilla/index.d.ts +0 -3
- package/dist/adapters/vanilla/index.js +0 -18
- package/dist/adapters/vanilla/phone-auth.d.ts +0 -46
- package/dist/adapters/vanilla/phone-auth.js +0 -138
- package/dist/adapters/vue/index.d.ts +0 -10
- package/dist/adapters/vue/index.js +0 -36
- package/dist/adapters/vue/useClient.d.ts +0 -115
- package/dist/adapters/vue/useClient.js +0 -131
- package/dist/adapters/vue/usePhoneAuth.d.ts +0 -94
- package/dist/adapters/vue/usePhoneAuth.js +0 -103
- package/dist/browser.d.ts +0 -7
- package/dist/browser.js +0 -31
- package/dist/core/client.d.ts +0 -22
- package/dist/core/client.js +0 -77
- package/dist/core/logger.d.ts +0 -130
- package/dist/core/logger.js +0 -370
- package/dist/core/phone-auth/api-types.d.ts +0 -593
- package/dist/core/phone-auth/api-types.js +0 -215
- package/dist/core/phone-auth/client.d.ts +0 -189
- package/dist/core/phone-auth/client.js +0 -1441
- package/dist/core/phone-auth/error-utils.d.ts +0 -110
- package/dist/core/phone-auth/error-utils.js +0 -350
- package/dist/core/phone-auth/index.d.ts +0 -7
- package/dist/core/phone-auth/index.js +0 -50
- package/dist/core/phone-auth/status-types.d.ts +0 -107
- package/dist/core/phone-auth/status-types.js +0 -31
- package/dist/core/phone-auth/strategies/desktop.d.ts +0 -122
- package/dist/core/phone-auth/strategies/desktop.js +0 -596
- package/dist/core/phone-auth/strategies/index.d.ts +0 -11
- package/dist/core/phone-auth/strategies/index.js +0 -15
- package/dist/core/phone-auth/strategies/link.d.ts +0 -89
- package/dist/core/phone-auth/strategies/link.js +0 -384
- package/dist/core/phone-auth/strategies/ts43.d.ts +0 -32
- package/dist/core/phone-auth/strategies/ts43.js +0 -161
- package/dist/core/phone-auth/strategies/types.d.ts +0 -18
- package/dist/core/phone-auth/strategies/types.js +0 -6
- package/dist/core/phone-auth/type-guards.d.ts +0 -143
- package/dist/core/phone-auth/type-guards.js +0 -198
- package/dist/core/phone-auth/types.d.ts +0 -237
- package/dist/core/phone-auth/types.js +0 -93
- package/dist/core/phone-auth/ui/mobile-debug-console.d.ts +0 -25
- package/dist/core/phone-auth/ui/modal.d.ts +0 -88
- package/dist/core/phone-auth/ui/modal.js +0 -598
- package/dist/core/phone-auth/validation-utils.d.ts +0 -44
- package/dist/core/types.d.ts +0 -62
- package/dist/core/types.js +0 -2
- package/dist/core/version.d.ts +0 -1
- package/dist/core/version.js +0 -5
- package/dist/esm/adapters/angular/client.service.d.ts +0 -7
- package/dist/esm/adapters/angular/client.service.js +0 -27
- package/dist/esm/adapters/angular/index.d.ts +0 -3
- package/dist/esm/adapters/angular/index.js +0 -4
- package/dist/esm/adapters/angular/phone-auth.service.d.ts +0 -38
- package/dist/esm/adapters/angular/phone-auth.service.js +0 -127
- package/dist/esm/adapters/react/index.d.ts +0 -9
- package/dist/esm/adapters/react/index.js +0 -8
- package/dist/esm/adapters/react/useClient.d.ts +0 -26
- package/dist/esm/adapters/react/useClient.js +0 -116
- package/dist/esm/adapters/react/usePhoneAuth.d.ts +0 -23
- package/dist/esm/adapters/react/usePhoneAuth.js +0 -92
- package/dist/esm/adapters/vanilla/client.d.ts +0 -8
- package/dist/esm/adapters/vanilla/client.js +0 -29
- package/dist/esm/adapters/vanilla/index.d.ts +0 -3
- package/dist/esm/adapters/vanilla/index.js +0 -4
- package/dist/esm/adapters/vanilla/phone-auth.d.ts +0 -46
- package/dist/esm/adapters/vanilla/phone-auth.js +0 -134
- package/dist/esm/adapters/vue/index.d.ts +0 -10
- package/dist/esm/adapters/vue/index.js +0 -11
- package/dist/esm/adapters/vue/useClient.d.ts +0 -115
- package/dist/esm/adapters/vue/useClient.js +0 -127
- package/dist/esm/adapters/vue/usePhoneAuth.d.ts +0 -94
- package/dist/esm/adapters/vue/usePhoneAuth.js +0 -100
- package/dist/esm/browser.d.ts +0 -7
- package/dist/esm/core/client.d.ts +0 -22
- package/dist/esm/core/client.js +0 -70
- package/dist/esm/core/logger.d.ts +0 -130
- package/dist/esm/core/logger.js +0 -359
- package/dist/esm/core/phone-auth/api-types.d.ts +0 -593
- package/dist/esm/core/phone-auth/api-types.js +0 -203
- package/dist/esm/core/phone-auth/client.d.ts +0 -189
- package/dist/esm/core/phone-auth/client.js +0 -1404
- package/dist/esm/core/phone-auth/error-utils.d.ts +0 -110
- package/dist/esm/core/phone-auth/error-utils.js +0 -338
- package/dist/esm/core/phone-auth/index.d.ts +0 -7
- package/dist/esm/core/phone-auth/index.js +0 -8
- package/dist/esm/core/phone-auth/status-types.d.ts +0 -107
- package/dist/esm/core/phone-auth/status-types.js +0 -26
- package/dist/esm/core/phone-auth/strategies/desktop.d.ts +0 -122
- package/dist/esm/core/phone-auth/strategies/desktop.js +0 -590
- package/dist/esm/core/phone-auth/strategies/index.d.ts +0 -11
- package/dist/esm/core/phone-auth/strategies/index.js +0 -7
- package/dist/esm/core/phone-auth/strategies/link.d.ts +0 -89
- package/dist/esm/core/phone-auth/strategies/link.js +0 -380
- package/dist/esm/core/phone-auth/strategies/ts43.d.ts +0 -32
- package/dist/esm/core/phone-auth/strategies/ts43.js +0 -157
- package/dist/esm/core/phone-auth/strategies/types.d.ts +0 -18
- package/dist/esm/core/phone-auth/strategies/types.js +0 -5
- package/dist/esm/core/phone-auth/type-guards.d.ts +0 -143
- package/dist/esm/core/phone-auth/type-guards.js +0 -185
- package/dist/esm/core/phone-auth/types.d.ts +0 -237
- package/dist/esm/core/phone-auth/types.js +0 -76
- package/dist/esm/core/phone-auth/ui/modal.d.ts +0 -88
- package/dist/esm/core/phone-auth/ui/modal.js +0 -594
- package/dist/esm/core/phone-auth/validation-utils.d.ts +0 -44
- package/dist/esm/core/types.d.ts +0 -62
- package/dist/esm/core/version.d.ts +0 -1
- package/dist/esm/core/version.js +0 -2
- package/dist/esm/index.d.ts +0 -12
- package/dist/index.d.ts +0 -12
- package/dist/index.js +0 -55
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Link Strategy Handler
|
|
3
|
-
* Handles authentication via app links (iOS and Android)
|
|
4
|
-
* Opens authentication app while keeping user on current page
|
|
5
|
-
*/
|
|
6
|
-
import type { StrategyHandler } from './types';
|
|
7
|
-
import type { PrepareResponse } from '../types';
|
|
8
|
-
export interface LinkAuthOptions {
|
|
9
|
-
/** Fixed polling interval in milliseconds (default: 2000) */
|
|
10
|
-
pollingInterval?: number;
|
|
11
|
-
/** Maximum polling attempts before timeout (default: 30 = 1 minute with 2s interval) */
|
|
12
|
-
maxPollingAttempts?: number;
|
|
13
|
-
/** Custom polling endpoint (overrides backend-provided or configured endpoint) */
|
|
14
|
-
pollingEndpoint?: string;
|
|
15
|
-
/** Developer environment (adds 'developer' header to requests) */
|
|
16
|
-
devEnv?: string;
|
|
17
|
-
/** Callback when link is opened */
|
|
18
|
-
onLinkOpened?: () => void;
|
|
19
|
-
/** Callback for polling status updates */
|
|
20
|
-
onStatusUpdate?: (status: PollingStatus) => void;
|
|
21
|
-
/** Callback when authentication times out */
|
|
22
|
-
onTimeout?: () => void;
|
|
23
|
-
/** Callback when authentication is cancelled by user */
|
|
24
|
-
onCancel?: () => void;
|
|
25
|
-
}
|
|
26
|
-
export interface PollingStatus {
|
|
27
|
-
/** Current status of the authentication */
|
|
28
|
-
status: 'pending' | 'authenticated' | 'expired' | 'cancelled' | 'error';
|
|
29
|
-
/** Optional message */
|
|
30
|
-
message?: string;
|
|
31
|
-
/** Authentication result data if status is 'authenticated' */
|
|
32
|
-
data?: any;
|
|
33
|
-
}
|
|
34
|
-
export interface LinkAuthResult {
|
|
35
|
-
/** Whether authentication was successful */
|
|
36
|
-
authenticated: boolean;
|
|
37
|
-
/** Authentication credential if successful */
|
|
38
|
-
credential?: string;
|
|
39
|
-
/** Session info for subsequent requests */
|
|
40
|
-
session?: any;
|
|
41
|
-
/** Error message if authentication failed */
|
|
42
|
-
error?: string;
|
|
43
|
-
}
|
|
44
|
-
export declare class LinkHandler implements StrategyHandler {
|
|
45
|
-
private pollingInterval?;
|
|
46
|
-
private isPollingActive;
|
|
47
|
-
private isCancelled;
|
|
48
|
-
private onCancel?;
|
|
49
|
-
private pollingReject?;
|
|
50
|
-
private isPollingInProgress;
|
|
51
|
-
/**
|
|
52
|
-
* Invoke link-based authentication
|
|
53
|
-
* Opens authentication app while keeping user on current page
|
|
54
|
-
*/
|
|
55
|
-
invoke(data: PrepareResponse, options?: LinkAuthOptions): Promise<LinkAuthResult>;
|
|
56
|
-
/**
|
|
57
|
-
* Open authentication link by navigating to the URL
|
|
58
|
-
*/
|
|
59
|
-
private openAuthenticationLink;
|
|
60
|
-
/**
|
|
61
|
-
* Start polling for authentication status with constant interval
|
|
62
|
-
*/
|
|
63
|
-
private startPolling;
|
|
64
|
-
/**
|
|
65
|
-
* Stop polling
|
|
66
|
-
*/
|
|
67
|
-
private stopPolling;
|
|
68
|
-
/**
|
|
69
|
-
* Format response for backend processing
|
|
70
|
-
*/
|
|
71
|
-
formatResponse(response: LinkAuthResult): any;
|
|
72
|
-
/**
|
|
73
|
-
* Check if link strategy is supported
|
|
74
|
-
* Returns true for mobile devices (iOS and Android)
|
|
75
|
-
*/
|
|
76
|
-
isSupported(): boolean;
|
|
77
|
-
/**
|
|
78
|
-
* Clean up resources (stop polling if active)
|
|
79
|
-
*/
|
|
80
|
-
cleanup(): void;
|
|
81
|
-
/**
|
|
82
|
-
* Check if polling is currently active
|
|
83
|
-
*/
|
|
84
|
-
isPolling(): boolean;
|
|
85
|
-
/**
|
|
86
|
-
* Cancel the ongoing authentication
|
|
87
|
-
*/
|
|
88
|
-
cancel(): void;
|
|
89
|
-
}
|
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Link Strategy Handler
|
|
3
|
-
* Handles authentication via app links (iOS and Android)
|
|
4
|
-
* Opens authentication app while keeping user on current page
|
|
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 LinkHandler {
|
|
16
|
-
constructor() {
|
|
17
|
-
this.isPollingActive = false;
|
|
18
|
-
this.isCancelled = false;
|
|
19
|
-
this.isPollingInProgress = false;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Invoke link-based authentication
|
|
23
|
-
* Opens authentication app while keeping user on current page
|
|
24
|
-
*/
|
|
25
|
-
invoke(data, options) {
|
|
26
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
-
console.log('[Link Auth] 🔗 invoke() called with data:', JSON.stringify(data, null, 2));
|
|
28
|
-
console.log('[Link Auth] Options:', options ? JSON.stringify({
|
|
29
|
-
pollingInterval: options.pollingInterval,
|
|
30
|
-
maxPollingAttempts: options.maxPollingAttempts,
|
|
31
|
-
pollingEndpoint: options.pollingEndpoint
|
|
32
|
-
}) : 'none');
|
|
33
|
-
// Extract link data from prepare response
|
|
34
|
-
const linkData = data.data;
|
|
35
|
-
if (!linkData || !linkData.url) {
|
|
36
|
-
throw new Error('Invalid link data: missing URL');
|
|
37
|
-
}
|
|
38
|
-
const sessionKey = data.session.session_key;
|
|
39
|
-
console.log('[Link Auth] Session key:', sessionKey);
|
|
40
|
-
console.log('[Link Auth] Link URL:', linkData.url);
|
|
41
|
-
// Open authentication app without navigating away from current page
|
|
42
|
-
this.openAuthenticationLink(linkData.url);
|
|
43
|
-
// Notify that link was opened
|
|
44
|
-
if (options === null || options === void 0 ? void 0 : options.onLinkOpened) {
|
|
45
|
-
options.onLinkOpened();
|
|
46
|
-
}
|
|
47
|
-
// Start polling for authentication status
|
|
48
|
-
// Use constant interval (no exponential backoff)
|
|
49
|
-
return this.startPolling(sessionKey, linkData, options);
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Open authentication link by navigating to the URL
|
|
54
|
-
*/
|
|
55
|
-
openAuthenticationLink(url) {
|
|
56
|
-
// Use location.href to navigate directly - required for App Clips to open properly
|
|
57
|
-
window.location.href = url;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Start polling for authentication status with constant interval
|
|
61
|
-
*/
|
|
62
|
-
startPolling(sessionKey, linkData, options) {
|
|
63
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
-
const interval = (options === null || options === void 0 ? void 0 : options.pollingInterval) || 2000; // Fixed 2 second interval
|
|
65
|
-
const maxAttempts = (options === null || options === void 0 ? void 0 : options.maxPollingAttempts) || 30; // 1 minute with 2s interval
|
|
66
|
-
let attempts = 0;
|
|
67
|
-
console.log('[Link Auth] 🚀 Starting polling:', {
|
|
68
|
-
sessionKey,
|
|
69
|
-
interval: `${interval}ms`,
|
|
70
|
-
maxAttempts,
|
|
71
|
-
linkDataAvailable: !!linkData
|
|
72
|
-
});
|
|
73
|
-
return new Promise((resolve, reject) => {
|
|
74
|
-
this.isPollingActive = true;
|
|
75
|
-
this.pollingReject = reject; // Store reject function for cancel()
|
|
76
|
-
const poll = () => __awaiter(this, void 0, void 0, function* () {
|
|
77
|
-
if (!this.isPollingActive) {
|
|
78
|
-
return; // Polling was stopped
|
|
79
|
-
}
|
|
80
|
-
// Skip if another poll is already in progress
|
|
81
|
-
if (this.isPollingInProgress) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
let statusUrl = ''; // Declare at function scope for catch block access
|
|
85
|
-
try {
|
|
86
|
-
this.isPollingInProgress = true;
|
|
87
|
-
// Check max attempts before making the request
|
|
88
|
-
if (attempts >= maxAttempts) {
|
|
89
|
-
this.stopPolling();
|
|
90
|
-
if (options === null || options === void 0 ? void 0 : options.onTimeout) {
|
|
91
|
-
options.onTimeout();
|
|
92
|
-
}
|
|
93
|
-
// Calculate actual timeout duration
|
|
94
|
-
const timeoutSeconds = Math.round((maxAttempts * interval) / 1000);
|
|
95
|
-
const timeoutMessage = timeoutSeconds >= 60
|
|
96
|
-
? `${Math.floor(timeoutSeconds / 60)} minute${Math.floor(timeoutSeconds / 60) > 1 ? 's' : ''}`
|
|
97
|
-
: `${timeoutSeconds} seconds`;
|
|
98
|
-
if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
|
|
99
|
-
options.onStatusUpdate({
|
|
100
|
-
status: 'expired',
|
|
101
|
-
message: `Authentication timeout after ${timeoutMessage}`
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
reject(new Error(`Authentication timeout after ${timeoutMessage}`));
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
// Build public status endpoint URL
|
|
108
|
-
// Use the same priority logic as Desktop strategy:
|
|
109
|
-
// 1. options?.pollingEndpoint (already contains invoke options OR client config from client.ts)
|
|
110
|
-
// 2. Backend-provided status_url from linkData
|
|
111
|
-
// 3. Hardcoded fallback to API server
|
|
112
|
-
let endpoint = options === null || options === void 0 ? void 0 : options.pollingEndpoint;
|
|
113
|
-
let endpointSource = 'options';
|
|
114
|
-
if (!endpoint && linkData.status_url) {
|
|
115
|
-
endpoint = linkData.status_url;
|
|
116
|
-
endpointSource = 'backend';
|
|
117
|
-
}
|
|
118
|
-
console.log('[Link Auth] Polling endpoint selection:');
|
|
119
|
-
console.log(' - options?.pollingEndpoint:', options === null || options === void 0 ? void 0 : options.pollingEndpoint);
|
|
120
|
-
console.log(' - linkData.status_url:', linkData.status_url);
|
|
121
|
-
console.log(' - selected endpoint:', endpoint, 'from source:', endpointSource);
|
|
122
|
-
// Build the status URL based on endpoint format (same as Desktop)
|
|
123
|
-
if (endpoint && (endpoint.startsWith('http://') || endpoint.startsWith('https://'))) {
|
|
124
|
-
// Full URL provided
|
|
125
|
-
statusUrl = endpoint;
|
|
126
|
-
}
|
|
127
|
-
else if (endpoint && endpoint !== '') {
|
|
128
|
-
// Relative path provided (e.g. '/api/phone-auth/status')
|
|
129
|
-
const origin = typeof window !== 'undefined' ? window.location.origin : '';
|
|
130
|
-
if (endpoint.includes('{{session_id}}')) {
|
|
131
|
-
statusUrl = origin + endpoint.replace('{{session_id}}', sessionKey);
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
// Append session ID to the provided endpoint
|
|
135
|
-
statusUrl = origin + endpoint + '/' + sessionKey;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
// No endpoint provided - use hardcoded fallback
|
|
140
|
-
statusUrl = `https://api.glideidentity.app/public/status/${sessionKey}`;
|
|
141
|
-
endpointSource = 'fallback';
|
|
142
|
-
}
|
|
143
|
-
console.log(`[Link Auth] Using ${endpointSource} endpoint: ${statusUrl}`);
|
|
144
|
-
// Poll public status endpoint - no authentication required
|
|
145
|
-
console.log(`[Link Auth] Polling status (attempt ${attempts}/${maxAttempts}): ${statusUrl}`);
|
|
146
|
-
// Build headers
|
|
147
|
-
const headers = {
|
|
148
|
-
'Accept': 'application/json'
|
|
149
|
-
};
|
|
150
|
-
// Add developer header if devEnv is set
|
|
151
|
-
if (options === null || options === void 0 ? void 0 : options.devEnv) {
|
|
152
|
-
headers['developer'] = options.devEnv;
|
|
153
|
-
console.log(`[Link Auth] Adding developer header: ${options.devEnv}`);
|
|
154
|
-
}
|
|
155
|
-
const response = yield fetch(statusUrl, {
|
|
156
|
-
method: 'GET',
|
|
157
|
-
headers
|
|
158
|
-
});
|
|
159
|
-
console.log(`[Link Auth] Poll response - Status: ${response.status}, OK: ${response.ok}`);
|
|
160
|
-
// Handle based on HTTP status code
|
|
161
|
-
if (response.status === 200) {
|
|
162
|
-
// Session is active (pending or completed)
|
|
163
|
-
const result = yield response.json();
|
|
164
|
-
console.log('[Link Auth] Poll response data:', JSON.stringify(result, null, 2));
|
|
165
|
-
if (result.status === 'completed') {
|
|
166
|
-
// Authentication completed successfully
|
|
167
|
-
console.log('[Link Auth] ✅ Authentication COMPLETED! Session:', sessionKey);
|
|
168
|
-
console.log('[Link Auth] Full completion result:', JSON.stringify(result, null, 2));
|
|
169
|
-
this.stopPolling();
|
|
170
|
-
// Authentication completed successfully
|
|
171
|
-
if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
|
|
172
|
-
options.onStatusUpdate({
|
|
173
|
-
status: 'authenticated',
|
|
174
|
-
message: 'Authentication successful',
|
|
175
|
-
data: result
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
// Return the authentication result
|
|
179
|
-
this.pollingReject = undefined; // Clear reject function on success
|
|
180
|
-
resolve({
|
|
181
|
-
authenticated: true,
|
|
182
|
-
credential: result.credential || sessionKey,
|
|
183
|
-
session: result.session || {
|
|
184
|
-
session_key: sessionKey,
|
|
185
|
-
status: result.status,
|
|
186
|
-
protocol: result.protocol || 'link',
|
|
187
|
-
created_at: result.created_at,
|
|
188
|
-
last_updated: result.last_updated
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
else if (result.status === 'pending') {
|
|
193
|
-
// Continue polling
|
|
194
|
-
console.log('[Link Auth] Status still pending, continuing to poll...');
|
|
195
|
-
attempts++; // Increment attempts after successful poll
|
|
196
|
-
if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
|
|
197
|
-
options.onStatusUpdate({
|
|
198
|
-
status: 'pending',
|
|
199
|
-
message: 'Waiting for app authentication...'
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
else {
|
|
204
|
-
// Unexpected status value
|
|
205
|
-
console.log('[Link Auth] ⚠️ Unexpected status value:', result.status, 'Full result:', JSON.stringify(result, null, 2));
|
|
206
|
-
attempts++; // Increment for unexpected status too
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
else if (response.status === 410) {
|
|
210
|
-
// Session expired
|
|
211
|
-
console.log('[Link Auth] ❌ Session expired (410)');
|
|
212
|
-
this.stopPolling();
|
|
213
|
-
const errorData = yield response.json().catch(() => ({ message: 'Session expired' }));
|
|
214
|
-
if (options === null || options === void 0 ? void 0 : options.onTimeout) {
|
|
215
|
-
options.onTimeout();
|
|
216
|
-
}
|
|
217
|
-
if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
|
|
218
|
-
options.onStatusUpdate({
|
|
219
|
-
status: 'expired',
|
|
220
|
-
message: errorData.message || 'Session expired'
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
reject(new Error(errorData.message || 'Session expired'));
|
|
224
|
-
}
|
|
225
|
-
else if (response.status === 422) {
|
|
226
|
-
// Authentication failed
|
|
227
|
-
console.log('[Link Auth] ❌ Authentication failed (422)');
|
|
228
|
-
this.stopPolling();
|
|
229
|
-
const errorData = yield response.json().catch(() => ({ message: 'Authentication failed' }));
|
|
230
|
-
console.log('[Link Auth] Error data:', JSON.stringify(errorData, null, 2));
|
|
231
|
-
const isUserCancelled = errorData.code === 'USER_CANCELLED';
|
|
232
|
-
const errorMsg = isUserCancelled
|
|
233
|
-
? 'User cancelled authentication'
|
|
234
|
-
: (errorData.message || 'Verification failed');
|
|
235
|
-
// Authentication failed
|
|
236
|
-
if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
|
|
237
|
-
options.onStatusUpdate({
|
|
238
|
-
status: 'error',
|
|
239
|
-
message: errorMsg
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
reject(new Error(errorMsg));
|
|
243
|
-
}
|
|
244
|
-
else if (response.status === 404) {
|
|
245
|
-
// Session not found
|
|
246
|
-
console.log('[Link Auth] ❌ Session not found (404)');
|
|
247
|
-
this.stopPolling();
|
|
248
|
-
if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
|
|
249
|
-
options.onStatusUpdate({
|
|
250
|
-
status: 'error',
|
|
251
|
-
message: 'Session not found'
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
reject(new Error('Session not found'));
|
|
255
|
-
}
|
|
256
|
-
else if (response.status === 400) {
|
|
257
|
-
// Invalid session key
|
|
258
|
-
console.log('[Link Auth] ❌ Invalid session key (400)');
|
|
259
|
-
this.stopPolling();
|
|
260
|
-
const errorData = yield response.json().catch(() => ({ message: 'Invalid session key' }));
|
|
261
|
-
console.log('[Link Auth] Error data:', JSON.stringify(errorData, null, 2));
|
|
262
|
-
reject(new Error(errorData.message || 'Invalid session key'));
|
|
263
|
-
}
|
|
264
|
-
else {
|
|
265
|
-
// Unexpected status - continue polling
|
|
266
|
-
console.log('[Link Auth] ⚠️ Unexpected HTTP status:', response.status, 'continuing to poll...');
|
|
267
|
-
attempts++; // Increment for unexpected HTTP status
|
|
268
|
-
try {
|
|
269
|
-
const body = yield response.text();
|
|
270
|
-
console.log('[Link Auth] Response body:', body);
|
|
271
|
-
}
|
|
272
|
-
catch (e) {
|
|
273
|
-
console.log('[Link Auth] Could not read response body');
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
catch (error) {
|
|
278
|
-
// Network or other error - continue polling
|
|
279
|
-
console.error('[Link Auth] 🔴 Polling error:', error.message || error);
|
|
280
|
-
attempts++; // Increment for error case
|
|
281
|
-
console.error('[Link Auth] Error details:', {
|
|
282
|
-
name: error.name,
|
|
283
|
-
message: error.message,
|
|
284
|
-
stack: error.stack,
|
|
285
|
-
statusUrl: statusUrl,
|
|
286
|
-
attempt: attempts,
|
|
287
|
-
error: error
|
|
288
|
-
});
|
|
289
|
-
// Check if it's a CORS error (common on mobile)
|
|
290
|
-
if (error.message && error.message.toLowerCase().includes('failed')) {
|
|
291
|
-
console.error('[Link Auth] ⚠️ Possible CORS issue. Status URL:', statusUrl);
|
|
292
|
-
console.error('[Link Auth] Make sure the API endpoint allows CORS from your ngrok domain');
|
|
293
|
-
}
|
|
294
|
-
if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
|
|
295
|
-
options.onStatusUpdate({
|
|
296
|
-
status: 'pending',
|
|
297
|
-
message: `Connection issue, retrying... (${attempts}/${maxAttempts})`
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
finally {
|
|
302
|
-
// Always clear the polling flag when done
|
|
303
|
-
this.isPollingInProgress = false;
|
|
304
|
-
}
|
|
305
|
-
});
|
|
306
|
-
// Start initial poll immediately
|
|
307
|
-
poll();
|
|
308
|
-
// Set up constant interval polling (no backoff)
|
|
309
|
-
this.pollingInterval = setInterval(poll, interval);
|
|
310
|
-
});
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Stop polling
|
|
315
|
-
*/
|
|
316
|
-
stopPolling() {
|
|
317
|
-
console.log('[Link Auth] 🏁 Stopping polling');
|
|
318
|
-
this.isPollingActive = false;
|
|
319
|
-
this.isPollingInProgress = false;
|
|
320
|
-
if (this.pollingInterval) {
|
|
321
|
-
clearInterval(this.pollingInterval);
|
|
322
|
-
this.pollingInterval = undefined;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Format response for backend processing
|
|
327
|
-
*/
|
|
328
|
-
formatResponse(response) {
|
|
329
|
-
if (!response.authenticated || !response.credential) {
|
|
330
|
-
throw new Error('Authentication not completed');
|
|
331
|
-
}
|
|
332
|
-
return {
|
|
333
|
-
credential: response.credential,
|
|
334
|
-
session: response.session,
|
|
335
|
-
type: 'link'
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Check if link strategy is supported
|
|
340
|
-
* Returns true for mobile devices (iOS and Android)
|
|
341
|
-
*/
|
|
342
|
-
isSupported() {
|
|
343
|
-
// Link strategy is supported on mobile devices
|
|
344
|
-
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
|
|
345
|
-
return isMobile;
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Clean up resources (stop polling if active)
|
|
349
|
-
*/
|
|
350
|
-
cleanup() {
|
|
351
|
-
this.stopPolling();
|
|
352
|
-
this.isCancelled = false;
|
|
353
|
-
this.onCancel = undefined;
|
|
354
|
-
this.pollingReject = undefined;
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* Check if polling is currently active
|
|
358
|
-
*/
|
|
359
|
-
isPolling() {
|
|
360
|
-
return this.pollingInterval !== undefined;
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Cancel the ongoing authentication
|
|
364
|
-
*/
|
|
365
|
-
cancel() {
|
|
366
|
-
var _a;
|
|
367
|
-
console.log('[Link Auth] Cancelling authentication');
|
|
368
|
-
this.isCancelled = true;
|
|
369
|
-
this.stopPolling();
|
|
370
|
-
(_a = this.onCancel) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
371
|
-
// Immediately reject the polling promise
|
|
372
|
-
if (this.pollingReject) {
|
|
373
|
-
this.pollingReject({
|
|
374
|
-
code: 'USER_DENIED',
|
|
375
|
-
message: 'Authentication cancelled by user'
|
|
376
|
-
});
|
|
377
|
-
this.pollingReject = undefined;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TS-43 Strategy Handler
|
|
3
|
-
* Handles Digital Credentials API authentication for Android/Chromium
|
|
4
|
-
* Properly manages session objects with session_key and nonce
|
|
5
|
-
*/
|
|
6
|
-
import type { StrategyHandler } from './types';
|
|
7
|
-
import type { PrepareResponse } from '../types';
|
|
8
|
-
export declare class TS43Handler implements StrategyHandler {
|
|
9
|
-
/**
|
|
10
|
-
* Invoke TS-43 authentication using Digital Credentials API
|
|
11
|
-
* The data structure from backend is already in the correct format for navigator.credentials.get
|
|
12
|
-
*/
|
|
13
|
-
invoke(data: PrepareResponse): Promise<any>;
|
|
14
|
-
/**
|
|
15
|
-
* Format the credential response for backend processing
|
|
16
|
-
* Include the session key so backend can retrieve the full session
|
|
17
|
-
*/
|
|
18
|
-
formatResponse(response: any): any;
|
|
19
|
-
/**
|
|
20
|
-
* Check if Digital Credentials API is supported
|
|
21
|
-
*/
|
|
22
|
-
isSupported(): boolean;
|
|
23
|
-
/**
|
|
24
|
-
* Get browser support information
|
|
25
|
-
*/
|
|
26
|
-
getBrowserSupportInfo(): {
|
|
27
|
-
supported: boolean;
|
|
28
|
-
browser: string;
|
|
29
|
-
message?: string;
|
|
30
|
-
helpUrl?: string;
|
|
31
|
-
};
|
|
32
|
-
}
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TS-43 Strategy Handler
|
|
3
|
-
* Handles Digital Credentials API authentication for Android/Chromium
|
|
4
|
-
* Properly manages session objects with session_key and nonce
|
|
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 TS43Handler {
|
|
16
|
-
/**
|
|
17
|
-
* Invoke TS-43 authentication using Digital Credentials API
|
|
18
|
-
* The data structure from backend is already in the correct format for navigator.credentials.get
|
|
19
|
-
*/
|
|
20
|
-
invoke(data) {
|
|
21
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
-
// Validate session structure - only session_key is actually required
|
|
23
|
-
if (!data.session || !data.session.session_key) {
|
|
24
|
-
throw new Error('Invalid TS43 session: missing required session_key');
|
|
25
|
-
}
|
|
26
|
-
// Check if Digital Credentials API is available
|
|
27
|
-
if (!this.isSupported()) {
|
|
28
|
-
throw new Error('Digital Credentials API not supported in this browser');
|
|
29
|
-
}
|
|
30
|
-
// Extract TS43 data from the prepare response
|
|
31
|
-
const ts43Data = data.data;
|
|
32
|
-
// The data is already in the correct format from backend
|
|
33
|
-
// Just pass it through to navigator.credentials.get
|
|
34
|
-
const credentialRequest = {
|
|
35
|
-
digital: {
|
|
36
|
-
requests: [{
|
|
37
|
-
protocol: ts43Data.protocol, // e.g., "openid4vp-v1-unsigned"
|
|
38
|
-
data: ts43Data.data // Pass the entire data object as-is
|
|
39
|
-
}]
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
try {
|
|
43
|
-
// @ts-ignore - Digital Credentials API types not yet in TypeScript
|
|
44
|
-
const credential = yield navigator.credentials.get(credentialRequest);
|
|
45
|
-
if (!credential) {
|
|
46
|
-
throw new Error('No credential received from Digital Credentials API');
|
|
47
|
-
}
|
|
48
|
-
// Success vibration (haptic feedback)
|
|
49
|
-
if (typeof navigator !== 'undefined' && navigator.vibrate) {
|
|
50
|
-
// Add a small delay to ensure the browser has regained focus/visibility
|
|
51
|
-
// after the native bottom sheet closes
|
|
52
|
-
setTimeout(() => {
|
|
53
|
-
try {
|
|
54
|
-
// Double tap pattern: vibrate 80ms, pause 50ms, vibrate 80ms
|
|
55
|
-
// Slightly longer duration (80ms vs 50ms) ensures it registers on more devices
|
|
56
|
-
navigator.vibrate([80, 50, 80]);
|
|
57
|
-
}
|
|
58
|
-
catch (e) {
|
|
59
|
-
// Ignore vibration errors
|
|
60
|
-
}
|
|
61
|
-
}, 200);
|
|
62
|
-
}
|
|
63
|
-
// @ts-ignore - credential.data is not typed yet
|
|
64
|
-
return credential;
|
|
65
|
-
}
|
|
66
|
-
catch (error) {
|
|
67
|
-
// Handle browser-specific errors
|
|
68
|
-
if (error instanceof Error) {
|
|
69
|
-
if (error.name === 'NotAllowedError') {
|
|
70
|
-
throw new Error('User denied the authentication request');
|
|
71
|
-
}
|
|
72
|
-
if (error.name === 'NotSupportedError') {
|
|
73
|
-
throw new Error('Digital Credentials API not supported');
|
|
74
|
-
}
|
|
75
|
-
if (error.name === 'AbortError') {
|
|
76
|
-
throw new Error('Authentication was aborted');
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
throw error;
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Format the credential response for backend processing
|
|
85
|
-
* Include the session key so backend can retrieve the full session
|
|
86
|
-
*/
|
|
87
|
-
formatResponse(response) {
|
|
88
|
-
var _a;
|
|
89
|
-
// Extract vp_token from the response
|
|
90
|
-
const vpToken = (_a = response.data) === null || _a === void 0 ? void 0 : _a.vp_token;
|
|
91
|
-
if (!vpToken) {
|
|
92
|
-
throw new Error('Invalid TS43 response: missing vp_token');
|
|
93
|
-
}
|
|
94
|
-
return {
|
|
95
|
-
vp_token: vpToken,
|
|
96
|
-
type: 'ts43'
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Check if Digital Credentials API is supported
|
|
101
|
-
*/
|
|
102
|
-
isSupported() {
|
|
103
|
-
if (typeof window === 'undefined') {
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
// Check for DigitalCredential constructor
|
|
107
|
-
// @ts-ignore - DigitalCredential not yet in TypeScript
|
|
108
|
-
return 'DigitalCredential' in window;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Get browser support information
|
|
112
|
-
*/
|
|
113
|
-
getBrowserSupportInfo() {
|
|
114
|
-
if (typeof window === 'undefined') {
|
|
115
|
-
return {
|
|
116
|
-
supported: false,
|
|
117
|
-
browser: 'unknown',
|
|
118
|
-
message: 'Not running in a browser environment'
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
const userAgent = navigator.userAgent;
|
|
122
|
-
const isChrome = /Chrome/.test(userAgent) && /Google Inc/.test(navigator.vendor);
|
|
123
|
-
const isEdge = /Edg\//.test(userAgent);
|
|
124
|
-
const isAndroid = /Android/.test(userAgent);
|
|
125
|
-
const isSupported = this.isSupported();
|
|
126
|
-
if (isSupported) {
|
|
127
|
-
return {
|
|
128
|
-
supported: true,
|
|
129
|
-
browser: isChrome ? 'Chrome' : isEdge ? 'Edge' : 'Chromium'
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
// Provide specific guidance based on browser
|
|
133
|
-
if ((isChrome || isEdge) && isAndroid) {
|
|
134
|
-
return {
|
|
135
|
-
supported: false,
|
|
136
|
-
browser: isChrome ? 'Chrome' : 'Edge',
|
|
137
|
-
message: 'Digital Credentials API requires Chrome 128+ on Android. Please update your browser.',
|
|
138
|
-
helpUrl: 'https://play.google.com/store/apps/details?id=com.android.chrome'
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
if (isChrome || isEdge) {
|
|
142
|
-
return {
|
|
143
|
-
supported: false,
|
|
144
|
-
browser: isChrome ? 'Chrome' : 'Edge',
|
|
145
|
-
message: 'Digital Credentials API is not enabled. Please enable the #web-identity-digital-credentials flag.',
|
|
146
|
-
helpUrl: isChrome
|
|
147
|
-
? 'chrome://flags/#web-identity-digital-credentials'
|
|
148
|
-
: 'edge://flags/#web-identity-digital-credentials'
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
return {
|
|
152
|
-
supported: false,
|
|
153
|
-
browser: 'unsupported',
|
|
154
|
-
message: 'Your browser does not support Digital Credentials API'
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Strategy Handler Interface
|
|
3
|
-
* Defines the contract for authentication strategy implementations
|
|
4
|
-
*/
|
|
5
|
-
export interface StrategyHandler {
|
|
6
|
-
/**
|
|
7
|
-
* Invoke authentication using strategy-specific data
|
|
8
|
-
*/
|
|
9
|
-
invoke(data: any): Promise<any>;
|
|
10
|
-
/**
|
|
11
|
-
* Format response for backend processing
|
|
12
|
-
*/
|
|
13
|
-
formatResponse(response: any): any;
|
|
14
|
-
/**
|
|
15
|
-
* Check if this strategy is supported in the current environment
|
|
16
|
-
*/
|
|
17
|
-
isSupported(): boolean;
|
|
18
|
-
}
|