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