@glideidentity/web-client-sdk 5.0.0 → 5.0.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 +108 -8
- package/dist/adapters/angular/index.js +0 -1
- package/dist/adapters/angular/phone-auth.service.d.ts +0 -18
- package/dist/adapters/angular/phone-auth.service.js +0 -26
- package/dist/adapters/react/index.js +0 -3
- package/dist/adapters/react/useClient.js +0 -1
- package/dist/adapters/react/usePhoneAuth.js +1 -16
- package/dist/adapters/vanilla/client.js +0 -1
- package/dist/adapters/vanilla/index.js +0 -1
- package/dist/adapters/vanilla/phone-auth.js +0 -31
- package/dist/adapters/vue/index.js +0 -4
- package/dist/adapters/vue/useClient.js +0 -5
- package/dist/adapters/vue/usePhoneAuth.js +1 -20
- package/dist/browser/web-client-sdk.min.js +1 -1
- package/dist/browser.js +0 -6
- package/dist/core/client.js +0 -12
- package/dist/core/logger.js +1 -81
- package/dist/core/phone-auth/api-types.js +0 -83
- package/dist/core/phone-auth/client.js +27 -366
- package/dist/core/phone-auth/error-utils.js +1 -83
- package/dist/core/phone-auth/index.js +0 -1
- package/dist/core/phone-auth/status-types.d.ts +0 -78
- package/dist/core/phone-auth/status-types.js +0 -17
- package/dist/core/phone-auth/strategies/desktop.js +8 -126
- package/dist/core/phone-auth/strategies/index.d.ts +0 -4
- package/dist/core/phone-auth/strategies/index.js +0 -4
- package/dist/core/phone-auth/strategies/link.js +10 -88
- package/dist/core/phone-auth/strategies/ts43.d.ts +0 -19
- package/dist/core/phone-auth/strategies/ts43.js +2 -33
- package/dist/core/phone-auth/strategies/types.js +0 -4
- package/dist/core/phone-auth/type-guards.js +0 -131
- package/dist/core/phone-auth/types.js +0 -32
- package/dist/core/phone-auth/ui/mobile-debug-console.js +2 -28
- package/dist/core/phone-auth/ui/modal.d.ts +33 -55
- package/dist/core/phone-auth/ui/modal.js +889 -422
- package/dist/core/phone-auth/validation-utils.js +2 -40
- package/dist/core/version.js +1 -2
- package/dist/esm/adapters/angular/index.js +0 -1
- package/dist/esm/adapters/angular/phone-auth.service.d.ts +0 -18
- package/dist/esm/adapters/angular/phone-auth.service.js +0 -26
- package/dist/esm/adapters/react/index.js +0 -3
- package/dist/esm/adapters/react/useClient.js +0 -1
- package/dist/esm/adapters/react/usePhoneAuth.js +1 -16
- package/dist/esm/adapters/vanilla/client.js +0 -1
- package/dist/esm/adapters/vanilla/index.js +0 -1
- package/dist/esm/adapters/vanilla/phone-auth.d.ts +0 -24
- package/dist/esm/adapters/vanilla/phone-auth.js +0 -31
- package/dist/esm/adapters/vue/index.js +0 -4
- package/dist/esm/adapters/vue/useClient.js +0 -5
- package/dist/esm/adapters/vue/usePhoneAuth.js +1 -20
- package/dist/esm/browser.js +0 -6
- package/dist/esm/core/client.d.ts +0 -10
- package/dist/esm/core/client.js +0 -12
- package/dist/esm/core/logger.d.ts +0 -53
- package/dist/esm/core/logger.js +1 -81
- package/dist/esm/core/phone-auth/api-types.d.ts +0 -315
- package/dist/esm/core/phone-auth/api-types.js +0 -83
- package/dist/esm/core/phone-auth/client.d.ts +0 -144
- package/dist/esm/core/phone-auth/client.js +27 -366
- package/dist/esm/core/phone-auth/error-utils.d.ts +0 -29
- package/dist/esm/core/phone-auth/error-utils.js +1 -83
- package/dist/esm/core/phone-auth/index.js +1 -3
- package/dist/esm/core/phone-auth/status-types.d.ts +0 -78
- package/dist/esm/core/phone-auth/status-types.js +0 -17
- package/dist/esm/core/phone-auth/strategies/desktop.d.ts +0 -63
- package/dist/esm/core/phone-auth/strategies/desktop.js +8 -126
- package/dist/esm/core/phone-auth/strategies/index.d.ts +0 -4
- package/dist/esm/core/phone-auth/strategies/index.js +0 -4
- package/dist/esm/core/phone-auth/strategies/link.d.ts +0 -48
- package/dist/esm/core/phone-auth/strategies/link.js +10 -88
- package/dist/esm/core/phone-auth/strategies/ts43.d.ts +0 -19
- package/dist/esm/core/phone-auth/strategies/ts43.js +2 -33
- package/dist/esm/core/phone-auth/strategies/types.d.ts +0 -13
- package/dist/esm/core/phone-auth/strategies/types.js +0 -4
- package/dist/esm/core/phone-auth/type-guards.d.ts +0 -128
- package/dist/esm/core/phone-auth/type-guards.js +0 -131
- package/dist/esm/core/phone-auth/types.d.ts +0 -108
- package/dist/esm/core/phone-auth/types.js +0 -32
- package/dist/esm/core/phone-auth/ui/mobile-debug-console.d.ts +0 -4
- package/dist/esm/core/phone-auth/ui/mobile-debug-console.js +2 -28
- package/dist/esm/core/phone-auth/ui/modal.d.ts +27 -68
- package/dist/esm/core/phone-auth/ui/modal.js +889 -422
- package/dist/esm/core/phone-auth/validation-utils.d.ts +0 -31
- package/dist/esm/core/phone-auth/validation-utils.js +2 -40
- package/dist/esm/core/types.d.ts +0 -35
- package/dist/esm/core/version.js +1 -2
- package/dist/esm/index.js +1 -9
- package/dist/index.js +0 -7
- package/package.json +1 -1
|
@@ -65,43 +65,14 @@ export declare const PhoneAuthErrorCode: {
|
|
|
65
65
|
};
|
|
66
66
|
export type PhoneAuthErrorCode = typeof PhoneAuthErrorCode[keyof typeof PhoneAuthErrorCode];
|
|
67
67
|
import type { AuthError } from './types';
|
|
68
|
-
/**
|
|
69
|
-
* Type guard to check if an error is a PhoneAuthError
|
|
70
|
-
*/
|
|
71
68
|
export declare function isPhoneAuthError(error: any): error is AuthError;
|
|
72
|
-
/**
|
|
73
|
-
* Check if error should be shown to user
|
|
74
|
-
*/
|
|
75
69
|
export declare function isUserError(error: AuthError): boolean;
|
|
76
|
-
/**
|
|
77
|
-
* Get user-friendly error message
|
|
78
|
-
*/
|
|
79
70
|
export declare function getUserMessage(error: AuthError): string;
|
|
80
|
-
/**
|
|
81
|
-
* Check if error matches a specific code
|
|
82
|
-
*/
|
|
83
71
|
export declare function isErrorCode(error: AuthError, code: PhoneAuthErrorCode): boolean;
|
|
84
|
-
/**
|
|
85
|
-
* Get retry delay for rate-limited requests
|
|
86
|
-
*/
|
|
87
72
|
export declare function getRetryDelay(error: AuthError): number | null;
|
|
88
|
-
/**
|
|
89
|
-
* Check if error is retryable
|
|
90
|
-
*/
|
|
91
73
|
export declare function isRetryableError(error: AuthError): boolean;
|
|
92
|
-
/**
|
|
93
|
-
* Parse error response from backend API
|
|
94
|
-
*/
|
|
95
74
|
export declare function parseBackendError(response: any): AuthError;
|
|
96
|
-
/**
|
|
97
|
-
* Serialize error for logging/observability tools like Sentry
|
|
98
|
-
* This ensures all error details are captured in a format that can be sent over the network
|
|
99
|
-
*/
|
|
100
75
|
export declare function serializeError(error: AuthError): Record<string, any>;
|
|
101
|
-
/**
|
|
102
|
-
* Create a breadcrumb trail for error tracking
|
|
103
|
-
* Useful for understanding the sequence of events leading to an error
|
|
104
|
-
*/
|
|
105
76
|
export declare function createErrorBreadcrumb(error: AuthError): {
|
|
106
77
|
category: string;
|
|
107
78
|
message: string;
|
|
@@ -1,36 +1,29 @@
|
|
|
1
1
|
import { SDK_VERSION } from '../version';
|
|
2
|
-
// Error constants matching the backend for consistency
|
|
3
2
|
export const PhoneAuthErrorCode = {
|
|
4
|
-
// 400 Bad Request errors
|
|
5
3
|
BAD_REQUEST: 'BAD_REQUEST',
|
|
6
4
|
VALIDATION_ERROR: 'VALIDATION_ERROR',
|
|
7
5
|
INVALID_PARAMETERS: 'INVALID_PARAMETERS',
|
|
8
6
|
MISSING_PARAMETERS: 'MISSING_PARAMETERS',
|
|
9
7
|
INVALID_PHONE_NUMBER: 'INVALID_PHONE_NUMBER',
|
|
10
8
|
INVALID_MCC_MNC: 'INVALID_MCC_MNC',
|
|
11
|
-
// 401 Unauthorized errors
|
|
12
9
|
UNAUTHORIZED: 'UNAUTHORIZED',
|
|
13
10
|
INVALID_CREDENTIALS: 'INVALID_CREDENTIALS',
|
|
14
11
|
EXPIRED_TOKEN: 'EXPIRED_TOKEN',
|
|
15
12
|
TOKEN_ACQUISITION_FAILED: 'TOKEN_ACQUISITION_FAILED',
|
|
16
13
|
INVALID_API_KEY: 'INVALID_API_KEY',
|
|
17
14
|
MISSING_AUTH_HEADER: 'MISSING_AUTH_HEADER',
|
|
18
|
-
// 403 Forbidden errors
|
|
19
15
|
FORBIDDEN: 'FORBIDDEN',
|
|
20
16
|
INSUFFICIENT_PERMISSIONS: 'INSUFFICIENT_PERMISSIONS',
|
|
21
17
|
ACCESS_DENIED: 'ACCESS_DENIED',
|
|
22
|
-
// 404 Not Found errors
|
|
23
18
|
NOT_FOUND: 'NOT_FOUND',
|
|
24
19
|
RESOURCE_NOT_FOUND: 'RESOURCE_NOT_FOUND',
|
|
25
20
|
SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',
|
|
26
21
|
CARRIER_NOT_FOUND: 'CARRIER_NOT_FOUND',
|
|
27
22
|
ENDPOINT_NOT_FOUND: 'ENDPOINT_NOT_FOUND',
|
|
28
|
-
// 409 Conflict errors
|
|
29
23
|
CONFLICT: 'CONFLICT',
|
|
30
24
|
RESOURCE_ALREADY_EXISTS: 'RESOURCE_ALREADY_EXISTS',
|
|
31
25
|
DUPLICATE_SESSION: 'DUPLICATE_SESSION',
|
|
32
26
|
CONCURRENT_MODIFICATION: 'CONCURRENT_MODIFICATION',
|
|
33
|
-
// 422 Unprocessable Entity errors
|
|
34
27
|
UNPROCESSABLE_ENTITY: 'UNPROCESSABLE_ENTITY',
|
|
35
28
|
UNSUPPORTED_VERIFICATION: 'UNSUPPORTED_VERIFICATION',
|
|
36
29
|
INVALID_VERIFICATION: 'INVALID_VERIFICATION',
|
|
@@ -46,160 +39,117 @@ export const PhoneAuthErrorCode = {
|
|
|
46
39
|
INVALID_SESSION_STATE: 'INVALID_SESSION_STATE',
|
|
47
40
|
PHONE_NUMBER_MISMATCH: 'PHONE_NUMBER_MISMATCH',
|
|
48
41
|
INVALID_CREDENTIAL_FORMAT: 'INVALID_CREDENTIAL_FORMAT',
|
|
49
|
-
// 429 Too Many Requests errors
|
|
50
42
|
RATE_LIMIT_EXCEEDED: 'RATE_LIMIT_EXCEEDED',
|
|
51
43
|
TOO_MANY_REQUESTS: 'TOO_MANY_REQUESTS',
|
|
52
44
|
QUOTA_EXCEEDED: 'QUOTA_EXCEEDED',
|
|
53
|
-
// 500 Internal Server errors
|
|
54
45
|
INTERNAL_SERVER_ERROR: 'INTERNAL_SERVER_ERROR',
|
|
55
46
|
CIRCUIT_BREAKER_CONFIGURATION_ERROR: 'CIRCUIT_BREAKER_CONFIGURATION_ERROR',
|
|
56
47
|
DATABASE_ERROR: 'DATABASE_ERROR',
|
|
57
48
|
CACHE_ERROR: 'CACHE_ERROR',
|
|
58
49
|
SERIALIZATION_ERROR: 'SERIALIZATION_ERROR',
|
|
59
50
|
CRYPTO_ERROR: 'CRYPTO_ERROR',
|
|
60
|
-
// 502 Bad Gateway errors
|
|
61
51
|
BAD_GATEWAY: 'BAD_GATEWAY',
|
|
62
52
|
UPSTREAM_ERROR: 'UPSTREAM_ERROR',
|
|
63
53
|
INVALID_RESPONSE: 'INVALID_RESPONSE',
|
|
64
|
-
// 503 Service Unavailable errors
|
|
65
54
|
SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE',
|
|
66
55
|
DOWNSTREAM_SERVICE_ERROR: 'DOWNSTREAM_SERVICE_ERROR',
|
|
67
56
|
PROVIDER_ERROR: 'PROVIDER_ERROR',
|
|
68
57
|
CIRCUIT_BREAKER_OPEN: 'CIRCUIT_BREAKER_OPEN',
|
|
69
58
|
MAINTENANCE_MODE: 'MAINTENANCE_MODE',
|
|
70
|
-
// 504 Gateway Timeout errors
|
|
71
59
|
GATEWAY_TIMEOUT: 'GATEWAY_TIMEOUT',
|
|
72
60
|
REQUEST_TIMEOUT: 'REQUEST_TIMEOUT',
|
|
73
61
|
UPSTREAM_TIMEOUT: 'UPSTREAM_TIMEOUT',
|
|
74
62
|
DEADLINE_EXCEEDED: 'DEADLINE_EXCEEDED',
|
|
75
|
-
// Browser-specific errors (never thrown by backend)
|
|
76
63
|
BROWSER_NOT_SUPPORTED: 'BROWSER_NOT_SUPPORTED',
|
|
77
64
|
USER_DENIED: 'USER_DENIED',
|
|
78
65
|
NETWORK_ERROR: 'NETWORK_ERROR',
|
|
79
66
|
};
|
|
80
|
-
// User-facing error messages - NEVER expose carrier names or phone numbers
|
|
81
67
|
const USER_ERROR_MESSAGES = {
|
|
82
|
-
// Privacy-conscious messages - no carrier/phone info exposed
|
|
83
68
|
CARRIER_NOT_ELIGIBLE: 'Your carrier is not eligible for this verification method.',
|
|
84
69
|
CARRIER_IDENTIFICATION_FAILED: 'Unable to identify carrier for the provided phone number.',
|
|
85
70
|
CARRIER_NOT_FOUND: 'Carrier information not available.',
|
|
86
71
|
UNSUPPORTED_CARRIER: 'This carrier is not supported.',
|
|
87
|
-
// Rate limiting
|
|
88
72
|
RATE_LIMIT_EXCEEDED: 'Too many attempts. Please wait a moment and try again.',
|
|
89
73
|
TOO_MANY_REQUESTS: 'Too many requests. Please slow down and try again.',
|
|
90
74
|
QUOTA_EXCEEDED: 'Usage limit reached. Please try again later.',
|
|
91
|
-
// Session errors
|
|
92
75
|
SESSION_NOT_FOUND: 'Your session has expired. Please start over.',
|
|
93
76
|
INVALID_SESSION_STATE: 'Invalid session state. Please start over.',
|
|
94
77
|
DUPLICATE_SESSION: 'A session already exists. Please complete or cancel it first.',
|
|
95
|
-
// Browser/platform errors
|
|
96
78
|
BROWSER_NOT_SUPPORTED: 'Digital Credentials API is not available. Please enable the #web-identity-digital-credentials flag in chrome://flags',
|
|
97
79
|
UNSUPPORTED_PLATFORM: 'This platform is not supported for authentication.',
|
|
98
80
|
UNSUPPORTED_STRATEGY: 'This authentication method is not available.',
|
|
99
81
|
USER_DENIED: 'Authentication was cancelled. Please try again when you\'re ready.',
|
|
100
|
-
// Service availability
|
|
101
82
|
SERVICE_UNAVAILABLE: 'The service is temporarily unavailable. Please try again later.',
|
|
102
83
|
CIRCUIT_BREAKER_OPEN: 'Service is experiencing issues. Please try again later.',
|
|
103
84
|
MAINTENANCE_MODE: 'Service is under maintenance. Please try again later.',
|
|
104
85
|
DOWNSTREAM_SERVICE_ERROR: 'A required service is unavailable. Please try again later.',
|
|
105
|
-
// Authentication errors
|
|
106
86
|
TOKEN_ACQUISITION_FAILED: 'Failed to acquire authentication token. Please try again.',
|
|
107
87
|
EXPIRED_TOKEN: 'Your authentication has expired. Please start over.',
|
|
108
88
|
INVALID_CREDENTIALS: 'Invalid credentials provided.',
|
|
109
|
-
// Validation errors
|
|
110
89
|
INVALID_PHONE_NUMBER: 'Please enter a valid phone number.',
|
|
111
90
|
PHONE_NUMBER_MISMATCH: 'Phone number mismatch. Please verify your number.',
|
|
112
91
|
INVALID_PARAMETERS: 'Invalid parameters provided.',
|
|
113
92
|
MISSING_PARAMETERS: 'Required information is missing.',
|
|
114
93
|
VALIDATION_ERROR: 'Validation failed. Please check your input.',
|
|
115
|
-
// Network errors
|
|
116
94
|
NETWORK_ERROR: 'Network connection failed. Please check your connection and try again.',
|
|
117
95
|
GATEWAY_TIMEOUT: 'Request timed out. Please try again.',
|
|
118
96
|
REQUEST_TIMEOUT: 'Request timed out. Please try again.',
|
|
119
97
|
DEADLINE_EXCEEDED: 'Operation took too long. Please try again.',
|
|
120
|
-
// Verification errors
|
|
121
98
|
VERIFICATION_FAILED: 'Verification failed. Please try again.',
|
|
122
99
|
INVALID_VERIFICATION: 'Invalid verification response.',
|
|
123
100
|
INVALID_CREDENTIAL_FORMAT: 'Invalid credential format.',
|
|
124
|
-
// Generic fallbacks
|
|
125
101
|
BAD_REQUEST: 'Invalid request. Please try again.',
|
|
126
102
|
UNAUTHORIZED: 'Authentication required.',
|
|
127
103
|
FORBIDDEN: 'Access denied.',
|
|
128
104
|
NOT_FOUND: 'Resource not found.',
|
|
129
105
|
INTERNAL_SERVER_ERROR: 'An error occurred. Please try again later.',
|
|
130
106
|
};
|
|
131
|
-
// Errors that should be shown to users vs logged internally
|
|
132
107
|
const USER_FACING_ERRORS = new Set([
|
|
133
|
-
// Carrier errors (privacy-safe messages)
|
|
134
108
|
'CARRIER_NOT_ELIGIBLE',
|
|
135
109
|
'CARRIER_IDENTIFICATION_FAILED',
|
|
136
110
|
'CARRIER_NOT_FOUND',
|
|
137
111
|
'UNSUPPORTED_CARRIER',
|
|
138
|
-
// Rate limiting
|
|
139
112
|
'RATE_LIMIT_EXCEEDED',
|
|
140
113
|
'TOO_MANY_REQUESTS',
|
|
141
114
|
'QUOTA_EXCEEDED',
|
|
142
|
-
// Browser/platform
|
|
143
115
|
'BROWSER_NOT_SUPPORTED',
|
|
144
116
|
'UNSUPPORTED_PLATFORM',
|
|
145
117
|
'UNSUPPORTED_STRATEGY',
|
|
146
118
|
'USER_DENIED',
|
|
147
|
-
// Session
|
|
148
119
|
'SESSION_NOT_FOUND',
|
|
149
120
|
'INVALID_SESSION_STATE',
|
|
150
121
|
'EXPIRED_TOKEN',
|
|
151
|
-
// Service availability
|
|
152
122
|
'SERVICE_UNAVAILABLE',
|
|
153
123
|
'CIRCUIT_BREAKER_OPEN',
|
|
154
124
|
'MAINTENANCE_MODE',
|
|
155
|
-
// Network
|
|
156
125
|
'NETWORK_ERROR',
|
|
157
126
|
'GATEWAY_TIMEOUT',
|
|
158
127
|
'REQUEST_TIMEOUT',
|
|
159
|
-
// Validation
|
|
160
128
|
'INVALID_PHONE_NUMBER',
|
|
161
129
|
'PHONE_NUMBER_MISMATCH',
|
|
162
130
|
'MISSING_PARAMETERS',
|
|
163
131
|
'VALIDATION_ERROR',
|
|
164
132
|
]);
|
|
165
|
-
/**
|
|
166
|
-
* Type guard to check if an error is a PhoneAuthError
|
|
167
|
-
*/
|
|
168
133
|
export function isPhoneAuthError(error) {
|
|
169
134
|
return error &&
|
|
170
135
|
typeof error.code === 'string' &&
|
|
171
136
|
typeof error.message === 'string';
|
|
172
137
|
}
|
|
173
|
-
/**
|
|
174
|
-
* Check if error should be shown to user
|
|
175
|
-
*/
|
|
176
138
|
export function isUserError(error) {
|
|
177
139
|
return USER_FACING_ERRORS.has(error.code);
|
|
178
140
|
}
|
|
179
|
-
/**
|
|
180
|
-
* Get user-friendly error message
|
|
181
|
-
*/
|
|
182
141
|
export function getUserMessage(error) {
|
|
183
142
|
return USER_ERROR_MESSAGES[error.code] || 'An unexpected error occurred. Please try again.';
|
|
184
143
|
}
|
|
185
|
-
/**
|
|
186
|
-
* Check if error matches a specific code
|
|
187
|
-
*/
|
|
188
144
|
export function isErrorCode(error, code) {
|
|
189
145
|
return error.code === code;
|
|
190
146
|
}
|
|
191
|
-
/**
|
|
192
|
-
* Get retry delay for rate-limited requests
|
|
193
|
-
*/
|
|
194
147
|
export function getRetryDelay(error) {
|
|
195
148
|
if (error.code === PhoneAuthErrorCode.RATE_LIMIT_EXCEEDED && error.retryAfter) {
|
|
196
|
-
return error.retryAfter * 1000;
|
|
149
|
+
return error.retryAfter * 1000;
|
|
197
150
|
}
|
|
198
151
|
return null;
|
|
199
152
|
}
|
|
200
|
-
/**
|
|
201
|
-
* Check if error is retryable
|
|
202
|
-
*/
|
|
203
153
|
export function isRetryableError(error) {
|
|
204
154
|
const retryableCodes = [
|
|
205
155
|
PhoneAuthErrorCode.NETWORK_ERROR,
|
|
@@ -209,12 +159,8 @@ export function isRetryableError(error) {
|
|
|
209
159
|
];
|
|
210
160
|
return retryableCodes.includes(error.code);
|
|
211
161
|
}
|
|
212
|
-
/**
|
|
213
|
-
* Parse error response from backend API
|
|
214
|
-
*/
|
|
215
162
|
export function parseBackendError(response) {
|
|
216
163
|
var _a, _b;
|
|
217
|
-
// Direct error structure from backend
|
|
218
164
|
if (response && typeof response === 'object' && (response.code || response.error)) {
|
|
219
165
|
const errorCode = response.code || response.error;
|
|
220
166
|
const error = {
|
|
@@ -224,18 +170,15 @@ export function parseBackendError(response) {
|
|
|
224
170
|
requestId: response.requestId || response.request_id,
|
|
225
171
|
timestamp: response.timestamp,
|
|
226
172
|
details: response.details,
|
|
227
|
-
// Include trace info for observability
|
|
228
173
|
traceId: response.trace_id || response.traceId,
|
|
229
174
|
spanId: response.span_id || response.spanId,
|
|
230
175
|
service: response.service
|
|
231
176
|
};
|
|
232
|
-
// Extract retryAfter from details if present
|
|
233
177
|
if ((_a = response.details) === null || _a === void 0 ? void 0 : _a.retryAfter) {
|
|
234
178
|
error.retryAfter = response.details.retryAfter;
|
|
235
179
|
}
|
|
236
180
|
return error;
|
|
237
181
|
}
|
|
238
|
-
// Handle HTTP response with error
|
|
239
182
|
if (response && response.status) {
|
|
240
183
|
const code = mapStatusToErrorCode(response.status);
|
|
241
184
|
return {
|
|
@@ -245,16 +188,12 @@ export function parseBackendError(response) {
|
|
|
245
188
|
requestId: (_b = response.headers) === null || _b === void 0 ? void 0 : _b['x-request-id']
|
|
246
189
|
};
|
|
247
190
|
}
|
|
248
|
-
// Default to unexpected error
|
|
249
191
|
return {
|
|
250
192
|
code: PhoneAuthErrorCode.INTERNAL_SERVER_ERROR,
|
|
251
193
|
message: 'An unexpected error occurred',
|
|
252
194
|
status: 500
|
|
253
195
|
};
|
|
254
196
|
}
|
|
255
|
-
/**
|
|
256
|
-
* Map HTTP status to error code
|
|
257
|
-
*/
|
|
258
197
|
function mapStatusToErrorCode(status) {
|
|
259
198
|
switch (status) {
|
|
260
199
|
case 400: return PhoneAuthErrorCode.BAD_REQUEST;
|
|
@@ -271,56 +210,35 @@ function mapStatusToErrorCode(status) {
|
|
|
271
210
|
default: return PhoneAuthErrorCode.INTERNAL_SERVER_ERROR;
|
|
272
211
|
}
|
|
273
212
|
}
|
|
274
|
-
/**
|
|
275
|
-
* Serialize error for logging/observability tools like Sentry
|
|
276
|
-
* This ensures all error details are captured in a format that can be sent over the network
|
|
277
|
-
*/
|
|
278
213
|
export function serializeError(error) {
|
|
279
214
|
return {
|
|
280
|
-
// Core error info
|
|
281
215
|
code: error.code,
|
|
282
216
|
message: error.message,
|
|
283
|
-
// Backend error details
|
|
284
217
|
status: error.status,
|
|
285
218
|
requestId: error.requestId,
|
|
286
219
|
timestamp: error.timestamp,
|
|
287
|
-
// Trace context for distributed tracing
|
|
288
220
|
traceId: error.traceId,
|
|
289
221
|
spanId: error.spanId,
|
|
290
222
|
service: error.service,
|
|
291
|
-
// Specific error fields
|
|
292
223
|
retryAfter: error.retryAfter,
|
|
293
|
-
// Browser error details
|
|
294
224
|
browserError: error.browserError,
|
|
295
|
-
// Context
|
|
296
225
|
context: error.context,
|
|
297
|
-
// Additional details (sanitized - no sensitive info)
|
|
298
226
|
details: sanitizeDetails(error.details),
|
|
299
|
-
// SDK metadata
|
|
300
227
|
sdkVersion: SDK_VERSION,
|
|
301
228
|
errorCapturedAt: new Date().toISOString()
|
|
302
229
|
};
|
|
303
230
|
}
|
|
304
|
-
/**
|
|
305
|
-
* Sanitize error details to remove sensitive information
|
|
306
|
-
*/
|
|
307
231
|
function sanitizeDetails(details) {
|
|
308
232
|
if (!details || typeof details !== 'object') {
|
|
309
233
|
return details;
|
|
310
234
|
}
|
|
311
|
-
// Clone the object
|
|
312
235
|
const sanitized = JSON.parse(JSON.stringify(details));
|
|
313
|
-
// Remove sensitive fields
|
|
314
236
|
const sensitiveFields = ['carrier', 'phone_number', 'mnc', 'mcc', 'carrier_name'];
|
|
315
237
|
for (const field of sensitiveFields) {
|
|
316
238
|
delete sanitized[field];
|
|
317
239
|
}
|
|
318
240
|
return sanitized;
|
|
319
241
|
}
|
|
320
|
-
/**
|
|
321
|
-
* Create a breadcrumb trail for error tracking
|
|
322
|
-
* Useful for understanding the sequence of events leading to an error
|
|
323
|
-
*/
|
|
324
242
|
export function createErrorBreadcrumb(error) {
|
|
325
243
|
var _a, _b, _c;
|
|
326
244
|
return {
|
|
@@ -3,6 +3,4 @@ export * from './types';
|
|
|
3
3
|
export { PhoneAuthErrorCode, isPhoneAuthError, isUserError, getUserMessage, isErrorCode, getRetryDelay, isRetryableError, serializeError, createErrorBreadcrumb } from './error-utils';
|
|
4
4
|
export { validatePhoneNumber, validatePlmn, validateUseCaseRequirements, validateNonce } from './validation-utils';
|
|
5
5
|
export { MobileDebugConsole } from './ui/mobile-debug-console';
|
|
6
|
-
export { isExtendedResponse, isCredential, isAuthCredential, isLinkStrategy, isTS43Strategy, isDesktopStrategy, getStrategy, hasPollingControls, hasTrigger,
|
|
7
|
-
// Deprecated aliases
|
|
8
|
-
isHeadlessResult, requiresPolling, requiresUserAction } from './type-guards';
|
|
6
|
+
export { isExtendedResponse, isCredential, isAuthCredential, isLinkStrategy, isTS43Strategy, isDesktopStrategy, getStrategy, hasPollingControls, hasTrigger, isHeadlessResult, requiresPolling, requiresUserAction } from './type-guards';
|
|
@@ -1,69 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Status Types for Public Status Endpoint
|
|
3
|
-
*
|
|
4
|
-
* These types define the response format for the public status endpoint
|
|
5
|
-
* Used for polling authentication status without exposing sensitive data
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Status values returned by the public endpoint (HTTP 200 only)
|
|
9
|
-
*/
|
|
10
1
|
export type AuthenticationStatus = 'pending' | 'completed';
|
|
11
|
-
/**
|
|
12
|
-
* Authentication protocol/strategy used
|
|
13
|
-
*/
|
|
14
2
|
export type AuthenticationProtocol = 'ts43' | 'link' | 'desktop';
|
|
15
|
-
/**
|
|
16
|
-
* Public Status Response (HTTP 200 OK)
|
|
17
|
-
*
|
|
18
|
-
* This response is only returned with HTTP 200 status code
|
|
19
|
-
* Failed/expired sessions return HTTP 4xx with ErrorResponse
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```typescript
|
|
23
|
-
* // Public endpoint (no auth required)
|
|
24
|
-
* const response = await fetch('/public/public/status/{sessionKey}');
|
|
25
|
-
*
|
|
26
|
-
* if (response.status === 200) {
|
|
27
|
-
* const status: StatusResponse = await response.json();
|
|
28
|
-
* if (status.status === 'completed') {
|
|
29
|
-
* // Authentication successful - now call process endpoint
|
|
30
|
-
* const result = await processAuthentication(sessionKey);
|
|
31
|
-
* }
|
|
32
|
-
* } else if (response.status === 410) {
|
|
33
|
-
* // Session expired
|
|
34
|
-
* } else if (response.status === 422) {
|
|
35
|
-
* // Authentication failed (user cancelled, etc.)
|
|
36
|
-
* }
|
|
37
|
-
* ```
|
|
38
|
-
*/
|
|
39
3
|
export interface StatusResponse {
|
|
40
|
-
/**
|
|
41
|
-
* The session key/identifier
|
|
42
|
-
*/
|
|
43
4
|
session_key: string;
|
|
44
|
-
/**
|
|
45
|
-
* Current status of the authentication (only successful states)
|
|
46
|
-
*/
|
|
47
5
|
status: AuthenticationStatus;
|
|
48
|
-
/**
|
|
49
|
-
* Protocol/strategy used for authentication
|
|
50
|
-
* Optional - may not be present during pending state
|
|
51
|
-
*/
|
|
52
6
|
protocol?: AuthenticationProtocol;
|
|
53
|
-
/**
|
|
54
|
-
* ISO 8601 timestamp when session was created
|
|
55
|
-
*/
|
|
56
7
|
created_at: string;
|
|
57
|
-
/**
|
|
58
|
-
* ISO 8601 timestamp of last status update
|
|
59
|
-
*/
|
|
60
8
|
last_updated: string;
|
|
61
9
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Error Response (HTTP 4xx)
|
|
64
|
-
*
|
|
65
|
-
* Returned when session is expired, failed, or not found
|
|
66
|
-
*/
|
|
67
10
|
export interface StatusErrorResponse {
|
|
68
11
|
code: 'SESSION_EXPIRED' | 'USER_CANCELLED' | 'AUTHENTICATION_FAILED' | 'SESSION_NOT_FOUND' | 'INVALID_SESSION_KEY';
|
|
69
12
|
message: string;
|
|
@@ -76,32 +19,11 @@ export interface StatusErrorResponse {
|
|
|
76
19
|
duration_seconds?: number;
|
|
77
20
|
};
|
|
78
21
|
}
|
|
79
|
-
/**
|
|
80
|
-
* Type guard to check if authentication was successful
|
|
81
|
-
*/
|
|
82
22
|
export declare function isSuccessStatus(status: AuthenticationStatus): boolean;
|
|
83
|
-
/**
|
|
84
|
-
* Helper to determine if polling should continue based on HTTP status
|
|
85
|
-
*/
|
|
86
23
|
export declare function shouldContinuePolling(httpStatus: number, response?: StatusResponse): boolean;
|
|
87
|
-
/**
|
|
88
|
-
* Helper to determine if session is terminated based on HTTP status
|
|
89
|
-
*/
|
|
90
24
|
export declare function isTerminalHttpStatus(httpStatus: number): boolean;
|
|
91
|
-
/**
|
|
92
|
-
* Session binding types for parent-child relationships
|
|
93
|
-
*/
|
|
94
25
|
export interface SessionBinding {
|
|
95
|
-
/**
|
|
96
|
-
* Parent session ID (desktop QR code session)
|
|
97
|
-
*/
|
|
98
26
|
parent_session_id?: string;
|
|
99
|
-
/**
|
|
100
|
-
* Child session ID (mobile authentication session)
|
|
101
|
-
*/
|
|
102
27
|
child_session_id?: string;
|
|
103
|
-
/**
|
|
104
|
-
* Whether this is a parent or child session
|
|
105
|
-
*/
|
|
106
28
|
session_type?: 'parent' | 'child';
|
|
107
29
|
}
|
|
@@ -1,26 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Status Types for Public Status Endpoint
|
|
3
|
-
*
|
|
4
|
-
* These types define the response format for the public status endpoint
|
|
5
|
-
* Used for polling authentication status without exposing sensitive data
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Type guard to check if authentication was successful
|
|
9
|
-
*/
|
|
10
1
|
export function isSuccessStatus(status) {
|
|
11
2
|
return status === 'completed';
|
|
12
3
|
}
|
|
13
|
-
/**
|
|
14
|
-
* Helper to determine if polling should continue based on HTTP status
|
|
15
|
-
*/
|
|
16
4
|
export function shouldContinuePolling(httpStatus, response) {
|
|
17
|
-
// Only continue if HTTP 200 and status is pending
|
|
18
5
|
return httpStatus === 200 && (response === null || response === void 0 ? void 0 : response.status) === 'pending';
|
|
19
6
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Helper to determine if session is terminated based on HTTP status
|
|
22
|
-
*/
|
|
23
7
|
export function isTerminalHttpStatus(httpStatus) {
|
|
24
|
-
// 410 Gone (expired), 422 Unprocessable (failed), 404 Not Found
|
|
25
8
|
return httpStatus === 410 || httpStatus === 422 || httpStatus === 404;
|
|
26
9
|
}
|
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Desktop Strategy Handler
|
|
3
|
-
* Handles QR code-based authentication for desktop browsers
|
|
4
|
-
* Manages QR code display and polling for authentication status
|
|
5
|
-
*/
|
|
6
1
|
import type { StrategyHandler } from './types';
|
|
7
2
|
import type { PrepareResponse } from '../types';
|
|
8
|
-
/**
|
|
9
|
-
* QR code data structure for dual-platform support
|
|
10
|
-
*/
|
|
11
3
|
export interface QRCodeData {
|
|
12
4
|
iosQRCode: string;
|
|
13
5
|
androidQRCode?: string;
|
|
@@ -15,39 +7,24 @@ export interface QRCodeData {
|
|
|
15
7
|
androidUrl?: string;
|
|
16
8
|
}
|
|
17
9
|
export interface DesktopAuthOptions {
|
|
18
|
-
/** Custom polling interval in milliseconds (overrides server-provided value) */
|
|
19
10
|
pollingInterval?: number;
|
|
20
|
-
/** Maximum polling attempts before timeout (default: 30 = 1 minute with 2s interval) */
|
|
21
11
|
maxPollingAttempts?: number;
|
|
22
|
-
/** Custom polling endpoint (overrides backend-provided or uses configured endpoint) */
|
|
23
12
|
pollingEndpoint?: string;
|
|
24
|
-
/** Callback when QR code is ready to display */
|
|
25
13
|
onQRCodeReady?: (qrCodeData: string | QRCodeData) => void;
|
|
26
|
-
/** Callback for polling status updates */
|
|
27
14
|
onStatusUpdate?: (status: PollingStatus) => void;
|
|
28
|
-
/** Callback when authentication expires */
|
|
29
15
|
onExpired?: () => void;
|
|
30
|
-
/** Callback when authentication is cancelled by user */
|
|
31
16
|
onCancel?: () => void;
|
|
32
|
-
/** Callback when polling times out (max attempts reached) */
|
|
33
17
|
onTimeout?: () => void;
|
|
34
18
|
}
|
|
35
19
|
export interface PollingStatus {
|
|
36
|
-
/** Current status of the authentication */
|
|
37
20
|
status: 'pending' | 'authenticated' | 'expired' | 'cancelled' | 'error';
|
|
38
|
-
/** Optional message */
|
|
39
21
|
message?: string;
|
|
40
|
-
/** Authentication result data if status is 'authenticated' */
|
|
41
22
|
data?: any;
|
|
42
23
|
}
|
|
43
24
|
export interface DesktopAuthResult {
|
|
44
|
-
/** Whether authentication was successful */
|
|
45
25
|
authenticated: boolean;
|
|
46
|
-
/** Authentication credential if successful */
|
|
47
26
|
credential?: string;
|
|
48
|
-
/** Session info for subsequent requests */
|
|
49
27
|
session?: any;
|
|
50
|
-
/** Error message if authentication failed */
|
|
51
28
|
error?: string;
|
|
52
29
|
}
|
|
53
30
|
export declare class DesktopHandler implements StrategyHandler {
|
|
@@ -57,62 +34,22 @@ export declare class DesktopHandler implements StrategyHandler {
|
|
|
57
34
|
private onCancel?;
|
|
58
35
|
private pollingReject?;
|
|
59
36
|
private isPollingInProgress;
|
|
60
|
-
/**
|
|
61
|
-
* Maps backend HTTP status codes to client status
|
|
62
|
-
* @param httpStatus HTTP status code from backend
|
|
63
|
-
* @param bodyStatus Optional status from response body (for 200 OK responses)
|
|
64
|
-
* @returns Mapped status string for client use
|
|
65
|
-
*/
|
|
66
37
|
private mapBackendStatus;
|
|
67
|
-
/**
|
|
68
|
-
* Invoke desktop authentication with QR code
|
|
69
|
-
* Returns QR code data for display and starts polling if endpoint is provided
|
|
70
|
-
*/
|
|
71
38
|
invoke(data: PrepareResponse, options?: DesktopAuthOptions): Promise<DesktopAuthResult>;
|
|
72
|
-
/**
|
|
73
|
-
* Start polling for authentication status
|
|
74
|
-
*/
|
|
75
39
|
private startPolling;
|
|
76
|
-
/**
|
|
77
|
-
* Stop polling
|
|
78
|
-
*/
|
|
79
40
|
private stopPolling;
|
|
80
|
-
/**
|
|
81
|
-
* Check if polling is currently active
|
|
82
|
-
*/
|
|
83
41
|
isPolling(): boolean;
|
|
84
|
-
/**
|
|
85
|
-
* Format response for backend processing
|
|
86
|
-
* Desktop strategy typically returns the credential from mobile authentication
|
|
87
|
-
*/
|
|
88
42
|
formatResponse(response: DesktopAuthResult): any;
|
|
89
|
-
/**
|
|
90
|
-
* Check if desktop authentication is supported
|
|
91
|
-
* Desktop auth with QR codes works in any modern browser
|
|
92
|
-
*/
|
|
93
43
|
isSupported(): boolean;
|
|
94
|
-
/**
|
|
95
|
-
* Clean up resources (stop polling if active)
|
|
96
|
-
*/
|
|
97
44
|
cleanup(): void;
|
|
98
|
-
/**
|
|
99
|
-
* Cancel the ongoing authentication
|
|
100
|
-
*/
|
|
101
45
|
cancel(): void;
|
|
102
46
|
}
|
|
103
|
-
/**
|
|
104
|
-
* Helper function to display QR code in a modal or inline
|
|
105
|
-
*/
|
|
106
47
|
export declare function createQRCodeDisplay(qrCodeData: string | QRCodeData, options?: {
|
|
107
48
|
container?: HTMLElement;
|
|
108
49
|
size?: number;
|
|
109
50
|
title?: string;
|
|
110
51
|
description?: string;
|
|
111
52
|
}): HTMLElement;
|
|
112
|
-
/**
|
|
113
|
-
* Helper function to create a modal for QR code display
|
|
114
|
-
* Supports both string QR codes and QRCodeData objects for dual-platform support
|
|
115
|
-
*/
|
|
116
53
|
export declare function showQRCodeModal(qrCodeData: string | QRCodeData, options?: {
|
|
117
54
|
title?: string;
|
|
118
55
|
description?: string;
|