@glideidentity/web-client-sdk 5.0.1 → 5.1.1-beta.3
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 -6
- 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 +312 -2
- 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
package/dist/browser.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// Browser-specific entry point for vanilla JavaScript usage
|
|
3
|
+
// This excludes framework-specific adapters that require Angular/React/Vue
|
|
2
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
5
|
exports.PhoneAuthManager = exports.ClientManager = exports.BrowserName = exports.BrowserErrorCode = exports.BrowserError = exports.AuthenticationStrategy = exports.UseCase = exports.createErrorBreadcrumb = exports.serializeError = exports.isRetryableError = exports.getRetryDelay = exports.isErrorCode = exports.getUserMessage = exports.isUserError = exports.isPhoneAuthError = exports.PhoneAuthErrorCode = exports.PhoneAuthClient = void 0;
|
|
6
|
+
// Phone Authentication - Core client
|
|
4
7
|
var phone_auth_1 = require("./core/phone-auth");
|
|
5
8
|
Object.defineProperty(exports, "PhoneAuthClient", { enumerable: true, get: function () { return phone_auth_1.PhoneAuthClient; } });
|
|
9
|
+
// Phone Auth Error Utilities
|
|
6
10
|
var phone_auth_2 = require("./core/phone-auth");
|
|
7
11
|
Object.defineProperty(exports, "PhoneAuthErrorCode", { enumerable: true, get: function () { return phone_auth_2.PhoneAuthErrorCode; } });
|
|
8
12
|
Object.defineProperty(exports, "isPhoneAuthError", { enumerable: true, get: function () { return phone_auth_2.isPhoneAuthError; } });
|
|
@@ -13,12 +17,14 @@ Object.defineProperty(exports, "getRetryDelay", { enumerable: true, get: functio
|
|
|
13
17
|
Object.defineProperty(exports, "isRetryableError", { enumerable: true, get: function () { return phone_auth_2.isRetryableError; } });
|
|
14
18
|
Object.defineProperty(exports, "serializeError", { enumerable: true, get: function () { return phone_auth_2.serializeError; } });
|
|
15
19
|
Object.defineProperty(exports, "createErrorBreadcrumb", { enumerable: true, get: function () { return phone_auth_2.createErrorBreadcrumb; } });
|
|
20
|
+
// Export constants for use case and strategy
|
|
16
21
|
var types_1 = require("./core/phone-auth/types");
|
|
17
22
|
Object.defineProperty(exports, "UseCase", { enumerable: true, get: function () { return types_1.USE_CASE; } });
|
|
18
23
|
Object.defineProperty(exports, "AuthenticationStrategy", { enumerable: true, get: function () { return types_1.AUTHENTICATION_STRATEGY; } });
|
|
19
24
|
Object.defineProperty(exports, "BrowserError", { enumerable: true, get: function () { return types_1.BrowserError; } });
|
|
20
25
|
Object.defineProperty(exports, "BrowserErrorCode", { enumerable: true, get: function () { return types_1.BrowserErrorCode; } });
|
|
21
26
|
Object.defineProperty(exports, "BrowserName", { enumerable: true, get: function () { return types_1.BrowserName; } });
|
|
27
|
+
// Vanilla adapters ONLY (no framework dependencies)
|
|
22
28
|
var client_1 = require("./adapters/vanilla/client");
|
|
23
29
|
Object.defineProperty(exports, "ClientManager", { enumerable: true, get: function () { return client_1.VanillaClient; } });
|
|
24
30
|
var phone_auth_3 = require("./adapters/vanilla/phone-auth");
|
package/dist/core/client.js
CHANGED
|
@@ -25,6 +25,7 @@ class SDKClient {
|
|
|
25
25
|
'Content-Type': 'application/json',
|
|
26
26
|
},
|
|
27
27
|
});
|
|
28
|
+
// Initialize Phone Auth client
|
|
28
29
|
this.phoneAuth = new phone_auth_1.PhoneAuthClient({
|
|
29
30
|
endpoints: config.phoneAuthEndpoints ? {
|
|
30
31
|
prepare: config.phoneAuthEndpoints.prepareRequest,
|
|
@@ -32,6 +33,7 @@ class SDKClient {
|
|
|
32
33
|
} : undefined,
|
|
33
34
|
debug: config.debug
|
|
34
35
|
});
|
|
36
|
+
// Add authentication interceptor
|
|
35
37
|
this.client.interceptors.request.use((config) => __awaiter(this, void 0, void 0, function* () {
|
|
36
38
|
if (this.token) {
|
|
37
39
|
config.headers.Authorization = `Bearer ${this.token}`;
|
|
@@ -39,12 +41,22 @@ class SDKClient {
|
|
|
39
41
|
return config;
|
|
40
42
|
}));
|
|
41
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Set authentication token for API requests
|
|
46
|
+
*/
|
|
42
47
|
setToken(token) {
|
|
43
48
|
this.token = token;
|
|
44
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Clear authentication token
|
|
52
|
+
*/
|
|
45
53
|
clearToken() {
|
|
46
54
|
this.token = undefined;
|
|
47
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Make a GET request to the API
|
|
58
|
+
* Note: Requires baseURL to be set in the config
|
|
59
|
+
*/
|
|
48
60
|
get(path, options) {
|
|
49
61
|
return __awaiter(this, void 0, void 0, function* () {
|
|
50
62
|
if (!this.config.baseURL) {
|
package/dist/core/logger.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Industry-grade logging for Glide Web SDK
|
|
4
|
+
* Following best practices from Stripe, Auth0, Twilio, and AWS Amplify
|
|
5
|
+
*/
|
|
2
6
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
7
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
8
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -21,6 +25,9 @@ var LogLevel;
|
|
|
21
25
|
LogLevel[LogLevel["INFO"] = 3] = "INFO";
|
|
22
26
|
LogLevel[LogLevel["DEBUG"] = 4] = "DEBUG";
|
|
23
27
|
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
|
28
|
+
/**
|
|
29
|
+
* Default browser console logger with automatic data sanitization
|
|
30
|
+
*/
|
|
24
31
|
class ConsoleLogger {
|
|
25
32
|
constructor(level = LogLevel.SILENT, prefix = '[Glide]', enableGrouping = false) {
|
|
26
33
|
this.level = level;
|
|
@@ -50,7 +57,9 @@ class ConsoleLogger {
|
|
|
50
57
|
log(level, message, fields) {
|
|
51
58
|
const timestamp = new Date().toISOString();
|
|
52
59
|
const sanitizedFields = fields ? this.sanitizeFields(fields) : {};
|
|
60
|
+
// Format the message
|
|
53
61
|
const formattedMessage = `${this.prefix} ${timestamp} [${level.toUpperCase()}] ${message}`;
|
|
62
|
+
// Use console grouping for better readability if enabled
|
|
54
63
|
if (this.enableGrouping && Object.keys(sanitizedFields).length > 0) {
|
|
55
64
|
console.groupCollapsed(formattedMessage);
|
|
56
65
|
Object.entries(sanitizedFields).forEach(([key, value]) => {
|
|
@@ -59,6 +68,7 @@ class ConsoleLogger {
|
|
|
59
68
|
console.groupEnd();
|
|
60
69
|
}
|
|
61
70
|
else {
|
|
71
|
+
// Standard logging with or without fields
|
|
62
72
|
if (Object.keys(sanitizedFields).length > 0) {
|
|
63
73
|
console[level](formattedMessage, sanitizedFields);
|
|
64
74
|
}
|
|
@@ -67,6 +77,9 @@ class ConsoleLogger {
|
|
|
67
77
|
}
|
|
68
78
|
}
|
|
69
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Sanitize sensitive data from log fields
|
|
82
|
+
*/
|
|
70
83
|
sanitizeFields(fields) {
|
|
71
84
|
const sanitized = {};
|
|
72
85
|
for (const [key, value] of Object.entries(fields)) {
|
|
@@ -74,7 +87,11 @@ class ConsoleLogger {
|
|
|
74
87
|
}
|
|
75
88
|
return sanitized;
|
|
76
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Redact sensitive information based on field name and value patterns
|
|
92
|
+
*/
|
|
77
93
|
sanitizeValue(key, value) {
|
|
94
|
+
// List of sensitive field patterns
|
|
78
95
|
const sensitiveFields = [
|
|
79
96
|
'apikey', 'api_key', 'apiKey',
|
|
80
97
|
'token', 'accesstoken', 'access_token', 'accessToken',
|
|
@@ -84,6 +101,7 @@ class ConsoleLogger {
|
|
|
84
101
|
'cookie', 'session',
|
|
85
102
|
];
|
|
86
103
|
const lowerKey = key.toLowerCase();
|
|
104
|
+
// Check if field name indicates sensitive data
|
|
87
105
|
for (const sensitive of sensitiveFields) {
|
|
88
106
|
if (lowerKey.includes(sensitive.toLowerCase())) {
|
|
89
107
|
if (typeof value === 'string' && value.length > 4) {
|
|
@@ -92,30 +110,38 @@ class ConsoleLogger {
|
|
|
92
110
|
return '****[REDACTED]';
|
|
93
111
|
}
|
|
94
112
|
}
|
|
113
|
+
// Handle specific value patterns
|
|
95
114
|
if (typeof value === 'string') {
|
|
115
|
+
// Phone number pattern - show area code only
|
|
96
116
|
const phoneRegex = /^\+?[1-9]\d{6,14}$/;
|
|
97
117
|
if (phoneRegex.test(value)) {
|
|
98
118
|
return value.substring(0, 6) + '****';
|
|
99
119
|
}
|
|
120
|
+
// Email pattern - show domain only
|
|
100
121
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
101
122
|
if (emailRegex.test(value)) {
|
|
102
123
|
const [, domain] = value.split('@');
|
|
103
124
|
return '****@' + domain;
|
|
104
125
|
}
|
|
126
|
+
// URL with credentials
|
|
105
127
|
if (value.includes('://') && value.includes('@')) {
|
|
106
128
|
return value.replace(/\/\/([^:]+):([^@]+)@/, '//****:****@');
|
|
107
129
|
}
|
|
130
|
+
// JWT tokens
|
|
108
131
|
if (value.startsWith('eyJ') && value.split('.').length === 3) {
|
|
109
132
|
return value.substring(0, 10) + '****[JWT]';
|
|
110
133
|
}
|
|
134
|
+
// Credit card numbers
|
|
111
135
|
const creditCardRegex = /\b\d{13,19}\b/;
|
|
112
136
|
if (creditCardRegex.test(value)) {
|
|
113
137
|
return value.substring(0, 4) + '****' + value.substring(value.length - 4);
|
|
114
138
|
}
|
|
115
139
|
}
|
|
140
|
+
// Recursively sanitize objects
|
|
116
141
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
117
142
|
return this.sanitizeFields(value);
|
|
118
143
|
}
|
|
144
|
+
// Sanitize arrays
|
|
119
145
|
if (Array.isArray(value)) {
|
|
120
146
|
return value.map((item, index) => this.sanitizeValue(`${key}[${index}]`, item));
|
|
121
147
|
}
|
|
@@ -123,6 +149,9 @@ class ConsoleLogger {
|
|
|
123
149
|
}
|
|
124
150
|
}
|
|
125
151
|
exports.ConsoleLogger = ConsoleLogger;
|
|
152
|
+
/**
|
|
153
|
+
* No-op logger for when logging is disabled
|
|
154
|
+
*/
|
|
126
155
|
class NoopLogger {
|
|
127
156
|
debug(message, fields) { }
|
|
128
157
|
info(message, fields) { }
|
|
@@ -130,16 +159,22 @@ class NoopLogger {
|
|
|
130
159
|
error(message, fields) { }
|
|
131
160
|
}
|
|
132
161
|
exports.NoopLogger = NoopLogger;
|
|
162
|
+
/**
|
|
163
|
+
* Remote logger for sending logs to a backend service
|
|
164
|
+
* Useful for debugging production issues
|
|
165
|
+
*/
|
|
133
166
|
class RemoteLogger {
|
|
134
167
|
constructor(endpoint, apiKey, fallbackLogger) {
|
|
135
168
|
this.buffer = [];
|
|
136
|
-
this.flushInterval = 5000;
|
|
169
|
+
this.flushInterval = 5000; // 5 seconds
|
|
137
170
|
this.maxBufferSize = 100;
|
|
138
171
|
this.endpoint = endpoint;
|
|
139
172
|
this.apiKey = apiKey;
|
|
140
173
|
this.localLogger = fallbackLogger || new ConsoleLogger(LogLevel.ERROR);
|
|
174
|
+
// Set up automatic flushing
|
|
141
175
|
if (typeof window !== 'undefined') {
|
|
142
176
|
setInterval(() => this.flush(), this.flushInterval);
|
|
177
|
+
// Flush on page unload
|
|
143
178
|
window.addEventListener('beforeunload', () => this.flush());
|
|
144
179
|
}
|
|
145
180
|
}
|
|
@@ -165,7 +200,9 @@ class RemoteLogger {
|
|
|
165
200
|
url: typeof window !== 'undefined' ? window.location.href : undefined,
|
|
166
201
|
};
|
|
167
202
|
this.buffer.push(logEntry);
|
|
203
|
+
// Also log locally for immediate feedback
|
|
168
204
|
this.localLogger[level](message, fields);
|
|
205
|
+
// Flush if buffer is full
|
|
169
206
|
if (this.buffer.length >= this.maxBufferSize) {
|
|
170
207
|
this.flush();
|
|
171
208
|
}
|
|
@@ -187,12 +224,18 @@ class RemoteLogger {
|
|
|
187
224
|
});
|
|
188
225
|
}
|
|
189
226
|
catch (error) {
|
|
227
|
+
// Failed to send logs, log locally
|
|
190
228
|
this.localLogger.error('Failed to send logs to remote server', { error });
|
|
229
|
+
// Optionally, put logs back in buffer for retry
|
|
230
|
+
// this.buffer.unshift(...logs);
|
|
191
231
|
}
|
|
192
232
|
});
|
|
193
233
|
}
|
|
194
234
|
}
|
|
195
235
|
exports.RemoteLogger = RemoteLogger;
|
|
236
|
+
/**
|
|
237
|
+
* Parse log level from string
|
|
238
|
+
*/
|
|
196
239
|
function parseLogLevel(level) {
|
|
197
240
|
switch (level.toLowerCase()) {
|
|
198
241
|
case 'debug':
|
|
@@ -212,7 +255,11 @@ function parseLogLevel(level) {
|
|
|
212
255
|
return LogLevel.SILENT;
|
|
213
256
|
}
|
|
214
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Get log level from browser environment
|
|
260
|
+
*/
|
|
215
261
|
function getLogLevelFromEnv() {
|
|
262
|
+
// Check localStorage
|
|
216
263
|
if (typeof localStorage !== 'undefined') {
|
|
217
264
|
const storedLevel = localStorage.getItem('GLIDE_LOG_LEVEL');
|
|
218
265
|
if (storedLevel) {
|
|
@@ -223,6 +270,7 @@ function getLogLevelFromEnv() {
|
|
|
223
270
|
return LogLevel.DEBUG;
|
|
224
271
|
}
|
|
225
272
|
}
|
|
273
|
+
// Check URL parameters
|
|
226
274
|
if (typeof window !== 'undefined' && window.location) {
|
|
227
275
|
const params = new URLSearchParams(window.location.search);
|
|
228
276
|
const urlLogLevel = params.get('glide_log_level');
|
|
@@ -235,19 +283,31 @@ function getLogLevelFromEnv() {
|
|
|
235
283
|
}
|
|
236
284
|
return LogLevel.SILENT;
|
|
237
285
|
}
|
|
286
|
+
/**
|
|
287
|
+
* Performance timer for measuring operation duration
|
|
288
|
+
*/
|
|
238
289
|
class PerformanceTimer {
|
|
239
290
|
constructor(logger) {
|
|
240
291
|
this.marks = new Map();
|
|
241
292
|
this.startTime = performance.now();
|
|
242
293
|
this.logger = logger;
|
|
243
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Mark a point in time
|
|
297
|
+
*/
|
|
244
298
|
mark(name) {
|
|
245
299
|
this.marks.set(name, performance.now());
|
|
246
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* Log elapsed time with optional fields
|
|
303
|
+
*/
|
|
247
304
|
logElapsed(message, fields) {
|
|
248
305
|
const elapsed = performance.now() - this.startTime;
|
|
249
306
|
this.logger.debug(message, Object.assign(Object.assign({}, fields), { elapsedMs: elapsed, elapsed: `${elapsed.toFixed(2)}ms` }));
|
|
250
307
|
}
|
|
308
|
+
/**
|
|
309
|
+
* Log time between marks
|
|
310
|
+
*/
|
|
251
311
|
logMarkDuration(fromMark, toMark, message, fields) {
|
|
252
312
|
const from = this.marks.get(fromMark);
|
|
253
313
|
const to = this.marks.get(toMark);
|
|
@@ -259,29 +319,49 @@ class PerformanceTimer {
|
|
|
259
319
|
}
|
|
260
320
|
}
|
|
261
321
|
exports.PerformanceTimer = PerformanceTimer;
|
|
322
|
+
/**
|
|
323
|
+
* Generate a unique request ID for distributed tracing
|
|
324
|
+
*/
|
|
262
325
|
function generateRequestId() {
|
|
263
326
|
return `req_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
264
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* Logger factory for creating loggers with consistent configuration
|
|
330
|
+
*/
|
|
265
331
|
class LoggerFactory {
|
|
332
|
+
/**
|
|
333
|
+
* Set the default log level for all new loggers
|
|
334
|
+
*/
|
|
266
335
|
static setDefaultLevel(level) {
|
|
267
336
|
this.defaultLevel = level;
|
|
268
337
|
}
|
|
338
|
+
/**
|
|
339
|
+
* Set a default logger instance to use
|
|
340
|
+
*/
|
|
269
341
|
static setDefaultLogger(logger) {
|
|
270
342
|
this.defaultLogger = logger;
|
|
271
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* Create a logger instance based on configuration
|
|
346
|
+
*/
|
|
272
347
|
static create(options) {
|
|
273
348
|
var _a, _b;
|
|
349
|
+
// Use custom logger if provided
|
|
274
350
|
if (options === null || options === void 0 ? void 0 : options.custom) {
|
|
275
351
|
return options.custom;
|
|
276
352
|
}
|
|
353
|
+
// Use default logger if set
|
|
277
354
|
if (this.defaultLogger) {
|
|
278
355
|
return this.defaultLogger;
|
|
279
356
|
}
|
|
357
|
+
// Determine log level
|
|
280
358
|
const level = (_b = (_a = options === null || options === void 0 ? void 0 : options.level) !== null && _a !== void 0 ? _a : getLogLevelFromEnv()) !== null && _b !== void 0 ? _b : this.defaultLevel;
|
|
359
|
+
// Create remote logger if configured
|
|
281
360
|
if (options === null || options === void 0 ? void 0 : options.remote) {
|
|
282
361
|
const fallbackLogger = new ConsoleLogger(level, options === null || options === void 0 ? void 0 : options.prefix);
|
|
283
362
|
return new RemoteLogger(options.remote.endpoint, options.remote.apiKey, fallbackLogger);
|
|
284
363
|
}
|
|
364
|
+
// Create console logger
|
|
285
365
|
return new ConsoleLogger(level, options === null || options === void 0 ? void 0 : options.prefix);
|
|
286
366
|
}
|
|
287
367
|
}
|
|
@@ -25,8 +25,6 @@ export interface SessionInfo {
|
|
|
25
25
|
session_key: string;
|
|
26
26
|
/** Security nonce */
|
|
27
27
|
nonce?: string;
|
|
28
|
-
/** Encryption key for secure operations */
|
|
29
|
-
enc_key?: string;
|
|
30
28
|
/** Additional metadata from server */
|
|
31
29
|
metadata?: Record<string, string>;
|
|
32
30
|
}
|
|
@@ -82,7 +80,7 @@ export interface PrepareOptions {
|
|
|
82
80
|
}
|
|
83
81
|
/**
|
|
84
82
|
* Request to prepare authentication session
|
|
85
|
-
* Note:
|
|
83
|
+
* Note: id is auto-generated by SDK if not provided
|
|
86
84
|
*/
|
|
87
85
|
export interface PrepareRequest {
|
|
88
86
|
/** Use case for this authentication (optional when parent_session_id is provided - inherited from parent) */
|
|
@@ -92,9 +90,6 @@ export interface PrepareRequest {
|
|
|
92
90
|
phone_number?: PhoneNumber;
|
|
93
91
|
/** Alternative to phone_number */
|
|
94
92
|
plmn?: PLMN;
|
|
95
|
-
/** Optional: Auto-generated by SDKs if not provided */
|
|
96
|
-
/** Unique nonce (SDK generates secure random if not provided) */
|
|
97
|
-
nonce?: string;
|
|
98
93
|
/** Request identifier (SDK generates unique ID if not provided) */
|
|
99
94
|
id?: string;
|
|
100
95
|
/** Optional fields */
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Glide Phone Authentication API Types
|
|
4
|
+
*
|
|
5
|
+
* This file is copied from the master API specification at /glide-api-types.ts
|
|
6
|
+
* It defines the exact contract that ALL implementations must follow.
|
|
7
|
+
*
|
|
8
|
+
* NAMING CONVENTION:
|
|
9
|
+
* - ALL TYPES USE snake_case FOR API COMMUNICATION
|
|
10
|
+
* - Frontend SDKs should use snake_case throughout for consistency
|
|
11
|
+
* - This eliminates conversion errors and makes debugging easier
|
|
12
|
+
* - While not idiomatic JavaScript, it matches the API exactly
|
|
13
|
+
*/
|
|
2
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
15
|
exports.E164_REGEX = exports.ERROR_STATUS_CODES = exports.ERROR_MESSAGES = exports.ERROR_CODE = exports.AUTHENTICATION_STRATEGY = exports.USE_CASE = void 0;
|
|
4
16
|
exports.validatePhoneNumber = validatePhoneNumber;
|
|
@@ -10,31 +22,52 @@ exports.getErrorStatusCode = getErrorStatusCode;
|
|
|
10
22
|
exports.isTS43Data = isTS43Data;
|
|
11
23
|
exports.isLinkData = isLinkData;
|
|
12
24
|
exports.isErrorResponse = isErrorResponse;
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// USE CASES
|
|
27
|
+
// ============================================================================
|
|
13
28
|
exports.USE_CASE = {
|
|
14
29
|
GET_PHONE_NUMBER: 'GetPhoneNumber',
|
|
15
30
|
VERIFY_PHONE_NUMBER: 'VerifyPhoneNumber'
|
|
16
31
|
};
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// AUTHENTICATION STRATEGIES
|
|
34
|
+
// ============================================================================
|
|
17
35
|
exports.AUTHENTICATION_STRATEGY = {
|
|
18
36
|
TS43: 'ts43',
|
|
19
37
|
LINK: 'link',
|
|
20
38
|
DESKTOP: 'desktop'
|
|
21
39
|
};
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// ERROR HANDLING
|
|
42
|
+
// ============================================================================
|
|
43
|
+
/**
|
|
44
|
+
* Error codes - MUST match server implementation
|
|
45
|
+
*/
|
|
22
46
|
exports.ERROR_CODE = {
|
|
47
|
+
// 400 Bad Request
|
|
23
48
|
INVALID_PHONE_NUMBER: 'INVALID_PHONE_NUMBER',
|
|
24
49
|
MISSING_REQUIRED_FIELD: 'MISSING_REQUIRED_FIELD',
|
|
25
50
|
INVALID_USE_CASE: 'INVALID_USE_CASE',
|
|
51
|
+
// 404 Not Found
|
|
26
52
|
INVALID_SESSION: 'INVALID_SESSION',
|
|
27
53
|
SESSION_EXPIRED: 'SESSION_EXPIRED',
|
|
54
|
+
// 422 Unprocessable Entity
|
|
28
55
|
CARRIER_NOT_ELIGIBLE: 'CARRIER_NOT_ELIGIBLE',
|
|
29
56
|
UNSUPPORTED_PLATFORM: 'UNSUPPORTED_PLATFORM',
|
|
30
57
|
PHONE_NUMBER_MISMATCH: 'PHONE_NUMBER_MISMATCH',
|
|
31
58
|
INVALID_CREDENTIAL: 'INVALID_CREDENTIAL',
|
|
32
59
|
VERIFICATION_FAILED: 'VERIFICATION_FAILED',
|
|
33
60
|
USE_CASE_MISMATCH: 'USE_CASE_MISMATCH',
|
|
61
|
+
// 429 Too Many Requests
|
|
34
62
|
RATE_LIMIT_EXCEEDED: 'RATE_LIMIT_EXCEEDED',
|
|
63
|
+
// 500 Internal Server Error
|
|
35
64
|
INTERNAL_SERVER_ERROR: 'INTERNAL_SERVER_ERROR',
|
|
65
|
+
// 503 Service Unavailable
|
|
36
66
|
SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE'
|
|
37
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* Error messages - User-friendly messages for each error code
|
|
70
|
+
*/
|
|
38
71
|
exports.ERROR_MESSAGES = {
|
|
39
72
|
[exports.ERROR_CODE.INVALID_PHONE_NUMBER]: "Phone number must be in E.164 format",
|
|
40
73
|
[exports.ERROR_CODE.MISSING_REQUIRED_FIELD]: "Required field is missing",
|
|
@@ -51,6 +84,9 @@ exports.ERROR_MESSAGES = {
|
|
|
51
84
|
[exports.ERROR_CODE.INTERNAL_SERVER_ERROR]: "An unexpected error occurred",
|
|
52
85
|
[exports.ERROR_CODE.SERVICE_UNAVAILABLE]: "Service temporarily unavailable"
|
|
53
86
|
};
|
|
87
|
+
/**
|
|
88
|
+
* HTTP status codes for each error
|
|
89
|
+
*/
|
|
54
90
|
exports.ERROR_STATUS_CODES = {
|
|
55
91
|
[exports.ERROR_CODE.INVALID_PHONE_NUMBER]: 400,
|
|
56
92
|
[exports.ERROR_CODE.MISSING_REQUIRED_FIELD]: 400,
|
|
@@ -67,26 +103,50 @@ exports.ERROR_STATUS_CODES = {
|
|
|
67
103
|
[exports.ERROR_CODE.INTERNAL_SERVER_ERROR]: 500,
|
|
68
104
|
[exports.ERROR_CODE.SERVICE_UNAVAILABLE]: 503
|
|
69
105
|
};
|
|
106
|
+
// ============================================================================
|
|
107
|
+
// VALIDATION HELPERS
|
|
108
|
+
// ============================================================================
|
|
109
|
+
/**
|
|
110
|
+
* E.164 phone number validation regex
|
|
111
|
+
*/
|
|
70
112
|
exports.E164_REGEX = /^\+[1-9]\d{1,14}$/;
|
|
113
|
+
/**
|
|
114
|
+
* Validate phone number format
|
|
115
|
+
*/
|
|
71
116
|
function validatePhoneNumber(phone) {
|
|
72
117
|
return exports.E164_REGEX.test(phone);
|
|
73
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Validate PLMN format
|
|
121
|
+
*/
|
|
74
122
|
function validatePLMN(plmn) {
|
|
123
|
+
// MCC: exactly 3 digits
|
|
75
124
|
if (!/^\d{3}$/.test(plmn.mcc))
|
|
76
125
|
return false;
|
|
126
|
+
// MNC: 2 or 3 digits
|
|
77
127
|
if (!/^\d{2,3}$/.test(plmn.mnc))
|
|
78
128
|
return false;
|
|
79
129
|
return true;
|
|
80
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Validate session info
|
|
133
|
+
*/
|
|
81
134
|
function validateSession(session) {
|
|
82
135
|
if (!session.session_key || session.session_key.length < 16)
|
|
83
136
|
return false;
|
|
137
|
+
// nonce is optional and stored in metadata if needed
|
|
84
138
|
return true;
|
|
85
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Validate use case
|
|
142
|
+
*/
|
|
86
143
|
function validateUseCase(useCase) {
|
|
87
144
|
return useCase === exports.USE_CASE.GET_PHONE_NUMBER ||
|
|
88
145
|
useCase === exports.USE_CASE.VERIFY_PHONE_NUMBER;
|
|
89
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Create error response helper
|
|
149
|
+
*/
|
|
90
150
|
function createErrorResponse(code, details, requestId) {
|
|
91
151
|
return {
|
|
92
152
|
code,
|
|
@@ -96,37 +156,60 @@ function createErrorResponse(code, details, requestId) {
|
|
|
96
156
|
details
|
|
97
157
|
};
|
|
98
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Get HTTP status code for error
|
|
161
|
+
*/
|
|
99
162
|
function getErrorStatusCode(code) {
|
|
100
163
|
return exports.ERROR_STATUS_CODES[code] || 500;
|
|
101
164
|
}
|
|
165
|
+
// ============================================================================
|
|
166
|
+
// TYPE GUARDS
|
|
167
|
+
// ============================================================================
|
|
168
|
+
/**
|
|
169
|
+
* Check if data is TS43 strategy data
|
|
170
|
+
*/
|
|
102
171
|
function isTS43Data(data) {
|
|
172
|
+
// Check for TS43 data structure - has protocol and data.dcql_query
|
|
103
173
|
return data &&
|
|
104
174
|
typeof data.protocol === 'string' &&
|
|
105
175
|
data.data &&
|
|
106
176
|
data.data.dcql_query;
|
|
107
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Check if data is Link strategy data
|
|
180
|
+
*/
|
|
108
181
|
function isLinkData(data) {
|
|
109
182
|
return data && data.url && typeof data.url === 'string';
|
|
110
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Check if response is an error
|
|
186
|
+
*/
|
|
111
187
|
function isErrorResponse(response) {
|
|
112
188
|
return response &&
|
|
113
189
|
typeof response.code === 'string' &&
|
|
114
190
|
typeof response.message === 'string';
|
|
115
191
|
}
|
|
192
|
+
// ============================================================================
|
|
193
|
+
// EXPORTS FOR CONVENIENCE
|
|
194
|
+
// ============================================================================
|
|
116
195
|
exports.default = {
|
|
196
|
+
// Constants
|
|
117
197
|
USE_CASE: exports.USE_CASE,
|
|
118
198
|
AUTHENTICATION_STRATEGY: exports.AUTHENTICATION_STRATEGY,
|
|
119
199
|
ERROR_CODE: exports.ERROR_CODE,
|
|
120
200
|
ERROR_MESSAGES: exports.ERROR_MESSAGES,
|
|
121
201
|
ERROR_STATUS_CODES: exports.ERROR_STATUS_CODES,
|
|
122
202
|
E164_REGEX: exports.E164_REGEX,
|
|
203
|
+
// Validators
|
|
123
204
|
validatePhoneNumber,
|
|
124
205
|
validatePLMN,
|
|
125
206
|
validateSession,
|
|
126
207
|
validateUseCase,
|
|
208
|
+
// Type guards
|
|
127
209
|
isTS43Data,
|
|
128
210
|
isLinkData,
|
|
129
211
|
isErrorResponse,
|
|
212
|
+
// Helpers
|
|
130
213
|
createErrorResponse,
|
|
131
214
|
getErrorStatusCode
|
|
132
215
|
};
|