@glideidentity/web-client-sdk 5.0.1 → 5.1.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -108
- package/dist/adapters/angular/index.js +1 -0
- package/dist/adapters/angular/phone-auth.service.d.ts +18 -0
- package/dist/adapters/angular/phone-auth.service.js +26 -0
- package/dist/adapters/react/index.js +3 -0
- package/dist/adapters/react/useClient.js +1 -0
- package/dist/adapters/react/usePhoneAuth.js +16 -1
- package/dist/adapters/vanilla/client.js +1 -0
- package/dist/adapters/vanilla/index.js +1 -0
- package/dist/adapters/vanilla/phone-auth.js +31 -0
- package/dist/adapters/vue/index.js +4 -0
- package/dist/adapters/vue/useClient.js +5 -0
- package/dist/adapters/vue/usePhoneAuth.js +20 -1
- package/dist/browser/web-client-sdk.min.js +1 -2
- package/dist/browser.js +6 -0
- package/dist/core/client.js +12 -0
- package/dist/core/logger.js +81 -1
- package/dist/core/phone-auth/api-types.d.ts +1 -4
- package/dist/core/phone-auth/api-types.js +83 -0
- package/dist/core/phone-auth/client.js +374 -38
- package/dist/core/phone-auth/error-utils.js +83 -1
- package/dist/core/phone-auth/index.d.ts +1 -1
- package/dist/core/phone-auth/index.js +2 -2
- package/dist/core/phone-auth/status-types.d.ts +78 -0
- package/dist/core/phone-auth/status-types.js +17 -0
- package/dist/core/phone-auth/strategies/desktop.d.ts +2 -0
- package/dist/core/phone-auth/strategies/desktop.js +136 -13
- package/dist/core/phone-auth/strategies/index.d.ts +4 -0
- package/dist/core/phone-auth/strategies/index.js +4 -0
- package/dist/core/phone-auth/strategies/link.d.ts +2 -0
- package/dist/core/phone-auth/strategies/link.js +97 -13
- package/dist/core/phone-auth/strategies/ts43.d.ts +19 -0
- package/dist/core/phone-auth/strategies/ts43.js +33 -2
- package/dist/core/phone-auth/strategies/types.js +4 -0
- package/dist/core/phone-auth/type-guards.js +131 -0
- package/dist/core/phone-auth/types.d.ts +5 -0
- package/dist/core/phone-auth/types.js +32 -0
- package/dist/core/phone-auth/ui/mobile-debug-console.js +28 -2
- package/dist/core/phone-auth/ui/modal.d.ts +55 -33
- package/dist/core/phone-auth/ui/modal.js +422 -889
- package/dist/core/phone-auth/validation-utils.d.ts +0 -9
- package/dist/core/phone-auth/validation-utils.js +34 -25
- package/dist/core/version.js +2 -1
- package/dist/esm/adapters/angular/index.js +1 -0
- package/dist/esm/adapters/angular/phone-auth.service.d.ts +18 -0
- package/dist/esm/adapters/angular/phone-auth.service.js +26 -0
- package/dist/esm/adapters/react/index.js +3 -0
- package/dist/esm/adapters/react/useClient.js +1 -0
- package/dist/esm/adapters/react/usePhoneAuth.js +16 -1
- package/dist/esm/adapters/vanilla/client.js +1 -0
- package/dist/esm/adapters/vanilla/index.js +1 -0
- package/dist/esm/adapters/vanilla/phone-auth.d.ts +24 -0
- package/dist/esm/adapters/vanilla/phone-auth.js +31 -0
- package/dist/esm/adapters/vue/index.js +4 -0
- package/dist/esm/adapters/vue/useClient.js +5 -0
- package/dist/esm/adapters/vue/usePhoneAuth.js +20 -1
- package/dist/esm/browser.js +6 -0
- package/dist/esm/core/client.d.ts +10 -0
- package/dist/esm/core/client.js +12 -0
- package/dist/esm/core/logger.d.ts +53 -0
- package/dist/esm/core/logger.js +81 -1
- package/dist/esm/core/phone-auth/api-types.d.ts +313 -1
- package/dist/esm/core/phone-auth/api-types.js +83 -0
- package/dist/esm/core/phone-auth/client.d.ts +144 -0
- package/dist/esm/core/phone-auth/client.js +375 -39
- package/dist/esm/core/phone-auth/error-utils.d.ts +29 -0
- package/dist/esm/core/phone-auth/error-utils.js +83 -1
- package/dist/esm/core/phone-auth/index.d.ts +1 -1
- package/dist/esm/core/phone-auth/index.js +4 -2
- package/dist/esm/core/phone-auth/status-types.d.ts +78 -0
- package/dist/esm/core/phone-auth/status-types.js +17 -0
- package/dist/esm/core/phone-auth/strategies/desktop.d.ts +65 -0
- package/dist/esm/core/phone-auth/strategies/desktop.js +136 -13
- package/dist/esm/core/phone-auth/strategies/index.d.ts +4 -0
- package/dist/esm/core/phone-auth/strategies/index.js +4 -0
- package/dist/esm/core/phone-auth/strategies/link.d.ts +50 -0
- package/dist/esm/core/phone-auth/strategies/link.js +97 -13
- package/dist/esm/core/phone-auth/strategies/ts43.d.ts +19 -0
- package/dist/esm/core/phone-auth/strategies/ts43.js +33 -2
- package/dist/esm/core/phone-auth/strategies/types.d.ts +13 -0
- package/dist/esm/core/phone-auth/strategies/types.js +4 -0
- package/dist/esm/core/phone-auth/type-guards.d.ts +128 -0
- package/dist/esm/core/phone-auth/type-guards.js +131 -0
- package/dist/esm/core/phone-auth/types.d.ts +113 -0
- package/dist/esm/core/phone-auth/types.js +32 -0
- package/dist/esm/core/phone-auth/ui/mobile-debug-console.d.ts +4 -0
- package/dist/esm/core/phone-auth/ui/mobile-debug-console.js +28 -2
- package/dist/esm/core/phone-auth/ui/modal.d.ts +68 -27
- package/dist/esm/core/phone-auth/ui/modal.js +422 -889
- package/dist/esm/core/phone-auth/validation-utils.d.ts +26 -4
- package/dist/esm/core/phone-auth/validation-utils.js +34 -24
- package/dist/esm/core/types.d.ts +35 -0
- package/dist/esm/core/version.js +2 -1
- package/dist/esm/index.js +9 -1
- package/dist/index.js +7 -0
- package/package.json +1 -1
- package/dist/browser/web-client-sdk.min.js.LICENSE.txt +0 -1
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type Guards and Helper Functions for Phone Authentication
|
|
3
|
+
*
|
|
4
|
+
* These utilities help developers work with the SDK responses in a type-safe way
|
|
5
|
+
* without having to write their own type checking logic.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Type guard to check if the result is an ExtendedResponse (extended mode)
|
|
9
|
+
* or a Credential (standard mode).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const result = await invokeSecurePrompt(sdkRequest, { executionMode: 'extended' });
|
|
14
|
+
*
|
|
15
|
+
* if (isExtendedResponse(result)) {
|
|
16
|
+
* // TypeScript knows this is ExtendedResponse
|
|
17
|
+
* console.log(result.strategy);
|
|
18
|
+
* await result.cancel();
|
|
19
|
+
* } else {
|
|
20
|
+
* // TypeScript knows this is a Credential
|
|
21
|
+
* const processedResult = await verifyPhoneNumberCredential(result, session);
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
1
25
|
export function isExtendedResponse(result) {
|
|
2
26
|
return result &&
|
|
3
27
|
typeof result === 'object' &&
|
|
@@ -6,16 +30,41 @@ export function isExtendedResponse(result) {
|
|
|
6
30
|
'cancel' in result &&
|
|
7
31
|
typeof result.cancel === 'function';
|
|
8
32
|
}
|
|
33
|
+
/**
|
|
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.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* if (isCredential(result)) {
|
|
40
|
+
* // Process the credential directly
|
|
41
|
+
* const verified = await verifyPhoneNumberCredential(result, session);
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
9
45
|
export function isCredential(result) {
|
|
10
46
|
if (!result)
|
|
11
47
|
return false;
|
|
48
|
+
// String credentials are valid
|
|
12
49
|
if (typeof result === 'string')
|
|
13
50
|
return true;
|
|
51
|
+
// Object credentials should NOT have ExtendedResponse properties
|
|
14
52
|
if (typeof result === 'object') {
|
|
15
53
|
return !('strategy' in result) && !('credential' in result) && !('cancel' in result);
|
|
16
54
|
}
|
|
17
55
|
return false;
|
|
18
56
|
}
|
|
57
|
+
/**
|
|
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
|
+
*/
|
|
19
68
|
export function isAuthCredential(result) {
|
|
20
69
|
return result &&
|
|
21
70
|
typeof result === 'object' &&
|
|
@@ -23,32 +72,114 @@ export function isAuthCredential(result) {
|
|
|
23
72
|
'authenticated' in result &&
|
|
24
73
|
'session' in result;
|
|
25
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Type guard to check if an ExtendedResponse is using the Link strategy.
|
|
77
|
+
* Link strategy involves opening an app link (App Clip on iOS, app on Android).
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* if (isExtendedResponse(result) && isLinkStrategy(result)) {
|
|
82
|
+
* // Re-trigger app opening if needed
|
|
83
|
+
* result.trigger();
|
|
84
|
+
* await result.credential;
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
26
88
|
export function isLinkStrategy(result) {
|
|
27
89
|
return result.strategy === 'link';
|
|
28
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Type guard to check if an ExtendedResponse is using the TS43 strategy.
|
|
93
|
+
* TS43 strategy uses the browser's Digital Credentials API.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* if (isExtendedResponse(result) && isTS43Strategy(result)) {
|
|
98
|
+
* // Re-trigger credential request if needed
|
|
99
|
+
* await result.trigger();
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
29
103
|
export function isTS43Strategy(result) {
|
|
30
104
|
return result.strategy === 'ts43';
|
|
31
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Type guard to check if an ExtendedResponse is using the Desktop strategy.
|
|
108
|
+
* Desktop strategy involves QR codes for cross-device authentication.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* if (isExtendedResponse(result) && isDesktopStrategy(result)) {
|
|
113
|
+
* // Show custom QR code UI
|
|
114
|
+
* displayQRCode(result.qr_code_data);
|
|
115
|
+
* await result.start_polling();
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
32
119
|
export function isDesktopStrategy(result) {
|
|
33
120
|
return result.strategy === 'desktop';
|
|
34
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Helper function to safely get the authentication strategy from any result.
|
|
124
|
+
* Returns undefined if the result is not an ExtendedResponse.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const strategy = getStrategy(result);
|
|
129
|
+
* if (strategy === 'link') {
|
|
130
|
+
* // Handle link strategy
|
|
131
|
+
* }
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
35
134
|
export function getStrategy(result) {
|
|
36
135
|
if (isExtendedResponse(result)) {
|
|
37
136
|
return result.strategy;
|
|
38
137
|
}
|
|
39
138
|
return undefined;
|
|
40
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Helper function to determine if a result has polling controls.
|
|
142
|
+
* Link and Desktop strategies have polling controls in extended mode.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* if (hasPollingControls(result)) {
|
|
147
|
+
* await result.start_polling();
|
|
148
|
+
* }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
41
151
|
export function hasPollingControls(result) {
|
|
42
152
|
if (!isExtendedResponse(result))
|
|
43
153
|
return false;
|
|
44
154
|
return (result.strategy === 'link' && 'start_polling' in result) ||
|
|
45
155
|
(result.strategy === 'desktop' && 'start_polling' in result);
|
|
46
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Helper function to determine if a result has a trigger method.
|
|
159
|
+
* Link and TS43 strategies have trigger methods in extended mode.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```typescript
|
|
163
|
+
* if (hasTrigger(result)) {
|
|
164
|
+
* result.trigger();
|
|
165
|
+
* }
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
47
168
|
export function hasTrigger(result) {
|
|
48
169
|
if (!isExtendedResponse(result))
|
|
49
170
|
return false;
|
|
50
171
|
return 'trigger' in result && typeof result.trigger === 'function';
|
|
51
172
|
}
|
|
173
|
+
// Export legacy function names as deprecated aliases for backward compatibility
|
|
174
|
+
/**
|
|
175
|
+
* @deprecated Use isExtendedResponse instead
|
|
176
|
+
*/
|
|
52
177
|
export const isHeadlessResult = isExtendedResponse;
|
|
178
|
+
/**
|
|
179
|
+
* @deprecated Use hasPollingControls instead
|
|
180
|
+
*/
|
|
53
181
|
export const requiresPolling = hasPollingControls;
|
|
182
|
+
/**
|
|
183
|
+
* @deprecated This function is no longer needed as extended mode handles user actions differently
|
|
184
|
+
*/
|
|
54
185
|
export const requiresUserAction = (result) => false;
|
|
@@ -1,33 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phone Authentication Types
|
|
3
|
+
*
|
|
4
|
+
* This file exports the types used by the Phone Auth SDK.
|
|
5
|
+
* All API types are imported from api-types.ts to ensure consistency.
|
|
6
|
+
* No backward compatibility - using clean API specification only.
|
|
7
|
+
*/
|
|
1
8
|
export * from './api-types';
|
|
2
9
|
import type { PrepareRequest as APIPrepareRequest, GetPhoneNumberResponse, VerifyPhoneNumberResponse, UseCase as APIUseCase, AuthenticationStrategy as APIAuthStrategy } from './api-types';
|
|
3
10
|
export type PhoneAuthOptions = APIPrepareRequest;
|
|
4
11
|
export type PhoneAuthResult = GetPhoneNumberResponse | VerifyPhoneNumberResponse;
|
|
5
12
|
export type UseCaseType = APIUseCase;
|
|
6
13
|
export type AuthenticationStrategyType = APIAuthStrategy;
|
|
14
|
+
/**
|
|
15
|
+
* SDK-specific error codes from error-utils
|
|
16
|
+
*/
|
|
7
17
|
import type { PhoneAuthErrorCode as ErrorCodeFromUtils } from './error-utils';
|
|
8
18
|
export type PhoneAuthErrorCode = ErrorCodeFromUtils;
|
|
19
|
+
/**
|
|
20
|
+
* SDK configuration callbacks
|
|
21
|
+
*/
|
|
9
22
|
export interface PhoneAuthCallbacks {
|
|
23
|
+
/**
|
|
24
|
+
* Called when cross-device authentication is detected (e.g., QR code shown)
|
|
25
|
+
*/
|
|
10
26
|
onCrossDeviceDetected?: () => void;
|
|
27
|
+
/**
|
|
28
|
+
* Called when a retry attempt is made
|
|
29
|
+
* @param attempt Current attempt number
|
|
30
|
+
* @param maxAttempts Maximum number of attempts
|
|
31
|
+
*/
|
|
11
32
|
onRetryAttempt?: (attempt: number, maxAttempts: number) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Called when authentication times out
|
|
35
|
+
*/
|
|
12
36
|
onTimeout?: () => void;
|
|
37
|
+
/**
|
|
38
|
+
* Called when user cancels authentication
|
|
39
|
+
*/
|
|
13
40
|
onCancel?: () => void;
|
|
41
|
+
/**
|
|
42
|
+
* Called when polling starts
|
|
43
|
+
*/
|
|
14
44
|
onPollingStart?: () => void;
|
|
45
|
+
/**
|
|
46
|
+
* Called when polling stops
|
|
47
|
+
*/
|
|
15
48
|
onPollingStop?: () => void;
|
|
16
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* SDK configuration options
|
|
52
|
+
*/
|
|
17
53
|
export interface AuthConfig extends PhoneAuthCallbacks {
|
|
54
|
+
/**
|
|
55
|
+
* Custom endpoints for authentication flow
|
|
56
|
+
*/
|
|
18
57
|
endpoints?: {
|
|
19
58
|
prepare?: string;
|
|
20
59
|
process?: string;
|
|
60
|
+
/** Desktop authentication status polling endpoint */
|
|
21
61
|
polling?: string;
|
|
22
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Timeout for API calls in milliseconds
|
|
65
|
+
* @default 30000
|
|
66
|
+
*/
|
|
23
67
|
timeout?: number;
|
|
68
|
+
/**
|
|
69
|
+
* Polling interval in milliseconds for status checks
|
|
70
|
+
* @default 2000
|
|
71
|
+
*/
|
|
24
72
|
pollingInterval?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Maximum polling attempts before timeout
|
|
75
|
+
* @default 30 (1 minute with 2s interval)
|
|
76
|
+
*/
|
|
25
77
|
maxPollingAttempts?: number;
|
|
78
|
+
/**
|
|
79
|
+
* Enable debug logging
|
|
80
|
+
* @default false
|
|
81
|
+
*/
|
|
26
82
|
debug?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Developer environment for testing (e.g., 'dev1', 'dev2')
|
|
85
|
+
* When set, adds a 'developer' header to polling requests
|
|
86
|
+
*/
|
|
87
|
+
devEnv?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Developer tools configuration for debugging
|
|
90
|
+
*/
|
|
27
91
|
devtools?: {
|
|
92
|
+
/**
|
|
93
|
+
* Show mobile console overlay for on-device debugging
|
|
94
|
+
* Displays all console logs at the bottom of the screen
|
|
95
|
+
* @default false
|
|
96
|
+
*/
|
|
28
97
|
showMobileConsole?: boolean;
|
|
29
98
|
};
|
|
30
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* SDK-enhanced error type with additional context
|
|
102
|
+
*/
|
|
31
103
|
export interface AuthError {
|
|
32
104
|
code: PhoneAuthErrorCode;
|
|
33
105
|
message: string;
|
|
@@ -54,7 +126,13 @@ export interface AuthError {
|
|
|
54
126
|
[key: string]: any;
|
|
55
127
|
};
|
|
56
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* SDK authentication flow steps
|
|
131
|
+
*/
|
|
57
132
|
export type AuthStep = 'idle' | 'requesting' | 'authenticating' | 'processing' | 'complete';
|
|
133
|
+
/**
|
|
134
|
+
* Browser error names
|
|
135
|
+
*/
|
|
58
136
|
export declare const BrowserError: {
|
|
59
137
|
readonly NOT_ALLOWED: "NotAllowedError";
|
|
60
138
|
readonly NETWORK: "NetworkError";
|
|
@@ -72,6 +150,9 @@ export declare const BrowserError: {
|
|
|
72
150
|
readonly SYNTAX: "SyntaxError";
|
|
73
151
|
};
|
|
74
152
|
export type BrowserErrorType = typeof BrowserError[keyof typeof BrowserError];
|
|
153
|
+
/**
|
|
154
|
+
* Browser error codes
|
|
155
|
+
*/
|
|
75
156
|
export declare const BrowserErrorCode: {
|
|
76
157
|
readonly USER_CANCELLED_DC_API: 19;
|
|
77
158
|
readonly PERMISSION_DENIED: 1;
|
|
@@ -83,6 +164,9 @@ export declare const BrowserErrorCode: {
|
|
|
83
164
|
readonly SECURITY: 18;
|
|
84
165
|
};
|
|
85
166
|
export type BrowserErrorCodeType = typeof BrowserErrorCode[keyof typeof BrowserErrorCode];
|
|
167
|
+
/**
|
|
168
|
+
* Browser names for detection
|
|
169
|
+
*/
|
|
86
170
|
export declare const BrowserName: {
|
|
87
171
|
readonly CHROME: "Chrome";
|
|
88
172
|
readonly EDGE: "Edge";
|
|
@@ -93,6 +177,9 @@ export declare const BrowserName: {
|
|
|
93
177
|
readonly OTHER: "other";
|
|
94
178
|
};
|
|
95
179
|
export type BrowserNameType = typeof BrowserName[keyof typeof BrowserName];
|
|
180
|
+
/**
|
|
181
|
+
* Browser Digital Credential type (extends standard Credential)
|
|
182
|
+
*/
|
|
96
183
|
export interface DigitalCredential extends Credential {
|
|
97
184
|
data: {
|
|
98
185
|
vp_token: {
|
|
@@ -100,6 +187,9 @@ export interface DigitalCredential extends Credential {
|
|
|
100
187
|
};
|
|
101
188
|
};
|
|
102
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Browser credential request structure
|
|
192
|
+
*/
|
|
103
193
|
export interface SecureCredentialRequest {
|
|
104
194
|
digital: {
|
|
105
195
|
requests: Array<{
|
|
@@ -108,17 +198,40 @@ export interface SecureCredentialRequest {
|
|
|
108
198
|
}>;
|
|
109
199
|
};
|
|
110
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Authentication status constants
|
|
203
|
+
* Maps to both client-side states and backend responses
|
|
204
|
+
*/
|
|
111
205
|
export declare const AuthStatus: {
|
|
206
|
+
/** Authentication in progress */
|
|
112
207
|
readonly PENDING: "pending";
|
|
208
|
+
/** Authentication completed successfully */
|
|
113
209
|
readonly COMPLETED: "completed";
|
|
210
|
+
/** User cancelled authentication */
|
|
114
211
|
readonly CANCELLED: "cancelled";
|
|
212
|
+
/** Authentication failed or expired */
|
|
115
213
|
readonly FAILED: "failed";
|
|
214
|
+
/** Session expired (backend returns 410 Gone) */
|
|
116
215
|
readonly EXPIRED: "expired";
|
|
216
|
+
/** Session not found (backend returns 404) */
|
|
117
217
|
readonly NOT_FOUND: "not_found";
|
|
118
218
|
};
|
|
119
219
|
export type AuthStatusType = typeof AuthStatus[keyof typeof AuthStatus];
|
|
220
|
+
/**
|
|
221
|
+
* Controller for managing authentication sessions
|
|
222
|
+
* Allows cancellation and cleanup of ongoing authentication
|
|
223
|
+
*/
|
|
120
224
|
export interface AuthController {
|
|
225
|
+
/**
|
|
226
|
+
* Cancel the ongoing authentication
|
|
227
|
+
*/
|
|
121
228
|
cancel(): void;
|
|
229
|
+
/**
|
|
230
|
+
* The authentication promise
|
|
231
|
+
*/
|
|
122
232
|
promise: Promise<any>;
|
|
233
|
+
/**
|
|
234
|
+
* Current status of the authentication
|
|
235
|
+
*/
|
|
123
236
|
status: AuthStatusType;
|
|
124
237
|
}
|
|
@@ -1,4 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phone Authentication Types
|
|
3
|
+
*
|
|
4
|
+
* This file exports the types used by the Phone Auth SDK.
|
|
5
|
+
* All API types are imported from api-types.ts to ensure consistency.
|
|
6
|
+
* No backward compatibility - using clean API specification only.
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// RE-EXPORT ALL API TYPES
|
|
10
|
+
// ============================================================================
|
|
1
11
|
export * from './api-types';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// BROWSER-SPECIFIC TYPES
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Browser error names
|
|
17
|
+
*/
|
|
2
18
|
export const BrowserError = {
|
|
3
19
|
NOT_ALLOWED: 'NotAllowedError',
|
|
4
20
|
NETWORK: 'NetworkError',
|
|
@@ -15,6 +31,9 @@ export const BrowserError = {
|
|
|
15
31
|
RANGE: 'RangeError',
|
|
16
32
|
SYNTAX: 'SyntaxError'
|
|
17
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Browser error codes
|
|
36
|
+
*/
|
|
18
37
|
export const BrowserErrorCode = {
|
|
19
38
|
USER_CANCELLED_DC_API: 19,
|
|
20
39
|
PERMISSION_DENIED: 1,
|
|
@@ -25,6 +44,9 @@ export const BrowserErrorCode = {
|
|
|
25
44
|
NETWORK: 19,
|
|
26
45
|
SECURITY: 18
|
|
27
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* Browser names for detection
|
|
49
|
+
*/
|
|
28
50
|
export const BrowserName = {
|
|
29
51
|
CHROME: 'Chrome',
|
|
30
52
|
EDGE: 'Edge',
|
|
@@ -34,11 +56,21 @@ export const BrowserName = {
|
|
|
34
56
|
BRAVE: 'Brave',
|
|
35
57
|
OTHER: 'other'
|
|
36
58
|
};
|
|
59
|
+
/**
|
|
60
|
+
* Authentication status constants
|
|
61
|
+
* Maps to both client-side states and backend responses
|
|
62
|
+
*/
|
|
37
63
|
export const AuthStatus = {
|
|
64
|
+
/** Authentication in progress */
|
|
38
65
|
PENDING: 'pending',
|
|
66
|
+
/** Authentication completed successfully */
|
|
39
67
|
COMPLETED: 'completed',
|
|
68
|
+
/** User cancelled authentication */
|
|
40
69
|
CANCELLED: 'cancelled',
|
|
70
|
+
/** Authentication failed or expired */
|
|
41
71
|
FAILED: 'failed',
|
|
72
|
+
/** Session expired (backend returns 410 Gone) */
|
|
42
73
|
EXPIRED: 'expired',
|
|
74
|
+
/** Session not found (backend returns 404) */
|
|
43
75
|
NOT_FOUND: 'not_found'
|
|
44
76
|
};
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mobile Debug Console
|
|
3
|
+
* A lightweight console overlay for debugging on mobile devices where dev tools aren't available
|
|
4
|
+
*/
|
|
1
5
|
export class MobileDebugConsole {
|
|
2
6
|
constructor() {
|
|
3
7
|
this.logs = [];
|
|
@@ -32,13 +36,15 @@ export class MobileDebugConsole {
|
|
|
32
36
|
['log', 'error', 'warn', 'debug', 'info'].forEach(method => {
|
|
33
37
|
const originalMethod = this.originalConsole[method];
|
|
34
38
|
console[method] = (...args) => {
|
|
39
|
+
// Call original
|
|
35
40
|
originalMethod.apply(console, args);
|
|
41
|
+
// Add to our display
|
|
36
42
|
this.addLog(method, args);
|
|
37
43
|
};
|
|
38
44
|
});
|
|
39
45
|
}
|
|
40
46
|
addLog(type, args) {
|
|
41
|
-
const timestamp = new Date().toTimeString().split(' ')[0];
|
|
47
|
+
const timestamp = new Date().toTimeString().split(' ')[0]; // HH:MM:SS
|
|
42
48
|
const content = args.map(arg => {
|
|
43
49
|
if (typeof arg === 'object') {
|
|
44
50
|
try {
|
|
@@ -50,6 +56,7 @@ export class MobileDebugConsole {
|
|
|
50
56
|
}
|
|
51
57
|
return String(arg);
|
|
52
58
|
}).join(' ');
|
|
59
|
+
// Create colored log entry
|
|
53
60
|
const colors = {
|
|
54
61
|
log: '#fff',
|
|
55
62
|
error: '#ff6b6b',
|
|
@@ -65,6 +72,7 @@ export class MobileDebugConsole {
|
|
|
65
72
|
</div>
|
|
66
73
|
`;
|
|
67
74
|
this.logs.push(logHtml);
|
|
75
|
+
// Keep only last 500 logs
|
|
68
76
|
if (this.logs.length > 500) {
|
|
69
77
|
this.logs.shift();
|
|
70
78
|
}
|
|
@@ -73,13 +81,17 @@ export class MobileDebugConsole {
|
|
|
73
81
|
updateDisplay() {
|
|
74
82
|
if (!this.logsContainer || !this.isVisible)
|
|
75
83
|
return;
|
|
84
|
+
// Check if scrolled to bottom before update
|
|
76
85
|
this.isAtBottom = this.logsContainer.scrollHeight - this.logsContainer.scrollTop <= this.logsContainer.clientHeight + 50;
|
|
86
|
+
// Update content
|
|
77
87
|
this.logsContainer.innerHTML = this.logs.join('');
|
|
88
|
+
// Auto-scroll only if was at bottom
|
|
78
89
|
if (this.isAtBottom) {
|
|
79
90
|
this.logsContainer.scrollTop = this.logsContainer.scrollHeight;
|
|
80
91
|
}
|
|
81
92
|
}
|
|
82
93
|
createUI() {
|
|
94
|
+
// Create styles
|
|
83
95
|
const style = document.createElement('style');
|
|
84
96
|
style.textContent = `
|
|
85
97
|
#mobile-debug-console {
|
|
@@ -172,11 +184,13 @@ export class MobileDebugConsole {
|
|
|
172
184
|
}
|
|
173
185
|
`;
|
|
174
186
|
document.head.appendChild(style);
|
|
187
|
+
// Create container
|
|
175
188
|
this.container = document.createElement('div');
|
|
176
189
|
this.container.id = 'mobile-debug-console';
|
|
177
190
|
if (!this.isVisible) {
|
|
178
191
|
this.container.className = 'hidden';
|
|
179
192
|
}
|
|
193
|
+
// Create header
|
|
180
194
|
const header = document.createElement('div');
|
|
181
195
|
header.id = 'debug-header';
|
|
182
196
|
const title = document.createElement('div');
|
|
@@ -184,12 +198,15 @@ export class MobileDebugConsole {
|
|
|
184
198
|
title.textContent = '📱 Mobile Debug Console';
|
|
185
199
|
const buttons = document.createElement('div');
|
|
186
200
|
buttons.id = 'debug-buttons';
|
|
201
|
+
// Clear button
|
|
187
202
|
const clearBtn = document.createElement('button');
|
|
188
203
|
clearBtn.textContent = 'Clear';
|
|
189
204
|
clearBtn.onclick = () => this.clear();
|
|
205
|
+
// Show/Hide button
|
|
190
206
|
const toggleBtn = document.createElement('button');
|
|
191
207
|
toggleBtn.textContent = 'Hide';
|
|
192
208
|
toggleBtn.onclick = () => this.toggle();
|
|
209
|
+
// Close button
|
|
193
210
|
const closeBtn = document.createElement('button');
|
|
194
211
|
closeBtn.textContent = '✕';
|
|
195
212
|
closeBtn.style.color = '#ff6b6b';
|
|
@@ -199,20 +216,25 @@ export class MobileDebugConsole {
|
|
|
199
216
|
buttons.appendChild(closeBtn);
|
|
200
217
|
header.appendChild(title);
|
|
201
218
|
header.appendChild(buttons);
|
|
219
|
+
// Create logs container
|
|
202
220
|
this.logsContainer = document.createElement('div');
|
|
203
221
|
this.logsContainer.id = 'debug-logs';
|
|
222
|
+
// Track scroll position
|
|
204
223
|
this.logsContainer.addEventListener('scroll', () => {
|
|
205
224
|
this.isAtBottom = this.logsContainer.scrollHeight - this.logsContainer.scrollTop <= this.logsContainer.clientHeight + 50;
|
|
206
225
|
});
|
|
226
|
+
// Assemble
|
|
207
227
|
this.container.appendChild(header);
|
|
208
228
|
this.container.appendChild(this.logsContainer);
|
|
209
229
|
document.body.appendChild(this.container);
|
|
230
|
+
// Create floating toggle button
|
|
210
231
|
this.floatingToggle = document.createElement('button');
|
|
211
232
|
this.floatingToggle.id = 'debug-floating-toggle';
|
|
212
|
-
this.floatingToggle.innerHTML = '🖥️';
|
|
233
|
+
this.floatingToggle.innerHTML = '🖥️'; // Console icon
|
|
213
234
|
this.floatingToggle.title = 'Show Debug Console';
|
|
214
235
|
this.floatingToggle.onclick = () => this.toggle();
|
|
215
236
|
document.body.appendChild(this.floatingToggle);
|
|
237
|
+
// Store reference for toggle button
|
|
216
238
|
window.__debugToggleBtn = toggleBtn;
|
|
217
239
|
}
|
|
218
240
|
escapeHtml(text) {
|
|
@@ -243,15 +265,19 @@ export class MobileDebugConsole {
|
|
|
243
265
|
}
|
|
244
266
|
}
|
|
245
267
|
cleanup() {
|
|
268
|
+
// Restore original console
|
|
246
269
|
Object.keys(this.originalConsole).forEach(method => {
|
|
247
270
|
console[method] = this.originalConsole[method];
|
|
248
271
|
});
|
|
272
|
+
// Remove UI
|
|
249
273
|
if (this.container) {
|
|
250
274
|
this.container.remove();
|
|
251
275
|
}
|
|
276
|
+
// Remove floating toggle
|
|
252
277
|
if (this.floatingToggle) {
|
|
253
278
|
this.floatingToggle.remove();
|
|
254
279
|
}
|
|
280
|
+
// Clean up references
|
|
255
281
|
delete window.__debugToggleBtn;
|
|
256
282
|
}
|
|
257
283
|
}
|
|
@@ -1,11 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modal UI Component for Phone Authentication
|
|
3
|
+
*
|
|
4
|
+
* This file creates the UI components (modals, buttons) that are shown
|
|
5
|
+
* when the SDK is NOT in headless mode. Think of it like a popup window
|
|
6
|
+
* that handles the authentication flow for you.
|
|
7
|
+
*/
|
|
1
8
|
import type { InvokeOptions } from '../api-types';
|
|
2
9
|
import type { QRCodeData } from '../strategies/desktop';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Creates and manages a modal dialog for authentication
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* const modal = new AuthModal({
|
|
15
|
+
* title: "Verify Your Phone",
|
|
16
|
+
* description: "Complete authentication to continue"
|
|
17
|
+
* });
|
|
18
|
+
* modal.show();
|
|
19
|
+
*/
|
|
9
20
|
export declare class AuthModal {
|
|
10
21
|
private container;
|
|
11
22
|
private backdrop;
|
|
@@ -13,35 +24,65 @@ export declare class AuthModal {
|
|
|
13
24
|
private options;
|
|
14
25
|
private callbacks;
|
|
15
26
|
private closeCallback?;
|
|
16
|
-
|
|
17
|
-
private currentStep;
|
|
18
|
-
private qrCodeData;
|
|
19
|
-
private statusMessage;
|
|
20
|
-
private originalBodyOverflow;
|
|
21
|
-
private isClosing;
|
|
22
|
-
private readonly iconApple;
|
|
23
|
-
private readonly iconAndroid;
|
|
24
|
-
private readonly iconBack;
|
|
25
|
-
constructor(options?: AuthModalOptions, callbacks?: InvokeOptions['callbacks']);
|
|
26
|
-
private shouldUseDarkMode;
|
|
27
|
+
constructor(options?: InvokeOptions['modalOptions'], callbacks?: InvokeOptions['callbacks']);
|
|
27
28
|
private handleEscapeKey;
|
|
29
|
+
/**
|
|
30
|
+
* Escape HTML to prevent XSS attacks
|
|
31
|
+
*/
|
|
28
32
|
private escapeHtml;
|
|
33
|
+
/**
|
|
34
|
+
* Shows the modal with a QR code for desktop authentication
|
|
35
|
+
* Supports both single QR code (legacy) and dual-platform QR codes (iOS + Android)
|
|
36
|
+
*/
|
|
29
37
|
showQRCode(qrCodeData: string | QRCodeData, statusMessage?: string): void;
|
|
30
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Creates a modal with iOS/Android platform toggle
|
|
40
|
+
*/
|
|
41
|
+
private createDualPlatformQRModal;
|
|
42
|
+
/**
|
|
43
|
+
* Sets a callback to be called when the modal is cancelled/closed
|
|
44
|
+
*/
|
|
31
45
|
setCloseCallback(callback: () => void): void;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Shows the modal with a button for Link authentication (App Clips)
|
|
48
|
+
* IMPORTANT: The button click is required for iOS to recognize the app link
|
|
49
|
+
*/
|
|
50
|
+
showLinkButton(url: string, buttonText?: string): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Shows the modal with a button for TS43 authentication
|
|
53
|
+
* IMPORTANT: The button click is required for Digital Credentials API (transient activation)
|
|
54
|
+
*/
|
|
55
|
+
showTS43Button(onAuthenticate: () => Promise<any>): Promise<any>;
|
|
56
|
+
/**
|
|
57
|
+
* Updates the status message in the modal
|
|
58
|
+
*/
|
|
59
|
+
updateStatus(message: string, isError?: boolean): void;
|
|
60
|
+
/**
|
|
61
|
+
* Creates the modal HTML structure
|
|
62
|
+
*/
|
|
38
63
|
private createModal;
|
|
39
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Injects CSS styles for the modal
|
|
66
|
+
*/
|
|
40
67
|
private injectStyles;
|
|
68
|
+
/**
|
|
69
|
+
* Shows the modal with animation
|
|
70
|
+
*/
|
|
41
71
|
show(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Setup click handlers for iOS/Android platform toggle
|
|
74
|
+
*/
|
|
42
75
|
private setupPlatformToggles;
|
|
43
|
-
|
|
44
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Closes the modal with animation
|
|
78
|
+
*/
|
|
45
79
|
close(): void;
|
|
80
|
+
/**
|
|
81
|
+
* Removes modal elements from DOM
|
|
82
|
+
*/
|
|
46
83
|
private cleanup;
|
|
84
|
+
/**
|
|
85
|
+
* Check if modal is currently open
|
|
86
|
+
*/
|
|
87
|
+
isModalOpen(): boolean;
|
|
47
88
|
}
|